:root {
  --red: #c41e24;
  --red-hot: #e0242a;
  --red-ink: #8f1218;
  --navy: #16202c;
  --navy-deep: #0d141c;
  --ink: #10151c;
  --muted: #5c6773;
  --line: #d9dee5;
  --paper: #f4f2ee;
  --paper-2: #eae7e1;
  --white: #ffffff;
  --font: "Source Sans 3", "Segoe UI", system-ui, sans-serif;
  --script: "Caveat", cursive;
  --max: 1240px;
  --ease: cubic-bezier(0.22, 1, 0.36, 1);
}

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

html {
  scroll-behavior: smooth;
  /* Unumgehbare Verteidigungslinie gegen den "durchsichtiger Rand beim
     Scrollen"-Bug auf iOS Safari, ergänzend zum eigentlichen Fix am
     .header selbst (siehe dortiger Kommentar: fehlendes viewport-fit=cover
     + nicht-deckender rgba-Hintergrund waren die tatsächliche Ursache).
     100% deckend statt rgba(...,0.92) – aus demselben Grund wie beim
     Header: Safari mischt einen teiltransparenten Hintergrund an dieser
     Stelle weiterhin mit dem Seiteninhalt, egal wie tief er in der
     Compositing-Ebene liegt. */
  background: rgb(13, 20, 28);
}

/* ——— Scroll-Reveal: jede Hauptsektion der Startseite (main.js beobachtet
   "main > section", siehe dort) startet leicht verschoben/unsichtbar und
   blendet einmalig sanft ein, sobald sie beim Scrollen ins Blickfeld
   kommt – analog zum bereits bestehenden Zeitstrahl-Reveal auf
   site/bewertungen.php, hier aber generisch für alle Sektionen statt nur
   eine einzelne Komponente. Der Hero (oben, sofort sichtbar) hat bereits
   seine eigene Eingangs-Animation (siehe .hero-content "rise" weiter unten)
   und wird von main.js bewusst nicht zusätzlich beobachtet. Kein Loop, kein
   Zurückklappen beim Hochscrollen – einmal sichtbar, bleibt sichtbar. ——— */
.js-reveal {
  opacity: 0;
  transform: translateY(28px);
  transition: opacity 0.7s var(--ease), transform 0.7s var(--ease);
}
.js-reveal.is-visible {
  opacity: 1;
  transform: translateY(0);
}
@media (prefers-reduced-motion: reduce) {
  .js-reveal { opacity: 1; transform: none; transition: none; }
}

/* Stellt sicher, dass das hidden-Attribut immer greift, auch wenn eine
   spätere Regel für dasselbe Element einen eigenen display-Wert setzt
   (z. B. .pd-inquiry-done { display: grid }). */
[hidden] {
  display: none !important;
}

body {
  font-family: var(--font);
  color: var(--ink);
  background: var(--paper);
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

body::before {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  /* War z-index: 400 – deutlich ÜBER dem Header (z-index: 60). Das war
     vermutlich die eigentliche Ursache des "durchsichtiger Rand beim
     Scrollen"-Bugs: dieses fixed-Element mit inset:0 (deckt den gesamten
     Viewport ab, auch den Safe-Area-Bereich oben) konkurrierte mit dem
     Header um dieselbe fixierte Position ganz oben, und iOS Safari konnte
     bei zwei überlappenden fixed-Elementen mit inset:0 im Safe-Area-
     Bereich offenbar inkonsistent rendern, welches davon dort sichtbar
     ist – trotz korrektem viewport-fit=cover und deckendem Header-
     Hintergrund. Die Textur muss nur über dem normalen Seiteninhalt
     liegen, nicht über dem Header selbst – z-index jetzt niedriger als
     .header (60). */
  z-index: 1;
  opacity: 0.045;
  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

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

/* ——— Generische Bild-Lade-Animation (Chat-Anforderung: "loading animation
   wenn die Bilder von den Objekten noch nicht geladen haben") ———
   .js-img-loading wird per JS (siehe imageLoadingSkeletons() in main.js)
   auf jeden Bild-Container gesetzt, dessen <img> noch nicht fertig geladen
   ist (img.complete === false), und automatisch entfernt, sobald es lädt.
   Bewusst EIN generisches Paar Klassen statt einer eigenen Lösung pro
   Bildbereich (Startseite: .featured-media/.prop-tile-visual,
   Objektliste: .prop-tile-visual, Objektseite: .pd-gallery) – alle drei
   sind bereits position: relative (nötig, damit der Skeleton-Hintergrund
   sich exakt über den Container legt), der Shimmer-Effekt selbst ist
   überall identisch. Der Container braucht kein eigenes ::before/::after,
   da background-image direkt auf ihm sitzt – einfacher als ein
   zusätzliches Pseudo-Element pro Bildbereich zu pflegen. */
.js-img-loading {
  background-color: var(--paper-2);
  background-image: linear-gradient(
    100deg,
    var(--paper-2) 30%,
    rgba(255, 255, 255, 0.75) 50%,
    var(--paper-2) 70%
  );
  background-size: 200% 100%;
  animation: imgShimmer 1.6s ease-in-out infinite;
}

/* Auf dunklen Bildbereichen (Objekt-Detailseite: .pd-gallery/.pd-stage
   liegt auf var(--navy-deep)) wäre der helle --paper-2-Shimmer ein
   Kontrastbruch – eigene, dunkle Variante mit demselben Bewegungsmuster. */
.js-img-loading.js-img-loading-dark {
  background-color: var(--navy);
  background-image: linear-gradient(
    100deg,
    var(--navy) 30%,
    rgba(255, 255, 255, 0.08) 50%,
    var(--navy) 70%
  );
  background-size: 200% 100%;
}

@keyframes imgShimmer {
  0% { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

@media (prefers-reduced-motion: reduce) {
  .js-img-loading {
    animation: none;
  }
}

a {
  color: inherit;
  text-decoration: none;
}

button,
input,
select {
  font: inherit;
}

button {
  cursor: pointer;
  border: none;
  background: none;
}

ul {
  list-style: none;
}

.container {
  width: min(100% - 2rem, var(--max));
  margin-inline: auto;
}

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--red);
  margin-bottom: 0.85rem;
}

.eyebrow::before {
  content: "";
  width: 1.25rem;
  height: 1.5px;
  background: var(--red);
}

.display {
  font-family: var(--font);
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.2;
}

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  min-height: 3rem;
  padding: 0.8rem 1.35rem;
  font-family: var(--font);
  font-weight: 600;
  letter-spacing: 0.01em;
  font-size: 0.95rem;
  transition: transform 0.3s var(--ease), background 0.25s ease, color 0.25s ease;
  border-radius: 2px;
}

.btn:hover {
  transform: translateY(-2px);
}

.btn-primary {
  background: var(--red);
  color: var(--white);
}

.btn-primary:hover {
  background: var(--red-ink);
}

.btn-ghost {
  background: transparent;
  color: var(--white);
  border: 1.5px solid rgba(255, 255, 255, 0.4);
  clip-path: none;
}

.btn-ghost:hover {
  border-color: var(--white);
  background: rgba(255, 255, 255, 0.08);
}

.btn-ink {
  background: var(--ink);
  color: var(--white);
}

/* ——— Logo ———
   Das komplette Logo (Dach + "immo" + "AKTIV") ist ein einziges SVG mit
   viewBox 460×215, damit alle Teile bei jeder Größe exakt zueinander sitzen.
   Gesteuert wird nur noch die Breite; die Höhe folgt dem Seitenverhältnis. */
.logo {
  display: inline-block;
  line-height: 0;
}

.logo-mark {
  display: block;
  width: 7.6rem;
  height: auto;
}

.logo-xl .logo-mark {
  width: clamp(11rem, 27vw, 21rem);
}

/* ——— Header ——— */
/* Der difference-Blend sitzt bewusst NICHT auf .header selbst, sondern nur
   auf den Textelementen: so bleibt das Logo in Originalfarben, während
   Navigation und CTA sich weiter gegen helle wie dunkle Hero-Bilder
   absetzen. (Ein Blend am Container würde jeden Nachfahren erfassen und
   liesse sich am Kind auch mit isolation nicht zurücknehmen.) */
.header {
  /* ——— iOS-Fix-Historie (wichtig für jede künftige Änderung hier!) ———
     Die tatsächliche Ursache des "durchsichtiger Rand beim Scrollen"-Bugs,
     gefunden per Frame-Analyse eines vom Nutzer aufgenommenen Bildschirm-
     Videos: iOS Safari feuert das `scroll`-Event während eines SCHNELLEN
     Wischens (Momentum-/Fling-Scroll) nicht kontinuierlich, sondern
     gedrosselt/verzögert. Der damalige Mechanismus (JS setzte .is-scrolled
     per scroll-Listener) reagierte dadurch zu spät: der Header blieb
     während der GESAMTEN schnellen Wisch-Bewegung im alten, transparenten
     Zustand. Der Fix: background HIER bleibt auf Mobile (<=960px) IMMER zu
     100% deckend (kein rgba-Alpha-Wert), unabhängig von jedem JS-Event.
     Der "transparent über dem Hero"-Look kehrt seit der Chat-Anforderung
     "Menü über das Hero-Bild" trotzdem zurück, siehe body.hero-top .header
     Regel weiter unten – gesteuert per scroll-Event (main.js,
     heroHeaderOverlay()), trotz der oben beschriebenen Drosselungs-
     Problematik: der echte .header-background HIER bleibt dabei die ganze
     Zeit unangetastet 100% deckend (siehe .header::before weiter unten für
     den eigentlichen, separaten Deckkraft-Aufbau) – selbst wenn das
     scroll-Event während eines schnellen Wischens ein paar Frames
     aussetzt, kann daher NIE der alte Durchscheinen-Bug zurückkehren,
     bestenfalls wirkt der Fade-Übergang selbst kurz sprunghaft statt
     perfekt gleichmäßig. Der hier gesetzte background bleibt der
     GARANTIERTE Normalzustand (100% deckend); nur die body.hero-top-Regel
     überschreibt ihn gezielt und ausschließlich ganz oben vor dem
     Scrollen. */
  /* position: fixed statt sticky (zurückgewechselt): ein Vergleich mit
     einem nachweislich funktionierenden Minimalbeispiel (gleiches Problem,
     gleiche Fix-Bausteine: viewport-fit=cover + deckender Hintergrund +
     padding-top: env(...) am Header) zeigte fixed statt sticky als
     Unterschied. backdrop-filter (Blur-Effekt) ebenfalls entfernt: erzwingt
     einen eigenen GPU-Compositing-Layer, der auf iOS Safari bekanntermaßen
     mit fixed/sticky-Positionierung kollidieren kann – nicht im
     funktionierenden Beispiel enthalten, daher als mögliche Restursache
     ebenfalls ausgeschlossen statt weiter mitgeführt. */
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 60;
  color: var(--white);
  /* 100% deckend (kein rgba-Alpha-Wert) – iOS Safari übernimmt die Farbe
     der Statusleiste vom fixierten Element am oberen Rand nur, wenn dessen
     Hintergrund vollständig deckend ist. WICHTIG: bleibt so auf MOBILE
     (siehe @media max-width:960px weiter oben, wo der iOS-Bug auftrat).
     Eine leicht transparente Desktop-Variante gibt es separat weiter unten
     (@media min-width:961px) – Desktop-Safari/-Browser kennen das
     Adressleisten-Verhalten nicht, das den Bug verursacht hat, daher dort
     unbedenklich. Der Fade-Effekt am unteren Rand (siehe .header::after
     weiter unten) sitzt bewusst in einem separaten Pseudo-Element statt
     hier direkt einen Gradient einzusetzen. */
  background: rgb(13, 20, 28);
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
  box-shadow: 0 8px 24px -16px rgba(0, 0, 0, 0.4);
  /* Puffer für den elastischen Overscroll ganz oben (Rubber-Band-Bounce)
     und die Statusleiste/Dynamic-Island-Aussparung – background füllt
     diesen Padding-Bereich automatisch mit (CSS background-origin:
     padding-box ist der Standard). Braucht viewport-fit=cover im
     viewport-Meta-Tag (siehe <head> jeder Seite), sonst liefert
     env(safe-area-inset-top) immer 0. */
  padding-top: env(safe-area-inset-top);
}

/* ——— Weicher Übergang am unteren Header-Rand (Chat-Anforderung: "nicht so
   hart wirken") – ein zusätzliches Pseudo-Element UNTERHALB des Headers
   (top: 100%, exakt an der Unterkante, NICHT davor), das von der Header-
   Farbe zu transparent verläuft. Ein früherer Versuch ließ es bei
   calc(100% - 0.75rem) beginnen, also ein Stück in den Header hineinragen
   – das überlagerte dabei sichtbar einen Teil des Logos ("AKTIV" wurde
   dadurch schwerer erkennbar, Chat-Rückmeldung), daher zurückgesetzt auf
   den exakten Kantenübergang. Bewusst NICHT als Änderung am
   .header-background selbst (siehe Kommentar oben) – der Header braucht
   seinen 100%-deckenden Hintergrund für den iOS-Safe-Area-Fix, dieser Fade
   ist rein additiv und überlappt nur optisch in den Content-Bereich
   hinein. pointer-events: none, damit er keine Klicks auf den Content
   direkt darunter abfängt. Verschwindet automatisch, sobald das mobile
   Menü aufklappt (.nav.open, siehe Media-Query weiter unten) – das
   aufgeklappte Menü hat einen eigenen soliden Hintergrund und soll klar
   abgegrenzt bleiben, kein Fade an dessen Übergang zum Header. ——— */
.header::after {
  content: "";
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  height: 1rem;
  pointer-events: none;
  background: linear-gradient(to bottom, rgb(13, 20, 28), transparent);
}
.header:has(.nav.open)::after {
  display: none;
}

/* ——— Mobile: Menü transparent über dem Hero-Bild, stufenlos beim Scrollen
   aufbauend (Chat-Anforderungen) ———
   Siehe ausführliche Erklärung im .header-Kommentar weiter oben, warum der
   echte .header-background selbst NIE wieder angefasst wird (iOS-Bug-
   Historie). Stattdessen: main.js (heroHeaderOverlay(), scroll-Event mit
   requestAnimationFrame-Throttling) berechnet fortlaufend einen
   Fortschrittswert und schreibt ihn als CSS-Variable --hero-fade auf
   <body> – kein zusätzliches DOM-Element, keine Logo/Nav-Duplizierung
   nötig. Der echte, immer 100% deckende .header-Hintergrund bleibt
   unverändert im DOM; .header::before (siehe unten) übernimmt den
   eigentlichen, sichtbaren Deckkraft-Aufbau. Klasse .hero-top bleibt als
   reiner Ein/Aus-Schalter für Dinge, die nicht stufenlos interpolierbar
   sind (border/box-shadow, siehe hier; mix-blend-mode, siehe unten). */
@media (max-width: 960px) {
  body.hero-top .header {
    background: transparent;
    border-bottom-color: transparent;
    box-shadow: none;
  }
  /* ——— Stufenloser Übergang statt hartem Sprung (Chat-Anforderung: "nicht
     so ein harter Übergang", soll sich "mit dem nach unten scrollen
     aufbauen"; Nachbesserung: "zuerst linear und dann auf einmal komplett
     dunkel" – siehe Kommentar in main.js zur Ease-out-Kurve) ———
     .header selbst bleibt background:transparent (siehe oben) – der
     eigentliche, sichtbare Deckkraft-Aufbau passiert in diesem separaten
     ::before-Pseudo-Element dahinter (z-index -1, liegt hinter
     .header-inner/Logo/Burger). Grund für den Umweg über ein eigenes
     Element statt direkt opacity auf .header zu animieren: opacity auf
     .header selbst würde auch Logo/Nav/Burger durchscheinend machen, nicht
     nur den Hintergrund. Der Fortschritt kommt von main.js
     (heroHeaderOverlay(), scroll-Event mit requestAnimationFrame-
     Throttling) als CSS-Variable --hero-fade (0 = ganz oben, 1 = Fade
     abgeschlossen), bereits mit eigener Ease-out-Kurve (main.js). Die
     CSS-transition hier ist bewusst länger als ein einzelnes rAF-Intervall
     (0.3s statt vorher 0.15s): bei normalem, nicht perfekt gleichmäßigem
     Scrollen (kurze Pausen, unterschiedlich schnelle Wischbewegungen)
     können zwei aufeinanderfolgende --hero-fade-Werte spürbar auseinander
     liegen – eine zu kurze Transition ließ das wie ein sichtbares
     "Einschnappen" statt eines fließenden Übergangs wirken, selbst mit der
     Ease-out-Kurve im JS. */
  .header::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    background: rgb(13, 20, 28);
    opacity: var(--hero-fade, 1);
    transition: opacity 0.3s ease-out;
  }
  /* Logo/Burger erst ab einer sichtbar transparenten Kopfzeile im
     Differenz-Blend-Modus (Lesbarkeit über hellen wie dunklen
     Hero-Bildbereichen) – ein stufenloses Überblenden des Blend-Modus
     selbst ist technisch nicht möglich (keine interpolierbare CSS-
     Eigenschaft), daher ein harter Wechsel bei --hero-fade < 0.5. Fällt
     dabei nicht negativ auf, da zu diesem Zeitpunkt der dunkle
     ::before-Hintergrund ohnehin schon den Großteil der Deckkraft trägt.
     "<" style-mäßig über eine eigene Klasse statt @property+Vergleich im
     CSS selbst, siehe main.js: ab 0.5 setzt der Observer-Callback direkt
     die Klasse .hero-fade-solid. */
  body.hero-top:not(.hero-fade-solid) .header .logo,
  body.hero-top:not(.hero-fade-solid) .header .menu-toggle {
    mix-blend-mode: difference;
    color: var(--white);
  }
  body.hero-top.hero-fade-solid .header .logo,
  body.hero-top.hero-fade-solid .header .menu-toggle {
    mix-blend-mode: normal;
    color: var(--white);
  }
  body.hero-top .header::after {
    display: none;
  }
  /* Aufgeklapptes mobiles Menü muss IMMER solide bleiben, auch ganz oben im
     Hero – sonst hätte die Leiste mit Logo/X-Icon keinen deckenden
     Hintergrund während .nav selbst schon einen hat (sichtbarer Bruch).
     Überschreibt die hero-top-Transparenz gezielt zurück auf den normalen
     deckenden Zustand, identisch zum .header-Basiswert. */
  body.hero-top .header:has(.nav.open) {
    background: rgb(13, 20, 28);
    border-bottom-color: rgba(255, 255, 255, 0.06);
  }
  body.hero-top .header:has(.nav.open)::before {
    display: none;
  }
  body.hero-top .header:has(.nav.open) .logo,
  body.hero-top .header:has(.nav.open) .menu-toggle {
    mix-blend-mode: normal;
    color: var(--white);
  }
}

/* ——— Desktop: auch der Fade-Übergang direkt unter dem Header transparenter
   (Chat-Anforderung: "den unteren Rand auch transparent machen") ———
   Der Header selbst geht am Desktop (siehe @media min-width:961px oben)
   bereits zur Unterkante hin in Transparenz über – dieser Fade direkt
   darunter startete aber weiterhin bei voller Deckfarbe, was am Übergang
   einen kleinen Sprung in der Deckkraft erzeugt hätte. Startet auf Desktop
   jetzt stattdessen bei derselben reduzierten Deckkraft wie das untere
   Ende des Headers (rgba .55), statt bei 100% – der gesamte untere
   Bereich wirkt dadurch durchgängig transparent, ohne Bruch am Übergang.
   Auf Mobile (<=960px, siehe Basis-Regel oben diesem Block) bleibt der
   Fade unverändert bei voller Deckfarbe startend, da der Header dort
   selbst zwingend 100% deckend bleiben muss (iOS-Fix). */
@media (min-width: 961px) {
  .header::after {
    background: linear-gradient(to bottom, rgba(13, 20, 28, 0.55), transparent);
  }
}

/* ——— Desktop: transparenterer Header (Chat-Anforderung, zwei Korrekturen
   durchlaufen – Endstand: oben deckend, ab der Hälfte nach unten hin
   transparent) ———
   NUR ab 961px (siehe @media min-width unten) – auf Mobile (<=960px) bleibt
   .header zwingend 100% deckend (siehe Kommentar an der Basis-Regel oben),
   da dort der iOS-Safari-Adressleisten-Bug auftrat, den ein transparenter
   Hintergrund wieder zurückbringen würde. Desktop-Browser kennen dieses
   Verhalten nicht, daher hier unbedenklich.
   Verlauf: oben (0%–50%) vollständig deckend (rgb ohne Alpha, Logo/Nav
   liegen hier), ab der Mitte (50%) nimmt die Deckkraft nach unten hin ab,
   bis der Header am unteren Rand (100%) am transparentesten ist – dort
   geht er nahtlos in den separaten Fade (.header::after, siehe oben) über.
   backdrop-filter sorgt im unteren, transparenten Bereich zusätzlich für
   einen dezenten Weichzeichner-Effekt auf dem durchscheinenden
   Seiteninhalt (Glass-Look) statt hartem Durchscheinen. */
@media (min-width: 961px) {
  .header {
    background: linear-gradient(
      to bottom,
      rgb(13, 20, 28) 0%,
      rgb(13, 20, 28) 50%,
      rgba(13, 20, 28, 0.55) 100%
    );
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    /* Chat-Anforderung: "ist da noch ein border?" – die Basis-Regel setzt
       border-bottom + box-shadow (beide als feste, harte Linie/Kante
       gedacht für den früheren, komplett deckenden Header). Beide passen
       nicht mehr zum jetzt bewusst sanft auslaufenden Desktop-Header – eine
       scharfe 1px-Linie bzw. ein Schlagschatten würden den weichen
       Transparenz-Verlauf wieder hart abschneiden. Auf Mobile (<=960px)
       bleiben beide unverändert bestehen, dort ist der Header ja weiterhin
       voll deckend und eine klare Abgrenzung zum Content sinnvoll. */
    border-bottom: none;
    box-shadow: none;
  }
}

/* ——— Aufgeräumt: .header ist jetzt (siehe Kommentar oben) IMMER solide,
   daher braucht es weder den mix-blend-mode:difference-Trick noch die
   vormals per is-scrolled/body:not(:has(.hero))-Klasse nachgezogenen
   Hintergrund-Regeln mehr – Logo/Nav/CTA sind jetzt einfach immer normal
   eingefärbt, kein Blend-Modus nötig. .header-solid und die alte
   .header-top-shield-Notfall-Blende wurden komplett entfernt (nicht mehr
   referenziert, auch nicht in header.php). ——— */

.header-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 4.25rem;
}

.nav {
  display: flex;
  gap: 1.6rem;
}

.nav a {
  font-size: 0.9rem;
  font-weight: 500;
  letter-spacing: 0.01em;
  opacity: 0.82;
  transition: opacity 0.2s ease;
}

.nav a:hover {
  opacity: 1;
}

.header-cta {
  font-size: 0.9rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  border-bottom: 1.5px solid var(--red);
  padding-bottom: 0.1rem;
  color: var(--white);
}

.menu-toggle {
  display: none;
  color: var(--white);
  width: 2.5rem;
  height: 2.5rem;
  place-items: center;
}

/* ——— Hero ——— */
.hero {
  position: relative;
  background: var(--navy-deep);
  color: var(--white);
}

.hero-stage {
  position: relative;
  min-height: 100vh;
  /* Statt 100dvh (das sich bei iOS Safari WÄHREND der Adressleisten-
     Animation live ändert und damit den Header-Flacker-Bug verursachte,
     siehe viewportHeightFix() in main.js): --vh wird per JS aus der
     tatsächlichen, nur nach abgeschlossenem resize aktualisierten
     window.innerHeight berechnet. 1vh als Fallback, falls JS (noch) nicht
     gelaufen ist – dann identisch zum ursprünglichen 100vh-Verhalten. */
  min-height: calc(var(--vh, 1vh) * 100);
  display: grid;
  align-items: end;
  overflow: hidden;
}

.hero-media {
  position: absolute;
  inset: 0;
}

/* ——— Desktop: Hero-Bild beginnt sichtbar erst unterhalb des Headers (Chat-
   Anforderung "Bilder im Hero faden unter dem Menü anfangen lassen") ———
   Der transparente/fadende Desktop-Header (siehe @media min-width:961px bei
   .header weiter oben) schwebte bisher über dem kompletten, bis ganz nach
   oben reichenden Hero-Bild. Jetzt wird .hero-media stattdessen erst ab der
   Header-Unterkante positioniert (top: Header-Höhe statt 0) – der Bereich
   darüber zeigt den normalen .hero-Hintergrund (var(--navy-deep)), kein Bild
   mehr darunter. Der Header bleibt bewusst weiterhin transparent/fadend
   (keine Rückkehr zu solide) – oben scheint jetzt einfach die dunkle
   Hero-Fläche statt des Fotos durch, was optisch ruhig wirkt und keine neue
   Regel am Header selbst braucht. 4.25rem = .header-inner min-height (die
   effektive Header-Höhe auf Desktop, siehe dort). Nur ab 961px: auf Mobile
   bleibt der Header ja ohnehin fixed/deckend ÜBER dem Vollbild-Hero (siehe
   body.hero-top-Logik), dort ergibt ein Versatz keinen Sinn. */
@media (min-width: 961px) {
  .hero-media {
    top: 4.25rem;
    bottom: 0;
    left: 0;
    right: 0;
  }

  /* .hero-cut (die rote Diagonale rechts, siehe dort) folgt demselben
     Versatz, damit sie optisch zum jetzt erst unterhalb des Headers
     beginnenden Bildbereich passt, statt in den jetzt bildlosen oberen
     Streifen hineinzuragen. .hero-veil (der dunkle Lesbarkeits-Scrim)
     bleibt bewusst bei inset:0 – er ist dunkel auf dunklem Hero-Hintergrund,
     ein Versatz dort wäre nicht sichtbar. */
  .hero-cut {
    top: 4.25rem;
  }
}

.hero-media img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 58% center;
  filter: saturate(0.92) contrast(1.06) brightness(0.92);
  opacity: 0;
  transform: scale(1.06);
  transition: opacity 1.8s ease;
}

.hero-media img.is-active {
  opacity: 1;
  transform: scale(1);
  z-index: 0;
  animation: heroKen 7s ease-out forwards;
}

@keyframes heroKen {
  from {
    transform: scale(1.06);
  }
  to {
    transform: scale(1);
  }
}

.hero-veil {
  position: absolute;
  inset: 0;
  z-index: 1;
  background:
    linear-gradient(
      105deg,
      rgba(13, 20, 28, 0.82) 0%,
      rgba(13, 20, 28, 0.55) 34%,
      rgba(13, 20, 28, 0.18) 62%,
      rgba(13, 20, 28, 0.28) 100%
    ),
    linear-gradient(to top, rgba(13, 20, 28, 0.72) 0%, transparent 38%);
}

.hero-cut {
  position: absolute;
  right: 0;
  top: 0;
  bottom: 0;
  width: min(46vw, 38rem);
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(
    200deg,
    transparent 0%,
    transparent 42%,
    rgba(196, 30, 36, 0.12) 100%
  );
  clip-path: polygon(28% 0, 100% 0, 100% 100%, 0 100%);
  border-left: 1px solid rgba(255, 255, 255, 0.08);
}

.hero-cut::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 2px;
  background: linear-gradient(
    to bottom,
    transparent 8%,
    var(--red) 28%,
    var(--red) 62%,
    transparent 92%
  );
  transform: skewX(-12deg);
  transform-origin: top left;
}

.hero-content {
  position: relative;
  z-index: 2;
  width: min(100% - 2.5rem, var(--max));
  margin-inline: auto;
  padding: 7.5rem 0 3.75rem;
  display: grid;
  gap: 2.5rem;
  animation: rise 1s var(--ease) both;
}

@keyframes rise {
  from {
    opacity: 0;
    transform: translateY(22px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.hero-copy {
  max-width: 34rem;
}

.hero-brand {
  margin-bottom: 1.6rem;
}

.hero-motto {
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.72);
  margin-bottom: 1rem;
}

.hero h1 {
  max-width: 14ch;
  font-size: clamp(1.75rem, 3.4vw, 2.85rem);
  line-height: 1.18;
  letter-spacing: -0.025em;
  font-weight: 600;
}

.hero-highlight-line {
  display: block;
  color: rgba(255, 255, 255, 0.78);
  font-weight: 500;
}

/* ——— Beide Wörter stehen zunächst ganz normal da (weiß, gleiches Gewicht
   wie der Rest der Zeile) und wechseln erst nach kurzer, gestaffelter
   Verzögerung zu fett+rot – "heute" zuerst, "morgen" danach. Der
   eigentliche Wechsel läuft über eine einzige CSS-transition auf
   color+font-weight (keine zwei überlagerten Textkopien mehr – das
   erzeugte zuvor Rendering-Artefakte); ausgelöst wird er, indem
   hero.php per kleinem Inline-Script die Klasse .is-highlighted
   zeitversetzt pro Wort hinzufügt (siehe <script> am Ende von
   site/components/hero.php). Moderne Browser blenden font-weight bei
   einer transition weich statt hart zwischen den Stufen, dadurch wirkt
   auch der Gewichtswechsel wie ein echtes "Fett-Werden" statt ein
   Sprung. ——— */
.hero-highlight-word {
  display: inline-block;
  font-weight: 500;
  color: rgba(255, 255, 255, 0.78);
  transition: color 0.7s cubic-bezier(0.16, 1, 0.3, 1), font-weight 0.7s cubic-bezier(0.16, 1, 0.3, 1);
}

.hero-highlight-word.is-highlighted {
  font-weight: 700;
  color: var(--red-hot);
}

@media (prefers-reduced-motion: reduce) {
  .hero-highlight-word {
    transition: none;
    font-weight: 700;
    color: var(--red-hot);
  }
}

/* ——— Generische Basis für alle scroll-ausgelösten Wort-Hervorhebungen
   (gleiches Prinzip wie .hero-highlight-word oben, aber durch
   Scroll-Sichtbarkeit statt einen festen Zeit-Delay ausgelöst): das Wort
   steht zunächst in der normalen Fließtextfarbe der jeweiligen Sektion da
   und färbt sich rot ein, sobald die zugehörige Sektion beim Scrollen ins
   Blickfeld kommt. Jede Verwendungsstelle bekommt zusätzlich eine eigene,
   nummerierte Klasse (z. B. .services-highlight-word-1) NUR als JS-Anker
   für die passende Sektion + Reihenfolge – keine eigenen Styles nötig,
   die Optik kommt komplett von hier. Auf dunklem Untergrund (siehe
   .hero-highlight-word) bleibt eine eigene Definition nötig, da dort auch
   die Ausgangsfarbe (helles Weiß statt dunkles Ink) eine andere ist. ——— */
.highlight-word {
  display: inline-block;
  color: var(--ink);
  transition: color 0.6s cubic-bezier(0.16, 1, 0.3, 1);
}
.highlight-word.is-highlighted { color: var(--red); }

@media (prefers-reduced-motion: reduce) {
  .highlight-word { transition: none; }
}

.hero-sub {
  margin-top: 1.1rem;
  max-width: 28rem;
  color: rgba(255, 255, 255, 0.72);
  font-size: 1.02rem;
  line-height: 1.55;
}

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: 1.85rem;
}

.hero-actions-desktop {
  display: flex;
}

.hero-meta {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin-top: 0.5rem;
}

.hero-progress {
  display: flex;
  gap: 0.45rem;
  pointer-events: auto;
}

.hero-progress button {
  width: 1.75rem;
  height: 2px;
  background: rgba(255, 255, 255, 0.28);
  transition: width 0.35s var(--ease), background 0.25s ease;
}

.hero-progress button.is-active {
  width: 2.75rem;
  background: var(--red);
}

.hero-counter {
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  color: rgba(255, 255, 255, 0.55);
}

.hero-counter i {
  font-style: normal;
  margin-inline: 0.2rem;
  opacity: 0.5;
}

.hero-cta-rail {
  display: none;
  background: var(--paper);
  color: var(--ink);
  border-top: 3px solid var(--red);
}

/* ——— Marquee ——— */
.marquee {
  background: var(--red);
  color: var(--white);
  overflow: hidden;
  border-block: 0;
  transform: skewY(-1.2deg);
  margin-block: -0.4rem;
  position: relative;
  z-index: 4;
}

.marquee-track {
  display: flex;
  width: max-content;
  gap: 0;
  animation: marquee 28s linear infinite;
  padding: 0.95rem 0;
}

.marquee-track span {
  font-weight: 600;
  font-size: clamp(0.85rem, 1.6vw, 1rem);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding-inline: 1.4rem;
  white-space: nowrap;
}

.marquee-track i {
  font-style: normal;
  opacity: 0.45;
}

@keyframes marquee {
  to {
    transform: translateX(-50%);
  }
}

/* ——— Services ——— */
.services {
  background: var(--navy);
  color: var(--white);
  padding: clamp(4.5rem, 9vw, 7rem) 0;
  position: relative;
}

.services-head {
  display: grid;
  grid-template-columns: 1.2fr 0.8fr;
  gap: 2rem;
  margin-bottom: 2.5rem;
  align-items: end;
}

.services-head .display {
  font-size: clamp(1.7rem, 3.4vw, 2.6rem);
  line-height: 1.2;
  letter-spacing: -0.02em;
  max-width: 18ch;
}

.services-head p {
  color: rgba(255, 255, 255, 0.65);
  max-width: 28rem;
}

.service-rows {
  border-top: 1px solid rgba(255, 255, 255, 0.14);
}

.service-row {
  display: grid;
  grid-template-columns: 5.5rem 1fr auto;
  gap: 1.5rem;
  align-items: center;
  padding: 1.6rem 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.14);
  transition: background 0.3s ease, padding 0.35s var(--ease);
}

.service-row:hover {
  background: rgba(255, 255, 255, 0.03);
  padding-left: 0.75rem;
}

.service-num {
  font-size: 1.35rem;
  font-weight: 600;
  color: var(--red);
  letter-spacing: 0;
  line-height: 1;
}

.service-row h3 {
  font-size: clamp(1.05rem, 1.8vw, 1.25rem);
  font-weight: 600;
  letter-spacing: -0.01em;
  margin-bottom: 0.3rem;
}

.service-row p {
  color: rgba(255, 255, 255, 0.62);
  max-width: 34rem;
}

.service-ico {
  width: 3.4rem;
  height: 3.4rem;
  border: 1.5px solid rgba(255, 255, 255, 0.35);
  border-radius: 50%;
  display: grid;
  place-items: center;
  transition: border-color 0.25s ease, background 0.25s ease;
}

.service-row:hover .service-ico {
  border-color: var(--red);
  background: var(--red);
}

/* ——— Properties ——— */
.properties {
  background: var(--paper);
  padding: clamp(4.5rem, 9vw, 7rem) 0;
  position: relative;
}

.properties::before {
  content: "";
  position: absolute;
  inset: 0 auto auto 0;
  width: 100%;
  height: 7rem;
  background: var(--navy);
  clip-path: polygon(0 0, 100% 0, 100% 0, 0 100%);
}

.prop-head {
  display: flex;
  justify-content: space-between;
  align-items: end;
  gap: 1.5rem;
  margin-bottom: 2.5rem;
  position: relative;
}

.prop-head .display {
  font-size: clamp(1.7rem, 3.4vw, 2.5rem);
  line-height: 1.2;
  letter-spacing: -0.02em;
  max-width: 16ch;
}

.featured {
  display: grid;
  grid-template-columns: 1.35fr 0.9fr;
  min-height: 32rem;
  margin-bottom: 1.25rem;
  background: var(--navy);
  color: var(--white);
  overflow: hidden;
  cursor: pointer;
}

.featured-cta {
  align-self: flex-start;
  pointer-events: none;
}

.featured-media {
  position: relative;
  min-height: 22rem;
  overflow: hidden;
}

.featured-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.8s var(--ease);
}

.featured:hover .featured-media img {
  transform: scale(1.05);
}

.featured-slash {
  position: absolute;
  right: -1px;
  top: 0;
  bottom: 0;
  width: 18%;
  background: var(--navy);
  clip-path: polygon(100% 0, 100% 100%, 0 100%);
}

.featured-body {
  padding: clamp(1.75rem, 4vw, 2.75rem);
  display: flex;
  flex-direction: column;
  justify-content: center;
  position: relative;
}

.featured-body::before {
  content: "";
  position: absolute;
  left: 0;
  top: 12%;
  bottom: 12%;
  width: 3px;
  background: var(--red);
}

.featured-status {
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--red);
  margin-bottom: 0.65rem;
}

.featured-price {
  font-size: clamp(1.55rem, 2.8vw, 2rem);
  font-weight: 600;
  letter-spacing: -0.02em;
  margin-bottom: 0.5rem;
}

.featured-body h3 {
  font-size: clamp(1.1rem, 1.8vw, 1.35rem);
  font-weight: 600;
  letter-spacing: -0.015em;
  line-height: 1.25;
  margin-bottom: 0.65rem;
}

.featured-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  color: rgba(255, 255, 255, 0.65);
  font-size: 0.92rem;
  margin: 1.25rem 0 1.75rem;
}

.featured-meta span {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
}

/* Horizontal scrollbares Karussell (auf allen Breiten, nicht nur mobil) –
   zeigt bei der üblichen Container-Breite (max. 1240px) rund 5 Karten,
   der Rest lässt sich per Maus-Wheel/Trackpad/Touch/Drag seitlich
   durchscrollen. Endet, sofern es weitere Objekte gibt, in einer
   .prop-tile-more-Hinweiskarte (siehe site/components/properties.php). */
.prop-rail {
  display: flex;
  gap: 1rem;
  overflow-x: auto;
  scroll-snap-type: x proximity;
  padding-bottom: 0.35rem;
  scrollbar-width: thin;
}
.prop-rail .prop-tile,
.prop-rail .prop-tile-more {
  flex: 0 0 15.5rem;
  scroll-snap-align: start;
}

.prop-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(17rem, 1fr));
  gap: 1.5rem;
}

/* Listenansicht: eine Spalte, großzügigere Karten mit Rundung, Schatten und
   Hover-Lift statt einer nüchternen, eng anliegenden Zeile – Bildbereich
   links (abgerundet, eigene kleine Bildkachel), Infos rechts, mit klarer
   Preis-Auszeichnung (auf .prop-tile-price). */
.prop-grid.prop-grid-list {
  grid-template-columns: 1fr;
  gap: 1.25rem;
}
.prop-grid-list .prop-tile {
  display: flex;
  flex-direction: row;
  align-items: stretch;
  min-height: 0;
  color: var(--ink);
  background: var(--white);
  border: none;
  border-radius: 16px;
  box-shadow: 0 1px 2px rgba(16, 21, 28, 0.06), 0 8px 24px rgba(16, 21, 28, 0.06);
  transition: box-shadow 0.25s ease, transform 0.25s ease;
}
.prop-grid-list .prop-tile:hover {
  box-shadow: 0 4px 10px rgba(16, 21, 28, 0.08), 0 16px 36px rgba(16, 21, 28, 0.12);
  transform: translateY(-2px);
}
.prop-grid-list .prop-tile-visual {
  position: relative;
  aspect-ratio: auto;
  flex: 0 0 15rem;
  min-height: 12rem;
  margin: 0.75rem 0 0.75rem 0.75rem;
  border-radius: 12px;
  overflow: hidden;
}
/* In der Listenansicht ist .prop-tile-info der rechte Flex-Bereich (Text +
   Button nebeneinander im Fluss); in der Rasteransicht bleibt es beim
   normalen Block-Layout unter dem Bild (siehe .prop-tile-info weiter unten). */
.prop-grid-list .prop-tile-info {
  flex: 1;
  padding: 1.5rem 1.75rem;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 0.15rem;
  background: none;
}
.prop-grid-list .prop-tile-price {
  color: var(--red);
  font-size: 1.2rem;
}
.prop-grid-list .prop-tile h3 { font-size: 1.05rem; }
.prop-grid-list .prop-tile-loc { color: var(--muted); }
.prop-grid-list .prop-tile-cta {
  margin-top: 1rem;
  background: none;
  color: var(--ink);
  padding: 0;
  font-size: 0.85rem;
}
.prop-grid-list .prop-tile-cta:hover {
  background: none;
  color: var(--red-hot);
  transform: translateX(3px);
}

@media (max-width: 640px) {
  .prop-grid-list .prop-tile { flex-direction: column; }
  .prop-grid-list .prop-tile-visual {
    flex-basis: auto;
    aspect-ratio: 16 / 10;
    margin: 0.75rem 0.75rem 0 0.75rem;
  }
}

.prop-view-toggle {
  display: inline-flex;
  border: 1.5px solid var(--line);
  background: var(--white);
}
.prop-view-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.6rem;
  height: 2.6rem;
  background: none;
  border: none;
  color: var(--muted);
  cursor: pointer;
  transition: background 0.2s ease, color 0.2s ease;
}
.prop-view-btn + .prop-view-btn { border-left: 1.5px solid var(--line); }
.prop-view-btn:hover { color: var(--ink); }
.prop-view-btn.is-active { background: var(--ink); color: var(--white); }

.prop-tile {
  position: relative;
  display: block;
  overflow: hidden;
  color: var(--ink);
  isolation: isolate;
}

/* Jede .prop-tile-Karte (Raster, Rail, "Ähnliche Objekte") hat inzwischen
   dieselbe Struktur: Bildbereich (.prop-tile-visual, mit oder ohne
   Swipe/Dots) oben, eigene weiße Info-Box (.prop-tile-info) darunter – statt
   der früheren Variante mit Text als Overlay direkt auf dem Foto. Dadurch
   ist ein abdunkelnder Verlauf über das ganze Bild nicht mehr nötig; er
   bleibt nur noch, wo tatsächlich Punkte/Pfeile fürs Bilder-Swipen auf dem
   Foto liegen (siehe .prop-tile-visual:has(.prop-tile-dots)::after unten).
   Nur in der Rasteransicht – die Listenansicht hat mit .prop-grid-list
   .prop-tile ihr eigenes, mit Absicht anderes (row-)Layout, das hier nicht
   überschrieben werden soll. */
.prop-grid:not(.prop-grid-list) .prop-tile,
.prop-rail .prop-tile {
  display: flex;
  flex-direction: column;
  /* CSS-Grid/Flex streckt Zellen standardmäßig (align-items:stretch) auf die
     höchste Karte einer Zeile – ohne background hier bliebe der so
     entstehende Freiraum unterhalb von .prop-tile-info transparent und
     zeigt als dunkler "Rand-Rest" durch. */
  background: var(--white);
}
/* .prop-tile-info füllt den durch das Grid-/Flex-Stretching entstehenden
   Freiraum unterhalb von Preis/Titel/Button selbst aus (flex:1), und der
   Button wird per margin-top:auto ganz nach unten gedrückt (siehe
   .prop-tile-cta weiter unten) – so sitzt "Jetzt ansehen" bei jeder Karte
   auf exakt derselben Höhe unten links, unabhängig von unterschiedlich
   langen Titeln. */
.prop-grid:not(.prop-grid-list) .prop-tile-info,
.prop-rail .prop-tile-info {
  flex: 1;
  display: flex;
  flex-direction: column;
}

/* Variante ohne Bilder-Swipe (Startseite-Rail, "Ähnliche Objekte"): nur ein
   Bild, direktes <img>-Kind in .prop-tile-visual statt des
   .prop-tile-media-Wrappers der Swipe-Variante. */
.prop-tile-visual > img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.7s var(--ease);
}

.prop-tile:hover .prop-tile-visual > img {
  transform: scale(1.08);
}

/* .prop-tile-visual ist der gemeinsame Bezugsrahmen für Bild(er), Nav-Pfeile
   und Dots. In der Rasteransicht nimmt er eine feste Bildhöhe ein (statt wie
   früher per position:absolute;inset:0 die GANZE Karte samt Textbereich zu
   überdecken – der Button/Info-Bereich braucht jetzt echten Platz UNTER dem
   Bild); in der Listenansicht bleibt er absolut auf den linken Bildbereich
   beschränkt (siehe .prop-grid-list weiter oben). */
.prop-tile-visual {
  position: relative;
  aspect-ratio: 4 / 3;
  flex-shrink: 0;
}

.prop-tile-media {
  position: absolute;
  inset: 0;
}

.prop-tile-media img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 0.35s ease, transform 0.7s var(--ease);
  pointer-events: none;
}

.prop-tile-media img.is-active { opacity: 1; }

.prop-tile:hover .prop-tile-media img.is-active {
  transform: scale(1.08);
}

/* Swipe-Bereich: eigener Touch-Ziel, damit ein Tap/Drag hier NICHT den
   umschließenden Link zur Detailseite auslöst (siehe property-search.js /
   das Swipe-JS unten in immobilien.php, welches preventDefault nur bei
   erkanntem horizontalem Drag setzt). */
.prop-tile-media.has-swipe {
  touch-action: pan-y;
  cursor: grab;
}

.prop-tile:hover .prop-tile-nav { opacity: 1; }

.prop-tile-nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 2;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  background: rgba(13, 20, 28, 0.45);
  color: var(--white);
  border: none;
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.2s ease, background 0.2s ease;
}
.prop-tile-nav:hover { background: rgba(13, 20, 28, 0.75); }
.prop-tile-nav-prev { left: 0.6rem; }
.prop-tile-nav-next { right: 0.6rem; }

/* Auf Touch-Geräten gibt es kein :hover, das die Pfeile normalerweise
   einblendet (siehe .prop-tile:hover .prop-tile-nav oben) – dort blieben sie
   bislang unsichtbar UND mit 32×32px unter Apples 44px-Mindestmaß für
   Tap-Ziele. @media (hover: none) erkennt echte Touch-Geräte (nicht nur
   schmale Viewports, ein per Maus bedientes schmales Fenster bekäme weiter
   das Hover-Verhalten) – dort bleiben die Pfeile dauerhaft sichtbar und
   werden größer. Swipe funktioniert davon unabhängig weiterhin. */
@media (hover: none) {
  .prop-tile-nav {
    opacity: 1;
    width: 2.75rem;
    height: 2.75rem;
  }
}

.prop-tile-dots {
  position: absolute;
  left: 50%;
  bottom: 0.8rem;
  transform: translateX(-50%);
  z-index: 2;
  display: flex;
  gap: 0.35rem;
}
.prop-tile-dot {
  width: 0.4rem;
  height: 0.4rem;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.45);
  cursor: pointer;
  transition: background 0.2s ease, transform 0.2s ease;
}
.prop-tile-dot.is-active { background: var(--white); transform: scale(1.25); }

/* Text liegt inzwischen nirgends mehr direkt auf dem Foto (siehe
   .prop-tile-info weiter unten) – ein Verlauf übers ganze Bild ist daher
   nicht mehr nötig. Nur wo tatsächlich Punkte/Pfeile fürs Bilder-Swipen auf
   dem Foto liegen (.prop-tile-visual:has(.prop-tile-dots)), bekommen sie
   einen schmalen Abdunklungs-Streifen am unteren Rand, damit die halb-
   transparenten Punkte (siehe .prop-tile-dot) darauf ablesbar bleiben –
   bewusst nur so hoch wie der Dot-/Pfeil-Bereich, nicht das ganze Bild.
   Beim Hover (Maus) bzw. während des Durchblätterns/Swipens (Klasse
   .is-interacting, per JS gesetzt – Touch-Geräte kennen kein :hover) wird
   er ausgeblendet, damit das Bild kurz ungetrübt sichtbar ist. */
.prop-tile-visual:has(.prop-tile-dots)::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 2.75rem;
  background: linear-gradient(to top, rgba(13, 20, 28, 0.55), rgba(13, 20, 28, 0));
  z-index: 1;
  pointer-events: none;
  transition: opacity 0.25s ease;
}
.prop-tile:hover .prop-tile-visual::after,
.prop-tile-visual.is-interacting::after {
  opacity: 0;
}

/* .prop-tile-info bündelt Text (.prop-tile-body) + Button (.prop-tile-cta).
   In der Rasteransicht liegt es als normaler Block-Bereich UNTER dem Bild
   (eigener weißer Kartenfuß, kein Overlay mehr) – dafür ist .prop-tile-body
   dort selbst kein Overlay-Link mit position:absolute mehr, sondern normaler
   Fluss. In der Listenansicht bleibt es der rechte Flex-Bereich neben dem
   Bild (siehe .prop-grid-list weiter oben). */
.prop-tile-info {
  position: relative;
  z-index: 3;
  padding: 1rem 1.25rem 1.25rem;
  background: var(--white);
  color: var(--ink);
}

.prop-tile-body {
  color: inherit;
  text-decoration: none;
  display: block;
}

.prop-tile-price {
  font-weight: 600;
  font-size: 1.1rem;
  letter-spacing: -0.015em;
}

.prop-tile h3 {
  font-size: 0.95rem;
  font-weight: 500;
  margin-top: 0.2rem;
  line-height: 1.35;
}

.prop-tile-loc {
  margin-top: 0.4rem;
  font-size: 0.8rem;
  letter-spacing: 0.02em;
  color: var(--muted);
}

/* Deutlich sichtbarer Button, statt sich darauf zu verlassen, dass Preis/
   Titel/Ort als Ganzes klickbar "wirken" – gerade seitdem der Bildbereich
   selbst per Swipe/Klick nur noch die Bilder wechselt, statt zur
   Detailseite zu führen, braucht es ein eindeutiges Klick-Ziel. */
.prop-tile-cta {
  display: inline-flex;
  align-self: flex-start;
  align-items: center;
  justify-content: center;
  gap: 0.35rem;
  /* auto drückt den Button in der Rasteransicht (.prop-tile-info ist dort
     flex-column, siehe oben) ganz ans untere Kartenende – so sitzt er bei
     jeder Karte auf derselben Höhe, egal wie lang Titel/Ort sind. */
  margin-top: auto;
  padding: 0.4rem 0.75rem;
  /* min-height 44px = Apples HIG-Mindestmaß für Tap-Ziele – vorher landete
     der Button (nur per padding bestimmt) bei ~32px Höhe. Dies ist der
     primäre Klickpfad von jeder Objektkarte zur Detailseite, also der
     zentrale Conversion-Schritt der ganzen Seite. */
  min-height: 44px;
  background: var(--ink);
  color: var(--white);
  font-size: 0.78rem;
  font-weight: 600;
  text-decoration: none;
  border-radius: 999px;
  transition: background 0.2s ease, transform 0.2s ease;
}
.prop-tile-cta:hover {
  background: var(--red-hot);
  transform: translateX(2px);
}

/* Hinweiskarte ans Ende der Startseiten-Rail, wenn es dort mehr Objekte
   gibt als die 5 gezeigten (siehe $hasMoreProperties in
   site/components/properties.php) – dieselbe Kartenform wie .prop-tile,
   aber als durchgehend dunkler, klickbarer Block statt Bild+Infobox. */
.prop-tile-more {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  gap: 0.6rem;
  padding: 1.5rem 1.25rem;
  background: var(--ink);
  color: var(--white);
  text-decoration: none;
  border-radius: 12px;
  transition: background 0.2s ease;
}
.prop-tile-more:hover { background: var(--red-hot); }
.prop-tile-more-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.12);
}
.prop-tile-more-text { font-size: 0.95rem; font-weight: 600; }
.prop-tile-more-sub { font-size: 0.8rem; color: rgba(255, 255, 255, 0.65); }

/* ——— Calculator ——— */
.calculator {
  position: relative;
  background: var(--ink);
  color: var(--white);
  padding: clamp(4.5rem, 9vw, 7.5rem) 0;
  overflow: hidden;
}

.calculator::before {
  content: "WERT";
  position: absolute;
  right: -4%;
  top: 8%;
  font-weight: 600;
  font-size: clamp(7rem, 24vw, 18rem);
  line-height: 0.8;
  letter-spacing: -0.04em;
  color: transparent;
  -webkit-text-stroke: 1px rgba(255, 255, 255, 0.05);
  pointer-events: none;
  user-select: none;
}

.calc-layout {
  display: grid;
  grid-template-columns: 1fr 1.05fr;
  gap: clamp(2rem, 5vw, 4rem);
  align-items: start;
  position: relative;
  z-index: 1;
}

.calc-copy .display {
  font-size: clamp(1.7rem, 3.6vw, 2.75rem);
  line-height: 1.2;
  letter-spacing: -0.02em;
  max-width: 14ch;
}

.calc-copy .display em {
  font-style: normal;
  /* Farbe kommt jetzt komplett von .highlight-word (siehe dort) – vorher
     stand hier eine feste color: var(--red), wodurch der Scroll-Trigger
     wirkungslos geblieben wäre ("Haus" war ja schon die ganze Zeit rot). */
}

/* Auf dem dunklen Calculator-Hintergrund (.calculator { background:
   var(--ink) }) muss die Ausgangsfarbe des Highlight-Worts hell statt
   dunkel sein – sonst wäre "Haus" vor dem Scroll-Trigger unsichtbar
   (dunkles Ink-Text auf dunklem Ink-Hintergrund). Gleiches Rot-Ziel wie
   überall sonst, siehe .highlight-word.is-highlighted. */
.calc-highlight-word { color: var(--white); }

.calc-copy p {
  margin-top: 1.25rem;
  color: rgba(255, 255, 255, 0.65);
  max-width: 28rem;
  font-size: 1.05rem;
}

.calc-points {
  margin-top: 2rem;
  display: grid;
  gap: 0.85rem;
}

.calc-points li {
  display: flex;
  gap: 0.7rem;
  align-items: flex-start;
  color: rgba(255, 255, 255, 0.8);
}

.calc-points svg {
  color: var(--red);
  margin-top: 0.15rem;
  flex-shrink: 0;
}

.calc-panel {
  background: var(--paper);
  color: var(--ink);
  padding: clamp(1.4rem, 3vw, 2rem);
  border-radius: 2px;
  position: relative;
}

.calc-panel::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 3px;
  background: var(--red);
}

.calc-panel h3 {
  font-size: 1.1rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  margin-bottom: 1.15rem;
}

.type-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0.55rem;
  margin-bottom: 1.15rem;
}

.type-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.4rem;
  padding: 0.9rem 0.4rem;
  border: 1.5px solid var(--line);
  color: var(--muted);
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  transition: all 0.25s ease;
  border-radius: 2px;
}

.type-btn.active,
.type-btn:hover {
  border-color: var(--red);
  color: var(--red);
  background: rgba(196, 30, 36, 0.06);
}

.form-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.85rem;
}

.field {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}

.field label {
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--muted);
}

.field input,
.field textarea,
.field select {
  min-height: 2.9rem;
  padding: 0.65rem 0.85rem;
  border: none;
  border-bottom: 2px solid var(--line);
  background: transparent;
  color: var(--ink);
  outline: none;
  transition: border-color 0.2s ease;
  font: inherit;
  width: 100%;
  resize: vertical;
}

.field input:focus,
.field textarea:focus,
.field select:focus {
  border-color: var(--red);
}

.field input:disabled {
  opacity: 0.4;
}

.field > span {
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--muted);
}

/* ——— Datenschutz-Einwilligung (Pflichtfeld in allen Kontaktformularen) ——— */
.consent-check {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
  margin: 0.9rem 0;
  cursor: pointer;
}

.consent-check input[type="checkbox"] {
  flex-shrink: 0;
  width: 1.1rem;
  height: 1.1rem;
  margin-top: 0.15rem;
  accent-color: var(--red);
  cursor: pointer;
}

.consent-check span {
  font-size: 0.82rem;
  line-height: 1.5;
  color: var(--muted);
}

.consent-check a {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 2px;
}

.consent-check a:hover {
  color: var(--red);
}

.calc-submit {
  width: 100%;
  margin-top: 1.25rem;
}

.calc-error {
  margin-top: 0.75rem;
  color: var(--red);
  font-size: 0.9rem;
  font-weight: 600;
}

.calc-result {
  margin-top: 1.25rem;
  padding: 1.25rem;
  background: var(--navy);
  color: var(--white);
  border-radius: 2px;
  animation: rise 0.45s var(--ease) both;
}

.calc-result-label {
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.55);
  margin-bottom: 0.4rem;
}

.calc-result-value {
  font-size: clamp(1.25rem, 2.4vw, 1.55rem);
  font-weight: 600;
  letter-spacing: -0.015em;
  line-height: 1.3;
}

.calc-result-value em {
  font-style: normal;
  color: #ff8b8f;
}

.calc-result p {
  margin-top: 0.65rem;
  font-size: 0.88rem;
  color: rgba(255, 255, 255, 0.68);
}

/* ——— Values ——— */
.values {
  background: var(--paper);
  padding: clamp(4rem, 8vw, 6rem) 0;
}

.values-band {
  display: grid;
  grid-template-columns: 1fr 1.3fr;
  background: var(--navy);
  color: var(--white);
  overflow: hidden;
  margin-bottom: 2rem;
}

.values-band-title {
  padding: clamp(1.75rem, 3.5vw, 2.5rem);
  background: var(--red);
  display: flex;
  align-items: center;
}

.values-band-title .display {
  font-size: clamp(1.45rem, 2.8vw, 2rem);
  max-width: 16ch;
  line-height: 1.2;
}

.values-checks {
  padding: clamp(1.75rem, 3.5vw, 2.5rem) clamp(1.5rem, 3vw, 2.5rem);
  display: grid;
  gap: 0.85rem;
  align-content: center;
}

.values-checks li {
  display: flex;
  gap: 0.7rem;
  align-items: flex-start;
  font-size: 1rem;
}

.values-checks svg {
  color: var(--red);
  flex-shrink: 0;
  margin-top: 0.15rem;
}

.values-triad {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0;
  border-top: 1px solid var(--line);
}

.value-item {
  padding: 2rem 1.5rem;
  text-align: left;
  border-right: 1px solid var(--line);
  position: relative;
}

.value-item:last-child {
  border-right: none;
}

.value-item svg {
  color: var(--red);
  margin-bottom: 1rem;
}

.value-item h3 {
  font-size: 1.05rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  margin-bottom: 0.4rem;
}

.value-item p {
  color: var(--muted);
  font-size: 0.95rem;
}

/* ——— Partners preview (Startseite) ——— */
.partners-preview {
  background: var(--white);
  padding: clamp(4rem, 8vw, 6rem) 0;
}

.partners-preview-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1.5rem;
  margin-bottom: clamp(2rem, 4vw, 2.75rem);
}

.partners-preview-all {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.92rem;
  font-weight: 700;
  color: var(--red);
  text-decoration: none;
  white-space: nowrap;
  flex-shrink: 0;
}
.partners-preview-all svg { transition: transform 0.25s ease; }
.partners-preview-all:hover svg { transform: translateX(4px); }

.partners-preview-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(9.5rem, 1fr));
  gap: 1.1rem;
}

.partners-preview-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.75rem;
  padding: 1.4rem 1rem 1.2rem;
  background: var(--paper);
  border-radius: 18px;
  text-decoration: none;
  color: inherit;
  transition: transform 0.3s cubic-bezier(0.16, 1, 0.3, 1), box-shadow 0.3s cubic-bezier(0.16, 1, 0.3, 1), background 0.3s ease;
}
.partners-preview-card:hover {
  transform: translateY(-4px);
  background: var(--white);
  box-shadow: 0 16px 32px -18px rgba(16, 21, 28, 0.28);
}

.partners-preview-media {
  width: 100%;
  aspect-ratio: 1/1;
  border-radius: 14px;
  overflow: hidden;
  background: linear-gradient(135deg, #eef0f3, #e2e5ea);
}
.partners-preview-media img {
  width: 100%; height: 100%; object-fit: cover; display: block;
  transition: transform 0.5s cubic-bezier(0.16, 1, 0.3, 1);
}
.partners-preview-card:hover .partners-preview-media img { transform: scale(1.08); }

.partners-preview-name {
  font-size: 0.85rem;
  font-weight: 700;
  text-align: center;
  line-height: 1.3;
}

@media (max-width: 30rem) {
  .partners-preview-head { flex-direction: column; align-items: flex-start; gap: 0.75rem; }
  .partners-preview-grid { grid-template-columns: repeat(auto-fill, minmax(7.5rem, 1fr)); gap: 0.8rem; }
}

/* ——— Contact ——— */
.contact {
  position: relative;
  color: var(--white);
  padding: clamp(4.5rem, 9vw, 7rem) 0;
  overflow: hidden;
  background: var(--navy-deep);
}

.contact-bg {
  position: absolute;
  inset: 0;
}

.contact-bg img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: grayscale(0.35) contrast(1.1);
  opacity: 0.35;
}

.contact-bg::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(115deg, rgba(13, 20, 28, 0.92) 35%, rgba(13, 20, 28, 0.55)),
    linear-gradient(to top, rgba(13, 20, 28, 0.9), transparent 50%);
}

.contact-inner {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: 1.15fr 0.85fr;
  gap: 2.5rem;
  align-items: end;
}

.contact .script {
  font-family: var(--script);
  font-size: clamp(1.35rem, 2.4vw, 1.75rem);
  color: #ff8b8f;
  margin-bottom: 0.3rem;
}

.contact .display {
  font-size: clamp(1.7rem, 3.4vw, 2.6rem);
  line-height: 1.2;
  letter-spacing: -0.02em;
  max-width: 16ch;
  margin-bottom: 0.9rem;
}

.contact-lead {
  color: rgba(255, 255, 255, 0.7);
  max-width: 28rem;
  margin-bottom: 1.75rem;
}

.contact-panel {
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.14);
  padding: 1.75rem;
  backdrop-filter: blur(10px);
  border-radius: 2px;
}

.contact-panel .label {
  font-size: 0.78rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.5);
}

.contact-panel .name {
  font-size: 1.35rem;
  font-weight: 600;
  letter-spacing: -0.015em;
  margin: 0.2rem 0 1.15rem;
}

.contact-list {
  display: grid;
  gap: 0.95rem;
}

/* Nur die direkten Zeilen der Liste als Flex-Row auslegen – ohne
   Kindselektor würde die Regel auch .contact-icon (selbst ein <span>)
   treffen und dessen gap/align-items überschreiben das Zentrieren. */
.contact-list > a,
.contact-list > span {
  display: flex;
  gap: 0.8rem;
  align-items: flex-start;
  color: rgba(255, 255, 255, 0.85);
  transition: color 0.2s ease;
}

.contact-list a:hover {
  color: var(--white);
}

.contact-icon {
  width: 2rem;
  height: 2rem;
  border: 1.5px solid var(--red);
  border-radius: 50%;
  display: grid;
  place-items: center;
  gap: 0;
  color: var(--red);
  flex-shrink: 0;
}

.contact-icon svg {
  display: block;
}

/* ——— Footer ——— */
.footer {
  background: var(--ink);
  color: rgba(255, 255, 255, 0.6);
  padding: 2rem 0 0;
}

.footer-top {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1.5rem;
  flex-wrap: wrap;
  padding-bottom: 1.5rem;
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}

.footer-nav {
  display: flex;
  flex-wrap: wrap;
  gap: 1.25rem;
}

.footer-nav a {
  font-size: 0.88rem;
  font-weight: 500;
  letter-spacing: 0.01em;
}

.footer-nav a:hover {
  color: var(--white);
}

.footer-bottom {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1rem;
  flex-wrap: wrap;
  padding: 1.25rem 0 1.5rem;
  font-size: 0.85rem;
}

.footer-bottom-text p + p { margin-top: 0.2rem; }

.footer-legal {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  color: rgba(255, 255, 255, 0.55);
}

.footer-legal a { color: rgba(255, 255, 255, 0.55); }
.footer-legal a:hover { color: var(--white); }

.footer-slash {
  height: 10px;
  background: linear-gradient(90deg, var(--red) 0 38%, transparent 38%);
  clip-path: polygon(0 0, 100% 0, 97% 100%, 0 100%);
}

/* ——— Responsive ——— */
@media (max-width: 960px) {
  .container {
    width: min(100% - 1.5rem, var(--max));
  }

  .header-cta {
    display: none;
  }

  .menu-toggle {
    display: grid;
  }

  /* .header ist jetzt global (siehe Basis-Regel oben) immer solide und
     ohne mix-blend-mode – hier bleibt nur noch das mobile Layout selbst
     (Nav/CTA ausblenden, Burger-Menü einblenden, Header-Höhe anpassen). */

  .header-inner {
    position: relative;
    min-height: 3.75rem;
  }

  /* ——— Sanfte Öffnen/Schließen-Animation (Chat-Anforderung) ———
     Vorher: .nav war per display:none/flex hart ein-/ausgeblendet – display
     lässt sich nicht animieren/übergangsweise darstellen, das Menü
     "sprang" ohne jeden Übergang auf. Jetzt bleibt .nav immer im Layout
     (display: flex, absolut positioniert wie zuvor), ist im geschlossenen
     Zustand aber unsichtbar (opacity: 0) UND per visibility: hidden
     wirklich unerreichbar (kein Tab-Fokus auf die Links, kein Hover/Klick),
     nicht nur pointer-events – reine opacity: 0 würde Screenreadern/
     Tastatur-Nutzern weiterhin unsichtbare, aber fokussierbare Links
     lassen. Chat-Feedback nach der ersten Version: kaum wahrnehmbar (nur
     8px Versatz, 220ms) – jetzt deutlich ausgeprägter: größerer Weg
     (-1rem), längere Dauer (0.32s) UND zusätzlich transform-origin: top,
     damit die Öffnung sichtbar "von oben aufklappt" statt nur zu faden.
     Die einzelnen Links faden zusätzlich leicht gestaffelt nacheinander
     ein (siehe .nav.open a nth-child-Verzögerungen unten) – das macht die
     Bewegung als echte Animation erkennbar statt als reinen Opacity-Fade. ——— */
  .nav {
    display: flex;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    flex-direction: column;
    gap: 0;
    background: var(--navy);
    padding: 0.35rem 1.25rem 1rem;
    opacity: 0;
    visibility: hidden;
    transform: translateY(-1rem);
    transform-origin: top;
    transition: opacity 0.32s var(--ease), transform 0.32s var(--ease), visibility 0.32s;
  }

  .nav.open {
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
  }

  .nav a {
    padding: 0.95rem 0;
    border-bottom: 1px solid rgba(255, 255, 255, 0.1);
    opacity: 1;
    font-size: 0.8rem;
  }

  /* Gestaffelte Einblendung: jeder Link fadet einzeln mit kleinem
     Zeitversatz ein, statt alle gleichzeitig – verstärkt den Eindruck
     einer echten Bewegung zusätzlich zum translateY/opacity des Nav-
     Containers selbst. Im geschlossenen Zustand (kein .open) immer
     opacity: 0, damit beim erneuten Öffnen wieder von vorn gestaffelt
     eingeblendet wird statt sofort alle sichtbar zu zeigen. */
  .nav a {
    opacity: 0;
    transition: opacity 0.28s var(--ease);
  }
  .nav.open a {
    opacity: 1;
  }
  .nav.open a:nth-child(1) { transition-delay: 0.04s; }
  .nav.open a:nth-child(2) { transition-delay: 0.08s; }
  .nav.open a:nth-child(3) { transition-delay: 0.12s; }
  .nav.open a:nth-child(4) { transition-delay: 0.16s; }
  .nav.open a:nth-child(5) { transition-delay: 0.2s; }
  .nav.open a:nth-child(6) { transition-delay: 0.24s; }
  .nav.open a:nth-child(7) { transition-delay: 0.28s; }

  @media (prefers-reduced-motion: reduce) {
    .nav {
      transition: opacity 0.12s linear, visibility 0.12s;
      transform: none;
    }
    .nav a {
      transition: opacity 0.12s linear;
      transition-delay: 0s !important;
    }
  }

  .display {
    line-height: 1.22;
    letter-spacing: -0.015em;
  }

  .hero-stage {
    /* Siehe Kommentar bei der Basis-.hero-stage-Regel weiter oben. */
    min-height: calc(var(--vh, 1vh) * 100);
  }

  .hero-cut {
    display: none;
  }

  .hero-veil {
    background:
      linear-gradient(
        to top,
        rgba(13, 20, 28, 0.88) 0%,
        rgba(13, 20, 28, 0.35) 32%,
        rgba(13, 20, 28, 0.15) 58%,
        rgba(13, 20, 28, 0.35) 100%
      );
  }

  .hero-content {
    /* Siehe Kommentar bei der Basis-.hero-stage-Regel weiter oben. */
    min-height: calc(var(--vh, 1vh) * 100);
    width: min(100% - 1.5rem, var(--max));
    padding: 5.25rem 0 2rem;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    gap: 1.5rem;
  }

  .hero-brand {
    margin-bottom: 1.15rem;
  }

  .hero-motto {
    font-size: 0.68rem;
    letter-spacing: 0.16em;
    margin-bottom: 0.75rem;
  }

  .hero h1 {
    font-size: clamp(1.45rem, 5vw, 1.85rem);
    max-width: 16ch;
  }

  .hero-sub {
    display: none;
  }

  .hero-actions-desktop {
    display: none;
  }

  .hero-meta {
    margin-top: 0.25rem;
  }

  .hero-cta-rail {
    display: block;
    padding: 1.75rem 0 2rem;
  }

  .hero-cta-inner {
    display: grid;
    gap: 1.15rem;
  }

  .hero-cta-inner p {
    font-size: 0.95rem;
    color: var(--muted);
    line-height: 1.5;
    max-width: 28rem;
  }

  .hero-cta-rail .hero-actions {
    margin-top: 0;
  }

  .marquee {
    transform: none;
    margin-block: 0;
  }

  .marquee-track {
    padding: 0.7rem 0;
  }

  .marquee-track span {
    font-size: 0.78rem;
    letter-spacing: 0.16em;
    padding-inline: 1rem;
  }

  .services,
  .properties,
  .calculator,
  .values,
  .contact {
    padding: 3.25rem 0;
  }

  .services-head,
  .featured,
  .calc-layout,
  .values-band,
  .contact-inner {
    grid-template-columns: 1fr;
  }

  .services-head {
    gap: 0.85rem;
    margin-bottom: 1.75rem;
  }

  .services-head .display,
  .prop-head .display,
  .calc-copy .display,
  .contact .display,
  .values-band-title .display {
    font-size: clamp(1.45rem, 4.5vw, 1.85rem);
    max-width: none;
  }

  .services-head p {
    font-size: 0.95rem;
  }

  .service-row {
    grid-template-columns: 2.75rem 1fr;
    gap: 0.85rem;
    padding: 1.15rem 0;
  }

  .service-row:hover {
    padding-left: 0;
    background: transparent;
  }

  .service-num {
    font-size: 1.05rem;
  }

  .service-row h3 {
    font-size: 1rem;
    letter-spacing: -0.01em;
  }

  .service-row p {
    font-size: 0.9rem;
  }

  .service-ico {
    display: none;
  }

  .properties::before {
    height: 3.5rem;
  }

  .prop-head {
    flex-direction: column;
    align-items: start;
    gap: 1rem;
    margin-bottom: 1.5rem;
  }

  .featured {
    min-height: 0;
  }

  .featured-media {
    min-height: 14.5rem;
    aspect-ratio: 16 / 10;
  }

  .featured-slash {
    display: none;
  }

  .featured-body {
    padding: 1.35rem 1.25rem 1.5rem;
  }

  .featured-body::before {
    display: none;
  }

  .featured-price {
    font-size: 1.55rem;
  }

  .featured-body h3 {
    font-size: 1.1rem;
  }

  .featured-meta {
    gap: 0.75rem;
    font-size: 0.85rem;
    margin: 0.9rem 0 1.2rem;
  }

  /* Auf schmalen Screens: engerer Gap, randloses Scrollen bis an den
     Viewport-Rand und ausgeblendete Scrollbar (Touch-Geräte haben ohnehin
     keine sichtbare) – .prop-rail selbst ist bereits per Default-Regel
     oben horizontal scrollbar. */
  .prop-rail {
    gap: 0.75rem;
    scroll-snap-type: x mandatory;
    margin-inline: -0.25rem;
    padding-inline: 0.25rem;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }

  .prop-rail::-webkit-scrollbar {
    display: none;
  }

  .prop-rail .prop-tile,
  .prop-rail .prop-tile-more {
    flex-basis: min(78vw, 18rem);
  }

  .calculator::before {
    display: none;
  }

  .calc-copy p {
    font-size: 0.95rem;
    margin-top: 0.85rem;
  }

  .calc-points {
    margin-top: 1.25rem;
    gap: 0.65rem;
  }

  .calc-points li {
    font-size: 0.9rem;
  }

  .calc-panel {
    clip-path: none;
    padding: 1.25rem;
  }

  .calc-panel h3 {
    font-size: 1rem;
  }

  .calc-result {
    clip-path: none;
  }

  .calc-result-value {
    font-size: 1.25rem;
    line-height: 1.25;
  }

  .btn {
    clip-path: none;
    min-height: 2.85rem;
    font-size: 0.92rem;
  }

  .type-btn {
    clip-path: none;
  }

  .values-band {
    margin-bottom: 0;
  }

  .values-band-title {
    clip-path: none;
    padding: 1.35rem 1.25rem;
  }

  .values-checks {
    padding: 1.25rem;
    gap: 0.7rem;
  }

  .values-checks li {
    font-size: 0.92rem;
  }

  /* ——— "Persönlich / Kompetent / Vertrauensvoll" auf Mobile: statt einer
     schlichten Liste mit dünnen Trennlinien (die neben dem kräftigen roten
     Rundum-Sorglos-Band darüber flach wirkte) jetzt einzelne Karten mit
     rundem Icon-Badge, nebeneinander liegend statt gestapelt (Icon links,
     Text rechts) – kompakter, klarer strukturiert und näher am übrigen
     Card-Look der Seite (z. B. Bewertungs-Karten). ——— */
  .values-triad {
    grid-template-columns: 1fr;
    border-top: none;
    gap: 0.7rem;
  }

  .value-item {
    display: flex;
    align-items: center;
    gap: 1rem;
    text-align: left;
    background: #fff;
    border: 1px solid var(--line);
    border-right: 1px solid var(--line);
    border-radius: 14px;
    padding: 1.1rem 1.2rem;
    box-shadow: 0 10px 24px -18px rgba(20, 24, 34, 0.25);
  }

  .value-item-icon {
    flex-shrink: 0;
    display: grid;
    place-items: center;
    width: 2.75rem;
    height: 2.75rem;
    background: rgba(196, 30, 36, 0.08);
    border-radius: 50%;
  }

  .value-item svg {
    margin-bottom: 0;
  }

  .value-item-body h3 {
    font-size: 0.98rem;
    margin-bottom: 0.15rem;
  }

  .value-item-body p {
    font-size: 0.86rem;
    line-height: 1.4;
  }

  .contact .script {
    font-size: 1.45rem;
  }

  .contact-lead {
    font-size: 0.95rem;
    margin-bottom: 1.25rem;
  }

  .contact-panel {
    clip-path: none;
    padding: 1.25rem;
  }

  .contact-panel .name {
    font-size: 1.25rem;
    margin-bottom: 1rem;
  }

  .footer-top {
    flex-direction: column;
    align-items: flex-start;
    gap: 1.1rem;
  }

  .footer-nav {
    gap: 0.85rem 1.1rem;
  }

  .footer-bottom {
    flex-direction: column;
    gap: 0.35rem;
    font-size: 0.8rem;
  }
}

@media (max-width: 640px) {
  .eyebrow {
    font-size: 0.68rem;
    letter-spacing: 0.16em;
    margin-bottom: 0.75rem;
  }

  .logo-xl .logo-mark {
    width: 11rem;
  }

  .hero-content {
    padding: 4.75rem 0 1.75rem;
  }

  .hero h1 {
    font-size: 1.4rem;
    line-height: 1.22;
  }

  .hero-cta-rail {
    padding: 1.5rem 0 1.85rem;
  }

  .hero-cta-inner p {
    font-size: 0.9rem;
  }

  .hero-cta-rail .hero-actions {
    flex-direction: column;
    align-items: stretch;
    gap: 0.6rem;
  }

  .form-grid {
    grid-template-columns: 1fr;
  }

  .type-grid {
    grid-template-columns: repeat(3, 1fr);
    gap: 0.4rem;
  }

  .type-btn {
    padding: 0.75rem 0.25rem;
    font-size: 0.72rem;
  }

  .type-btn svg {
    width: 18px;
    height: 18px;
  }

  .services,
  .properties,
  .calculator,
  .values,
  .contact {
    padding: 2.75rem 0;
  }

  .prop-tile-body {
    padding: 1rem;
  }

  .prop-tile-price {
    font-size: 1.05rem;
  }

  .prop-tile h3 {
    font-size: 0.88rem;
  }
}

/* ——— Login gate ——— */
.login {
  position: relative;
  min-height: 100svh;
  display: grid;
  overflow: hidden;
  color: var(--white);
}

.login-media {
  position: absolute;
  inset: 0;
}

.login-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  animation: loginKen 18s ease-in-out infinite alternate;
  transform: scale(1.08);
}

.login-veil {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(
      115deg,
      rgba(13, 20, 28, 0.88) 0%,
      rgba(13, 20, 28, 0.62) 48%,
      rgba(196, 30, 36, 0.28) 100%
    ),
    linear-gradient(to top, rgba(13, 20, 28, 0.55), transparent 42%);
}

.login-panel {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2rem 1.25rem;
  animation: loginRise 0.9s var(--ease) both;
}

.login-card {
  width: min(100%, 26.5rem);
}

.login-brand {
  margin-bottom: 2.25rem;
  animation: loginRise 0.9s var(--ease) 0.08s both;
}

.login-brand .logo {
  pointer-events: none;
}

.login-motto {
  margin-top: 1.1rem;
  font-size: 0.92rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.72);
}

.login-intro {
  margin-bottom: 1.75rem;
  animation: loginRise 0.9s var(--ease) 0.16s both;
}

.login-intro h1 {
  font-size: clamp(1.85rem, 4vw, 2.35rem);
  margin-bottom: 0.55rem;
}

.login-intro p {
  color: rgba(255, 255, 255, 0.72);
  font-size: 1.02rem;
  max-width: 22rem;
}

.login-form {
  display: grid;
  gap: 1.05rem;
  animation: loginRise 0.9s var(--ease) 0.24s both;
}

.login-field {
  display: grid;
  gap: 0.45rem;
}

.login-field > span {
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.7);
}

.login-input {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  min-height: 3.15rem;
  padding: 0 0.9rem;
  border: 1.5px solid rgba(255, 255, 255, 0.22);
  background: rgba(255, 255, 255, 0.08);
  backdrop-filter: blur(10px);
  border-radius: 2px;
  transition: border-color 0.25s ease, background 0.25s ease;
}

.login-input:focus-within {
  border-color: rgba(255, 255, 255, 0.55);
  background: rgba(255, 255, 255, 0.12);
}

.login-input svg {
  flex-shrink: 0;
  color: rgba(255, 255, 255, 0.55);
}

.login-input input {
  flex: 1;
  min-width: 0;
  border: none;
  outline: none;
  background: transparent;
  color: var(--white);
  font-size: 1rem;
  padding: 0.7rem 0;
}

.login-input input::placeholder {
  color: rgba(255, 255, 255, 0.4);
}

.login-reveal {
  display: inline-flex;
  color: rgba(255, 255, 255, 0.55);
  padding: 0.25rem;
  transition: color 0.2s ease;
}

.login-reveal:hover {
  color: var(--white);
}

.login-error {
  font-size: 0.9rem;
  color: #ffb4b7;
  background: rgba(196, 30, 36, 0.22);
  border: 1px solid rgba(255, 180, 183, 0.35);
  padding: 0.7rem 0.85rem;
  border-radius: 2px;
}

.login-submit {
  width: 100%;
  margin-top: 0.35rem;
  min-height: 3.2rem;
}

.login-submit:disabled {
  opacity: 0.75;
  transform: none;
  cursor: wait;
}

.login-card.is-shake {
  animation: loginShake 0.45s ease;
}

@keyframes loginKen {
  from {
    transform: scale(1.08) translate3d(0, 0, 0);
  }
  to {
    transform: scale(1.16) translate3d(-1.5%, -1%, 0);
  }
}

@keyframes loginRise {
  from {
    opacity: 0;
    transform: translateY(18px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@media (max-width: 640px) {
  .login-panel {
    align-items: flex-end;
    padding: 1.5rem 1rem 2rem;
  }

  .login-brand {
    margin-bottom: 1.6rem;
  }

  .login-intro {
    margin-bottom: 1.35rem;
  }
}

/* ——— Property detail ——— */
.pd {
  background: var(--paper);
}

.pd-hero {
  position: relative;
  color: var(--white);
  background: var(--navy-deep);
}

.pd-gallery {
  position: relative;
}

.pd-stage {
  position: relative;
  min-height: min(78vh, 46rem);
  overflow: hidden;
}

.pd-stage > img,
.pd-stage > video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transform: scale(1.06) translate3d(1.5%, 0, 0);
  transition:
    opacity 1s var(--ease),
    transform 1.35s var(--ease);
  will-change: opacity, transform;
}

.pd-stage > video.is-active {
  opacity: 1;
  transform: scale(1) translate3d(0, 0, 0);
  z-index: 1;
}

/* Weicher Übergang vom Bild-/Video-Bereich zum folgenden Text (Titel, Preis
   etc. in .pd-hero-content) – löst die bisherige harte Kante am unteren
   Rand der Stage in einen fließenden Verlauf zur Hintergrundfarbe auf. */
.pd-stage-fade {
  position: absolute;
  inset: auto 0 0 0;
  height: min(14rem, 32%);
  z-index: 3;
  pointer-events: none;
  background: linear-gradient(to bottom, transparent 0%, var(--navy-deep) 100%);
}

/* Steht als letztes Kind in .pd-thumbs (rechtsbündig per margin-left: auto)
   statt frei über dem Bild zu schweben – dort, wo man beim Durchklicken der
   Vorschaubilder ohnehin schon hinschaut, statt an einer Ecke, die man beim
   Betrachten des Hero-Bilds leicht übersieht. */
.pd-stage-gallery-btn {
  flex-shrink: 0;
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.6rem 1.1rem;
  background: rgba(255, 255, 255, 0.1);
  border: 1.5px solid rgba(255, 255, 255, 0.3);
  border-radius: 999px;
  color: var(--white);
  font-family: var(--font);
  font-size: 0.85rem;
  font-weight: 600;
  cursor: pointer;
  backdrop-filter: blur(4px);
  transition: background 0.2s ease, border-color 0.2s ease, transform 0.2s ease;
}

.pd-stage-gallery-btn:hover {
  background: rgba(13, 20, 28, 0.8);
  border-color: var(--white);
  transform: translateY(-2px);
}

.pd-stage > img.is-active {
  opacity: 1;
  transform: scale(1) translate3d(0, 0, 0);
  z-index: 1;
  /* animation-delay = Dauer der Eintritts-Transition oben, damit der Ken-Burns-
     Effekt erst startet, wenn Opacity/Transform-Übergang abgeschlossen ist –
     sonst konkurrieren Transition und Animation kurz um "transform" und es
     ruckelt sichtbar beim Bildwechsel. */
  animation: pdKen 14s ease-in-out 1.35s infinite alternate;
}

.pd-stage-veil {
  position: absolute;
  inset: 0;
  z-index: 2;
  background:
    linear-gradient(
      to top,
      rgba(13, 20, 28, 0.94) 0%,
      rgba(13, 20, 28, 0.35) 42%,
      rgba(13, 20, 28, 0.2) 100%
    );
  pointer-events: none;
}

/* Nur noch der Galerie-Button steht hier (die Bild-Thumbnails wurden
   entfernt) – bleibt eine eigene, schmale Leiste am unteren Bildrand, mit
   demselben dunklen Verlauf-Hintergrund wie zuvor, damit der Button auch
   auf hellen Fotos gut lesbar bleibt. */
.pd-thumbs {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 5;
  display: flex;
  justify-content: flex-end;
  padding: 1.75rem max(1rem, calc((100vw - var(--max)) / 2 + 1rem)) 1.15rem;
  pointer-events: auto;
  background: linear-gradient(
    to top,
    rgba(13, 20, 28, 0.55) 0%,
    transparent 100%
  );
}


.pd-thumb-progress {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 2.5px;
  transform-origin: left center;
  background: var(--red);
  animation: pdThumbProgress linear forwards;
}

.pd-thumb-progress.is-paused {
  animation-play-state: paused;
}

@keyframes pdKen {
  from {
    transform: scale(1) translate3d(0, 0, 0);
  }
  to {
    transform: scale(1.06) translate3d(-1.2%, -0.6%, 0);
  }
}

@keyframes pdThumbProgress {
  from {
    transform: scaleX(0);
  }
  to {
    transform: scaleX(1);
  }
}

.pd-counter {
  margin-left: auto;
  font-size: 0.82rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: rgba(255, 255, 255, 0.78);
  flex-shrink: 0;
}

.pd-counter i {
  font-style: normal;
  opacity: 0.45;
  margin: 0 0.15rem;
}

.pd-nav {
  position: absolute;
  top: 42%;
  z-index: 5;
  transform: translateY(-50%);
  width: 2.75rem;
  height: 2.75rem;
  display: grid;
  place-items: center;
  color: var(--white);
  background: rgba(13, 20, 28, 0.45);
  border: 1px solid rgba(255, 255, 255, 0.25);
  backdrop-filter: blur(8px);
  transition: background 0.2s ease, border-color 0.2s ease;
  cursor: pointer;
}

.pd-nav:hover {
  background: rgba(13, 20, 28, 0.7);
  border-color: rgba(255, 255, 255, 0.55);
}

.pd-nav-prev {
  left: max(1rem, calc((100vw - var(--max)) / 2));
}

.pd-nav-next {
  right: max(1rem, calc((100vw - var(--max)) / 2));
}

.pd-hero-content {
  position: relative;
  z-index: 3;
  margin-top: 0;
  padding: clamp(2rem, 4vw, 3rem) 0 clamp(2.5rem, 5vw, 3.5rem);
  background: var(--navy-deep);
  pointer-events: none;
}

.pd-hero-inner {
  max-width: 42rem;
  animation: loginRise 0.85s var(--ease) both;
  pointer-events: none;
}

.pd-hero-inner a,
.pd-hero-inner .btn {
  pointer-events: auto;
}

.pd-back {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  font-size: 0.88rem;
  font-weight: 600;
  color: rgba(255, 255, 255, 0.72);
  margin-bottom: 1.5rem;
  transition: color 0.2s ease;
}

.pd-back:hover {
  color: var(--white);
}

.pd-status {
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: #ff8f93;
  margin-bottom: 0.55rem;
}

.pd-price {
  font-size: clamp(1.7rem, 3.5vw, 2.35rem);
  font-weight: 600;
  letter-spacing: -0.03em;
  margin-bottom: 0.45rem;
}

.pd-hero-inner .display {
  font-size: clamp(1.85rem, 4.2vw, 3rem);
  max-width: 16ch;
  margin-bottom: 0.85rem;
}

.pd-location {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.45rem;
  color: rgba(255, 255, 255, 0.7);
  font-size: 0.95rem;
  margin-bottom: 1rem;
}

.pd-headline {
  font-size: clamp(1.05rem, 2vw, 1.25rem);
  line-height: 1.45;
  color: rgba(255, 255, 255, 0.84);
  max-width: 34ch;
  margin-bottom: 1.75rem;
}

.pd-hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
}

.pd-facts {
  background: var(--navy);
  color: var(--white);
  border-top: 1px solid rgba(255, 255, 255, 0.08);
}

.pd-facts-row {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 0;
}

.pd-fact {
  padding: 1.35rem 1rem;
  border-right: 1px solid rgba(255, 255, 255, 0.1);
  animation: loginRise 0.7s var(--ease) both;
}

.pd-fact:last-child {
  border-right: none;
}

.pd-fact span {
  display: block;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.5);
  margin-bottom: 0.4rem;
}

.pd-fact strong {
  font-size: 1.05rem;
  font-weight: 600;
  letter-spacing: -0.01em;
}

.pd-story {
  padding: clamp(4rem, 8vw, 6.5rem) 0;
}

.pd-story-layout {
  display: grid;
  grid-template-columns: 1.15fr 0.85fr;
  gap: clamp(2rem, 5vw, 4rem);
  align-items: start;
}

.pd-story .display {
  font-size: clamp(1.7rem, 3.2vw, 2.4rem);
  max-width: 12ch;
  margin-bottom: 1.25rem;
}

.pd-story-text {
  font-size: 1.08rem;
  line-height: 1.7;
  color: var(--muted);
  max-width: 38rem;
}

.pd-highlights {
  display: grid;
  gap: 0.85rem;
  padding-top: 0.5rem;
}

.pd-highlights li {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  font-size: 1rem;
  font-weight: 500;
  line-height: 1.4;
  padding-bottom: 0.85rem;
  border-bottom: 1px solid var(--line);
}

.pd-highlights li:last-child {
  border-bottom: none;
}

.pd-highlights svg {
  flex-shrink: 0;
  color: var(--red);
  margin-top: 0.15rem;
}

.pd-inquiry {
  background: var(--ink);
  color: var(--white);
  padding: clamp(4rem, 8vw, 6.5rem) 0;
  position: relative;
  overflow: hidden;
}

.pd-inquiry::before {
  content: "";
  position: absolute;
  width: 28rem;
  height: 28rem;
  right: -8rem;
  top: -10rem;
  background: radial-gradient(circle, rgba(196, 30, 36, 0.28), transparent 68%);
  pointer-events: none;
}

.pd-inquiry-layout {
  position: relative;
  display: grid;
  grid-template-columns: 0.9fr 1.1fr;
  gap: clamp(2rem, 5vw, 4rem);
  align-items: start;
}

.pd-inquiry-copy .display {
  font-size: clamp(1.8rem, 3.5vw, 2.6rem);
  max-width: 12ch;
  margin-bottom: 1rem;
}

.pd-inquiry-copy .display em {
  font-style: normal;
  color: #ff8f93;
}

.pd-inquiry-copy > p {
  color: rgba(255, 255, 255, 0.7);
  max-width: 28ch;
  margin-bottom: 1.5rem;
}

.pd-inquiry-direct {
  display: grid;
  gap: 0.75rem;
}

.pd-inquiry-direct a {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  color: rgba(255, 255, 255, 0.82);
  font-weight: 500;
  transition: color 0.2s ease;
}

.pd-inquiry-direct a:hover {
  color: var(--white);
}

.pd-inquiry-form,
.pd-inquiry-done {
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.12);
  padding: clamp(1.35rem, 3vw, 2rem);
  animation: loginRise 0.75s var(--ease) both;
}

.pd-inquiry-object {
  font-size: 0.9rem;
  color: rgba(255, 255, 255, 0.65);
  margin-bottom: 1.25rem;
}

.pd-inquiry-object strong {
  color: var(--white);
  font-weight: 600;
}

.pd-inquiry-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.9rem;
  margin-bottom: 0.9rem;
}

.pd-inquiry-grid .field:last-child {
  grid-column: 1 / -1;
}

.pd-inquiry-form .field {
  margin-bottom: 0.9rem;
}

.pd-inquiry-form .field > span {
  color: rgba(255, 255, 255, 0.55);
}

.pd-inquiry-form .field input,
.pd-inquiry-form .field textarea {
  color: var(--white);
  border-bottom-color: rgba(255, 255, 255, 0.22);
}

.pd-inquiry-form .field input:focus,
.pd-inquiry-form .field textarea:focus {
  border-bottom-color: var(--red);
}

.pd-inquiry-form .field input::placeholder,
.pd-inquiry-form .field textarea::placeholder {
  color: rgba(255, 255, 255, 0.35);
}

.pd-inquiry-form .consent-check span {
  color: rgba(255, 255, 255, 0.55);
}

.pd-inquiry-done {
  display: grid;
  gap: 0.75rem;
  align-content: start;
  min-height: 16rem;
}

.pd-inquiry-done svg {
  color: #7ddea4;
}

.pd-inquiry-done h3 {
  font-size: 1.4rem;
  letter-spacing: -0.02em;
}

.pd-inquiry-done p {
  color: rgba(255, 255, 255, 0.7);
  max-width: 34ch;
}

.pd-inquiry-error {
  background: rgba(196, 30, 36, 0.12);
  border: 1px solid rgba(196, 30, 36, 0.35);
  color: #ffb4b7;
  font-size: 0.85rem;
  padding: 0.65rem 0.8rem;
  border-radius: 3px;
  margin-bottom: 1rem;
}

.pd-related {
  padding: clamp(3.5rem, 7vw, 5.5rem) 0;
}

.pd-related-head {
  margin-bottom: 1.75rem;
}

.pd-related-head .display {
  font-size: clamp(1.55rem, 3vw, 2.1rem);
}

/* ——— Public property catalog ——— */
.catalog-page {
  background: var(--paper);
  min-height: 100svh;
}

.catalog-hero {
  background:
    linear-gradient(135deg, var(--navy-deep), #1a2735 55%, #24161a);
  color: var(--white);
  padding: 7rem 0 3.25rem;
}

.catalog-hero .display {
  font-size: clamp(2rem, 4.5vw, 3.1rem);
  max-width: 12ch;
  margin-bottom: 0.85rem;
}

.catalog-hero-lead {
  max-width: 36rem;
  color: rgba(255, 255, 255, 0.72);
  margin-bottom: 1.5rem;
  font-size: 1.05rem;
}

.catalog-section {
  padding: clamp(2rem, 4vw, 3.25rem) 0 clamp(4rem, 8vw, 6rem);
}

.catalog {
  display: grid;
  gap: 1rem;
}

.catalog-toolbar {
  display: grid;
  gap: 1rem;
  padding: 1.15rem 1.2rem;
  background: var(--white);
  border: 1px solid var(--line);
}

.catalog-toolbar-top {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 0.85rem;
  align-items: center;
}

.catalog-view-toggle {
  display: inline-flex;
  border: 1.5px solid var(--line);
  overflow: hidden;
}

.catalog-view-toggle button {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  min-height: 2.9rem;
  padding: 0 0.9rem;
  font: inherit;
  font-size: 0.88rem;
  font-weight: 600;
  color: var(--muted);
  background: transparent;
  transition: background 0.2s ease, color 0.2s ease;
}

.catalog-view-toggle button.is-active {
  background: var(--ink);
  color: var(--white);
}

.catalog-view-toggle button:not(.is-active):hover {
  color: var(--ink);
  background: rgba(16, 21, 28, 0.04);
}

.catalog-map,
.catalog-map-loading,
.catalog-map-empty {
  min-height: 28rem;
  background: var(--white);
  border: 1px solid var(--line);
}

.catalog-map {
  display: grid;
  gap: 0;
  overflow: hidden;
  background:
    linear-gradient(180deg, rgba(22, 32, 44, 0.03), transparent 40%),
    var(--white);
  box-shadow: 0 18px 40px rgba(16, 21, 28, 0.06);
}

.catalog-map-frame {
  position: relative;
}

.catalog-map-frame::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.35);
  z-index: 2;
}

.catalog-map-loading,
.catalog-map-empty {
  display: grid;
  place-items: center;
  color: var(--muted);
  padding: 2rem;
  text-align: center;
}

.catalog-map-canvas {
  width: 100%;
  height: min(62vh, 34rem);
  z-index: 1;
  background: #e8eee8;
}

.catalog-map-hint {
  padding: 0.85rem 1.1rem;
  font-size: 0.86rem;
  color: var(--muted);
  border-top: 1px solid var(--line);
  background: rgba(244, 242, 238, 0.65);
}

.catalog-map-layout {
  display: grid;
  gap: 1.25rem;
}

.catalog-marker {
  background: transparent !important;
  border: none !important;
}

.catalog-marker-pin {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.35rem 0.55rem 0.35rem 0.4rem;
  border-radius: 999px;
  background: rgba(13, 20, 28, 0.92);
  color: var(--white);
  border: 1px solid rgba(255, 255, 255, 0.18);
  box-shadow: 0 10px 24px rgba(13, 20, 28, 0.28);
  transform: translateY(0);
  transition: transform 0.2s ease, background 0.2s ease;
}

.catalog-marker-pin i {
  width: 0.55rem;
  height: 0.55rem;
  border-radius: 999px;
  background: var(--red);
  box-shadow: 0 0 0 3px rgba(196, 30, 36, 0.25);
}

.catalog-marker-pin em {
  font-style: normal;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.01em;
  white-space: nowrap;
}

.catalog-marker.is-active .catalog-marker-pin {
  background: var(--red);
  transform: translateY(-2px) scale(1.04);
}

.catalog-marker.is-active .catalog-marker-pin i {
  background: var(--white);
  box-shadow: none;
}

.catalog-map-card {
  display: grid;
  grid-template-columns: 4.8rem 1fr;
  gap: 0.7rem;
  min-width: 15rem;
}

.catalog-map-card img {
  width: 4.8rem;
  height: 3.6rem;
  object-fit: cover;
  border-radius: 2px;
}

.catalog-map-status {
  margin: 0;
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--red);
}

.catalog-map-card strong {
  display: block;
  font-size: 0.9rem;
  line-height: 1.3;
  margin: 0.15rem 0;
}

.catalog-map-card p {
  margin: 0;
  font-size: 0.8rem;
  color: var(--muted);
}

.catalog-map-card a {
  display: inline-block;
  margin-top: 0.4rem;
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--red);
}

.catalog-card.is-active {
  border-color: var(--red);
  box-shadow: 0 12px 28px rgba(196, 30, 36, 0.12);
}

.catalog-empty-hint {
  font-size: 0.9rem;
  color: var(--muted);
}

.cms-coords-hint {
  display: block;
  margin-top: 0.35rem;
  color: var(--muted);
  font-size: 0.8rem;
}

.catalog-search {
  position: relative;
  display: flex;
  align-items: center;
  gap: 0.7rem;
  min-height: 3.1rem;
  padding: 0 0.9rem;
  border-bottom: 2px solid var(--line);
}

.catalog-search svg {
  color: var(--muted);
  flex-shrink: 0;
}

.catalog-search input {
  flex: 1;
  min-width: 0;
  border: none;
  outline: none;
  background: transparent;
  font: inherit;
  font-size: 1.02rem;
  color: var(--ink);
  padding: 0.75rem 0;
}

.catalog-search input::placeholder {
  color: var(--muted);
}

.catalog-search-clear {
  display: inline-flex;
  color: var(--muted);
  padding: 0.2rem;
}

.catalog-search-clear:hover {
  color: var(--ink);
}

.catalog-filters {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0.75rem 1rem;
  align-items: end;
}

.catalog-filters .catalog-reset {
  justify-self: start;
}

.catalog-reset {
  min-height: 2.9rem;
}

.catalog-count {
  font-size: 0.9rem;
  color: var(--muted);
}

.catalog-empty {
  display: grid;
  gap: 1rem;
  justify-items: start;
  padding: 2rem 1.25rem;
  background: var(--white);
  border: 1px solid var(--line);
  color: var(--muted);
}

.catalog-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1rem;
}

.catalog-card {
  display: grid;
  grid-template-rows: auto 1fr;
  background: var(--white);
  border: 1px solid var(--line);
  color: var(--ink);
  overflow: hidden;
  transition: transform 0.3s var(--ease), border-color 0.25s ease;
}

.catalog-card:hover {
  transform: translateY(-3px);
  border-color: rgba(196, 30, 36, 0.35);
}

.catalog-card-media {
  position: relative;
  aspect-ratio: 16 / 11;
  overflow: hidden;
  background: var(--navy);
}

.catalog-card-media img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transform: scale(1.04);
  transition:
    opacity 0.9s var(--ease),
    transform 1.2s var(--ease);
  will-change: opacity, transform;
}

.catalog-card-media img.is-active {
  opacity: 1;
  transform: scale(1);
}

.catalog-card:hover .catalog-card-media img.is-active {
  transform: scale(1.05);
}

@media (prefers-reduced-motion: reduce) {
  .catalog-card-media img {
    transition: none;
    transform: none;
  }

  .catalog-card:hover .catalog-card-media img.is-active {
    transform: none;
  }
}

.catalog-card-status {
  position: absolute;
  left: 0.75rem;
  top: 0.75rem;
  padding: 0.3rem 0.55rem;
  background: rgba(13, 20, 28, 0.78);
  color: var(--white);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

.catalog-card-body {
  display: grid;
  gap: 0.45rem;
  padding: 1.1rem 1.05rem 1.2rem;
  align-content: start;
}

.catalog-card-price {
  font-size: 1.15rem;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--red);
}

.catalog-card-body h2 {
  font-size: 1.02rem;
  font-weight: 600;
  letter-spacing: -0.015em;
  line-height: 1.35;
}

.catalog-card-loc {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  color: var(--muted);
  font-size: 0.88rem;
}

.catalog-card-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: 0.25rem;
  color: var(--muted);
  font-size: 0.84rem;
}

.catalog-card-meta span {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
}

.catalog-card-cta {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  margin-top: 0.55rem;
  font-size: 0.88rem;
  font-weight: 600;
  color: var(--ink);
}

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

  .catalog-toolbar-top {
    grid-template-columns: 1fr;
  }

  .catalog-view-toggle {
    width: 100%;
  }

  .catalog-view-toggle button {
    flex: 1;
    justify-content: center;
  }

  .catalog-filters {
    grid-template-columns: 1fr 1fr;
  }

  .catalog-reset {
    grid-column: 1 / -1;
  }
}

@media (max-width: 640px) {
  .catalog-hero {
    padding: 6rem 0 2.5rem;
  }

  .catalog-grid {
    grid-template-columns: 1fr;
  }

  .catalog-filters {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 960px) {
  /* ——— Mobile: Bild-Galerie der Objekt-Detailseite beginnt unter dem Menü
     (Chat-Anforderung: "das Menü schneidet das Bild oben zu sehr ab") ———
     .pd-stage (das eigentliche Bild/Video) lag bisher bei top:0 – der
     Header ist hier IMMER solide deckend (anders als der Hero auf der
     Startseite, keine .hero-top-Logik auf dieser Seite), schnitt also
     einfach den oberen Bildbereich (z. B. Dachspitze/Himmel) optisch ab.
     Statt den sichtbaren Bildausschnitt zu verschieben (object-position),
     bekommt .pd-gallery hier oben Platz für die Header-Höhe – .pd-hero
     (dunkler Hintergrund, var(--navy-deep)) füllt diesen Streifen hinter
     dem Header, der Bildinhalt selbst bleibt komplett erhalten, nur sein
     Startpunkt rutscht nach unten. 3.75rem ≈ typische Header-Höhe auf
     Mobile (.header-inner min-height) + etwas Puffer für die Safe-Area. */
  .pd-gallery {
    padding-top: calc(3.75rem + env(safe-area-inset-top));
  }

  .pd-facts-row {
    grid-template-columns: repeat(3, 1fr);
  }

  .pd-fact:nth-child(3) {
    border-right: none;
  }

  .pd-fact:nth-child(n + 4) {
    border-top: 1px solid rgba(255, 255, 255, 0.1);
  }

  .pd-story-layout,
  .pd-inquiry-layout {
    grid-template-columns: 1fr;
  }

  .pd-stage {
    min-height: 58vh;
  }

  .pd-hero-content {
    padding: 1.75rem 0 2rem;
  }

  .pd-thumbs {
    padding: 2rem 1rem 1rem;
  }

  .pd-nav {
    top: 38%;
  }

  .pd-nav-prev {
    left: 0.75rem;
  }

  .pd-nav-next {
    right: 0.75rem;
  }
}

@media (max-width: 640px) {
  .pd-stage {
    min-height: 52vh;
  }

  .pd-facts-row {
    grid-template-columns: repeat(2, 1fr);
  }

  .pd-fact {
    border-right: 1px solid rgba(255, 255, 255, 0.1);
  }

  .pd-fact:nth-child(2n) {
    border-right: none;
  }

  .pd-fact:nth-child(n + 3) {
    border-top: 1px solid rgba(255, 255, 255, 0.1);
  }

  .pd-inquiry-grid {
    grid-template-columns: 1fr;
  }

  .pd-hero-actions {
    flex-direction: column;
  }

  .pd-hero-actions .btn {
    width: 100%;
  }

  .pd-thumbs {
    padding: 2.25rem 0.85rem 0.95rem;
  }
}

@keyframes loginShake {
  0%,
  100% {
    transform: translateX(0);
  }
  20% {
    transform: translateX(-8px);
  }
  40% {
    transform: translateX(8px);
  }
  60% {
    transform: translateX(-5px);
  }
  80% {
    transform: translateX(5px);
  }
}

/* ——— Booking modal ——— */
.booking {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: grid;
  place-items: center;
  padding: 1rem;
  background: rgba(13, 20, 28, 0.62);
  backdrop-filter: blur(10px);
  animation: bookingFade 0.28s ease both;
}

.booking-dialog {
  width: min(100%, 34rem);
  max-height: min(92vh, 44rem);
  overflow: auto;
  background:
    linear-gradient(165deg, #1a2430 0%, #101820 55%, #0d141c 100%);
  color: var(--white);
  border: 1px solid rgba(255, 255, 255, 0.1);
  box-shadow: 0 28px 80px rgba(0, 0, 0, 0.45);
  outline: none;
  animation: bookingRise 0.4s var(--ease) both;
}

.booking-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 1rem;
  padding: 1.35rem 1.35rem 0.85rem;
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}

.booking-kicker {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: #ff8f93;
  margin-bottom: 0.35rem;
}

.booking-head .display {
  font-size: clamp(1.35rem, 3vw, 1.7rem);
}

.booking-close {
  width: 2.4rem;
  height: 2.4rem;
  display: grid;
  place-items: center;
  color: rgba(255, 255, 255, 0.7);
  border: 1px solid rgba(255, 255, 255, 0.14);
  transition: color 0.2s ease, border-color 0.2s ease, background 0.2s ease;
}

.booking-close:hover {
  color: var(--white);
  border-color: rgba(255, 255, 255, 0.4);
  background: rgba(255, 255, 255, 0.06);
}

.booking-steps {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0.5rem;
  padding: 1rem 1.35rem 0;
}

.booking-steps li {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: rgba(255, 255, 255, 0.4);
}

.booking-steps li span {
  width: 1.35rem;
  height: 1.35rem;
  display: grid;
  place-items: center;
  border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, 0.18);
  font-size: 0.72rem;
}

.booking-steps li.is-active {
  color: var(--white);
}

.booking-steps li.is-active span {
  background: var(--red);
  border-color: var(--red);
}

.booking-steps li.is-done {
  color: rgba(255, 255, 255, 0.72);
}

.booking-steps li.is-done span {
  background: rgba(125, 222, 164, 0.2);
  border-color: rgba(125, 222, 164, 0.55);
  color: #7ddea4;
}

.booking-body {
  padding: 1.1rem 1.35rem 1.45rem;
}

.booking-panel {
  animation: bookingRise 0.35s var(--ease) both;
}

.booking-month {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 1rem;
}

.booking-month h3 {
  font-size: 1.05rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  text-transform: capitalize;
}

.booking-month-nav {
  width: 2.2rem;
  height: 2.2rem;
  display: grid;
  place-items: center;
  color: var(--white);
  border: 1px solid rgba(255, 255, 255, 0.16);
  transition: background 0.2s ease, border-color 0.2s ease;
}

.booking-month-nav:hover:not(:disabled) {
  background: rgba(255, 255, 255, 0.08);
  border-color: rgba(255, 255, 255, 0.35);
}

.booking-month-nav:disabled {
  opacity: 0.3;
  cursor: not-allowed;
}

.booking-weekdays {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 0.3rem;
  margin-bottom: 0.4rem;
}

.booking-weekdays span {
  text-align: center;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.45);
  padding: 0.25rem 0;
}

.booking-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 0.3rem;
}

.booking-day {
  aspect-ratio: 1;
  display: grid;
  place-items: center;
  font-size: 0.92rem;
  font-weight: 600;
  color: rgba(255, 255, 255, 0.88);
  border: 1px solid transparent;
  background: rgba(255, 255, 255, 0.04);
  transition: background 0.2s ease, border-color 0.2s ease, color 0.2s ease,
    transform 0.2s ease;
}

.booking-day:not(.is-empty):not(.is-disabled):hover {
  background: rgba(255, 255, 255, 0.1);
  transform: translateY(-1px);
}

.booking-day.is-empty {
  background: transparent;
  pointer-events: none;
}

.booking-day.is-disabled {
  opacity: 0.28;
  cursor: not-allowed;
  background: transparent;
}

.booking-day.is-today:not(.is-selected) {
  border-color: rgba(255, 143, 147, 0.55);
  color: #ffb4b7;
}

.booking-day.is-selected {
  background: var(--red);
  color: var(--white);
  border-color: var(--red);
}

.booking-hint {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  margin-top: 1rem;
  font-size: 0.82rem;
  color: rgba(255, 255, 255, 0.55);
}

.booking-summary {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.92rem;
  font-weight: 500;
  color: rgba(255, 255, 255, 0.78);
  margin-bottom: 1rem;
  padding-bottom: 0.85rem;
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
  width: 100%;
}

.booking-times {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 0.55rem;
}

.booking-time {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.45rem;
  min-height: 2.85rem;
  padding: 0.65rem 0.8rem;
  border: 1px solid rgba(255, 255, 255, 0.14);
  background: rgba(255, 255, 255, 0.04);
  color: rgba(255, 255, 255, 0.86);
  font-weight: 600;
  font-size: 0.92rem;
  transition: background 0.2s ease, border-color 0.2s ease, color 0.2s ease;
}

.booking-time:hover {
  border-color: rgba(255, 255, 255, 0.35);
  background: rgba(255, 255, 255, 0.08);
}

.booking-time.is-selected {
  background: var(--red);
  border-color: var(--red);
  color: var(--white);
}

.booking-topics {
  display: flex;
  flex-wrap: wrap;
  gap: 0.45rem;
  margin-bottom: 1rem;
}

.booking-topic {
  min-height: 2.2rem;
  padding: 0.4rem 0.75rem;
  border: 1px solid rgba(255, 255, 255, 0.16);
  color: rgba(255, 255, 255, 0.72);
  font-size: 0.82rem;
  font-weight: 600;
  transition: background 0.2s ease, border-color 0.2s ease, color 0.2s ease;
}

.booking-topic:hover {
  border-color: rgba(255, 255, 255, 0.35);
  color: var(--white);
}

.booking-topic.is-selected {
  background: rgba(196, 30, 36, 0.22);
  border-color: var(--red);
  color: #ffb4b7;
}

.booking-fields {
  display: grid;
  gap: 0.75rem;
}

.booking-fields .field > span {
  color: rgba(255, 255, 255, 0.55);
}

.booking-fields .field input,
.booking-fields .field textarea {
  color: var(--white);
  border-bottom-color: rgba(255, 255, 255, 0.2);
}

.booking-fields .field input:focus,
.booking-fields .field textarea:focus {
  border-bottom-color: var(--red);
}

.booking-fields .field input::placeholder,
.booking-fields .field textarea::placeholder {
  color: rgba(255, 255, 255, 0.32);
}

.booking-panel .consent-check span {
  color: rgba(255, 255, 255, 0.55);
}

.booking-error {
  margin-top: 0.75rem;
  color: #ffb4b7;
  font-size: 0.88rem;
  font-weight: 600;
}

.booking-actions {
  margin-top: 1.25rem;
}

.booking-actions .btn {
  width: 100%;
}

.booking-actions .btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
  transform: none;
}

.booking-actions-split {
  display: grid;
  grid-template-columns: 1fr 1.35fr;
  gap: 0.65rem;
}

.booking-actions-split .btn {
  width: auto;
}

.booking-done {
  text-align: center;
  padding: 1.5rem 0.5rem 0.5rem;
  animation: bookingRise 0.4s var(--ease) both;
}

.booking-done-icon {
  width: 3.5rem;
  height: 3.5rem;
  margin: 0 auto 1rem;
  display: grid;
  place-items: center;
  border-radius: 999px;
  background: rgba(125, 222, 164, 0.15);
  color: #7ddea4;
}

.booking-done-icon-pending {
  background: rgba(255, 255, 255, 0.1);
  color: rgba(255, 255, 255, 0.75);
  animation: bookingPulse 1.4s ease-in-out infinite;
}

.booking-done-icon-error {
  background: rgba(196, 30, 36, 0.15);
  color: var(--red-hot, #e0242a);
}

@keyframes bookingPulse {
  0%, 100% { opacity: 0.6; }
  50% { opacity: 1; }
}

.booking-done h3 {
  font-size: 1.45rem;
  letter-spacing: -0.02em;
  margin-bottom: 0.55rem;
}

.booking-done > p {
  color: rgba(255, 255, 255, 0.75);
  margin-bottom: 0.75rem;
}

.booking-done-note {
  font-size: 0.9rem;
  color: rgba(255, 255, 255, 0.55) !important;
  max-width: 28ch;
  margin: 0 auto 1.35rem !important;
}

@keyframes bookingFade {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

@keyframes bookingRise {
  from {
    opacity: 0;
    transform: translateY(14px) scale(0.98);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

@media (max-width: 640px) {
  .booking {
    padding: 0;
    place-items: end stretch;
  }

  .booking-dialog {
    width: 100%;
    max-height: 94vh;
    border-radius: 12px 12px 0 0;
  }

  .booking-steps li {
    font-size: 0.7rem;
  }

  .booking-times {
    grid-template-columns: 1fr;
  }

  .booking-actions-split {
    grid-template-columns: 1fr;
  }
}

/* ——— CMS ——— */
.cms {
  padding: 6.5rem 0 4rem;
  background:
    radial-gradient(circle at top right, rgba(196, 30, 36, 0.08), transparent 40%),
    var(--paper);
  min-height: 100svh;
}

.cms-wrap {
  display: grid;
  gap: 1.5rem;
}

.cms-head {
  display: flex;
  justify-content: space-between;
  gap: 1.25rem;
  align-items: end;
  flex-wrap: wrap;
}

.cms-head .display {
  font-size: clamp(1.8rem, 3.5vw, 2.5rem);
  margin-bottom: 0.4rem;
}

.cms-lead {
  color: var(--muted);
  max-width: 40rem;
}

.cms-banner {
  padding: 1.1rem 1.2rem;
  border: 1px solid var(--line);
  background: var(--white);
  display: grid;
  gap: 0.55rem;
}

.cms-banner-warn {
  border-color: rgba(196, 30, 36, 0.35);
  background: rgba(196, 30, 36, 0.06);
}

.cms-banner code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.85em;
  background: rgba(16, 21, 28, 0.06);
  padding: 0.1rem 0.3rem;
}

.cms-seed {
  display: grid;
  gap: 0.5rem;
  justify-items: start;
  margin-top: 0.35rem;
}

.cms-seed p {
  font-size: 0.9rem;
  color: var(--muted);
}

.cms-list {
  display: grid;
  gap: 0.85rem;
}

.cms-toolbar-wrap {
  display: grid;
  gap: 0.85rem;
}

.cms-toolbar {
  display: grid;
  gap: 0.85rem;
  padding: 1rem 1.1rem;
  background: var(--white);
  border: 1px solid var(--line);
}

.cms-search {
  position: relative;
  display: flex;
  align-items: center;
  gap: 0.65rem;
  min-height: 2.9rem;
  padding: 0 0.85rem;
  border-bottom: 2px solid var(--line);
}

.cms-search svg {
  flex-shrink: 0;
  color: var(--muted);
}

.cms-search input {
  flex: 1;
  min-width: 0;
  border: none;
  outline: none;
  background: transparent;
  font: inherit;
  color: var(--ink);
  padding: 0.7rem 0;
}

.cms-search input::placeholder {
  color: var(--muted);
}

.cms-search-clear {
  display: inline-flex;
  color: var(--muted);
  padding: 0.2rem;
}

.cms-search-clear:hover {
  color: var(--ink);
}

.cms-filters {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr)) auto;
  gap: 0.75rem 1rem;
  align-items: end;
}

.cms-reset {
  min-height: 2.9rem;
  align-self: end;
}

.cms-count {
  font-size: 0.88rem;
  color: var(--muted);
}

.cms-empty {
  display: grid;
  gap: 0.85rem;
  justify-items: start;
  padding: 1.5rem 1.1rem;
  background: var(--white);
  border: 1px solid var(--line);
  color: var(--muted);
}

.cms-row {
  display: grid;
  grid-template-columns: 7.5rem 1fr auto;
  gap: 1rem;
  align-items: center;
  padding: 0.85rem;
  background: var(--white);
  border: 1px solid var(--line);
}

.cms-row img {
  width: 7.5rem;
  height: 5rem;
  object-fit: cover;
}

.cms-row h2 {
  font-size: 1.05rem;
  letter-spacing: -0.01em;
  margin: 0.15rem 0;
}

.cms-row-meta {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--red);
}

.cms-row p {
  color: var(--muted);
  font-size: 0.92rem;
}

.cms-row-actions {
  display: flex;
  gap: 0.5rem;
}

.cms-form {
  display: grid;
  gap: 1.25rem;
}

.cms-section {
  background: var(--white);
  border: 1px solid var(--line);
  padding: 1.25rem;
  display: grid;
  gap: 1rem;
}

.cms-section h2 {
  font-size: 1.05rem;
  letter-spacing: -0.01em;
}

.cms-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.9rem 1rem;
}

.cms-grid-4 {
  grid-template-columns: repeat(4, 1fr);
}

.cms-span-2 {
  grid-column: 1 / -1;
}

.cms-section small {
  color: var(--muted);
  font-size: 0.8rem;
}

.cms-preview {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin-bottom: 0.5rem;
}

.cms-preview img {
  width: 8rem;
  height: 5.5rem;
  object-fit: cover;
  border: 1px solid var(--line);
}

.cms-preview p {
  color: var(--muted);
  font-size: 0.88rem;
}

.cms-delete {
  background: transparent;
  color: var(--red-ink);
  border: 1.5px solid rgba(196, 30, 36, 0.35);
  margin-left: auto;
}

.cms-delete:hover {
  background: rgba(196, 30, 36, 0.08);
}

.cms-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  align-items: center;
}

.cms-error {
  color: var(--red-ink);
  font-weight: 600;
  background: rgba(196, 30, 36, 0.08);
  border: 1px solid rgba(196, 30, 36, 0.25);
  padding: 0.8rem 1rem;
}

.cms-success {
  color: #1f6b45;
  font-weight: 600;
  background: rgba(125, 222, 164, 0.18);
  border: 1px solid rgba(31, 107, 69, 0.25);
  padding: 0.8rem 1rem;
}

@media (max-width: 900px) {
  .cms-grid,
  .cms-grid-4 {
    grid-template-columns: 1fr;
  }

  .cms-filters {
    grid-template-columns: 1fr;
  }

  .cms-row {
    grid-template-columns: 5.5rem 1fr;
  }

  .cms-row-actions {
    grid-column: 1 / -1;
  }

  .cms-row img {
    width: 5.5rem;
    height: 4.2rem;
  }
}

/* ——— Entdecken / TikTok-Feed ——— */
.feed-page {
  min-height: 100dvh;
  background: var(--paper);
}

.feed-setup {
  min-height: 100dvh;
  display: grid;
  place-items: center;
  padding: 5.5rem 1.25rem 2rem;
  background:
    radial-gradient(ellipse at top, rgba(196, 30, 36, 0.08), transparent 55%),
    linear-gradient(180deg, #ece8e2, var(--paper));
}

.feed-setup-card {
  width: min(100%, 34rem);
  display: grid;
  gap: 1rem;
  padding: 1.5rem 1.35rem 1.4rem;
  background: var(--white);
  border: 1px solid var(--line);
  box-shadow: 0 18px 40px rgba(16, 21, 28, 0.06);
}

.feed-setup-card .display {
  font-size: clamp(1.85rem, 5vw, 2.4rem);
  margin-bottom: 0;
}

.feed-setup-lead {
  color: var(--muted);
  font-size: 0.98rem;
  line-height: 1.5;
  margin-top: -0.25rem;
}

.feed-setup-filters {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.85rem 1rem;
}

.feed-setup-actions {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.75rem;
  align-items: center;
  margin-top: 0.35rem;
}

.feed-setup-actions .btn-primary {
  width: 100%;
}

.feed-setup-reset {
  min-height: 2.9rem;
  padding-inline: 0.85rem;
  color: var(--ink);
  border: 1.5px solid var(--line);
  background: transparent;
  font-weight: 600;
}

.feed-setup-alt {
  font-size: 0.88rem;
  color: var(--muted);
  text-align: center;
}

.feed-setup-alt a {
  color: var(--ink);
  font-weight: 600;
  border-bottom: 1px solid rgba(16, 21, 28, 0.25);
}

.feed-stage {
  position: fixed;
  inset: 0;
  z-index: 70;
  background: #0a1016;
}

.feed-topbar {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: 5;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding: calc(0.7rem + env(safe-area-inset-top)) 0.9rem 0.7rem;
  background: linear-gradient(
    180deg,
    rgba(10, 16, 22, 0.72),
    transparent
  );
  pointer-events: none;
}

.feed-topbar > * {
  pointer-events: auto;
}

.feed-back {
  display: inline-flex;
  align-items: center;
  gap: 0.2rem;
  min-height: 2.35rem;
  padding: 0.35rem 0.7rem;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.12);
  color: var(--white);
  font-size: 0.88rem;
  font-weight: 600;
  backdrop-filter: blur(8px);
}

.feed-back-icon {
  width: 2.35rem;
  padding: 0;
  justify-content: center;
}

.feed-topbar-count {
  color: rgba(255, 255, 255, 0.78);
  font-size: 0.84rem;
  font-weight: 600;
}

.feed-scroller {
  height: 100%;
  overflow-x: hidden;
  overflow-y: auto;
  overscroll-behavior-y: contain;
  scroll-snap-type: y mandatory;
  -webkit-overflow-scrolling: touch;
}

.feed-slide {
  position: relative;
  height: 100%;
  min-height: 100%;
  scroll-snap-align: start;
  scroll-snap-stop: always;
  overflow: hidden;
}

.feed-slide-media {
  position: absolute;
  inset: 0;
  background: #121820;
}

.feed-slide-media img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transform: scale(1.05);
  transition:
    opacity 0.9s var(--ease),
    transform 1.2s var(--ease);
}

.feed-slide-media img.is-active {
  opacity: 1;
  transform: scale(1);
}

.feed-slide-veil {
  position: absolute;
  inset: 0;
  background: linear-gradient(
    180deg,
    rgba(10, 16, 22, 0.25) 0%,
    transparent 28%,
    transparent 48%,
    rgba(10, 16, 22, 0.55) 72%,
    rgba(10, 16, 22, 0.92) 100%
  );
  pointer-events: none;
}

.feed-slide-content {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 2;
  display: grid;
  gap: 0.35rem;
  padding: 1.25rem 1.2rem calc(1.4rem + env(safe-area-inset-bottom));
  color: var(--white);
}

.feed-slide-status {
  justify-self: start;
  padding: 0.28rem 0.55rem;
  background: rgba(255, 255, 255, 0.14);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

.feed-slide-price {
  font-size: 1.35rem;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: #ffb4b7;
}

.feed-slide-content h2 {
  font-size: clamp(1.2rem, 4.5vw, 1.55rem);
  line-height: 1.25;
  letter-spacing: -0.02em;
  max-width: 18ch;
}

.feed-slide-loc,
.feed-slide-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.65rem;
  color: rgba(255, 255, 255, 0.8);
  font-size: 0.9rem;
}

.feed-slide-loc,
.feed-slide-meta span {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
}

.feed-slide-cta {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  justify-self: start;
  margin-top: 0.45rem;
  min-height: 2.5rem;
  padding: 0.45rem 0.95rem;
  background: var(--red);
  color: var(--white);
  font-weight: 600;
  font-size: 0.9rem;
}

.feed-slide-progress {
  position: absolute;
  right: 1.2rem;
  bottom: calc(1.4rem + env(safe-area-inset-bottom));
  font-size: 0.78rem;
  font-weight: 600;
  color: rgba(255, 255, 255, 0.55);
}

.feed-empty {
  height: 100%;
  display: grid;
  place-content: center;
  gap: 1rem;
  justify-items: center;
  color: rgba(255, 255, 255, 0.8);
  padding: 2rem;
  text-align: center;
}

@media (max-width: 560px) {
  .feed-setup-filters {
    grid-template-columns: 1fr;
  }

  .feed-setup-actions {
    grid-template-columns: 1fr;
  }
}

@media (prefers-reduced-motion: reduce) {
  .feed-scroller {
    scroll-snap-type: none;
  }

  .feed-slide-media img {
    transition: none;
    transform: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation: none !important;
    transition: none !important;
  }
}


/* ——— Calculator: Phase-2-Platzhalter ——— */
.calc-panel-disabled {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.85rem;
}

.calc-disabled-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 3rem;
  height: 3rem;
  border-radius: 50%;
  background: var(--paper-2);
  color: var(--red);
}

.calc-panel-disabled h3 {
  font-size: 1.15rem;
  font-weight: 600;
}

.calc-panel-disabled p {
  color: var(--muted);
  font-size: 0.95rem;
  line-height: 1.6;
}

.calc-panel-disabled .btn {
  margin-top: 0.4rem;
}

/* ——— Cookie-Hinweis ——— */
/* Von Anfang an sichtbar (opacity:1), kein Einblend-Fade mehr beim Laden –
   vorher stand hier opacity:0 + eine 0.35s-Transition, die per JS
   (cookie-banner.php) nach dem ersten Paint auf opacity:1 umgeschaltet
   wurde. Das ließ Lighthouse den Banner-Text unter simulierter
   CPU-Drosselung fälschlich als sehr späten Largest-Contentful-Paint
   erkennen (mehrere Sekunden "Render Delay", obwohl alle Netzwerk-Requests
   längst fertig waren) – Chrome zählt ein zunächst opacity:0-Element erst
   dann als LCP-fähig, wenn es seine finale, sichtbare Opacity erreicht.
   Für Erstbesucher (der Normalfall, Cookie-Hinweis noch nicht bestätigt)
   ist der Banner jetzt sofort da statt einzublenden; für wiederkehrende
   Besucher bleibt die Ausblend-Transition beim Bestätigen (.is-dismissed
   unten) erhalten. */
.cookie-banner {
  position: fixed;
  left: 1.25rem;
  right: 1.25rem;
  /* + env(safe-area-inset-bottom): ohne diesen Puffer saß der "Verstanden"-
     Button auf einem iPhone mit Home-Indicator (z. B. 13 mini) fast direkt
     auf der Wisch-Geste-Zone am unteren Rand – der Banner ist praktisch die
     erste Interaktion jedes neuen Besuchers, sollte also nicht mit einer
     System-Geste kollidieren. env() löst auf Geräten ohne Home-Indicator zu
     0 auf, ändert dort also nichts. */
  bottom: calc(1.25rem + env(safe-area-inset-bottom));
  z-index: 200;
  display: flex;
  justify-content: center;
  pointer-events: auto;
  opacity: 1;
  transform: translateY(0);
  transition: opacity 0.3s var(--ease), transform 0.3s var(--ease);
}

/* Wird per JS gesetzt: beim Bestätigen (sofort) und wenn der Hinweis beim
   Laden schon bestätigt war (ohne Transition, siehe cookie-banner.php). */
.cookie-banner.is-dismissed {
  opacity: 0;
  transform: translateY(1.25rem);
  pointer-events: none;
}

.cookie-banner-inner {
  display: flex;
  align-items: center;
  gap: 1.1rem;
  max-width: 46rem;
  width: 100%;
  background: var(--navy);
  color: var(--white);
  border-radius: 4px;
  border: 1px solid rgba(255, 255, 255, 0.08);
  box-shadow: 0 1.5rem 3rem rgba(13, 20, 28, 0.35);
  padding: 1.35rem 1.5rem;
}

.cookie-banner-icon {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: 50%;
  background: rgba(196, 30, 36, 0.16);
  color: var(--red-hot);
}

.cookie-banner-text { flex: 1; min-width: 0; }

.cookie-banner-title {
  font-family: var(--font);
  font-weight: 700;
  font-size: 0.98rem;
  letter-spacing: -0.01em;
  margin-bottom: 0.3rem;
}

.cookie-banner-desc {
  font-size: 0.85rem;
  line-height: 1.55;
  color: rgba(255, 255, 255, 0.7);
}

.cookie-banner-desc a {
  color: var(--white);
  text-decoration: underline;
  text-underline-offset: 2px;
  text-decoration-color: rgba(255, 255, 255, 0.4);
}

.cookie-banner-desc a:hover {
  text-decoration-color: var(--red-hot);
}

.cookie-banner-actions { flex-shrink: 0; }

.cookie-banner .cookie-banner-accept {
  min-height: 2.6rem;
  padding: 0.65rem 1.4rem;
  font-size: 0.88rem;
  border: none;
  cursor: pointer;
}

@media (max-width: 720px) {
  .cookie-banner { left: 0.75rem; right: 0.75rem; bottom: calc(0.75rem + env(safe-area-inset-bottom)); }

  .cookie-banner-inner {
    flex-wrap: wrap;
    padding: 1.15rem 1.15rem 1.25rem;
  }

  .cookie-banner-icon { width: 2.25rem; height: 2.25rem; }
  .cookie-banner-icon svg { width: 20px; height: 20px; }

  .cookie-banner-actions {
    /* Bug: width:100% bezog sich auf die Breite des Flex-Containers, OHNE
       den zusätzlichen margin-left abzuziehen – der "Verstanden"-Button
       ragte dadurch ca. 22px über den rechten Bildschirmrand hinaus und
       war dort weder sichtbar noch antippbar (Chat-Meldung mit Screenshot).
       calc() zieht den margin-left jetzt von der Breite ab, damit die
       Actions-Zeile bündig mit dem Container endet statt darüber
       hinauszuragen. */
    width: calc(100% - 2.25rem - 1.1rem);
    margin-left: calc(2.25rem + 1.1rem);
  }

  .cookie-banner-actions .btn { width: 100%; }
}

@media (prefers-reduced-motion: reduce) {
  .cookie-banner { transition: none; }
}

/* ——— Objektsuche & Filter (Übersicht) ——— */
.prop-search-bar {
  display: flex;
  gap: 0.75rem;
  margin-bottom: 1rem;
  flex-wrap: wrap;
}

.prop-search-input {
  flex: 1;
  min-width: 14rem;
  display: flex;
  align-items: center;
  gap: 0.6rem;
  background: var(--white);
  border: 1.5px solid var(--line);
  padding: 0.7rem 1rem;
  color: var(--muted);
  transition: border-color 0.2s ease;
}

.prop-search-input:focus-within {
  border-color: var(--red);
  color: var(--ink);
}

.prop-search-input svg { flex-shrink: 0; }

.prop-search-input input {
  flex: 1;
  border: none;
  outline: none;
  font: inherit;
  /* 1rem statt vorher 0.95rem (15.2px): unter 16px zoomt iOS Safari beim
     Fokussieren die ganze Seite hinein (gerätespezifisch, nicht nur bei
     schmalen Viewports) – siehe gleicher Fix in site/suchauftrag.php. */
  font-size: 1rem;
  color: var(--ink);
  background: none;
}

.prop-search-input input::placeholder { color: var(--muted); }

.prop-filter-toggle {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.7rem 1.1rem;
  background: var(--white);
  border: 1.5px solid var(--line);
  color: var(--ink);
  font: inherit;
  font-weight: 600;
  font-size: 0.9rem;
  cursor: pointer;
  transition: border-color 0.2s ease, background 0.2s ease;
}

.prop-filter-toggle:hover { border-color: var(--ink); }
.prop-filter-toggle[aria-expanded="true"] { background: var(--ink); color: var(--white); border-color: var(--ink); }

.prop-filter-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.35rem;
  height: 1.35rem;
  padding: 0 0.35rem;
  border-radius: 50%;
  background: var(--red);
  color: var(--white);
  font-size: 0.72rem;
  font-weight: 700;
}

.prop-filter-panel {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
  gap: 0.9rem;
  align-items: end;
  background: var(--white);
  border: 1.5px solid var(--line);
  padding: 1.25rem;
  margin-bottom: 1.25rem;
}

.prop-filter-field label {
  display: block;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 0.35rem;
}

.prop-filter-field select,
.prop-filter-field input {
  width: 100%;
  padding: 0.55rem 0.65rem;
  border: 1.5px solid var(--line);
  font: inherit;
  /* 1rem statt vorher 0.88rem (14.08px) – gleicher iOS-Zoom-Fix wie bei
     .prop-search-input input oben. */
  font-size: 1rem;
  color: var(--ink);
  background: var(--white);
}

.prop-filter-field select:focus,
.prop-filter-field input:focus {
  outline: none;
  border-color: var(--red);
}

.prop-filter-reset {
  padding: 0.55rem 0.9rem;
  background: none;
  border: 1.5px solid transparent;
  color: var(--muted);
  font: inherit;
  font-size: 0.85rem;
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
  justify-self: start;
}

.prop-filter-reset:hover { color: var(--red); }

.prop-search-meta {
  font-size: 0.85rem;
  color: var(--muted);
  margin-bottom: 1rem;
}

@media (max-width: 640px) {
  .prop-filter-panel { grid-template-columns: 1fr 1fr; }
}

/* ——— Bildergalerie-Lightbox (Objekt-Detailseite) ———
   Cinematisch statt eines schlichten Overlays: das Bild selbst liefert (stark
   geblurt + abgedunkelt) seinen eigenen Hintergrund, Bildwechsel laufen als
   weiche Kreuzblende mit leichtem Rutsch in Wechselrichtung, eine
   Segment-Fortschrittsleiste ersetzt die reine "3/6"-Zahl, und ein
   Filmstreifen mit Gruppen-Badge + Beschriftung im Glass-Look ersetzt die
   nackte Caption-Zeile. */
.pd-lightbox {
  position: fixed;
  inset: 0;
  z-index: 500;
  display: flex;
  flex-direction: column;
  opacity: 0;
  transition: opacity 0.32s var(--ease);
}

.pd-lightbox.is-visible { opacity: 1; }
.pd-lightbox[hidden] { display: none; }

.pd-lightbox-bg {
  position: absolute;
  inset: -5%;
  background-size: cover;
  background-position: center;
  filter: blur(48px) saturate(1.3) brightness(0.55);
  transform: scale(1.15);
  transition: background-image 0.5s ease;
}

.pd-lightbox-scrim {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(120% 90% at 50% 10%, rgba(8, 12, 17, 0.35) 0%, rgba(8, 12, 17, 0.82) 65%),
    linear-gradient(to bottom, rgba(8, 12, 17, 0.55) 0%, rgba(8, 12, 17, 0.25) 20%, rgba(8, 12, 17, 0.25) 70%, rgba(8, 12, 17, 0.88) 100%);
}

.pd-lightbox-topbar {
  position: relative;
  z-index: 3;
  flex-shrink: 0;
}

/* Pillen-Leiste mit Dots (wie im Referenzbild): ein grauer Kapsel-
   Container, darin ein runder Punkt pro Bild; das aktive Bild morpht seinen
   Punkt zu einem länglichen Oval, in dem sich ein dunkler Fortschrittsbalken
   von links nach rechts füllt, bis das nächste Bild kommt. */
.pd-lightbox-progress {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  margin: 1.1rem auto 0;
  padding: 0.55rem 0.7rem;
  width: fit-content;
  background: rgba(255, 255, 255, 0.1);
  backdrop-filter: blur(6px);
  border-radius: 999px;
}

.pd-lightbox-progress span {
  position: relative;
  flex: 0 0 auto;
  width: 0.4rem;
  height: 0.4rem;
  background: rgba(255, 255, 255, 0.35);
  border-radius: 999px;
  overflow: hidden;
  transition: width 0.35s var(--ease), background 0.35s ease;
}

.pd-lightbox-progress span::before {
  content: "";
  position: absolute;
  inset: 0;
  transform: scaleX(0);
  transform-origin: left center;
  background: var(--white);
  border-radius: inherit;
  box-shadow: 0 0 6px rgba(255, 255, 255, 0.6);
}

/* Bereits durchlaufene Bilder: schlichter heller Punkt, kein Balken mehr nötig. */
.pd-lightbox-progress span.is-filled {
  background: rgba(255, 255, 255, 0.75);
}

/* Aktuelles Bild: der Punkt wird zur Kapsel (Track) – deutlich länger und
   im Ruhezustand klar dunkler/transparenter als der Fortschrittsbalken
   selbst, damit die Füllung gut erkennbar ist. */
.pd-lightbox-progress span.is-active {
  width: 3.5rem;
  background: rgba(255, 255, 255, 0.22);
}

/* Aktuelles Bild ohne laufenden Autoplay (z. B. pausiert): Kapsel einfach
   als "hier stehen wir" komplett gefüllt markieren, ohne Animation.
   :not(.is-filling) trennt diesen Zustand explizit von der Animation unten
   – beide Regeln setzen sonst dieselbe Property (transform) mit derselben
   Selektor-Spezifität auf demselben Element, was sich nicht auf die
   Reihenfolge im Stylesheet verlassen sollte. */
.pd-lightbox-progress span.is-active:not(.is-filling)::before { transform: scaleX(1); }

/* Aktuelles Bild MIT laufendem Autoplay: eine echte @keyframes-Animation
   (statt einer transition, die bei unsichtbaren/neu eingefügten Elementen
   unzuverlässig startet) füllt die Kapsel linear über --autoplay-duration
   (vom JS gesetzt, Default 5s). JS hört auf "animationend" dieses Elements,
   um zuverlässig genau dann zum nächsten Bild zu wechseln, wenn der Balken
   komplett voll ist – Start/Stop laufen rein über An-/Abwesenheit der
   Klasse, kein Reflow-Timing-Trick mehr nötig. */
@keyframes pdLightboxFill {
  from { transform: scaleX(0); }
  to { transform: scaleX(1); }
}

.pd-lightbox-progress span.is-filling::before {
  animation: pdLightboxFill var(--autoplay-duration, 5s) linear forwards;
}

.pd-lightbox-topbar-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.85rem 1.25rem;
}

.pd-lightbox-counter {
  color: rgba(255, 255, 255, 0.65);
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  font-variant-numeric: tabular-nums;
}

.pd-lightbox-close {
  /* 2.75rem = 44px, Apples HIG-Mindestmaß für Tap-Ziele (vorher 2.5rem/40px) –
     besonders wichtig hier, da dieser Button der einzige offensichtliche Weg
     ist, die Vollbild-Galerie wieder zu schließen. */
  width: 2.75rem;
  height: 2.75rem;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(255, 255, 255, 0.08);
  backdrop-filter: blur(6px);
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: 50%;
  color: var(--white);
  cursor: pointer;
  transition: background 0.2s ease, transform 0.2s ease;
}

.pd-lightbox-close:hover { background: rgba(255, 255, 255, 0.2); transform: rotate(90deg); }

.pd-lightbox-autoplay-controls {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-left: auto;
  margin-right: 0.75rem;
}

.pd-lightbox-play-toggle {
  /* 2.75rem = 44px, siehe Kommentar bei .pd-lightbox-close. */
  width: 2.75rem;
  height: 2.75rem;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(255, 255, 255, 0.08);
  backdrop-filter: blur(6px);
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: 50%;
  color: var(--white);
  cursor: pointer;
  transition: background 0.2s ease;
}

.pd-lightbox-play-toggle:hover { background: rgba(255, 255, 255, 0.2); }
.pd-lightbox-play-toggle.is-paused { color: rgba(255, 255, 255, 0.6); }

.pd-lightbox-speed {
  height: 2.5rem;
  padding: 0 1.75rem 0 0.75rem;
  background: rgba(255, 255, 255, 0.08) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E") no-repeat right 0.4rem center / 0.9rem;
  backdrop-filter: blur(6px);
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: 999px;
  color: var(--white);
  font: inherit;
  font-size: 0.78rem;
  font-weight: 600;
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
}

.pd-lightbox-speed:hover { background-color: rgba(255, 255, 255, 0.16); }
.pd-lightbox-speed option { color: var(--ink); }

@media (max-width: 640px) {
  .pd-lightbox-autoplay-controls { margin-right: 0.5rem; }
  .pd-lightbox-speed { display: none; } /* auf kleinen Screens: Play/Pause reicht, Tempo bleibt beim zuletzt gewählten Wert */
}

.pd-lightbox-nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 3;
  width: 3rem;
  height: 3rem;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(255, 255, 255, 0.08);
  backdrop-filter: blur(6px);
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: 50%;
  color: var(--white);
  cursor: pointer;
  transition: background 0.2s ease, transform 0.2s ease;
}

.pd-lightbox-nav:hover { background: rgba(255, 255, 255, 0.2); }
.pd-lightbox-prev { left: 1.25rem; }
.pd-lightbox-prev:hover { transform: translateY(-50%) translateX(-3px); }
.pd-lightbox-next { right: 1.25rem; }
.pd-lightbox-next:hover { transform: translateY(-50%) translateX(3px); }

.pd-lightbox-stage {
  position: relative;
  z-index: 2;
  flex: 1;
  min-height: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0.5rem 4.5rem;
  cursor: zoom-out;
}

.pd-lightbox-figure {
  position: relative;
  max-width: 100%;
  max-height: 100%;
  display: flex;
  cursor: default;
  animation: pdLightboxIn 0.4s var(--ease) both;
}

.pd-lightbox-figure img,
.pd-lightbox-figure video {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  border-radius: 3px;
  box-shadow: 0 2rem 6rem rgba(0, 0, 0, 0.55), 0 0 0 1px rgba(255, 255, 255, 0.06);
}

@keyframes pdLightboxIn {
  from { opacity: 0; transform: scale(0.97); }
  to { opacity: 1; transform: scale(1); }
}

.pd-lightbox-figure.is-entering-r { animation: pdLightboxSlideR 0.42s var(--ease) both; }
.pd-lightbox-figure.is-entering-l { animation: pdLightboxSlideL 0.42s var(--ease) both; }

@keyframes pdLightboxSlideR {
  from { opacity: 0; transform: translateX(2.5%) scale(0.98); }
  to { opacity: 1; transform: translateX(0) scale(1); }
}

@keyframes pdLightboxSlideL {
  from { opacity: 0; transform: translateX(-2.5%) scale(0.98); }
  to { opacity: 1; transform: translateX(0) scale(1); }
}

.pd-lightbox-bottom {
  position: relative;
  z-index: 3;
  flex-shrink: 0;
  padding: 0.5rem 1.25rem 1.25rem;
}

.pd-lightbox-caption {
  text-align: center;
  margin-bottom: 0.9rem;
  min-height: 1.4rem;
}

.pd-lightbox-group {
  display: inline-flex;
  align-items: center;
  background: var(--red);
  color: var(--white);
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  padding: 0.28rem 0.75rem;
  border-radius: 999px;
  margin-right: 0.6rem;
  box-shadow: 0 4px 14px rgba(196, 30, 36, 0.4);
}

.pd-lightbox-text {
  font-size: 0.95rem;
  color: rgba(255, 255, 255, 0.9);
  font-weight: 500;
}

.pd-lightbox-filmstrip {
  display: flex;
  justify-content: center;
  gap: 0.5rem;
  overflow-x: auto;
  padding: 0.35rem;
  scrollbar-width: none;
}

.pd-lightbox-filmstrip::-webkit-scrollbar { display: none; }

.pd-lightbox-film-btn {
  position: relative;
  flex-shrink: 0;
  width: 3.6rem;
  height: 2.5rem;
  padding: 0;
  border-radius: 4px;
  overflow: hidden;
  border: 2px solid transparent;
  opacity: 0.5;
  cursor: pointer;
  transition: opacity 0.2s ease, border-color 0.2s ease, transform 0.2s ease;
}

.pd-lightbox-film-btn img,
.pd-lightbox-film-btn video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  pointer-events: none;
}

.pd-lightbox-film-play {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(13, 20, 28, 0.35);
  color: var(--white);
}

.pd-lightbox-film-btn:hover { opacity: 0.85; transform: translateY(-2px); }

.pd-lightbox-film-btn.is-active {
  opacity: 1;
  border-color: var(--white);
  transform: translateY(-2px);
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.4);
}

@media (max-width: 720px) {
  .pd-lightbox-stage { padding: 0.5rem 0.75rem; }
  /* 2.75rem = 44px (vorher 2.35rem/37.6px, unter Apples HIG-Mindestmaß) –
     Bild-Vor/Zurück ist die häufigste Interaktion in der Galerie. */
  .pd-lightbox-nav { width: 2.75rem; height: 2.75rem; }
  .pd-lightbox-prev { left: 0.4rem; }
  .pd-lightbox-next { right: 0.4rem; }
  .pd-lightbox-topbar-row { padding: 0.65rem 0.9rem; }
  .pd-lightbox-progress { padding: 0.75rem 0.9rem 0; }
  .pd-lightbox-bottom { padding: 0.5rem 0.9rem 1rem; }
  .pd-stage-gallery-btn { padding: 0.5rem 0.85rem; font-size: 0.8rem; }
}

@media (prefers-reduced-motion: reduce) {
  .pd-lightbox,
  .pd-lightbox-nav,
  .pd-lightbox-close,
  .pd-lightbox-figure,
  .pd-lightbox-film-btn,
  .pd-stage-gallery-btn {
    transition: none;
    animation: none;
  }
}

/* ——— Dokumente-Download (Freigabe-Seite site/share.php) ———
   Grid aus Karten (nebeneinander statt volle Breite), sitzt zwischen der
   Objekt-Story und dem Kontaktformular. */
.pd-documents {
  padding: 1rem 0 3.5rem;
}

.pd-documents-title {
  margin-bottom: 1.5rem;
  font-size: clamp(1.4rem, 3vw, 1.9rem);
}

.pd-document-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
  gap: 1.1rem;
}

.pd-document-card {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.5rem;
  padding: 1.35rem 1.25rem;
  background: var(--white);
  border: 1.5px solid var(--line);
  border-radius: 4px;
  text-decoration: none;
  color: var(--ink);
  box-shadow: 0 1px 2px rgba(16, 21, 28, 0.04);
  transition: border-color 0.2s ease, transform 0.2s ease, box-shadow 0.2s ease;
}

.pd-document-card:hover {
  border-color: var(--red);
  transform: translateY(-3px);
  box-shadow: 0 12px 24px rgba(16, 21, 28, 0.08);
}

.pd-document-card-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.9rem;
  height: 2.9rem;
  border-radius: 50%;
  background: var(--paper-2);
  color: var(--red);
  margin-bottom: 0.2rem;
}

.pd-document-card-title {
  font-size: 0.98rem;
  font-weight: 700;
  line-height: 1.35;
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}

.pd-document-card-meta {
  font-size: 0.76rem;
  color: var(--muted);
  letter-spacing: 0.02em;
}

.pd-document-card-action {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  margin-top: 0.5rem;
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--red);
}
