/* =====================================================================
   ARTEFAKT – Basis-CSS für jede veröffentlichte Seite.
   Enthält nur Struktur und Verhalten. Alles Gestalterische (Farben,
   Schriften, Abstände) kommt aus site.css (Theme) und dem Seiten-CSS.
   ===================================================================== */

*, *::before, *::after { box-sizing: border-box; }
:root { interpolate-size: allow-keywords; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
/* Erster Besuch: nichts vor den Augen aufbauen (artefakt-kopf.js); fehlt das Skript, gilt das nicht */
body { transition: opacity 280ms ease; }
html.art-laedt body { opacity: 0; }
.nav-logo { color: transparent; }
/* Erster Besuch: das Hero-Bild kommt erst, wenn es ganz da ist, und blendet weich ein (kein Aufbau von oben nach unten) */
html.art-fade .sec-bild { opacity: 0; transition: opacity 500ms ease; }
html.art-fade .sec-bild.art-da { opacity: 1; }
body { margin: 0; line-height: 1.5; -webkit-font-smoothing: antialiased; }
h1, h2, h3, h4, p, ul, ol { margin: 0; }
h1, h2, h3, h4 { font-weight: inherit; }
img, video { max-width: 100%; height: auto; }

/* ---------- Weiche Zustandswechsel (Oli, 28.09.2026) ----------
   Darüberfahren, Fokus, Drücken: Farbe, Fläche, Rahmen, Unterstreichung,
   Deckkraft und Schatten wechseln weich – nie Maße oder Lage (kein Ruckeln).
   Eine Sprache für die ganze Website: 0,5 s mit auslaufender Kurve
   („expo-out“). Sie antwortet sofort – drei Viertel des Wechsels sind nach
   0,1 s da, nichts wirkt träge – und kommt dann ruhig an. So liefen die
   Buttons schon (wie auf Olis Semplice-Seite: ease-out-expo); Menülinie und
   Umschalter (vorher 0,3 s ease) sprechen jetzt dieselbe Sprache.
   Seitenwechsel, Menü-Overlay und Akkordeon bleiben eigene Bewegungen.
   Der Fokusrahmen (Tastatur) erscheint bewusst sofort.
   Dauer und Kurve: --art-dur und --art-ease – für die ganze Website an
   :root oder nur für einen Bereich (Sektion, Code-Modul). Die fertige Liste
   --art-state entsteht deshalb an jedem Element neu (:where(*)), nicht nur
   einmal an :root – sonst käme ein lokaler Wert unten nie an. */
:root {
  --art-dur: .5s;
  --art-ease: cubic-bezier(.16, 1, .3, 1);
}
:where(*) {
  --art-state: color var(--art-dur) var(--art-ease), background-color var(--art-dur) var(--art-ease),
    border-color var(--art-dur) var(--art-ease), text-decoration-color var(--art-dur) var(--art-ease),
    opacity var(--art-dur) var(--art-ease), box-shadow var(--art-dur) var(--art-ease),
    fill var(--art-dur) var(--art-ease), stroke var(--art-dur) var(--art-ease);
}
/* Spezifität 0: ein eigener Übergang (Code-Modul, Kunde) gewinnt immer.
   Wer selbst einen setzt, nimmt var(--art-state) in seine Liste auf. */
:where(a, button, summary, input, select, textarea, a img, .nav-menu a span, .nav-extra a span) {
  transition: var(--art-state);
}

/* ---------- Struktur: Sektion > Zeile > Spalte > Modul ---------- */
.sec {
  --display: flex;
  position: relative;
  display: flex;
  flex-direction: column;
  scroll-margin-top: var(--nav-h, 0px);
}
.sec-inner { position: relative; z-index: 1; width: 100%; }
/* Sektion hinter Kopf- und Hinweisleiste: --topbar-h setzt artefakt.js auf die Sektion direkt unter der Hinweisleiste */
.sec-under-bars { margin-top: calc(-1 * (var(--nav-h, 0px) + var(--topbar-h, 0px))); }
.topbar { position: relative; z-index: 3; }
/* Handy: Hinweisleiste als Button (topBarKnopf). „zu“ = nur der Button; Antippen: die Hinweisleiste fährt von oben über ihn herunter */
.topbar > .topbar-knopf { display: none; }
@media (max-width: 767px) {
  html[data-news="zu"] .topbar-mit-knopf > .sec { display: none; }
  html[data-news="zu"] .topbar > .topbar-knopf, .topbar-oeffnet > .topbar-knopf { display: block; padding: 20px 5%; background: var(--c-light, #fdfcfa); }
  .topbar > .topbar-knopf .btn { font-size: 16px; }
  .topbar-oeffnet { overflow: hidden; }
  .topbar-oeffnet > .topbar-knopf { position: absolute; left: 0; right: 0; top: 0; }
  .topbar-oeffnet > .sec { position: relative; z-index: 1; }
}
}
.sec-inner.container { max-width: var(--container); margin-inline: auto; }
.sec-video, .sec-overlay { position: absolute; inset: 0; width: 100%; height: 100%; }
.sec-video { object-fit: cover; }

.row {
  display: flex;
  flex-wrap: wrap;
  width: 100%;
  /* Abstand, begrenzt: die schmalste Spalte der Zeile bleibt mindestens 8 px breit
     (--gap-fit setzt der Renderer je Zeile; Spaltenformel und Abstand rechnen mit --g) */
  --g: min(var(--gap, 0px), var(--gap-fit, var(--gap, 0px)));
  column-gap: var(--g);
  row-gap: var(--gap, 0px);
}
.col {
  --display: flex;
  position: relative;
  display: flex;
  flex-direction: column;
  flex: 0 0 100%;
  max-width: 100%;
  min-width: 0;
}
.mod { --display: block; display: var(--display); min-width: 0; }
/* Basis-Abstände mit :where() (Spezifität 0): eigene Abstände eines Moduls
   gewinnen immer. Reihenfolge wichtig – der Modulabstand kommt nach dem
   Zurücksetzen der <figure>-Ränder. */
:where(figure.mod-image) { margin: 0; }
:where(.col > .mod + .mod) { margin-top: var(--mod-gap, 0px); }
/* Gruppe (mehrere Module als ein Block): innen derselbe Modulabstand */
:where(.mod-group > .mod + .mod) { margin-top: var(--mod-gap, 0px); }
/* Positioniertes Modul (Flex): diese Kinder behalten trotzdem volle Breite */
:where(.mod-image > a, .img-placeholder, .mod-accordion > .acc-item) { align-self: stretch; }

/* ---------- Module ---------- */
.mod-text > :last-child { margin-bottom: 0; }

.mod-image img { display: inline-block; vertical-align: bottom; height: auto; }
.mod-image figcaption { margin-top: .6em; font-size: .85em; opacity: .8; }
.img-placeholder {
  aspect-ratio: 4 / 3;
  background: linear-gradient(135deg, #ece8e1 0%, #cdd8d2 100%);
}

/* Unterstreichung wie im Original: 6 px Abstand, 0,7 px dick, bei Hover 1,2 px; in der Fußzeile keine.
   Stärker als die Stil-Regel des Themes (.art .mod-text a), die die Stärke sonst zurücksetzt */
:root .art .mod-text a { text-decoration-thickness: 0.7px; text-underline-offset: 6px; }
:root .art .mod-text a:hover { text-decoration-thickness: 1.2px; }
.art .s-footer .mod-text a { text-decoration: none; }

/* Karten in einer Spalte füllen die Höhe der Spalte (Nachbarspalte bestimmt sie) */
[class*="c-"]:has(> .mod-map) { display: flex; flex-direction: column; }
.mod-map { flex: 1 1 0; }

/* Kopfleiste: beim Scrollen nach unten fährt sie nach oben raus, beim Scrollen nach oben kommt sie zurück (artefakt.js) */
.nav { transition: transform .4s cubic-bezier(.45, 0, .2, 1); }
.nav.nav-weg { transform: translateY(-100%); }
@media (prefers-reduced-motion: reduce) { .nav { transition: none; } }

/* Parallax im Hero: das Bild bleibt beim Scrollen stehen, der Text wandert. Ohne das (Handy, reduzierte Bewegung) bleibt es ein normales Hintergrundbild. */
@media (min-width: 768px) and (hover: hover) and (prefers-reduced-motion: no-preference) {
  .s-cover { background-attachment: fixed; }
}

/* Kurze Texte in Kästen werden nicht silbentrennt (sonst „Abklä-rung“) */
/* In Kästen nur trennen, wo ein weiches Trennzeichen steht (&shy;) und sonst nichts mehr passt */
[class*="c-box-"], .s-buchen { hyphens: manual; overflow-wrap: normal; }

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  transition: var(--art-state);
}

/* Symbol am Button (Pfeil …): Form aus der Grafik des Kunden (Maske),
   Farbe = Schriftfarbe, auch beim Darüberfahren. Abstand = halbe Größe. */
.btn-icon {
  flex: none;
  width: var(--icon, 1em);
  height: var(--icon, 1em);
  background-color: currentColor;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
  -webkit-mask-size: contain;
  mask-size: contain;
}
.btn-icon + .btn-label, .btn-label + .btn-icon { margin-left: calc(var(--icon, 1em) / 2); }
/* Symbol und Text bleiben eine Zeile (gesetzte Zeilenumbrüche gelten weiter);
   Telefonnummern brechen nie um */
.btn-label, .btn[href^="tel:"] { white-space: nowrap; }

/* Terminkalender (artefakt-termin.js): erscheint nach dem Klick unter der Zeile des Buttons,
   volle Breite der Sektion, in der Gestaltung der Website (Farben, Schrift) */
.booking {
  width: 100%;
  margin-top: clamp(24px, 4vw, 48px);
  scroll-margin-top: calc(var(--nav-h, 0px) + 12px);
  opacity: 0;
  translate: 0 12px;
  transition: opacity .5s ease, translate .5s ease;
}
.booking.is-open { opacity: 1; translate: 0 0; }
.booking:focus { outline: none; }
.booking-bar { display: flex; justify-content: center; padding: 1.2em 0 .6em; }
.booking-close {
  display: grid; place-items: center;
  width: 48px; height: 48px;
  color: inherit;
  background: none;
  border: 0;
  border-radius: 50%;
  padding: 0;
  cursor: pointer;
  opacity: .75;
}
.booking-close:hover, .booking-close:focus-visible { opacity: 1; }
.booking-frame { display: block; width: 100%; height: clamp(560px, 82vh, 780px); border: 0; background: transparent; }
/* Solange der Anbieter lädt: ruhiges Warterad mit Satz, in Farbe und Schrift der Website */
.booking-stage { position: relative; }
.booking-wait {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1.1em;
  margin: 0; opacity: .85; pointer-events: none;
  transition: opacity .4s ease;
}
.booking-wait::before {
  content: ""; width: 1.6em; height: 1.6em; border-radius: 50%;
  border: 3px solid currentColor; border-top-color: transparent;
  animation: art-booking-spin 1s linear infinite;
}
.booking.is-ready .booking-wait { opacity: 0; }
/* Der Rahmen bleibt unsichtbar, bis der Kalender fertig ist – nur eine Ladeanzeige, nicht zwei */
.booking-frame { opacity: 0; transition: opacity .4s ease; }
.booking.is-ready .booking-frame { opacity: 1; }
@keyframes art-booking-spin { to { rotate: 360deg; } }
@media (max-width: 767px) { .booking-frame { height: 740px; } }

.mod-divider hr {
  width: 100%;
  margin: 0 auto;
  border: 0;
  border-top: 1px solid currentColor;
}

.badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: var(--c-primary, #333);
  color: #fff;
  line-height: 1;
}

.acc-item { border-top: 1px solid currentColor; border-bottom: 1px solid currentColor; }
/* Zwischen zwei Akkordeons nur eine Linie, nicht zwei */
.acc-item + .acc-item { border-top: 0; }
/* Handy: steht das Akkordeon ganz am Ende einer Spalte, entfällt seine Abschlusslinie – darunter folgt gleich die Linie der Sektion (sonst doppelt) */
@media (max-width: 767px) { :is([class*="c-"], .sec-inner) > .mod-accordion:last-child > .acc-item:last-child:not([open]) { border-bottom-color: transparent; } }
.acc-item summary {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1em;
  padding: .8em 0;
  cursor: pointer;
  list-style: none;
}
.acc-item summary::-webkit-details-marker { display: none; }
/* Zeichen aus dünnen Linien wie im Original: waagerechte Linie bleibt, senkrechte schrumpft
   beim Öffnen zum Minus (weich, 350 ms). Größe 1,3 × Schrift */
.acc-item summary { position: relative; }
.acc-item summary::before,
.acc-item summary::after {
  content: "";
  position: absolute;
  right: 0;
  top: 50%;
  width: 1.1em;
  height: 1.1em;
  translate: 0 -50%;
  background: linear-gradient(currentColor, currentColor) center / 100% 1px no-repeat;
}
.acc-item summary::after {
  background: linear-gradient(currentColor, currentColor) center / 1px 100% no-repeat;
  transition: transform .35s cubic-bezier(.45, 0, .2, 1);
}
.acc-item[open] summary::after { transform: scaleY(0); }
.acc-body { padding-bottom: 1em; overflow: hidden; }

.scroll-hint {
  position: absolute;
  left: 50%;
  bottom: 30px;
  z-index: 2;
  translate: -50% 0;
  animation: art-hint 2.4s ease-in-out infinite;
  animation-delay: var(--hint-delay, 0ms);
}
.scroll-hint img { display: block; width: 30px; height: auto; }
/* Der Hero reicht bis ganz zum Rand des Bildschirms (--bar-unten), der Pfeil bleibt über der Leiste des Browsers */
.scroll-hint-svh { bottom: calc(30px + var(--bar-unten, 0px)); }
@keyframes art-hint { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(8px); } }

/* ---------- Navigation ---------- */
.nav {
  position: sticky;
  top: 0;
  z-index: 100;
  display: flex;
  align-items: center;
  height: var(--nav-h, 80px);
}
/* min-width: im Raster (Menü mittig) darf das Logo nie schrumpfen */
.nav-logo { display: block; flex: none; min-width: max-content; }
.nav-logo img { display: block; width: 160px; height: auto; }
.nav-menu ul { list-style: none; margin: 0; padding: 0; }
/* Nur die obere Ebene nebeneinander – sonst gewänne display: flex gegen .sub und jedes Untermenü stünde immer offen */
.nav-menu > ul { display: flex; }
.nav-menu a { display: block; padding: 0 15px; line-height: var(--nav-h, 80px); color: inherit; text-decoration: none; }
.nav-menu a span { border-bottom: 1px solid transparent; }
.logo-left-menu-left .nav-menu { margin-left: 40px; }
.logo-left-menu-right .nav-menu { margin-left: auto; }
/* Menü mittig: drei Spalten Logo · Menü · Zusatz (dazu Hamburger und noscript).
   Die äußeren Spalten teilen sich den freien Platz gleich – das Menü steht
   genau in der Seitenmitte, solange links und rechts Platz ist. Wird es eng
   (z. B. Umschalter plus „Termin“-Button zwischen 768 und 1300 px), behält
   die rechte Spalte, was ihr Inhalt braucht, und das Menü rückt nach links:
   nie eine Überlappung, nie ein Umbruch (Oli, 29.09.2026). Vorher stand das
   Menü absolut in der Mitte und der Zusatz lief darüber. */
.logo-left-menu-center { display: grid; grid-template-columns: 1fr auto 1fr auto auto; }
.logo-left-menu-center .nav-logo { grid-column: 1; }
.logo-left-menu-center .nav-menu { grid-column: 2; }
.logo-left-menu-center .nav-extra { grid-column: 3; justify-self: end; }
.logo-left-menu-center .nav-burger { grid-column: 4; }
.logo-left-menu-center > noscript { grid-column: 5; }
/* Logo mittig; ein Menü steht mittig darunter, der Hamburger frei am rechten Rand */
.logo-center { justify-content: center; }
.logo-center .nav-menu { position: absolute; left: 50%; bottom: 0; translate: -50% 0; }
.logo-center .nav-menu a { line-height: 2.5; }
.logo-center .nav-burger, .logo-center > noscript { position: absolute; top: 50%; right: var(--nav-px, 20px); translate: 0 -50%; margin: 0; }

/* Zusatz rechts (nav.extra): Button(s) oder zweite Navigation, auch auf dem Handy sichtbar.
   --extra-fit: passt nicht alles in die Zeile, verkleinert artefakt.js die
   Einträge stufenweise (0,9 · 0,8 · 0,7) – jeden als Ganzes, mit Innenabstand
   und Rahmen (zoom); ohne zoom (ältere Firefox) bleiben sie in voller Größe.
   Logo, Hamburger und die Mindestabstände behalten immer ihre Größe. */
.nav-extra { display: flex; align-items: center; column-gap: var(--extra-gap, 1em); margin-left: auto; line-height: 1; white-space: nowrap; }
/* Mindestabstand zu Logo und Menü: der Abstand der Einträge, mindestens 16 px – nie näher, auch verkleinert nicht */
.nav-extra { padding-left: max(16px, var(--extra-gap, 16px)); }
.nav-extra a { display: inline-flex; align-items: center; zoom: var(--extra-fit, 1); }
.nav-extra a:not(.btn) { color: inherit; text-decoration: none; }
.nav-extra a:not(.btn) span { border-bottom: 1px solid transparent; }
.nav-extra ~ .nav-burger, .nav-extra ~ noscript { margin-left: var(--extra-gap, 16px); }
/* Art „Kontur“ und „Fläche“ (Voreinstellungen): in den Farben der Kopfleiste
   (--nav-fg Schrift, --nav-bg Hintergrund, site.css); beim Darüberfahren
   tauschen sie. Innenabstand in em – wächst mit der Schrift. */
.nav-extra a.nav-x-outline, .nav-extra a.nav-x-solid { padding: .45em 1em; border: 1px solid currentColor; }
/* „a.“: gewinnt gegen .nav-extra a:not(.btn) { color: inherit } (gleich spezifisch wie .nav-extra a.x) */
.nav-extra a.nav-x-solid { color: var(--nav-bg, #fff); background: var(--nav-fg, #000); border-color: var(--nav-fg, #000); }
.nav-extra a.nav-x-outline:hover, .nav-extra a.nav-x-outline:focus-visible { color: var(--nav-bg, #fff); background: var(--nav-fg, #000); }
.nav-extra a.nav-x-solid:hover, .nav-extra a.nav-x-solid:focus-visible { color: var(--nav-fg, #000); background: transparent; }
/* Ecken (Voreinstellungen): Eckig, Leicht rund, Pille – auch über einen Button-Stil */
.nav-extra a.nav-x-square { border-radius: 0; }
.nav-extra a.nav-x-soft { border-radius: .3em; }
.nav-extra a.nav-x-pill { border-radius: 9999px; }
/* Reicht der Platz auch verkleinert nicht (artefakt.js): auf dem Tablet wandert
   zuerst das Menü in den Hamburger (wie auf dem Handy), zuletzt der Zusatz ins Menü */
.nav-menu-collapsed .nav-menu { display: none; }
.nav-menu-collapsed .nav-burger { display: flex; }
.nav-extra-in-menu .nav-extra { display: none; }
.nav-overlay-extra { display: none; margin-top: .8em; padding-top: .8em; border-top: 1px solid currentColor; }
.nav-extra-in-menu + .nav-overlay .nav-overlay-extra { display: block; }
/* Umschalter (z. B. Orte): die eigene Seite hell, die anderen leicht ausgeblendet.
   Kein eigener Übergang hier – die Deckkraft wechselt über --art-state mit Farbe und Fläche. */
.nav-extra-switch a { opacity: .4; }
.nav-extra-switch a[aria-current], .nav-extra-switch a:hover, .nav-extra-switch a:focus-visible { opacity: 1; }
/* Tastatur: ein ausgeblendeter Eintrag ist mit dem Fokus sofort ganz da – sonst
   blendete der Fokusrahmen mit der Deckkraft ein (anfangs nur zu 40 % sichtbar) */
.nav-extra-switch a:focus-visible { transition: none; }

.has-sub { position: relative; }
/* Untermenü: blendet weich ein und aus (Deckkraft, nie Maße oder Lage).
   Versteckt ist es display: none – für Maus, Tastatur und Screenreader nicht
   da. Das Überblenden von und zu display: none braucht @starting-style und
   allow-discrete; Browser ohne beides zeigen es wie bisher sofort. */
.sub {
  display: none;
  position: absolute;
  top: 100%;
  left: 0;
  flex-direction: column;
  min-width: 220px;
  background: var(--nav-bg, #fff);
  opacity: 0;
  transition: opacity var(--art-dur) var(--art-ease), display var(--art-dur) allow-discrete;
}
.sub a { line-height: 1.4; padding: .6em 15px; }
.has-sub:hover > .sub, .has-sub:focus-within > .sub, .has-sub.open > .sub { display: flex; opacity: 1; }
@starting-style {
  .has-sub:hover > .sub, .has-sub:focus-within > .sub, .has-sub.open > .sub { opacity: 0; }
}

.nav-burger {
  display: none;
  position: relative;
  align-items: center;
  flex: none; /* schrumpft nie, egal wie viel rechts daneben steht */
  width: 28px;
  height: 20px;
  margin-left: auto;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  cursor: pointer;
}
.nav-burger span, .nav-burger span::before, .nav-burger span::after {
  display: block;
  width: 100%;
  height: 2px;
  background: currentColor;
  transition: transform .3s ease, background-color .3s ease;
}
.nav-burger span { position: relative; }
.nav-burger span::before, .nav-burger span::after { content: ""; position: absolute; left: 0; }
.nav-burger span::before { transform: translateY(-7px); }
.nav-burger span::after { transform: translateY(7px); }
.nav-open .nav-burger span { background: transparent; }
.nav-open .nav-burger span::before { transform: rotate(45deg); }
.nav-open .nav-burger span::after { transform: rotate(-45deg); }

.nav-overlay {
  position: fixed;
  inset: var(--nav-h, 80px) 0 0 0;
  z-index: 90;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #fff;
  opacity: 0;
  visibility: hidden;
  transition: opacity .3s ease, visibility .3s;
}
/* Beim Öffnen sofort sichtbar (Fokus lässt sich gleich hineinsetzen), beim Schließen erst nach dem Ausblenden */
.nav-open .nav-overlay { opacity: 1; visibility: visible; transition: opacity .3s ease, visibility 0s; }
.nav-open { overflow: hidden; }
.nav-overlay ul { list-style: none; margin: 0; padding: 0; text-align: center; }
.nav-overlay a { display: block; padding: .4em 0; color: inherit; text-decoration: none; font-size: 32px; }

/* Ohne JavaScript: Link in <noscript> öffnet das Menü über :target, der
   Button (braucht Skript) tritt zurück. Mit JavaScript ist <noscript> leer.
   Rückfall ohne :has(): beide Symbole sichtbar, der Link funktioniert. */
.nav > noscript { margin-left: auto; }
.nav:has(> noscript > .nav-burger) > button.nav-burger { display: none; }
.nav-overlay:target { opacity: 1; visibility: visible; }
.nav-overlay .nav-close { margin-top: 1em; font-size: 16px; text-decoration: underline; }

/* ---------- Schwebender Kreis-Button ---------- */
.float-btn {
  position: fixed;
  top: calc(var(--nav-h, 80px) + 50px);
  right: 20px;
  z-index: 80;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 140px;
  height: 140px;
  border: 1px solid var(--c-primary, #333);
  border-radius: 50%;
  background: #fff;
  color: var(--c-primary, #333);
  font-size: 18px;
  line-height: 1.4;
  text-align: center;
  text-decoration: none;
  /* Farben weich wie überall; Ein- und Ausblenden beim Scrollen mit eigener Zeit */
  transition: var(--art-state), opacity .5s ease, visibility .5s;
}
/* visibility: ausgeblendet auch für Tastatur und Screenreader nicht erreichbar */
.float-btn.is-hidden { opacity: 0; visibility: hidden; pointer-events: none; }

/* ---------- Seitenübergang: Push-Slide über die View Transition API ----------
   Bekannt: Chromium meldet gelegentlich „InvalidStateError: Transition was
   aborted …“, wenn es einen Übergang selbst abbricht (v. a. Headless-Shell,
   selten beim schnellen Zurück). Die Seite wechselt trotzdem; abfangen ließe
   es sich nur mit einem Inline-Skript im <head> jeder Seite. */
@view-transition { navigation: auto; }
::view-transition-old(root), ::view-transition-new(root) {
  animation-duration: 700ms;
  animation-timing-function: cubic-bezier(.83, 0, .17, 1);
  mix-blend-mode: normal;
}
::view-transition-old(root) { animation-name: art-push-out; }
::view-transition-new(root) { animation-name: art-push-in; }
@keyframes art-push-out { to { transform: translateX(-100%); } }
@keyframes art-push-in { from { transform: translateX(100%); } }

/* Seitenwechsel mit Richtung (Button „Seitenwechsel: nach links / rechts“,
   wie der Pfeil zeigt): „links“ = die neue Seite kommt von links, die alte
   geht nach rechts. Beide Seiten schieben gemeinsam, 1 s mit sanftem
   Anlauf und Auslauf (wie Olis Semplice-Seite: Expo.easeInOut). */
html[data-swipe]::view-transition-old(root), html[data-swipe]::view-transition-new(root) {
  animation-duration: 1000ms;
  animation-timing-function: cubic-bezier(.45, 0, .2, 1);
}
/* Senkrecht (Fußzeile): „up“ = die neue Seite kommt von unten, „down“ = von oben */
html[data-swipe="up"]::view-transition-old(root) { animation-name: art-push-out-up; }
html[data-swipe="up"]::view-transition-new(root) { animation-name: art-push-in-up; }
html[data-swipe="down"]::view-transition-old(root) { animation-name: art-push-out-down; }
html[data-swipe="down"]::view-transition-new(root) { animation-name: art-push-in-down; }
@keyframes art-push-out-up { to { transform: translateY(-100%); } }
@keyframes art-push-in-up { from { transform: translateY(100%); } }
@keyframes art-push-out-down { to { transform: translateY(100%); } }
@keyframes art-push-in-down { from { transform: translateY(-100%); } }
html[data-swipe="left"]::view-transition-old(root) { animation-name: art-push-out-right; }
html[data-swipe="left"]::view-transition-new(root) { animation-name: art-push-in-left; }
@keyframes art-push-out-right { to { transform: translateX(100%); } }
@keyframes art-push-in-left { from { transform: translateX(-100%); } }
/* Firefox (ohne Seitenübergänge): die Zielseite im Rahmen neben der Seite,
   beide schieben gemeinsam (artefakt.js) */
.art-swipe-frame {
  position: fixed; top: 0; left: 0; width: 100%; height: 100%;
  border: 0; z-index: 2147483000; pointer-events: none;
}
html[data-swipe-wait] { overflow-x: hidden; }
/* Zu einer anderen Website: die Seite schiebt allein hinaus, anlaufend */
html[data-swipe-out] { overflow-x: hidden; }
html[data-swipe-out] body {
  animation: art-push-out 500ms cubic-bezier(.7, 0, .84, 0) forwards;
  pointer-events: none;
}
html[data-swipe-out="left"] body { animation-name: art-push-out-right; }

@media (prefers-reduced-motion: reduce) {
  /* Auch eigene Übergänge, die var(--art-state) benutzen, wechseln sofort */
  :root { --art-dur: 0s; }
  html { scroll-behavior: auto; }
  ::view-transition-old(root), ::view-transition-new(root) { animation: none; }
  html[data-swipe]::view-transition-old(root), html[data-swipe]::view-transition-new(root),
  html[data-swipe-out] body { animation: none; }
  .scroll-hint { animation: none; }
  .btn, .nav-burger span, .nav-burger span::before, .nav-burger span::after,
  .nav-overlay, .nav-open .nav-overlay, .float-btn, .acc-item summary::after, .sub { transition: none; }
  :where(a, button, summary, input, select, textarea, a img, .nav-menu a span, .nav-extra a span) { transition: none; }
  /* Eigene Regel: Browser ohne ::details-content verwerfen sonst die ganze Liste */
  .acc-item::details-content { transition: none; }
  .booking { transition: none; translate: none; }
  .booking-frame { transition: none; }
  .booking-wait::before { animation: none; border-top-color: currentColor; opacity: .5; }
}

/* ---------- Karte mit Zustimmung (Baustein „Karte“, artefakt-karte.js) ---------- */
.mod-map { position: relative; display: flex; align-items: center; justify-content: center; min-height: 20rem; background: #eee; background: color-mix(in srgb, var(--c-primary, #888) 10%, #fff); }
.mod-map .map-gate { max-width: 20rem; padding: 1.5em; text-align: center; }
.mod-map .map-gate p { margin: 0 0 1em; font-size: .85em; line-height: 1.5; }
.mod-map .map-btn { cursor: pointer; }
.mod-map iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }

/* Nur für Vorlese-Programme und Suchmaschinen sichtbar (z. B. Haupt­überschrift ohne eigene Zeile) */
.nur-lesbar { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

/* Zeitleiste im Akkordeon: Zeitraum links, Text rechts auf einer Linie, Umbruch unter dem Text */
.zeitleiste { display: grid; grid-template-columns: max-content 1fr; column-gap: 1em; row-gap: .5em; margin: 0; }
.zeitleiste > div { display: contents; }
.zeitleiste dt, .zeitleiste dd { margin: 0; }

/* Eigene Karte: Fläche mit der Karte, Info-Karte oben links; ohne JavaScript bleibt nur die Info-Karte */
.mod-map-eigen { position: relative; min-height: 420px; overflow: hidden; background: var(--c-light, #fdfcfa); }
.mod-map-eigen .karte-flaeche { position: absolute; inset: 0; }
.mod-map-eigen .karte-info {
  position: absolute; z-index: 2; left: 16px; top: 16px; max-width: min(340px, calc(100% - 32px));
  padding: 14px 16px 16px; background: var(--c-light, #fdfcfa); font-size: 13px; line-height: 1.55; border: 1px solid var(--c-primary, currentColor);
  border-radius: 20px; box-shadow: 0 6px 24px rgba(60, 90, 75, .16);
}
.mod-map-eigen .karte-info p { margin: 0; font-size: 13px; line-height: 1.55; }
/* Button wie auf der Seite, nur kleiner: gleiche Proportionen (Seite: 18 px Schrift, 11/49 px Innenabstand, 20 px Rundung = .61em / 2.72em / 1.11em) */
.mod-map-eigen .karte-info .btn { font-size: 13px; line-height: 1.6667; padding: .611em 2.72em; border-radius: 1.11em; }
.mod-map-eigen .karte-name { font-weight: 600; font-size: 14px !important; margin-bottom: 4px !important; }
.mod-map-eigen .karte-adresse { margin-bottom: 8px !important; }
.mod-map-eigen .karte-hinweis { margin-bottom: 14px !important; }
@media (max-width: 767px) { .mod-map-eigen .karte-info p, .mod-map-eigen .karte-info .btn { font-size: 14px; } }
.mod-map-eigen .karte-knoepfe { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.mod-map-eigen .karte-adresse + .karte-knoepfe { margin-top: 4px; }
.mod-map-eigen .karte-pin { width: 26px; height: 26px; border-radius: 50% 50% 50% 0; rotate: -45deg; background: var(--c-primary, #80a291); border: 3px solid #fff; box-shadow: 0 2px 8px rgba(0, 0, 0, .35); margin-bottom: 6px; }
.mod-map-eigen .karte-pin-halter { width: 26px; height: 34px; display: flex; align-items: flex-end; justify-content: center; }
.mod-map-eigen .maplibregl-ctrl-group { border-radius: 12px; box-shadow: none; border: 1px solid var(--c-primary, currentColor); background: var(--c-light, #fdfcfa); }
.mod-map-eigen .maplibregl-ctrl-attrib { font-size: 10px; background: rgba(253, 252, 250, .85); color: var(--c-primary, currentColor); }
.mod-map-eigen .maplibregl-ctrl-attrib a { color: inherit; }
.mod-map-eigen .maplibregl-cooperative-gesture-screen { font-family: inherit; }
@media (max-width: 767px) { .mod-map-eigen { min-height: 480px; } .mod-map-eigen .karte-info { left: 10px; right: auto; top: 10px; max-width: calc(100% - 20px); } }
