/* ============================================================
   Mas del Cullou – Mockup v1
   Design-Tokens PROVISORISCH (bis Styleguide/Logo final)
   ============================================================ */

/* ---------- Fonts (lokal, keine externen Requests) ---------- */
@font-face {
  font-family: 'Fraunces';
  src: url('../fonts/fraunces-latin.woff2') format('woff2');
  font-weight: 300 500;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Fraunces';
  src: url('../fonts/fraunces-latin-ext.woff2') format('woff2');
  font-weight: 300 500;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Inter';
  src: url('../fonts/inter-latin.woff2') format('woff2');
  font-weight: 400 500;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Inter';
  src: url('../fonts/inter-latin-ext.woff2') format('woff2');
  font-weight: 400 500;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ---------- Tokens ---------- */
:root {
  --creme: #F7F3E8;
  --white: #FFFFFF;
  --ink: #10201B;          /* Petrol-Schwarz */
  /* Der Footer legt oben eine 50-%-Schwarzauflage ueber --ink (.site-footer::before).
     Das ergibt genau diesen Ton. Die Flaeche hinter allem traegt ihn ebenfalls,
     sonst entsteht an der Footer-Oberkante eine sichtbare Naht. */
  --ink-tief: #08100E;
  --petrol: #1E3A34;       /* Akzent */
  --line: #D8D2C4;
  --serif: 'Fraunces', Georgia, serif;
  --sans: 'Inter', -apple-system, 'Helvetica Neue', Arial, sans-serif;
  --header-h: 76px;
  --footer-h: clamp(380px, 62vh, 620px);
  --pad: clamp(20px, 4vw, 64px);
}

/* ---------- Reset / Basis ---------- */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
/* Die Flaeche, die beim Ueberziehen am Rand sichtbar wird (Rubber-Band auf
   iOS), nimmt die Hintergrundfarbe der Wurzel. Stand die auf Creme, kam beim
   Weiterziehen unter dem dunklen Footer wieder Beige hoch - der Raum, in den
   sich das Blatt hebt, endete also mitten im Nichts (K-Rueckmeldung 23.08.).
   Die Wurzel traegt deshalb --ink-tief. Warum nicht --ink: der Footer beginnt
   an seiner Oberkante mit einer 50-%-Schwarzauflage (.site-footer::before), ist
   dort also deutlich dunkler als --ink. Zieht man ueber das Ende hinaus, oeffnet
   sich zwischen Seitenunterkante und Footer-Oberkante eine Luecke, und an deren
   unterer Kante traf #10201B auf #08100E - als Streifen sichtbar (24.08.).
   --ink-tief ist genau der Ton der Footer-Oberkante, damit die Kante verschwindet;
   nach unten hellt der Footer von dort aus ohnehin auf.
   `body` muss dafuer durchsichtig sein - hat der Body eine eigene Farbe,
   gewinnt die und faerbt die Flaeche mit. Sichtbar ist der Body-Grund sonst
   nirgends: `.page` malt seine Creme selbst, darueber liegt nur der feste
   Header, darunter der feste Footer. */
html {
  scroll-behavior: smooth;
  background: var(--ink-tief);
}
body {
  font-family: var(--sans);
  font-weight: 400;
  font-size: 16px;
  line-height: 1.6;
  color: var(--ink);
  background: transparent;
  -webkit-font-smoothing: antialiased;
}
img { display: block; max-width: 100%; }
a { color: inherit; }
ul { list-style: none; }
button { font: inherit; cursor: pointer; }

/* Scroll-Snap nur Desktop (auf Mobile bewusst deaktiviert) */
@media (min-width: 900px) {
  html { scroll-snap-type: y proximity; }
  .snap { scroll-snap-align: start; }
}

/* ---------- Typo-Helfer ---------- */
.kicker {
  font-family: var(--sans);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: uppercase;
}
.display {
  font-family: var(--serif);
  font-weight: 300;
  line-height: 0.95;
  letter-spacing: 0.01em;
}
.textlink {
  display: inline-block;
  font-family: var(--sans);
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  text-decoration: none;
  padding-bottom: 4px;
  border-bottom: 1px solid currentColor;
  transition: opacity 0.25s ease;
}
.textlink:hover { opacity: 0.6; }
.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ============================================================
   Intro (Logo-Vorhang) – pro Session einmal, reduced-motion: aus
   ============================================================ */
.intro {
  position: fixed;
  inset: 0;
  /* Ueber Header (95) und Overlay-Menue (100), unter dem Seitenwechsel-
     Vorhang (120): waehrend des Intros darf die Nav nicht durchscheinen. */
  z-index: 110;
  background: var(--ink);
  display: grid;
  place-items: center;
  /* 22.08. um 30 % gekuerzt (K-Entscheidung), war 0.9s */
  transition: transform 0.63s cubic-bezier(0.77, 0, 0.18, 1), visibility 0s linear 0.63s;
}
html.intro-done .intro { transform: translateY(-101%); visibility: hidden; }
html.no-intro .intro { display: none; }

.intro-logo { width: clamp(120px, 18vw, 200px); height: auto; color: var(--creme); }
/* Die 5 Logo-Elemente zeichnen sich gestaffelt (Wipe je Element).
   Alle Werte 22.08. um 30 % gekuerzt (K-Entscheidung); der Rhythmus bleibt,
   nur der Ablauf ist schneller. Vorher: 0.5s Dauer, Verzoegerungen bis 0.60s. */
.intro-logo path { animation: 0.35s cubic-bezier(0.3, 0, 0.2, 1) both; }
@keyframes wipe-down  { from { clip-path: inset(0 0 100% 0); } to { clip-path: inset(0 0 0 0); } }
@keyframes wipe-right { from { clip-path: inset(0 100% 0 0); } to { clip-path: inset(0 0 0 0); } }
.intro-logo .p-left   { animation-name: wipe-down;  animation-delay: 0.035s; }
.intro-logo .p-top    { animation-name: wipe-right; animation-delay: 0.14s; }
.intro-logo .p-bottom { animation-name: wipe-right; animation-delay: 0.245s; }
.intro-logo .p-inner  { animation-name: wipe-down;  animation-delay: 0.35s; }
.intro-logo .p-right  { animation-name: wipe-down;  animation-delay: 0.42s; }

/* ============================================================
   Header / Navigation
   ============================================================ */
.site-header {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 95;
  height: var(--header-h);
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 var(--pad);
  color: var(--creme);
  transition: background 0.35s ease, color 0.35s ease, box-shadow 0.35s ease;
}
.site-header::before {
  /* Scrim, damit Nav auf Bildern lesbar bleibt */
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(to bottom, rgba(16, 32, 27, 0.45), rgba(16, 32, 27, 0));
  pointer-events: none;
  transition: opacity 0.35s ease;
}
.site-header.scrolled { background: rgba(247, 243, 232, 0.92); color: var(--ink); box-shadow: 0 1px 0 var(--line); }
.site-header.scrolled::before { opacity: 0; }
.site-header > * { position: relative; }

.brand {
  display: flex;
  align-items: center;
  gap: 12px;
  text-decoration: none;
}
.brand svg { width: 36px; height: 36px; fill: currentColor; }
.brand-name {
  font-family: var(--sans);
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.26em;
  text-transform: uppercase;
}
.header-right { display: flex; align-items: center; gap: 22px; }

/* Buchungs-CTA im Header (Unterkunftsseiten): immer präsent, Ghost-Stil
   folgt via currentColor beiden Header-Zuständen */
.book-cta {
  display: inline-block;
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  text-decoration: none;
  border: 1px solid currentColor;
  padding: 10px 18px;
  transition: background 0.25s ease, color 0.25s ease, opacity 0.35s ease, visibility 0s linear 0s;
}
/* In der Buchungs-Sektion angekommen: CTA zieht sich zurück (JS setzt .is-away) */
.book-cta.is-away {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: background 0.25s ease, color 0.25s ease, opacity 0.35s ease, visibility 0s linear 0.35s;
}
/* Nur mit echtem Zeiger: auf Touch bleibt :hover nach dem Tippen haengen,
   der Knopf behielt dann seinen Hover-Anstrich, bis man erneut tippte. */
@media (hover: hover) {
  .book-cta:hover { background: var(--creme); color: var(--ink); }
  .site-header.scrolled .book-cta:hover { background: var(--ink); color: var(--creme); }
}
.book-short { display: none; }
@media (max-width: 720px) {
  .book-long { display: none; }
  .book-short { display: inline; }
  .book-cta { padding: 9px 14px; }
  /* Der Olivenoel-Knopf entfaellt mobil (K-Feedback 22.08.): das Oel ist
     ueber Menue und Startseiten-Teaser erreichbar, im schmalen Header
     konkurrierte er mit Wortmarke, Sprachwahl und Burger.
     Desktop unveraendert. */
  .book-cta--oel { display: none; }
  /* Platz schaffen: Wortmarke weicht, wenn ein CTA mit im Header sitzt.
     :has() zaehlt nur noch die mobil sichtbaren CTAs - der Oel-Knopf faellt
     hier, der Shop-Knopf wandert in die untere Leiste. Bliebe einer von
     beiden in der Liste, verschwaende die Wortmarke ohne Grund. */
  .site-header:has(.book-cta:not(.book-cta--oel):not(.book-cta--shop)) .brand-name { display: none; }
  .header-right, .menu-top-right { gap: 16px; }
}

.lang {
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.14em;
}
.lang a { text-decoration: none; opacity: 0.5; }
.lang a.active { opacity: 1; }
.burger {
  background: none;
  border: 0;
  color: inherit;
  display: grid;
  gap: 6px;
  padding: 8px 0;
}
.burger span { display: block; width: 30px; height: 1.5px; background: currentColor; }

/* ---------- Fullscreen-Menü ---------- */
.menu-overlay {
  position: fixed;
  inset: 0;
  z-index: 100;
  background: var(--ink);
  color: var(--creme);
  transform: translateY(-102%);
  transition: transform 0.65s cubic-bezier(0.77, 0, 0.18, 1);
  display: flex;
  flex-direction: column;
  padding: 0 var(--pad);
  overflow-y: auto;
}
body.menu-open .menu-overlay { transform: none; }
body.menu-open { overflow: hidden; }

.menu-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: var(--header-h);
  flex-shrink: 0;
}
/* Gleiche Reihenfolge und Abstaende wie .header-right, damit der
   Schliessen-Button exakt auf dem Burger liegt, den er ersetzt */
.menu-top-right { display: flex; align-items: center; gap: 22px; }
.menu-close {
  background: none;
  border: 0;
  color: inherit;
  font-size: 26px;
  line-height: 1;
  font-weight: 300;
  /* Breite und Innenabstand wie .burger: rechte Kante buendig, Glyphe mittig */
  width: 30px;
  padding: 8px 0;
  display: grid;
  place-items: center;
}
.menu-wordmark {
  font-family: var(--sans);
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  text-decoration: none;
  transition: opacity 0.2s ease;
}
.menu-wordmark:hover { opacity: 0.65; }
.menu-main {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  max-width: 880px;
  width: 100%;
  margin: 0 auto;
  padding: 32px 0;
}
.menu-item { border-top: 1px solid rgba(247, 243, 232, 0.18); padding: clamp(18px, 3vh, 34px) 0; }
.menu-item:last-child { border-bottom: 1px solid rgba(247, 243, 232, 0.18); }
.menu-item-head {
  display: flex;
  align-items: baseline;
  gap: 22px;
  text-decoration: none;
  transition: opacity 0.25s ease;
}
.menu-item-head:hover { opacity: 0.65; }
.menu-item-head:focus-visible { outline: 2px solid var(--creme); outline-offset: 4px; }
/* Eintraege ohne Unterpunkte: der Link nimmt die ganze Zeile inklusive
   Polsterung ein, damit auch neben Titel und Kicker geklickt werden kann. */
.menu-item--voll { padding: 0; }
.menu-item--voll .menu-item-head { display: block; padding: clamp(18px, 3vh, 34px) 0; }
.menu-item-zeile { display: flex; align-items: baseline; gap: 22px; }
.menu-num { font-size: 12px; letter-spacing: 0.2em; opacity: 0.55; }
.menu-title { font-family: var(--serif); font-weight: 300; font-size: clamp(30px, 5.4vw, 56px); line-height: 1.05; }
.menu-kicker { display: block; margin-top: 8px; margin-left: 44px; font-size: 11px; letter-spacing: 0.24em; text-transform: uppercase; opacity: 0.5; }
.menu-sub { margin: 16px 0 0 44px; display: grid; gap: 8px; }
.menu-sub a {
  text-decoration: none;
  font-size: 15px;
  opacity: 0.8;
  transition: opacity 0.2s ease;
}
.menu-sub a:hover { opacity: 1; }
.menu-sub span { opacity: 0.45; font-size: 13px; margin-left: 8px; }
.menu-bottom {
  flex-shrink: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 10px 28px;
  padding: 26px 0 34px;
  font-size: 13px;
}
.menu-bottom a { text-decoration: none; opacity: 0.65; transition: opacity 0.2s ease; }
.menu-bottom a:hover { opacity: 1; }

/* ============================================================
   Hero
   ============================================================ */
.hero {
  position: relative;
  height: 100vh;
  height: 100svh;
  overflow: hidden;
  display: flex;
  align-items: flex-end;
  color: var(--creme);
}
.hero-media { position: absolute; inset: 0; }
.hero-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Kein Ken-Burns mehr (K-Entscheidung 21.08.): der langsame Dauerzoom las
     sich am Seitenanfang so, als passiere beim Scrollen etwas Eigenes, statt
     dass Kapitel 2 hochkommt. Das Hero-Bild steht jetzt still, die einzige
     Bewegung kommt vom Scrollen selbst. */
}
.hero-media::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, rgba(16, 32, 27, 0.55) 0%, rgba(16, 32, 27, 0.08) 45%, rgba(16, 32, 27, 0.15) 100%);
}
.hero-content {
  position: relative;
  z-index: 2;
  padding: var(--pad);
  padding-bottom: clamp(48px, 10vh, 110px);
  max-width: 1100px;
}
.hero-content h1 {
  font-family: var(--serif);
  font-weight: 300;
  font-size: clamp(38px, 6.2vw, 88px);
  line-height: 1.04;
  margin: 14px 0 30px;
}
.btn {
  display: inline-block;
  background: var(--creme);
  color: var(--ink);
  text-decoration: none;
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  padding: 16px 34px;
  transition: background 0.25s ease;
}
.btn:hover { background: var(--white); }
/* Variante fuer helle Flaechen: der gefuellte .btn ist Creme auf Creme und
   damit im Textblock unsichtbar. */
.btn--linie {
  background: none;
  border: 1px solid var(--ink);
  color: var(--ink);
  padding: 14px 28px;
}
.btn--linie:hover { background: var(--ink); color: var(--creme); }
.umgebung-cta { margin-top: 30px; }

/* ============================================================
   Kapitel-Sektionen (Startseite)
   ============================================================ */
.chapter {
  position: relative;
  height: 100vh;
  height: 100svh;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  color: var(--creme);
}
.chapter-media { position: absolute; inset: 0; }
.chapter-media img { width: 100%; height: 100%; object-fit: cover; }
.chapter-media::after {
  content: '';
  position: absolute;
  inset: 0;
  background: rgba(16, 32, 27, 0.38);
}
.chapter-media.ph::after { content: none; }
.chapter-content { position: relative; z-index: 2; padding: var(--pad); max-width: 900px; }
.chapter-word {
  font-family: var(--serif);
  font-weight: 300;
  font-size: clamp(56px, 10vw, 150px);
  line-height: 1;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  margin: 12px 0 18px;
  /* Wörter bleiben einzeilig und mittig; die Größe deckelt die Media-Query
     unten, sonst läuft das längste Wort (GRIECHENLAND) mobil aus dem Bild */
  width: max-content;
  max-width: none;
  white-space: nowrap;
  margin-left: 50%;
  transform: translateX(-50%);
}
/* Auf schmalen Schirmen greift sonst der 56-px-Boden der clamp() oben und
   GRIECHENLAND (12 Zeichen, einzeilig) wird links und rechts abgeschnitten */
@media (max-width: 620px) {
  .chapter-word { font-size: clamp(28px, 10.5vw, 56px); }
}
.chapter-content p { max-width: 520px; margin: 0 auto 28px; font-size: 15px; opacity: 0.92; }
.chapter-links { display: flex; gap: 28px; justify-content: center; flex-wrap: wrap; }

/* Foto-Platzhalter (Farbflächen in Palette-Tönen) */
.ph {
  background: var(--petrol);
  display: flex;
  align-items: flex-end;
  justify-content: flex-start;
}
.ph::before {
  content: attr(data-label);
  font-family: var(--sans);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgba(247, 243, 232, 0.6);
  padding: 14px 16px;
  border: 1px dashed rgba(247, 243, 232, 0.35);
  margin: 16px;
}
.ph--light { background: #E9E2D0; }
.ph--light::before { color: rgba(16, 32, 27, 0.55); border-color: rgba(16, 32, 27, 0.3); }
.ph--deep { background: var(--ink); }

/* Einlauf-Animation (IntersectionObserver setzt .in) */
.reveal { opacity: 0; transform: translateY(26px) scale(0.985); transition: opacity 0.9s ease, transform 0.9s cubic-bezier(0.22, 0.6, 0.2, 1); }
.reveal.in { opacity: 1; transform: none; }
.reveal-up { opacity: 0; transform: translateY(70px); transition: opacity 1s ease, transform 1s cubic-bezier(0.22, 0.6, 0.2, 1); }
.reveal-up.in { opacity: 1; transform: none; }

/* ============================================================
   Scroll-Szenen (Startseite): gepinnte Kapitel, Übergänge per JS
   Fallback ohne JS / reduced-motion: normaler Stapel (Default)
   ============================================================ */
.scene { position: relative; }
.scene-shade {
  position: absolute;
  inset: 0;
  z-index: 4;
  background: var(--ink);
  opacity: 0;
  pointer-events: none;
}

/* Aktiv nur, wenn JS die Klasse setzt */
html.scenes-on .scenes-stage {
  position: sticky;
  top: 0;
  /* Bewusst die GROSSE Viewport-Höhe (lvh), nicht svh.
     Mit svh ist die Bühne so hoch wie der Viewport bei ausgefahrener
     URL-Leiste. Sobald die beim Scrollen einfährt, wird der Viewport größer
     als die Bühne – unter der Szene blitzt der nächste Abschnitt durch und
     das Hero-Bild scheint wegzuscrollen, bevor Kapitel 2 hochkommt.
     Mit lvh füllt die Bühne immer; der Preis ist, dass bei sichtbarer
     URL-Leiste die unteren ~60 px verdeckt sind. Bei randlosen Bildszenen
     ist das der deutlich kleinere Kompromiss.
     JS misst die Bühne selbst (siehe main.js, measure) – die Einheit hier
     und die Partitur dort können also nicht auseinanderlaufen. */
  height: 100vh;
  height: 100lvh;
  overflow: hidden;
}
/* Die Kehrseite von lvh, konkret gemacht: beim ersten Blick auf dem Handy ist
   nur 100svh zu sehen, die Differenz sind Safaris ein- und ausfahrende
   Leisten. Alles, was am unteren Rand der Hero-Szene sitzt, liegt dadurch
   hinter der Bedienleiste – ausgerechnet der CTA und die Scroll-Spur, also
   die beiden Elemente, die sagen, dass es weitergeht (K-Rückmeldung 28.08.,
   iOS Safari). Sie rücken um die Leistenhöhe nach oben; die Bühne selbst
   bleibt lvh, an der Bildwirkung ändert sich nichts.
   Bewusst statisch über svh und nicht dynamisch über dvh: dvh ändert sich
   während des Scrollens, und ein wandernder Knopf im Moment des
   Szenenwechsels ist schlimmer als einer, der bei eingefahrener Leiste etwas
   höher steht. Am Desktop ist der Term 0, dort ändert sich gar nichts. */
/* Erst 0px, dann die Rechnung: ein Browser ohne svh/lvh verwirft die
   zweite Zeile und behaelt die 0 – ohne den Fallback fiele die ganze
   padding-bottom-Deklaration aus und der CTA saesse falsch. */
html.scenes-on { --leisten: 0px; --leisten: calc(100lvh - 100svh); }
html.scenes-on .scene--hero .hero-content {
  padding-bottom: calc(clamp(48px, 10vh, 110px) + var(--leisten));
}
html.scenes-on .scene {
  position: absolute;
  inset: 0;
  height: 100%;
}
/* Eigene Stacking-Kontexte, damit Inhalte einer Szene nie über die nächste ragen */
html.scenes-on .scene--hero { z-index: 1; }
html.scenes-on .scene--es { z-index: 2; }
html.scenes-on .scene--gr { z-index: 3; }
html.scenes-on .scene--bg { z-index: 4; }
/* Startzustände vor dem ersten JS-Frame */
html.scenes-on .scene--es { transform: translate3d(0, 100%, 0); will-change: transform; }
html.scenes-on .scene--gr,
html.scenes-on .scene--bg {
  clip-path: polygon(103% -2%, 103% -2%, 103% 102%, 103% 102%);
  will-change: clip-path;
}
html.scenes-on .scene--gr .chapter-media,
html.scenes-on .scene--bg .chapter-media { will-change: transform, filter; }
/* Kapitel-Text blendet erst ein, wenn die Szene weitgehend deckt (JS setzt .in) */
html.scenes-on .scene .chapter-content {
  opacity: 0;
  transform: translateY(26px) scale(0.985);
  transition: opacity 0.9s ease, transform 0.9s cubic-bezier(0.22, 0.6, 0.2, 1);
}
html.scenes-on .scene .chapter-content.in { opacity: 1; transform: none; }

/* ============================================================
   Scroll-Indikator: senkrechte Spur, unten mittig
   Ersetzt die waagerechte Segmentleiste (K-Entscheidung 22.08.): vier
   liegende Striche wurden als Zierde gelesen, nicht als Aufforderung, zu
   scrollen. Ein senkrechter Strich zeigt die Richtung schon durch seine Lage.

   Zwei Zustände in einem Element:
   1. vor dem ersten Scrollen läuft ein heller Abschnitt nach unten
   2. danach zeigt die Füllung von oben, wie weit die vier Kapitel gelaufen
      sind (renderScenes() skaliert sie über scaleY)
   Der Umschaltpunkt hängt an .hat-gescrollt, das main.js einmal setzt und
   nicht zurücknimmt. Beides gleichzeitig wäre unruhig.

   Die Spur bleibt über alle vier Kapitel stehen, deshalb liegt sie in der
   Bühne und nicht in der Hero-Szene – die Szenen schieben sich übereinander.
   ============================================================ */
.scrollcue { display: none; }
html.scenes-on .scrollcue {
  display: block;
  position: absolute;
  left: 50%;
  bottom: calc(26px + var(--leisten));
  z-index: 6;
  width: 1.5px;
  --cue-hoehe: 64px;
  height: var(--cue-hoehe);
  transform: translateX(-50%);
  overflow: hidden;
  background: rgba(247, 243, 232, 0.38);
  /* Der Hero ist ein helles Foto (Meer und Himmel) – eine cremefarbene
     Haarlinie verschwindet darauf fast. Weicher dunkler Schatten statt
     kräftigerer Farbe, wie bei den Kartenbeschriftungen. */
  filter: drop-shadow(0 0 3px rgba(16, 32, 27, 0.6));
}
.scrollcue i {
  position: absolute;
  top: 0;
  left: 0;
  width: 1.5px;
  background: var(--creme);
}
/* 1. Laufender Abschnitt, nur solange noch nicht gescrollt wurde */
.scrollcue-lauf {
  height: 22px;
  animation: scrollcue 2.2s cubic-bezier(0.65, 0, 0.35, 1) infinite;
}
.scenes.hat-gescrollt .scrollcue-lauf { display: none; }
@keyframes scrollcue {
  0%   { transform: translateY(-22px); opacity: 0; }
  20%  { opacity: 1; }
  70%  { opacity: 1; }
  100% { transform: translateY(var(--cue-hoehe)); opacity: 0; }
}
/* 2. Füllstand, erst ab dem ersten Scrollen sichtbar */
.scrollcue-fuell {
  height: 100%;
  opacity: 0;
  transform: scaleY(0);
  transform-origin: top center;
  transition: opacity 0.4s ease;
}
.scenes.hat-gescrollt .scrollcue-fuell { opacity: 1; }
/* Bei „Bewegung reduzieren“ steht der Abschnitt still, statt zu laufen:
   die Szenen laufen dort weiter (K-Entscheidung 21.08.), gescrollt werden
   muss also genauso – nur ohne Laufbewegung. */
@media (prefers-reduced-motion: reduce) {
  .scrollcue-lauf { animation: none; height: 100%; opacity: 0.55; }
}
/* Mobil kürzer: der Hero-CTA endet rund 80 px über der Unterkante,
   eine 64-px-Spur bei 26 px Abstand stieße dagegen. Die Laufstrecke der
   Animation haengt an --cue-hoehe, damit sie nicht doppelt gepflegt wird. */
@media (max-width: 900px) {
  html.scenes-on .scrollcue { --cue-hoehe: 46px; bottom: calc(20px + var(--leisten)); }
}

/* ============================================================
   Familien-Sektion (Ghost-Typo)
   ============================================================ */
.family {
  position: relative;
  background: var(--creme);
  padding: clamp(110px, 18vh, 200px) var(--pad) clamp(80px, 12vh, 150px);
  overflow: hidden;
}
.ghost {
  position: absolute;
  top: 6%;
  left: 50%;
  transform: translateX(-50%);
  z-index: 0;
  font-family: var(--serif);
  font-weight: 300;
  font-size: clamp(90px, 17vw, 280px);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: rgba(16, 32, 27, 0.05);
  white-space: nowrap;
  pointer-events: none;
  user-select: none;
}
.family-inner { position: relative; max-width: 680px; margin: 0 auto; text-align: center; }
.family-inner h2 { font-family: var(--serif); font-weight: 300; font-size: clamp(30px, 4vw, 52px); line-height: 1.15; margin: 14px 0 22px; }
.family-inner p { font-size: 16px; margin-bottom: 18px; }
.family-inner p:last-child { margin-bottom: 0; }

/* Text und Foto stehen NEBENEINANDER, nicht gestapelt.
   Gestapelt war das Foto das einzige gerahmte Bild der Seite: die vier Kapitel
   laufen als Vollbild, der Oel-Teaser als 50/50-Split ueber die ganze Breite -
   ein 1100 px breiter Kasten in der Cremeflaeche war eine dritte Layoutsprache,
   und dahinter blieb bis zum naechsten Abschnitt ein Loch. Als Paar liest sich
   der Abschnitt als Komposition und uebergibt direkt an den Split.
   Unter 900 px bleibt es einspaltig, Text zuerst. */
.family-grid {
  position: relative;
  max-width: 1100px;
  margin: 0 auto;
  display: grid;
  gap: clamp(34px, 5vw, 80px);
  align-items: center;
}
@media (min-width: 901px) {
  .family-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 460px); }
  /* Mittig gesetzt lief das Geisterwort quer ueber Kopfzeile UND Foto und sah
     nach Versehen aus. Es gehoert hinter die Textspalte, nicht ueber das Bild. */
  .family .ghost {
    left: var(--pad);
    transform: none;
    font-size: clamp(90px, 11vw, 190px);
  }
  /* Zentriert war richtig, solange der Text allein stand. Neben einem Bild
     braucht er eine Kante, sonst franst die Paarung aus. */
  .family-inner { max-width: 560px; margin: 0; text-align: left; }
}
.family-bild { position: relative; margin: 0; }
/* 4:3 aus einem 16:9-Original: der Ausschnitt nimmt die Seiten weg, nicht oben
   und unten. Die Familie steht dadurch groesser im Bild, und der leere Beton
   vor ihr faellt weg. Der Fokus liegt leicht oberhalb der Mitte, dort stehen
   die drei. */
.family-bild img {
  display: block;
  width: 100%;
  /* Ohne height: auto gewinnt das height-Attribut des <img> (1440) als
     Praesentationshinweis - beide Masse waeren dann gesetzt und
     aspect-ratio bliebe wirkungslos. Das Bild stand 1440 px hoch da. */
  height: auto;
  /* Das Bild liegt bereits als 3:4-Ausschnitt vor, geschnitten aus dem
     4032er-Original. Kurz gab es den Ausschnitt stattdessen per object-fit
     hier im CSS - das Ergebnis war unscharf: der Browser waehlt seine
     Variante nach `sizes`, also nach der Kastenbreite, zeigt davon aber nur
     den Ausschnitt. Bei 40 % sichtbarer Breite blieb von einer 640er-Datei
     rund ein Viertel uebrig. Wer beschneidet, beschneidet die Datei.
     aspect-ratio bleibt trotzdem stehen: es haelt den Platz frei, bevor das
     Bild geladen ist. */
  aspect-ratio: 3 / 4;
}
.family-bild figcaption {
  margin-top: 14px;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  opacity: 0.5;
}
/* Mobil steht der Text der Sektion mittig, die Bildunterschrift gehoert dann
   mit in die Achse. Am Desktop bleibt sie linksbuendig unter dem Bild.
   Bewusst als max-width-Regel HINTER dem Grundfall: als Gegenstueck im
   901er-Block stand sie vor dieser Regel und verlor bei gleicher
   Spezifitaet - die Unterschrift stand dann auch am Desktop mittig. */
@media (max-width: 900px) {
  .family-bild figcaption { text-align: center; }
}

/* Platzhalter-Hinweis in eckigen Klammern */
.todo { color: var(--petrol); opacity: 0.75; font-style: italic; }

/* ============================================================
   Öl- und Label-Teaser
   ============================================================ */
.teaser {
  display: grid;
  grid-template-columns: 1fr 1fr;
  min-height: 78vh;
  background: var(--white);
}
.teaser-media { aspect-ratio: auto; min-height: 380px; }
/* Bis 23.08. lag hier nur eine Platzhalterflaeche (.ph), die ihre Groesse
   selbst mitbrachte. Mit echtem Foto braucht die Zelle diese Regel, sonst
   steht das Bild in Naturgroesse im Raster und sprengt die Spalte. */
.teaser-media img { display: block; width: 100%; height: 100%; object-fit: cover; }
/* Zwei Teaser-Bloecke direkt untereinander (Ernte, dann Bestellen) lesen sich
   mit dem Bild immer links wie derselbe Block zweimal. Der Modifier dreht nur
   am Desktop; mobil bleibt es einspaltig und das Bild zuerst, weil die
   Reihenfolge dort aus dem Markup kommt. */
@media (min-width: 901px) {
  .teaser--bildrechts .teaser-media { grid-column: 2; grid-row: 1; }
  .teaser--bildrechts .teaser-body  { grid-column: 1; grid-row: 1; }
}
.teaser-body {
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: clamp(48px, 6vw, 110px);
}
.teaser-body h2 { font-family: var(--serif); font-weight: 300; font-size: clamp(30px, 3.6vw, 50px); line-height: 1.1; margin: 14px 0 20px; }
.teaser-body p { max-width: 440px; margin-bottom: 30px; }
@media (max-width: 900px) {
  .teaser { grid-template-columns: 1fr; min-height: 0; }
  .teaser-media { min-height: 300px; }
}

.label-teaser {
  background: var(--ink);
  color: var(--creme);
  text-align: center;
  padding: clamp(90px, 14vh, 160px) var(--pad);
}
.label-teaser h2 { font-family: var(--serif); font-weight: 300; font-size: clamp(34px, 5vw, 64px); margin: 14px 0 18px; }
.label-teaser p { max-width: 480px; margin: 0 auto 30px; opacity: 0.85; }

/* Beispiel-Looks unter dem Teaser. Hochformat, weil Modefotos so kommen. */
.label-gallery {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: clamp(8px, 1vw, 16px);
  max-width: 1100px;
  margin: clamp(40px, 6vh, 68px) auto 0;
}
/* 2:3 statt 3:4: die gerahmten Poster kommen genau in diesem Format, bei 3:4
   schnitt der Zuschnitt ihnen den Rahmen oben und unten ab – das las sich wie
   ein Fehler. Die beiden Studio-Aufnahmen vertragen den Beschnitt seitlich. */
.label-gallery > * { aspect-ratio: 2 / 3; }
.label-gallery img { width: 100%; height: 100%; object-fit: cover; }
/* Die Platzhalter-Regeln sind mit den echten Fotos entfallen (21.08.) –
   so war es im Kommentar auch angekündigt. */
@media (max-width: 720px) {
  .label-gallery { grid-template-columns: repeat(2, 1fr); }
}

/* Schlanke, mittige Segmente: die Zahnheilkunde-Notiz der Startseite und das
   Schlussband der Oel-Seite. Beide bewusst kleiner als ein Teaser - sie sollen
   nicht mit den Bildblöcken darueber konkurrieren. */
.dental,
.abschluss {
  background: var(--creme);
  text-align: center;
  padding: clamp(64px, 9vh, 110px) var(--pad);
}
.dental h2,
.abschluss h2 {
  font-family: var(--serif);
  font-weight: 300;
  font-size: clamp(24px, 2.8vw, 38px);
  line-height: 1.15;
  margin: 12px 0 14px;
}
.dental p {
  max-width: 460px;
  margin: 0 auto 24px;
  font-size: 15px;
  opacity: 0.85;
}
.abschluss p {
  max-width: 440px;
  margin: 0 auto 26px;
  font-size: 15px;
  opacity: 0.85;
}
/* Mit Flaschenbild (Oel-Seite): Bild links, Text rechts, beides mittig
   zueinander. Das Band bleibt ein Band - das Bild ist ein schmales
   Hochformat, kein zweiter 50/50-Split wie die Ernte-Sektion darueber.
   Ohne Bild (Feld leer) gilt weiter die zentrierte Fassung oben. */
.abschluss--bild { text-align: left; }
.abschluss--bild .abschluss-inner {
  max-width: 900px;
  margin: 0 auto;
  display: grid;
  grid-template-columns: minmax(0, 380px) minmax(0, 1fr);
  gap: clamp(32px, 5vw, 72px);
  align-items: center;
}
.abschluss--bild .abschluss-media img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 5;
  object-fit: cover;
}
.abschluss--bild p { margin-left: 0; }
@media (max-width: 760px) {
  .abschluss--bild { text-align: center; }
  .abschluss--bild .abschluss-inner { grid-template-columns: 1fr; }
  .abschluss--bild .abschluss-media { max-width: 300px; margin: 0 auto; }
  .abschluss--bild p { margin-left: auto; }
}

/* ============================================================
   Filmstreifen der Oel-Seite: drei Hochformat-Clips
   ============================================================
   Dunkel, weil die Sektion zwischen dem weissen Ernte-Teaser und dem cremen
   Schlussband sitzt - creme auf creme haette beide zu einem Block verklebt.
   Derselbe Grund, aus dem die Karte der Uebersicht auf --ink liegt.

   9:16 ist nicht Deko, sondern das Format des Materials: die Familie filmt
   mit dem Handy hochkant. Ein 16:9-Zuschnitt daraus haette von jeder Aufnahme
   knapp zwei Drittel weggeschnitten.

   Mobil wird der Streifen waagerecht scrollbar statt einspaltig gestapelt:
   drei Hochformate untereinander sind bei 390 px rund 1900 px Scrollstrecke,
   und die Sektion ist eine Nebenerzaehlung, kein Kapitel. Dieselbe Loesung
   wie bei der Vergleichstabelle der Uebersicht. */
.film {
  background: var(--ink);
  color: var(--creme);
}
.film .kicker { opacity: 0.6; }
.film h2 {
  font-family: var(--serif);
  font-weight: 300;
  font-size: clamp(28px, 3.6vw, 48px);
  line-height: 1.12;
  margin: 12px 0 18px;
}
.film-vorspann { max-width: 46ch; font-size: 15px; opacity: 0.78; }

.filmstreifen {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(16px, 2.4vw, 30px);
  margin-top: clamp(34px, 5vh, 60px);
}
.film-clip { margin: 0; min-width: 0; }
.film-buehne {
  position: relative;
  aspect-ratio: 9 / 16;
  overflow: hidden;
  /* Etwas heller als der Grund: bevor das Video da ist, steht hier das
     Poster - faellt auch das aus, bleibt eine Flaeche statt eines Lochs. */
  background: var(--petrol);
}
/* Video und Poster fuellen die Buehne. `object-fit` gilt in allen Engines
   auch fuer das poster-Attribut, die Kachel bleibt also formatgleich. */
.film-buehne video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.film-text {
  display: flex;
  gap: 12px;
  margin-top: 16px;
  font-size: 14px;
  line-height: 1.5;
  opacity: 0.8;
}
.film-nr {
  flex: none;
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.14em;
  opacity: 0.55;
  padding-top: 2px;
}

@media (max-width: 760px) {
  /* Waagerechter Streifen mit Einrasten. Das negative Margin zieht ihn bis
     an beide Seitenraender, damit die dritte Kachel sichtbar angeschnitten
     ist - sonst liest sich der Streifen wie zwei Kacheln und Schluss. */
  .filmstreifen {
    display: flex;
    gap: 14px;
    margin-inline: calc(var(--pad) * -1);
    padding-inline: var(--pad);
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    /* Ohne scroll-padding rastet die erste Kachel buendig am Rand des
       Scrollports ein und schiebt dabei die eigene Innenpolsterung aus dem
       Bild - der Streifen klebte links an der Bildschirmkante, waehrend die
       Bildunterschriften noch eingerueckt standen. Snap-Punkte richten sich
       nach scroll-padding, nicht nach padding. */
    scroll-padding-inline: var(--pad);
    scrollbar-width: none;
  }
  .filmstreifen::-webkit-scrollbar { display: none; }
  .film-clip {
    flex: 0 0 68vw;
    max-width: 300px;
    scroll-snap-align: start;
  }
}

/* ============================================================
   Shop-Leiste der Oel-Seite: mobil am unteren Bildschirmrand
   ============================================================
   Am Desktop steht der Weg in den Shop im Kopf. Auf dem Handy gehoert er an
   den Daumen und nicht in die Kopfzeile, wo er mit Wortmarke, Sprachwahl und
   Burger um denselben Platz kaempft (K-Rueckmeldung 23.08.).
   z-index 90: unter dem Header (95) und dem Overlay-Menue (100), aber ueber
   der Seite (2). */
.shop-bar { display: none; }

@media (max-width: 720px) {
  /* Der Knopf wandert nach unten, im Kopf ist er dann weg. */
  .book-cta--shop { display: none; }

  .shop-bar {
    display: block;
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 90;
    /* env(): auf iPhones mit Homebar sonst halb unter der Leiste */
    padding: 12px var(--pad) calc(12px + env(safe-area-inset-bottom, 0px));
    background: rgba(247, 243, 232, 0.94);
    backdrop-filter: blur(10px);
    border-top: 1px solid var(--line);
    transition: transform 0.4s cubic-bezier(0.22, 0.61, 0.2, 1), opacity 0.3s ease;
  }
  .shop-bar .btn { display: block; width: 100%; text-align: center; }
  .shop-bar.is-away {
    transform: translateY(100%);
    opacity: 0;
    pointer-events: none;
  }
}

/* ============================================================
   Footer-Reveal (CSS-only): Content hebt sich, Footer liegt fix dahinter
   ============================================================ */
.page {
  position: relative;
  z-index: 2;
  background: var(--creme);
  margin-bottom: var(--footer-h);
  /* Die Seite ist ein Blatt, das sich vom dunklen Grund abhebt.
     Auf Dunkel trägt ein Petrol-Schatten nicht mehr, deshalb drei Lagen
     echtes Schwarz: harte Kontaktkante (das ist die Blattstärke), ein
     mittlerer Abfall und ein weiter, weicher Wurf für die Höhe.
     Eine helle Kante wäre hier falsch: die Unterseite eines abhebenden
     Blattes liegt im Schatten, und Creme auf Creme sieht man ohnehin nicht. */
  box-shadow:
    0 2px 3px rgba(0, 0, 0, 0.8),
    0 9px 20px rgba(0, 0, 0, 0.55),
    0 36px 76px rgba(0, 0, 0, 0.55);
}
.site-footer {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 1;
  height: var(--footer-h);
  /* Dunkel, damit die Kante sichtbar bleibt: alle Seiten enden auf Creme
     (Zahnheilkunde-Segment, Buchungsblock, Vertrauens-Zeile). Creme auf Creme
     hat den Vorhang-Effekt aufgehoben. Schließt den Bogen zum Intro-Vorhang. */
  /* Kein flaches Schwarz: unten aufgehellt, oben abgedunkelt. Der Raum
     bekommt dadurch eine Richtung, das Blatt darüber wirft in einen Raum
     statt auf eine Fläche. */
  background:
    radial-gradient(130% 90% at 50% 118%, #1B352E 0%, rgba(27, 53, 46, 0) 62%),
    var(--ink);
  color: var(--creme);
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  overflow: hidden;
}
/* Verschattung am oberen Rand: was direkt unter dem Blatt liegt, bekommt
   am wenigsten Licht. Liegt hinter dem Inhalt, nicht darüber. */
.site-footer::before {
  content: '';
  position: absolute;
  inset: 0 0 auto 0;
  height: 45%;
  background: linear-gradient(to bottom, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));
  pointer-events: none;
}
.site-footer > * { position: relative; }

/* Parallaxe: der Fußinhalt steigt beim Aufdecken nach, statt starr
   dazuliegen. --footer-reveal (0…1) setzt main.js. Gestaffelt, damit die
   drei Lagen unterschiedlich weit hinten liegen. */
.site-footer[data-parallax] .footer-wordmark,
.site-footer[data-parallax] .footer-links,
.site-footer[data-parallax] .footer-note {
  --nach: calc(1 - var(--footer-reveal, 1));
  opacity: calc(0.2 + var(--footer-reveal, 1) * 0.8);
  will-change: transform;
}
/* Die Wortmarke kommt zusätzlich leicht nach vorn – Bewegung allein liest
   sich flach, Bewegung plus Maßstab liest sich als Tiefe. */
.site-footer[data-parallax] .footer-wordmark {
  transform: translate3d(0, calc(var(--nach) * 78px), 0) scale(calc(1 - var(--nach) * 0.05));
  transform-origin: 50% 100%;
}
.site-footer[data-parallax] .footer-links    { transform: translate3d(0, calc(var(--nach) * 44px), 0); }
.site-footer[data-parallax] .footer-note     { transform: translate3d(0, calc(var(--nach) * 26px), 0); }
.footer-wordmark {
  font-family: var(--serif);
  font-weight: 300;
  font-size: 9.2vw;
  line-height: 1;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  text-align: center;
  white-space: nowrap;
  color: var(--creme);
  margin-bottom: 4vh;
}
.footer-links {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 26px;
  justify-content: center;
  padding: 0 var(--pad) 20px;
  font-size: 13px;
}
.footer-links a { text-decoration: none; opacity: 0.75; transition: opacity 0.2s ease; }
.footer-links a:hover { opacity: 1; }
/* Flex nur wegen des Umbruchs weiter unten. Deckkraft und Farbe bleiben,
   wie sie waren: die 0.45 gelten nur ohne Parallaxe (reduzierte Bewegung) -
   sobald der Footer aufgedeckt wird, ueberschreibt sie
   `.site-footer[data-parallax] .footer-note` und die Zeile steht voll da. */
.footer-note {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: baseline;
  text-align: center;
  font-size: 11px;
  letter-spacing: 0.08em;
  opacity: 0.45;
  padding: 0 var(--pad) 22px;
}
.footer-note a { text-decoration: none; }
/* Gestaltungs-Nachweis. Zurueckgenommen ist das LABEL, nicht der Name: der
   steht so hell wie die Copyright-Angabe daneben, das Wort davor tritt
   zurueck. Umgekehrt gewichtet las sich die Zeile falsch - "Gestaltung" ist
   nicht die Information. Gedaempft wird ueber die Farbe, nicht ueber
   `opacity`: die traegt an diesem Element schon die Parallaxe. Der
   Trennpunkt gehoert dem Credit, nicht dem Copyright - so verschwindet er
   mit ihm, wenn die Zeile bricht. */
.footer-credit { color: rgba(247, 243, 232, 0.6); }
.footer-credit::before { content: '·'; margin: 0 0.55em; }
.footer-credit a { color: var(--creme); }
.footer-credit a:hover {
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
}
/* Schmale Geraete: zwei ruhige Zeilen. Einzeilig bricht es sonst mitten im
   Namen um ("Lemon / Design"), gemessen ab etwa 330 px. */
@media (max-width: 430px) {
  .footer-credit { flex-basis: 100%; margin-top: 5px; }
  .footer-credit::before { content: none; }
}

/* ============================================================
   Unterkunftsseite
   ============================================================ */
/* Pfadzeile statt Reiter-Leiste (K-Entscheidung 28.08.). Die alte Leiste
   listete Uebersicht + alle vier Haeuser nebeneinander und brach auf dem
   Handy in die zweite Zeile um. Zwei Eintraege brechen nicht – und bleiben
   auch dann zwei, wenn ein fuenftes Haus dazukommt. */
.hauspfad {
  position: relative;
  z-index: 3;
  background: var(--ink);
  color: var(--creme);
  padding: calc(var(--header-h) + 18px) var(--pad) 18px;
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
}
.hauspfad ol {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: baseline;
  gap: 10px;
  margin: 0;
  padding: 0;
  list-style: none;
}
/* Der Eintrag selbst bleibt zusammen; umbrechen darf hoechstens die Liste. */
.hauspfad li { display: flex; align-items: baseline; gap: 10px; white-space: nowrap; }
/* Trenner als CSS-Inhalt: er gehoert zur Darstellung, nicht in den Text.
   letter-spacing zuruecknehmen, sonst schiebt die Laufweite ihn nach rechts
   aus seinem eigenen Abstand heraus. */
.hauspfad li + li::before { content: '\203A'; opacity: 0.4; letter-spacing: 0; }
.hauspfad a { text-decoration: none; opacity: 0.55; transition: opacity 0.2s ease; }
.hauspfad a:focus-visible { outline: 1.5px solid var(--creme); outline-offset: 4px; }
.hauspfad [aria-current] { opacity: 1; }
@media (hover: hover) {
  .hauspfad a:hover { opacity: 1; }
}

.house-hero {
  position: relative;
  height: 82vh;
  min-height: 480px;
  overflow: hidden;
  display: flex;
  align-items: flex-end;
  color: var(--creme);
}

section.block { padding: clamp(80px, 12vh, 150px) var(--pad); }
section.block--flush { padding-top: 0; }
section.block--white { background: var(--white); }
.block-inner { max-width: 1100px; margin: 0 auto; }
.narrow { max-width: 700px; }
.block h1, .block h2 { font-family: var(--serif); font-weight: 300; font-size: clamp(28px, 3.6vw, 48px); line-height: 1.12; margin: 12px 0 24px; }

/* Absaetze aus mehrzeiligen Textfeldern (KirbyText) hatten keinen Abstand:
   der Reset setzt margin: 0, und eine Gegenregel gab es nur fuer .rechtstext.
   Drei Absaetze lasen sich dadurch als ein Block mit Zeilenumbruechen.
   Betrifft Intro und Umgebung jeder Hausseite, Oel- und Kontaktseite.

   Zwei bewusste Einschraenkungen:
   - nur ZWISCHEN zwei Absaetzen (p + p), damit der Abstand zum naechsten
     Element (Fakten-Liste, Maps-Knopf, Infobox) unveraendert bleibt
   - :not([class]) trifft genau die KirbyText-Absaetze; Kicker, Smallprint
     und CTA tragen eigene Klassen und bringen ihre Abstaende selbst mit */
.block-inner p:not([class]) + p:not([class]),
.booking-preise p:not([class]) + p:not([class]) { margin-top: 1.15em; }

.facts {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  row-gap: 6px;
  margin: 28px 0 0;
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
/* Der Trenner haengt HINTER dem Eintrag statt als border-left davor.
   Vorher trug jeder Eintrag ausser dem ersten einen Strich links – beim
   Umbruch begann damit jede Folgezeile mit einem freistehenden Strich plus
   18 px Einzug. So kann kein Trenner an einen Zeilenanfang rutschen, egal
   wie viele USPs es sind und wie lang sie werden. */
.facts li { display: flex; align-items: center; padding: 4px 0; }
.facts li:not(:last-child)::after {
  content: '';
  flex: none;
  width: 1px;
  height: 1em;
  margin: 0 16px;
  background: var(--line);
}
.smallprint { margin-top: 22px; font-size: 12px; opacity: 0.55; }

/* Galerie */
.gallery {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 14px;
}
.gallery > * { aspect-ratio: 4 / 3; overflow: hidden; }
.gallery img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.6s ease; }
@media (hover: hover) {
  .gallery a:hover img, .gallery div:hover img, .gallery button:hover img { transform: scale(1.04); }
}
.gallery .tall { grid-row: span 2; aspect-ratio: auto; }
@media (max-width: 700px) {
  .gallery { grid-template-columns: repeat(2, 1fr); }
  /* 22 Fotos zweispaltig sind rund 1500 px Scrollen bis zur naechsten
     Sektion. Mobil bleiben zwei Reihen stehen; die vierte Kachel traegt die
     Zahl der restlichen Bilder und oeffnet wie jede andere die Lightbox.
     Nur ausgeblendet, nicht entfernt: lightbox.js liest weiter alle Kacheln,
     am Desktop bleibt das Raster unveraendert. */
  .gallery > *:nth-child(n+5) { display: none; }
  .gallery-item[data-mehr]::after {
    content: attr(data-mehr);
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
    background: rgba(16, 32, 27, 0.55);
    color: var(--creme);
    font-size: 13px;
    font-weight: 500;
    letter-spacing: 0.16em;
    text-transform: uppercase;
  }
}

/* Detail-Collage (im Prototyp statisch, Parallax erst im echten Build) */
.collage {
  position: relative;
  max-width: 1100px;
  margin: 0 auto;
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: 14px;
}
.collage .c1 { grid-column: 1 / 6; aspect-ratio: 3 / 4; margin-top: 60px; }
.collage .c2 { grid-column: 6 / 10; aspect-ratio: 4 / 5; }
.collage .c3 { grid-column: 10 / 13; aspect-ratio: 3 / 4; margin-top: 120px; }
@media (max-width: 700px) {
  .collage .c1 { grid-column: 1 / 8; margin-top: 0; }
  .collage .c2 { grid-column: 5 / 13; margin-top: -30px; }
  .collage .c3 { grid-column: 2 / 9; margin-top: 14px; }
}

/* Ausstattung */
.amenities {
  columns: 2;
  column-gap: 60px;
  max-width: 760px;
}
.amenities li {
  break-inside: avoid;
  padding: 14px 0;
  border-bottom: 1px solid var(--line);
  font-size: 15px;
}
@media (max-width: 640px) { .amenities { columns: 1; } }

/* Umgebung / Hinweisbox */
.infobox {
  margin-top: 34px;
  border: 1px solid var(--line);
  background: var(--white);
  padding: 24px 28px;
  font-size: 14px;
}
.infobox strong { display: block; margin-bottom: 6px; font-size: 12px; letter-spacing: 0.18em; text-transform: uppercase; }

/* ============================================================
   Kalender (Dummy) + Anfrage
   ============================================================ */
.booking { background: var(--white); }

/* Preise: schmaler Block ueber dem Kalender/Formular-Raster. Gleiche
   Aussenbreite wie das Raster (1100px), Text auf Lesebreite begrenzt. */
.booking-preise {
  max-width: 1100px;
  margin: 0 auto clamp(40px, 6vh, 70px);
}
.booking-preise p { max-width: 640px; }
.booking-preise .smallprint { margin-top: 10px; }
.booking-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(40px, 6vw, 100px);
  max-width: 1100px;
  margin: 0 auto;
}
@media (max-width: 900px) { .booking-grid { grid-template-columns: 1fr; } }
/* Grid- und Flex-Kinder stehen per Default auf min-width: auto und koennen
   damit nicht schmaler werden als ihr Inhalt. Passt der Kalender oder ein
   Datumsfeld nicht in die Spalte, wird die SPALTE breiter als der Bildschirm
   - und die ganze Seite scrollt waagerecht. Betraf auf schmalen Geraeten den
   Buchungsblock der Hausseiten (gemeldet 22.08.). */
.booking-grid > * { min-width: 0; }
.cal { min-width: 0; }

.cal-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 18px; }
.cal-head h3 { font-family: var(--serif); font-weight: 400; font-size: 22px; }
.cal-nav { display: flex; gap: 8px; }
.cal-nav button {
  width: 38px; height: 38px;
  border: 1px solid var(--line);
  background: none;
  font-size: 16px;
  color: var(--ink);
}
.cal-nav button:disabled { opacity: 0.3; cursor: default; }
.cal-dow {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  text-align: center;
  font-weight: 500;
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  opacity: 0.55;
  padding: 10px 0 8px;
}
/* 1px-Gap-Grid statt Tabelle: alle Kacheln exakt gleich groß */
.cal-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 1px;
  border: 1px solid var(--line);
  background: var(--line);
}
.cal-grid .day {
  aspect-ratio: 1;
  display: grid;
  place-items: center;
  padding: 0;
  border: 0;
  background: var(--white);
  font: inherit;
  font-size: 14px;
  color: var(--ink);
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease;
}
/* Hover nur mit echtem Zeiger – sonst blieb der zuletzt getippte Tag
   haengen. Ausserdem ist dieser Selektor mit :not(:disabled) spezifischer
   als .day--selected:hover: der Hintergrund wurde creme, die Schrift blieb
   creme, und die Tageszahl war im gewaehlten Zustand unsichtbar. Deshalb
   greift er jetzt nur noch auf Tagen ohne eigenen Zustand. */
@media (hover: hover) {
  .cal-grid .day:hover:not(:disabled):not(.day--selected):not(.day--range) { background: var(--creme); }
}
.cal-grid .day--empty { cursor: default; }
.cal-grid .day--past {
  color: rgba(16, 32, 27, 0.3);
  cursor: default;
}
.cal-grid .day--past { background: var(--white); }
.cal-grid .day--booked,
.cal-grid .day--booked:hover {
  background: #B4453A;
  color: var(--white);
  text-decoration: line-through;
  cursor: not-allowed;
}
.cal-grid .day--range,
.cal-grid .day--range:hover { background: #ECE6D2; }
.cal-grid .day--selected,
.cal-grid .day--selected:hover {
  background: var(--petrol);
  color: var(--creme);
}
.cal-legend { display: flex; flex-wrap: wrap; gap: 14px 20px; margin-top: 14px; font-size: 12px; opacity: 0.7; }
.cal-legend i { display: inline-block; width: 12px; height: 12px; margin-right: 6px; vertical-align: -1px; }
.cal-legend .free { border: 1px solid var(--line); background: var(--white); }
.cal-legend .booked-i { background: #B4453A; }

/* Formular */
.form h3 { font-family: var(--serif); font-weight: 400; font-size: 22px; margin-bottom: 18px; }
.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.form-row > * { min-width: 0; }
@media (max-width: 520px) { .form-row { grid-template-columns: 1fr; } }
.form label { display: block; font-size: 11px; font-weight: 500; letter-spacing: 0.16em; text-transform: uppercase; margin: 18px 0 6px; }
.form input, .form textarea {
  width: 100%;
  max-width: 100%;
  min-width: 0;
  border: 1px solid var(--line);
  background: var(--creme);
  padding: 13px 14px;
  font: inherit;
  font-size: 14px;
  color: var(--ink);
}
.form input:focus, .form textarea:focus { outline: 1.5px solid var(--petrol); }
/* iOS zoomt beim Antippen automatisch hinein, wenn ein Eingabefeld kleiner
   als 16 px Schrift hat - danach ist die Seite breiter als der Bildschirm
   und scrollt waagerecht. Ab 16 px unterbleibt der Zoom. Gilt nur auf
   schmalen Geraeten, am Desktop bleiben die 14 px. */
@media (max-width: 900px) {
  .form input, .form textarea, .form select { font-size: 16px; }
}
/* Datumsfelder: iOS gibt input[type=date] eine NATIVE Mindestbreite, die
   sich weder von width noch von max-width unterbieten laesst - das Feld ragt
   dann rechts aus dem Kasten, waehrend Name und E-Mail sauber sitzen
   (Screenshot vom 22.08. zeigt genau das). appearance: none nimmt dem Feld
   die native Groesse; der Datumswaehler oeffnet sich weiterhin, es sieht nur
   aus wie ein normales Textfeld.
   ::-webkit-date-and-time-value ist der innere Wert - ohne die Regel setzt
   iOS ihn mittig und mit eigenem Aussenabstand. */
.form input[type="date"] {
  -webkit-appearance: none;
  appearance: none;
}
.form input[type="date"]::-webkit-date-and-time-value {
  text-align: left;
  margin: 0;
  min-width: 0;
}
.form textarea { min-height: 110px; resize: vertical; }
.form .btn { border: 0; margin-top: 24px; background: var(--ink); color: var(--creme); }
.form .btn:hover { background: var(--petrol); }
.form-note { margin-top: 14px; font-size: 12px; opacity: 0.6; }

/* Honeypot: fuer Menschen unsichtbar, aber NICHT display:none – manche Bots
   ueberspringen ausgeblendete Felder und fielen sonst nicht auf. */
.hp {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.form-hinweis {
  margin-bottom: 20px;
  padding: 14px 16px;
  border-left: 3px solid;
  font-size: 14px;
  line-height: 1.5;
}
.form-hinweis p + p { margin-top: 6px; }
.form-hinweis--ok { border-color: var(--petrol); background: rgba(30, 58, 52, 0.07); }
.form-hinweis--fehler { border-color: #B4453A; background: rgba(180, 69, 58, 0.08); }

/* ============================================================
   Entdecken-Sektion (Kontaktseite)
   Fängt den Blick unter dem Formular ab – sonst steht dort sofort der
   Footer-Reveal. Zwei gleichrangige Karten, ganze Karte ist der Link.
   ============================================================ */
.entdecken-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(24px, 3vw, 44px);
  margin-top: 40px;
}
@media (max-width: 760px) { .entdecken-grid { grid-template-columns: 1fr; } }

.entdecken-karte {
  display: block;
  color: inherit;
  text-decoration: none;
}
.entdecken-media {
  aspect-ratio: 3 / 2;
  overflow: hidden;
  margin-bottom: 20px;
}
.entdecken-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.6s cubic-bezier(0.22, 0.6, 0.2, 1);
}
.entdecken-karte:hover .entdecken-media img { transform: scale(1.04); }
/* Bildfokus fuer Kacheln, deren Motiv nicht in der Mitte sitzt - gesetzt ueber
   die Klasse am <img>, weil Inline-Styles an der CSP scheitern. */
.entdecken-media img.fokus-unten { object-position: 50% 78%; }

.entdecken-body h3 {
  font-family: var(--serif);
  font-weight: 300;
  font-size: clamp(24px, 2.6vw, 32px);
  line-height: 1.15;
  margin-bottom: 10px;
}
.entdecken-body p {
  max-width: 42ch;
  margin-bottom: 20px;
  opacity: 0.85;
}
/* Der Textlink ist hier ein span in einem umschliessenden a – die Optik
   soll aber dieselbe sein, inklusive Hover ueber die ganze Karte. */
.entdecken-karte:hover .textlink { opacity: 0.6; }

@media (prefers-reduced-motion: reduce) {
  .entdecken-media img, .entdecken-karte:hover .entdecken-media img { transition: none; transform: none; }
}

/* ============================================================
   Rechtstexte (Impressum, Datenschutz)
   Lange Fliesstexte mit vier Ueberschriftenebenen. Ohne eigene Regeln
   faellt alles unterhalb h2 auf die Browser-Vorgabe zurueck und h3/h4
   sind kaum zu unterscheiden – bei ~550 Zeilen Erklaerung unlesbar.
   ============================================================ */
.rechtstext { font-size: 15px; line-height: 1.7; }

/* Rechtstexte sind voller langer Komposita. „Verbraucherstreitbeilegung/
   Universalschlichtungsstelle" ist als h2 rund 574px breit und sprengte auf
   dem Handy die Seite nach rechts. Die eRecht24-Vorlage loeste das mit
   weichen Trennstrichen im Markup; darauf verlassen wir uns nicht (sie
   ueberleben kein Copy-Paste). hyphens greift ueber lang="de" am <html>,
   overflow-wrap ist das Netz darunter. */
.rechtstext h2, .rechtstext h3, .rechtstext h4 {
  hyphens: auto;
  overflow-wrap: break-word;
}
.rechtstext p { margin-bottom: 16px; }

/* Deutlich kleiner als der Seitentitel: die Abschnittsnummern sollen die
   h1 nicht verdraengen. Die Haarlinie gliedert das Dokument. */
.rechtstext h2 {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(22px, 2.4vw, 28px);
  line-height: 1.2;
  margin: 56px 0 20px;
  padding-top: 28px;
  border-top: 1px solid var(--line);
}
.rechtstext > h2:first-child { margin-top: 24px; }

.rechtstext h3 {
  font-family: var(--serif);
  font-weight: 400;
  font-size: 19px;
  line-height: 1.3;
  margin: 34px 0 12px;
}

.rechtstext h4 {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  opacity: 0.65;
  margin: 26px 0 10px;
}

.rechtstext ul { margin: 0 0 16px; padding-left: 22px; }
.rechtstext li { margin-bottom: 8px; }

/* Die Erklaerung enthaelt rund 70 nackte URLs als Linktext. Ohne Umbruch
   schieben sie die 700px-Spalte auf. */
.rechtstext a {
  color: var(--petrol);
  overflow-wrap: anywhere;
}

/* ============================================================
   Kontaktseite
   Gleiches Raster wie der Buchungsblock der Hausseiten (.booking-grid):
   links die direkten Wege, rechts das Formular.
   ============================================================ */
.kontakt-block .kontakt-titel {
  font-family: var(--serif);
  font-weight: 400;
  font-size: 22px;
  margin-bottom: 18px;
}
.kontakt-wege { list-style: none; margin: 0; padding: 0; }
.kontakt-wege li + li { margin-top: 22px; }
.kontakt-label {
  display: block;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  opacity: 0.6;
  margin-bottom: 6px;
}
.kontakt-wege a {
  font-family: var(--serif);
  font-size: clamp(20px, 2.4vw, 26px);
  line-height: 1.2;
  color: var(--ink);
  text-decoration: none;
  border-bottom: 1px solid var(--line);
  overflow-wrap: anywhere;
}
.kontakt-wege a:hover { border-color: var(--petrol); color: var(--petrol); }
.kontakt-verweis {
  margin-top: 40px;
  padding-top: 24px;
  border-top: 1px solid var(--line);
  font-size: 14px;
  line-height: 1.6;
  opacity: 0.8;
}
.kontakt-verweis a { color: var(--petrol); }

/* ============================================================
   Häuser-Übersicht v2 (haeuser.html) – Kachel-Wahl
   K-Review 14.08.: v1 (60/40-Karten) zu inspirationslos. Die Wahl ist
   jetzt das visuelle Herzstück, nicht eine Sektion unter vielen.
   ============================================================ */
/* Seiten ohne dunklen Hero: Header startet im hellen Zustand */
body.header-light .site-header { background: rgba(247, 243, 232, 0.92); color: var(--ink); box-shadow: 0 1px 0 var(--line); }
body.header-light .site-header::before { opacity: 0; }

/* ---------- v3: Karte als Einstieg ----------
   Dunkler Ein-Screen-Block. Höhe bewusst 87svh statt 100svh: die restlichen
   ~13vh gehören den Panel-Oberkanten darunter, das ist der Scroll-Anreiz. */
.mapintro {
  position: relative;
  background: var(--ink);
  color: var(--creme);
  min-height: 87svh;
  display: flex;
  align-items: center;
  padding: calc(var(--header-h) + clamp(18px, 3vh, 40px)) var(--pad) clamp(20px, 3vh, 44px);
}
.mapintro-inner {
  display: grid;
  grid-template-columns: minmax(240px, 1fr) 2fr;
  gap: clamp(28px, 4vw, 72px);
  align-items: center;
  width: 100%;
  max-width: 1500px;
  margin: 0 auto;
}
.mapintro-text .kicker { opacity: 0.6; }
.mapintro-text h1 {
  font-family: var(--serif);
  font-weight: 300;
  font-size: clamp(34px, 3.9vw, 58px);
  line-height: 1.05;
  margin: 14px 0 16px;
}
.mapintro-text .sub { font-size: 15px; opacity: 0.78; max-width: 34ch; }
.mapintro-cta { margin-top: clamp(20px, 3vh, 34px); }
.mapintro-karte { min-width: 0; }
.map--hero { width: 100%; height: auto; }
/* Anker-Zeile ist die mobile Auswahlhilfe, am Desktop übernimmt das die Karte */
.mapintro-anker { display: none; }

/* ---------- Die vier Panels: sie SIND die Auswahl ---------- */
.panels {
  display: flex;
  gap: 4px;
  height: 75vh;
  min-height: 430px;
  scroll-margin-top: var(--header-h);
}
.panel {
  position: relative;
  flex: 1 1 0;
  min-width: 0;
  overflow: hidden;
  display: flex;
  align-items: flex-end;
  text-decoration: none;
  color: var(--creme);
  background: var(--petrol);
  transition: flex-grow 0.55s cubic-bezier(0.22, 0.61, 0.2, 1);
}
.panel-media { position: absolute; inset: 0; }
.panel-media img { width: 100%; height: 100%; object-fit: cover; }
/* Panels ohne Foto: tonaler Verlauf statt flacher Fläche, sonst wirkt die
   rechte Hälfte tot. Beide in der Petrol-Familie, damit die zwei Varna-Panels
   als Paar lesen; Varna II eine Spur tiefer, es tritt zurück. */
.panel-media--ph { background: linear-gradient(155deg, #2A4E45 0%, #1E3A34 58%, #172E28 100%); }
.panel-media--ph2 { background: linear-gradient(155deg, #22423A 0%, #1A342E 58%, #142823 100%); }

/* Abdunkler der jeweils NICHT gewählten Panels */
.panel::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
  background: var(--ink);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.45s ease;
}
.panels:hover .panel::after,
.panels:focus-within .panel::after { opacity: 0.5; }
/* gleiche Spezifität wie die Regel darüber, steht danach -> gewinnt */
.panels .panel:hover::after,
.panels .panel:focus-within::after { opacity: 0; }

.panels:hover .panel,
.panels:focus-within .panel { flex-grow: 0.92; }
.panels .panel:hover,
.panels .panel:focus-within { flex-grow: 2.2; }
/* Varna II hat noch keine Seite: aufhellen ja, aufziehen nein */
.panels .panel--soon:hover,
.panels .panel--soon:focus-within { flex-grow: 0.92; }

/* Label-Block sitzt im unteren Viertel, nicht auf der Kante; der Verlauf
   reicht entsprechend höher, damit die Schrift auf jedem Foto trägt (v2.1) */
.panel-body {
  position: relative;
  z-index: 2;
  width: 100%;
  padding: clamp(46px, 9vh, 96px) clamp(18px, 2.2vw, 30px) clamp(24px, 4vh, 48px);
  background: linear-gradient(to top,
    rgba(16, 32, 27, 0.86) 0%,
    rgba(16, 32, 27, 0.62) 34%,
    rgba(16, 32, 27, 0.2) 72%,
    rgba(16, 32, 27, 0) 100%);
}
/* „Foto folgt" – klein über dem Label, nicht mehr mittig im Panel */
.panel-hint {
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  opacity: 0.5;
  margin-bottom: 9px;
}
.panel-land {
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  opacity: 0.75;
}
.panel-name {
  font-family: var(--serif);
  font-weight: 300;
  font-size: clamp(21px, 2vw, 32px);
  line-height: 1.1;
  margin-top: 8px;
}

/* Chips + CTA erscheinen erst im geweiteten Panel.
   grid-template-rows 0fr -> 1fr animiert die Höhe ohne feste Maße. */
.panel-extra {
  display: grid;
  grid-template-rows: 0fr;
  opacity: 0;
  transition: grid-template-rows 0.5s cubic-bezier(0.22, 0.61, 0.2, 1), opacity 0.35s ease;
}
.panels .panel:hover .panel-extra,
.panels .panel:focus-within .panel-extra { grid-template-rows: 1fr; opacity: 1; }
.panel-extra > div { overflow: hidden; min-height: 0; }
.panel-chips { display: flex; flex-wrap: wrap; gap: 6px; margin: 16px 0 15px; }
.panel-chips li {
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  white-space: nowrap;
  border: 1px solid rgba(247, 243, 232, 0.45);
  padding: 6px 10px;
}
.panel-cta {
  display: inline-block;
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  padding-bottom: 4px;
  border-bottom: 1px solid currentColor;
}

/* „Bald" für Varna II: klein und halbtransparent neben dem Hausnamen, statt
   als kräftiger Chip oben rechts – oben stört er direkt unter dem Kopf (v2.1).
   Der Öl-Badge am Steinhaus ist entfallen: die Verbindung Haus/Öl gehört auf
   die Hausseite und in den Öl-Teaser, nicht in die Wahl-UI. */
.panel-badge {
  display: inline-block;
  margin-left: 10px;
  vertical-align: 0.22em;
  font-family: var(--sans);
  font-size: 9px;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--creme);
  background: rgba(247, 243, 232, 0.14);
  border: 1px solid rgba(247, 243, 232, 0.38);
  padding: 4px 9px;
}

@media (max-width: 900px) {
  /* Hero-Block: einspaltig, Text über der Karte, darunter die Anker-Zeile */
  .mapintro { min-height: 62svh; padding-bottom: clamp(22px, 4vh, 44px); }
  .mapintro-inner { grid-template-columns: 1fr; gap: clamp(16px, 3vh, 28px); }
  .mapintro-text { text-align: center; }
  .mapintro-text .sub { max-width: none; margin: 0 auto; }
  .mapintro-cta { display: none; }
  .mapintro-anker {
    display: flex;
    justify-content: center;
    flex-wrap: wrap;
    gap: 10px 26px;
    margin-top: clamp(14px, 2.5vh, 24px);
    font-size: 12px;
    font-weight: 500;
    letter-spacing: 0.18em;
    text-transform: uppercase;
  }
  .mapintro-anker a { text-decoration: none; opacity: 0.75; padding: 6px 0; }

  /* 2x2-Grid, kein Grow-Effekt, Chips stehen im Vergleich darunter */
  .panels { display: grid; grid-template-columns: 1fr 1fr; height: auto; min-height: 0; }
  .panel { height: 45vh; min-height: 250px; }
  .panels:hover .panel::after, .panels:focus-within .panel::after { opacity: 0; }
  .panel-extra { display: none; }
  .panel-body { padding-top: clamp(36px, 7vh, 70px); }
}

/* ============================================================
   Karten-Modul: handgezeichnete Linien-SVGs (Fontenille-Vorbild)
   Küstenlinien stark vereinfacht, Einzeichnen-Effekt wie das Logo-Intro
   ============================================================ */
.map { display: block; width: 100%; height: auto; }

.mapline {
  fill: none;
  stroke: var(--creme);
  stroke-width: 1.1;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: 0.72;
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  transition: stroke-dashoffset 1.9s cubic-bezier(0.3, 0, 0.2, 1);
}
.map.in .mapline { stroke-dashoffset: 0; }
.mapline--1 { transition-delay: 0.12s; }
.mapline--2 { transition-delay: 0.24s; }
.mapline--3 { transition-delay: 0.36s; }
.mapline--4 { transition-delay: 0.48s; }
.mapline--5 { transition-delay: 0.60s; }
.mapwater { fill: #16302A; stroke: none; opacity: 0; transition: opacity 1s ease 0.5s; }
.map.in .mapwater { opacity: 1; }

/* Marker, Verbindungslinien und Labels erscheinen nach den Küsten. Das Timing
   sitzt auf der GRUPPE `.mapziele`, nicht auf den einzelnen Zielen – die
   brauchen ihre Opacity für Hover/Fokus. Neue Karten bitte ebenso gruppieren. */
.mapziele { opacity: 0; transition: opacity 0.8s ease 1.2s; }
.map.in .mapziele { opacity: 1; }
.mapdot { fill: var(--creme); stroke: var(--creme); stroke-opacity: 0.3; stroke-width: 0; transition: stroke-width 0.25s ease; }
.mapdot--haus { stroke-width: 5; }
.mapleader { stroke: var(--creme); stroke-width: 0.8; opacity: 0.45; }
.maplabel {
  font-family: var(--serif);
  font-weight: 300;
  font-size: 15px;
  fill: var(--creme);
  paint-order: stroke;
  stroke: var(--petrol);
  stroke-width: 3.5px;
  stroke-linejoin: round;
}
.maplabel--ort {
  font-family: var(--sans);
  font-weight: 500;
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  opacity: 0.62;
  stroke-width: 3px;
}
.mapwasser {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 300;
  font-size: 14px;
  fill: var(--creme);
  opacity: 0.4;
}
a.mapziel, .mapziel-teil { cursor: pointer; }
a.mapziel:hover .mapdot { stroke-width: 7; }
a.mapziel:hover .maplabel,
a.mapziel-teil:hover .maplabel { text-decoration: underline; text-underline-offset: 3px; }
a.mapziel:focus-visible,
a.mapziel-teil:focus-visible { outline: 2px solid var(--creme); outline-offset: 3px; }

/* Regionalkarte (Pilion) liegt teils über Wasser -> weicher Schatten statt
   deckendem Halo, damit die Beschriftung auf beiden Flächen sitzt */
.map--region .maplabel { stroke: rgba(16, 32, 27, 0.6); }

/* ---------- Hero-Karte (v3): sie ist die Auswahl, nicht nur Illustration ----------
   Halo in der Blockfarbe, Fontenille-Duktus (Name Serif, Ort kursiv klein),
   Marker als offener Ring, der sich beim Hover füllt. */
/* Hausnamen stehen von Anfang an hell da. Weight 300 mit breitem Halo wirkte
   grau: der dunkle Rand liegt mittig auf den Serifen-Haarstrichen und frisst
   sie bei ~16 px optisch weg. Also kräftigerer Schnitt und schmalerer Halo. */
.map--hero .maplabel {
  stroke: var(--ink);
  stroke-width: 2.2px;
  font-weight: 400;
  font-size: 16px;
}
.map--hero .maplabel--ort {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 300;
  font-size: 11.5px;
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
  opacity: 0.72;
  stroke-width: 2.2px;
}
.map--hero .mapdot {
  fill: transparent;
  stroke: var(--creme);
  stroke-opacity: 1;
  stroke-width: 1.5;
  transition: fill 0.25s ease;
}
.map--hero .mapziel:hover .mapdot,
.map--hero .mapziel:focus-within .mapdot { fill: var(--creme); }
/* Unsichtbare Trefferflaeche: der sichtbare Punkt allein ist zu klein zum
   Treffen, und zwischen Punkt und Label nimmt leerer SVG-Raum keine Events an */
.maptreffer { fill: transparent; pointer-events: all; }
/* Nur mobil eingeschaltet, siehe Media Query weiter unten. */
.maptreffer--finger { display: none; }
/* Die eingeblendete Vorschau ist bis zu 280x186 gross und deckt dabei den
   naechsten Marker zu – die Varna-Vorschau liegt genau ueber Pilion. Weil sie
   selbst keine Events annimmt, klickte man durch das Bild hindurch auf das
   Haus darunter und landete in Griechenland statt in Varna (K-Meldung 28.08.).
   Solange ein Marker anvisiert ist, sind die anderen deshalb inert. Das
   Dimmen daneben ist nur Optik, hier geht es um den Klick.
   Die Kinder muessen mitgenannt werden: .maptreffer setzt pointer-events
   selbst auf all, und ein eigener Wert am Kind schlaegt den geerbten der
   Gruppe – ohne den Universalselektor bliebe der Trefferkreis anklickbar.
   NUR fuer echte Zeigegeraete. Touch-Browser lassen :hover nach dem Tippen
   auf dem getippten Element stehen; nach einem Tipp auf Varna und der
   Zurueck-Geste blieben Roche und Pilion deshalb dauerhaft inert
   (K-Meldung 28.08., iPhone). Auf Touch ist die Regel ohnehin sinnlos: die
   Vorschauen sind dort ausgeblendet, es gibt nichts zum Durchklicken. */
@media (hover: hover) {
  .map--hero:has(.mapziel:hover) .mapziel:not(:hover),
  .map--hero:has(.mapziel:hover) .mapziel:not(:hover) *,
  .map--hero:has(.mapziel:focus-within) .mapziel:not(:focus-within),
  .map--hero:has(.mapziel:focus-within) .mapziel:not(:focus-within) * {
    pointer-events: none;
  }
}

/* ---------- Bild-Vorschau ----------
   Geht beim Hover am Cursor auf. Positioniert wird in assets/js/main.js über
   das transform-Attribut der Gruppe; CSS macht nur Sichtbarkeit und Aufziehen.
   Skaliert wird aus der Kante, die zum Cursor zeigt: liegt die Karte über dem
   Cursor, wächst sie von unten, sonst von oben. */
.mapvorschau { pointer-events: none; }
.mapvorschau-in {
  transform-box: fill-box;
  transform-origin: 50% 100%;
  transform: scale(0.14);
  opacity: 0;
  transition: transform 0.38s cubic-bezier(0.22, 0.61, 0.2, 1), opacity 0.22s ease;
}
.mapvorschau--unten .mapvorschau-in { transform-origin: 50% 0%; }
.mapvorschau.ist-an .mapvorschau-in { transform: scale(1); opacity: 1; }
.mapvorschau-rahmen { fill: none; stroke: var(--creme); stroke-width: 1.1; opacity: 0.75; }
/* Varna hat noch keine Fotos – ehrliche Platzhalter-Karte statt Stockbild */
.mapvorschau-leer { fill: #24443C; }
/* Besonderheit als Fußleiste IM Bild statt als Symbol auf der Karte: sie
   erscheint genau dann, wenn die Aufmerksamkeit ohnehin auf diesem Haus
   liegt, und die Karte bleibt im Ruhezustand ruhig */
.mapvorschau-leiste { fill: rgba(16, 32, 27, 0.86); }
.mapvorschau-usp {
  font-family: var(--sans);
  font-size: 9.5px;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  fill: var(--creme);
  opacity: 0.85;
}
.mapvorschau-hinweis {
  font-family: var(--sans);
  font-size: 9px;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  fill: var(--creme);
  opacity: 0.6;
}
.map--hero .mapziel { transition: opacity 0.28s ease; }
/* Hover/Fokus auf einem Ziel dimmt die anderen leicht.
   Bedingung ist bewusst :has(.mapziel:hover) und NICHT .map--hero:hover –
   letzteres feuert schon beim Überfahren leerer Kartenflaeche und hat die
   Beschriftung grau werden lassen, ohne dass ein Ziel angefasst war.
   Kennt ein Browser :has() nicht, faellt die Regel ganz weg: dann bleibt
   alles hell, statt dauerhaft zu dimmen. */
.map--hero:has(.mapziel:hover) .mapziel,
.map--hero:has(.mapziel:focus-within) .mapziel { opacity: 0.38; }
/* Spezifitaet muss ueber der Regel oben liegen, sonst dimmt das aktive Ziel mit */
.map--hero:has(.mapziel:hover) .mapziel:hover,
.map--hero:has(.mapziel:focus-within) .mapziel:focus-within { opacity: 1; }
/* Varna: ein Marker, zwei Zeilen. Zeile 2 ist noch kein Link (Stub-Seite). */
.maplabel-bald {
  font-family: var(--sans);
  font-size: 8.5px;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  opacity: 0.5;
}
.mapziel-teil--aus .maplabel { opacity: 0.6; }

@media (max-width: 900px) {
  /* Mobil zeigt die Karte nur drei Punkte: keine Labels, keine
     Verbindungslinien, keine Vorschauen. Gewählt wird in der Anker-Zeile und
     den Panels – die Punkte sind aber sehr wohl antippbar, sie führen zum
     jeweiligen Haus. (Der Kommentar behauptete hier lange das Gegenteil,
     während `.maptreffer` mit seinem eigenen `pointer-events: all` das
     `none` der Gruppe längst überschrieb. Beschrieben ist jetzt, was
     passiert.) */
  .map--hero .maplabel,
  .map--hero .mapleader { display: none; }
  .map--hero .mapziel { pointer-events: none; }
  .map--hero .mapvorschau { display: none; }
  /* Fingergerechte Trefferfläche: der reguläre Kreis trägt r="13" und
     skaliert mit der Karte – mobil sind das 12 px, etwa ein Viertel dessen,
     was ein Finger braucht. Deshalb liegt im Markup ein zweiter Kreis mit
     r="44", der nur hier sichtbar geschaltet wird; das ergibt rund 38 px.
     Nicht über einen breiten transparenten Rand gelöst, obwohl das ohne
     zweites Element ausgekommen wäre: **WebKit berücksichtigt
     `non-scaling-stroke` beim Hit-Testing nicht** – der Rand ist dort sichtbar
     wirksam, aber nicht treffbar (28.08. nachgemessen). Und ohne
     `non-scaling` skaliert die Fläche wieder mit der Karte weg.
     Größer geht nicht: Pilion und Varna liegen auf dem Telefon nur 55 px
     auseinander, die Flächen würden sich sonst berühren. */
  .map--hero .maptreffer--finger { display: block; }
  /* Punktgroesse ueber stroke-width, NICHT ueber r: Safari unterstuetzt
     SVG-Geometrie (r, cx, cy) nicht als CSS-Eigenschaft und faellt auf das
     Attribut r="3.4" zurueck – in Chromium ein 13-px-Punkt, auf dem iPhone
     einer von 3 px (nachgemessen 28.08. in beiden Engines; genau der Grund,
     warum es in der Desktop-Vorschau richtig aussah und auf dem Geraet nicht).
     stroke-width ist dagegen ueberall CSS, und non-scaling-stroke haelt die
     Staerke in Bildschirmpixeln: der Punkt ist damit auf jedem Geraet gleich
     gross, statt mit der Kartenbreite zu schrumpfen – vorher war er auf dem
     schmalsten Telefon am kleinsten, also genau dort, wo er am meisten
     tragen muss. */
  .map--hero .mapdot {
    fill: var(--creme);
    stroke: var(--creme);
    stroke-width: 10;
    vector-effect: non-scaling-stroke;
  }
  /* Kein Dimmen: faengt den Tastaturfokus in schmalen Desktop-Fenstern ab */
  .map--hero:has(.mapziel:focus-within) .mapziel { opacity: 1; }
}

/* Auf dem Telefon ist der Punkt das einzige Zeichen auf der Karte – die
   Beschriftung ist ausgeblendet. Er darf deshalb etwas kraeftiger sein als
   auf dem Tablet; die Karte ist hier am schmalsten. */
@media (max-width: 600px) {
  .map--hero .mapdot { stroke-width: 13; }
}

@media (max-width: 700px) {
  .map--region .maplabel { font-size: 19px; }
  .map--region .maplabel--ort { font-size: 14px; letter-spacing: 0.08em; }
  .map--region .mapwasser { font-size: 17px; }
}

/* ============================================================
   Vergleichs-Streifen „Auf einen Blick"
   ============================================================ */
.compare-sec { background: var(--white); padding: clamp(70px, 11vh, 130px) var(--pad); }
.compare-inner { max-width: 1180px; margin: 0 auto; }
.compare-inner .kicker { opacity: 0.6; }
.compare-inner h2 {
  font-family: var(--serif);
  font-weight: 300;
  font-size: clamp(26px, 3.4vw, 44px);
  line-height: 1.12;
  margin: 12px 0 clamp(22px, 3vh, 40px);
}
.compare-scroll { overflow-x: auto; }
table.compare { width: 100%; min-width: 700px; border-collapse: collapse; }
.compare th, .compare td {
  text-align: left;
  vertical-align: top;
  padding: 15px 20px 15px 0;
  border-bottom: 1px solid var(--line);
  font-size: 14px;
  font-weight: 400;
}
.compare thead th {
  font-family: var(--serif);
  font-weight: 400;
  font-size: 19px;
  line-height: 1.2;
  border-bottom: 1px solid var(--ink);
  padding-bottom: 12px;
}
.compare thead th a { text-decoration: none; }
.compare thead th a:hover { opacity: 0.6; }
.compare tbody th {
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  opacity: 0.55;
  white-space: nowrap;
  width: 1%;
  padding-right: 34px;
}
.compare tbody tr:last-child td, .compare tbody tr:last-child th { border-bottom: 0; }
.compare .textlink { font-size: 11px; letter-spacing: 0.14em; }

/* Mobil keine Tabelle mehr, sondern ein Block je Merkmal.
   Vorher: 700-px-Tabelle in 350-px-Container, Scroll-Snap auf allen 30
   Zellen und eine 130 px breite Sticky-Spalte – jeder Snap schob die
   angesteuerte Zelle genau unter die stehende Spalte. Statt daran zu
   feilen entfaellt das seitliche Scrollen hier ganz: die Hausnamen kommen
   aus data-haus an der Zelle, die Kopfzeile wird nicht gebraucht. */
@media (max-width: 760px) {
  .compare-scroll { overflow-x: visible; }
  .compare, .compare tbody, .compare tr, .compare th, .compare td { display: block; }
  table.compare { min-width: 0; width: 100%; }
  .compare thead { display: none; }

  .compare tbody tr { padding: 18px 0; border-bottom: 1px solid var(--line); }
  .compare tbody tr:last-child { border-bottom: 0; }

  .compare tbody th {
    padding: 0 0 10px;
    border: 0;
    font-family: var(--serif);
    font-weight: 400;
    font-size: 18px;
    letter-spacing: 0;
    text-transform: none;
    opacity: 1;
  }

  .compare td {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 18px;
    padding: 5px 0;
    border: 0;
    /* Muss hier stehen, nicht nur auf td > *: ein Wert ohne eigenes Element
       (der haeufige Fall, blanker Text in der Zelle) wird zum anonymen
       Flex-Element. Passt er in eine Zeile, schiebt space-between ihn nach
       rechts und alles sieht buendig aus – bricht er um, fuellt er die
       Restbreite und richtet sich nach der Zelle aus. Ohne diese Zeile
       steht ein zweizeiliger Wert deshalb ploetzlich linksbuendig und an
       anderer Stelle als die Zeilen darueber. */
    text-align: right;
  }
  .compare td::before {
    content: attr(data-haus);
    flex: none;
    max-width: 45%;
    /* erbt sonst das text-align: right der Zelle und rutscht beim Umbruch
       eines langen Hausnamens nach rechts */
    text-align: left;
    font-size: 12px;
    font-weight: 500;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    opacity: 0.6;
  }
  .compare td > * { text-align: right; }
}

/* ============================================================
   Entscheidungshilfe + Vertrauens-Zeile (aus v1 übernommen)
   ============================================================ */
.match { background: var(--creme); padding: clamp(70px, 11vh, 140px) var(--pad); }
.match-inner { max-width: 900px; margin: 0 auto; }
.match h2 {
  font-family: var(--serif);
  font-weight: 300;
  font-size: clamp(26px, 3.4vw, 44px);
  line-height: 1.12;
  margin: 12px 0 32px;
}
.match-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px 40px;
  padding: 22px 0;
  border-top: 1px solid var(--line);
}
.match-row:last-of-type { border-bottom: 1px solid var(--line); }
.match-row p { font-size: 16px; }

/* ============================================================
   Gästestimmen (Hausseite gestapelt, Übersicht zweispaltig)
   ============================================================ */
.quotes { display: grid; gap: clamp(28px, 4vw, 44px); margin-top: 12px; }
.quote { margin: 0; }
.quote blockquote {
  font-family: var(--serif);
  font-weight: 300;
  font-size: clamp(18px, 2vw, 23px);
  line-height: 1.5;
}
.quote blockquote::before { content: '\201E'; }
.quote blockquote::after { content: '\201C'; }
html[lang='en'] .quote blockquote::before { content: '\201C'; }
html[lang='en'] .quote blockquote::after { content: '\201D'; }
.quote figcaption {
  margin-top: 12px;
  font-size: 13px;
  letter-spacing: 0.02em;
  opacity: 0.75;
}
.quote figcaption a { text-decoration: underline; text-underline-offset: 3px; }
.quotes + .smallprint { margin-top: clamp(24px, 3vw, 36px); }

.trust-quotes .quotes--zwei { grid-template-columns: 1fr 1fr; gap: clamp(32px, 5vw, 72px); }
@media (max-width: 860px) {
  .trust-quotes .quotes--zwei { grid-template-columns: 1fr; }
}

/* ============================================================
   Umgebungs-Sektion mit Regionalkarte (Unterkunftsseiten)
   ============================================================ */
.env-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(30px, 5vw, 72px);
  align-items: center;
  max-width: 1100px;
  margin: 0 auto;
}
.env-map { background: var(--petrol); }
.env-map .map { height: auto; }
@media (max-width: 860px) {
  .env-grid { grid-template-columns: 1fr; }
}

/* ============================================================
   Reduced Motion
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .reveal, .reveal-up { opacity: 1; transform: none; transition: none; }
  /* Szenen laufen weiter (siehe main.js), aber der Kapiteltext blendet nicht
     ein, sondern steht sofort – eine Bewegung weniger. */
  html.scenes-on .scene .chapter-content { transform: none; transition: none; }
  .intro { display: none; }
  .menu-overlay { transition: none; }

  /* Panels: keine Breiten-Animation, nur der sanfte Abdunkler bleibt */
  .panel { transition: none; }
  .panels:hover .panel,
  .panels:focus-within .panel,
  .panels .panel:hover,
  .panels .panel:focus-within { flex-grow: 1; }
  .panel-extra { display: none; }

  /* Vorschau blendet nur ein, statt aus dem Marker aufzuziehen */
  .mapvorschau-in { transform: none; transition: opacity 0.2s ease; }

  /* Karten stehen sofort fertig da */
  .mapline { stroke-dashoffset: 0; transition: none; }
  .mapwater { opacity: 1; transition: none; }
  .mapziele { opacity: 1; transition: none; }
}

/* ============================================================
   Galerie-Grossansicht (Lightbox)
   Markup: site/snippets/lightbox.php · Logik: assets/js/lightbox.js
   ============================================================ */

/* Galeriekacheln sind Buttons – Browser-Optik zurücksetzen, Grid-Verhalten
   von .gallery > * (aspect-ratio, overflow) bleibt erhalten */
.gallery-item {
  border: 0;
  padding: 0;
  background: none;
  display: block;
  cursor: zoom-in;
  position: relative;
}
.gallery-item:focus-visible {
  outline: 2px solid var(--creme);
  outline-offset: 3px;
}

.lb {
  position: fixed;
  inset: 0;
  z-index: 200;
  background: rgba(8, 16, 14, 0.975);
  opacity: 0;
  transition: opacity 0.22s ease;
}
.lb.ist-auf { opacity: 1; }
.lb[hidden] { display: none; }
body.lb-offen { overflow: hidden; }

.lb-buehne {
  position: absolute;
  inset: 0;
  display: grid;
  grid-template-columns: 88px 1fr 88px;
  align-items: center;
  padding: 64px 0;
}

.lb-figur {
  grid-column: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 16px;
  min-height: 0;
  height: 100%;
}
.lb-bild {
  max-width: 100%;
  /* Platz für Bildunterschrift und Ränder freihalten */
  max-height: calc(100vh - 190px);
  width: auto;
  height: auto;
  object-fit: contain;
  transform: scale(0.98);
  transition: transform 0.22s ease;
}
.lb.ist-auf .lb-bild { transform: none; }

.lb-fuss {
  display: flex;
  align-items: baseline;
  gap: 14px;
  flex-wrap: wrap;
  justify-content: center;
  font-family: var(--sans);
  font-size: 12px;
  letter-spacing: 0.08em;
  color: rgba(247, 243, 232, 0.62);
  text-align: center;
  max-width: 70ch;
}
.lb-zaehler {
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.16em;
  white-space: nowrap;
  color: rgba(247, 243, 232, 0.45);
}

/* Bedienelemente */
.lb-pfeil,
.lb-schliessen {
  border: 1px solid rgba(247, 243, 232, 0.22);
  background: rgba(247, 243, 232, 0.06);
  color: var(--creme);
  border-radius: 50%;
  display: grid;
  place-items: center;
  transition: background 0.2s ease, border-color 0.2s ease;
}
.lb-pfeil:hover,
.lb-schliessen:hover {
  background: rgba(247, 243, 232, 0.16);
  border-color: rgba(247, 243, 232, 0.5);
}
.lb-pfeil:focus-visible,
.lb-schliessen:focus-visible {
  outline: 2px solid var(--creme);
  outline-offset: 3px;
}

.lb-pfeil {
  width: 52px;
  height: 52px;
  font-size: 30px;
  line-height: 1;
  justify-self: center;
}
/* Optische Mitte: ‹ › sitzen in ihrer Zeile leicht zu tief */
.lb-pfeil span { transform: translateY(-2px); }
.lb-pfeil--zurueck { grid-column: 1; }
.lb-pfeil--vor { grid-column: 3; }
.lb-pfeil[hidden] { display: none; }

.lb-schliessen {
  position: absolute;
  top: 20px;
  right: 20px;
  width: 46px;
  height: 46px;
  font-size: 26px;
  line-height: 1;
  z-index: 2;
}

@media (max-width: 760px) {
  .lb-buehne {
    grid-template-columns: 1fr;
    padding: 72px 12px 24px;
  }
  .lb-figur { grid-column: 1; }
  .lb-bild { max-height: calc(100vh - 210px); }
  /* Auf Touch wird gewischt; die Pfeile rücken unter das Bild */
  .lb-pfeil {
    position: absolute;
    bottom: 22px;
    width: 46px;
    height: 46px;
  }
  .lb-pfeil--zurueck { left: 18%; }
  .lb-pfeil--vor { right: 18%; }
  .lb-fuss { font-size: 11px; }
}

@media (prefers-reduced-motion: reduce) {
  .lb, .lb-bild { transition: none; }
  .lb-bild { transform: none; }
}
