/* Joiel's Palace — shared stylesheet
   Editorial layout: Jost throughout (caps for display type), full-bleed
   photography and generous whitespace. The palette is built from three brand
   colours — slate blue, sand and sage — see the block below. Content stays
   entirely data-driven (see site.js), so this file and the HTML skeletons
   never need to change when text/images in /i18n/ change. */

:root {
  /* Sagt dem Browser, dass die Seite beide Modi beherrscht — davon haengen
     Formularfelder, Auswahllisten und die Scrollleiste ab, die sonst hell
     blieben. */
  color-scheme: light dark;

  /* Three brand colours carry the site: slate blue, sand and sage.
     Everything else is derived from them.

     Sand is the one that cannot hold text — at 2.3:1 against white it is a
     surface colour only (bands, table headers, frames). Text on sand always
     uses --color-heading. Every text pairing below meets WCAG AA; the one
     exception is sage on a sand band, where --color-accent-dark steps in. */
  --color-slate: #626e82;
  --color-sand: #b6a892;
  --color-sage: #667057;

  --color-bg: #f7f4ef;
  --color-bg-alt: #f2ece4;
  /* Sand mixed 60% into white — keep this in step when --color-sand moves. */
  --color-sand-soft: #e2dcd3;
  --color-surface: #ffffff;
  --color-text: #4b5361;
  --color-text-soft: #5f6673;
  /* Zeigt jetzt auf Slate statt auf den fast schwarzen Alt-Ton (#333c4b).
     Trägt Überschriften, Navigation, Tabellenköpfe, Auszeichnungstitel und
     die vier dunklen Flächen (Sprachwahl-Seite, Bild-Letterbox, Social-Hover,
     Skip-Link). --color-text bleibt bewusst separat und unverändert, das ist
     das eigentliche Fliesstext-Token und wird hier nicht berührt. */
  --color-heading: var(--color-slate);
  --color-border: rgba(98, 110, 130, 0.22);
  /* ---------- Titelbild: festgelegt am 18.10.2026, bleibt so ----------
     Jedes Titelbild der Website sitzt im selben Rahmen: volle Breite der
     Spalte, Seitenverhaeltnis 3 : 2 im Querformat. Das Foto fuellt ihn
     ganz, es gibt weder Balken noch Rahmen. Passt ein Foto nicht, wird
     das Foto in der Foto-Werkstatt auf 3 : 2 zugeschnitten; dieser Wert
     wird nicht geaendert. Wer ihn doch aendert, aendert den Zuschnitt
     jedes einzelnen Titelbildes der Website mit. */
  --titelbild-format: 3 / 2;
  --color-accent: #667057;
  --color-accent-dark: #4e5643;
  --color-accent-soft: rgba(102, 112, 87, 0.13);
  --color-deep: #2b323d;
  --color-cream: #f7f4ef;
  /* Das einzige Rot der Seite. Es markiert Befunde, die keine Bestaetigung
     sind — dort waere der gruene Haken eine Aussage, die der Text nicht
     macht. Bewusst gedeckt gehalten, damit es neben Sage und Sand nicht
     schreit: 6,4:1 auf Weiss, also auch fuer kleine Schrift ausreichend. */
  --color-alert: #a33a32;
  --color-alert-soft: rgba(163, 58, 50, 0.12);

  /* Eine einzige Familie trägt die Seite: Jost, eine geometrische Grotesk.
     Sie liegt dem Schriftzug im Logo am nächsten, dadurch spricht die Seite
     dieselbe Sprache wie das Wortzeichen. Der Unterschied zwischen Titel und
     Text entsteht nicht über eine zweite Schrift, sondern über Versalien und
     weite Laufweite — daher steht bei den Überschriften unten
     `text-transform: uppercase` mit grossem `letter-spacing`. */
  --font-display: "Jost", "Futura", "Century Gothic", sans-serif;

  /* Titel laufen auf Wunsch in Myriad Pro. Die liegt weder bei Google Fonts
     noch als Datei im Projekt — sie greift nur bei Besuchern, die sie lokal
     installiert haben (in der Regel mit Adobe-Programmen). Alle anderen
     bekommen Source Sans 3: dieselbe humanistische Grotesk-Linie, vom selben
     Zeichner wie Myriad, frei verwendbar und über Google Fonts geladen.
     Wer Myriad Pro fuer alle Besucher will, braucht eine Web-Lizenz und legt
     die Schriftdateien unter assets/ ab; dann kommt hier ein @font-face dazu
     und die Familie zieht von selbst. */
  --font-title: "Myriad Pro", "Source Sans 3", "Source Sans Pro", "Segoe UI", Helvetica, Arial, sans-serif;
  --font-body: "Jost", "Futura", "Century Gothic", sans-serif;

  /* ---- Schriftgrössen-Skala ----------------------------------------
     Vorher standen 23 einzelne Grössen im Stylesheet, viele davon nur
     Hundertstel auseinander (0.74 / 0.76 / 0.78 / 0.8 nebeneinander für
     dieselbe Sorte Mikro-Label). Ab hier greift jede Regel auf eine dieser
     acht Stufen zu — das ist der Grund, warum die Seite einheitlich wirkt.

     2xs  Versal-Mikrolabels: Buttons, Tabellenkopf, Pille, Auszeichnungen
     xs   Navigation, Bildunterschriften, Sprachwahl
     sm   Formulare, Tabellenzellen, Untermenü, Lightbox
     base Fliesstext
     lg   Einleitungssatz unter einer Überschrift
     xl   h3, Fusszeilen-Titel, Formular-Abschnitt, Splash-Zeile
     2xl  h2
     3xl  h1                                                            */
  --text-2xs: 0.74rem;
  --text-xs: 0.82rem;
  --text-sm: 0.92rem;
  --text-base: clamp(1.02rem, 0.94rem + 0.25vw, 1.12rem);
  --text-lg: clamp(1.06rem, 0.98rem + 0.3vw, 1.26rem);
  --text-xl: clamp(1.15rem, 1.05rem + 0.4vw, 1.45rem);
  --text-2xl: clamp(1.35rem, 1.15rem + 0.85vw, 1.95rem);
  --text-3xl: clamp(1.85rem, 1.45rem + 1.7vw, 2.9rem);

  --max-width: 1240px;
  --max-width-narrow: 760px;
  /* Fliesstext: breiter als die alten 760 px, aber nicht die ganze Seite
     (Nadine, 17.09.2026). Ueber etwa 1000 px werden die Zeilen so lang,
     dass das Auge den Anfang der naechsten nicht mehr findet. Titel und
     Baender gehen dagegen ueber die ganze Fensterbreite. */
  --max-width-text: 1000px;
  --gap: 1.5rem;

  --radius-l: 22px;
  --radius-m: 14px;
  --radius-s: 8px;

  --shadow-soft: 0 20px 45px -22px rgba(43, 50, 61, 0.26);
  --shadow-lift: 0 30px 60px -25px rgba(43, 50, 61, 0.34);

  --ease: cubic-bezier(0.22, 1, 0.36, 1);
}

/* ---------- Dark Mode ----------
   Neu gesetzt werden nur die Farbtoken; jede Regel weiter unten arbeitet
   ohnehin mit ihnen und zieht darum von selbst mit. Es gibt genau zwei
   Ausnahmen, die einen festen Wert brauchen — die durchscheinende Kopfzeile
   und das Logo.

   Der dunkle Grund ist nicht neutralgrau, sondern leicht ins Blaue gezogen,
   dieselbe Richtung wie Slate: so bleibt der Markenton auch im Dunkeln
   spuerbar. Sage und Sand werden aufgehellt — die Originaltoene sind auf
   dunklem Grund zu schwach, um noch als Akzent zu wirken. */
@media (prefers-color-scheme: dark) {
  :root {
    --color-bg: #1b1f26;
    --color-bg-alt: #22272f;
    --color-surface: #262c35;
    --color-sand-soft: #333a44;
    --color-sand: #c4b59d;
    --color-text: #d6dae0;
    --color-text-soft: #a9b1bc;
    --color-heading: #e8ebef;
    --color-border: rgba(214, 220, 228, 0.2);
    --color-accent: #93a07c;
    --color-accent-dark: #b6c39e;
    --color-accent-soft: rgba(147, 160, 124, 0.2);
    --color-alert: #e6938c;
    --color-alert-soft: rgba(230, 147, 140, 0.18);
  }

}

* {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-body);
  font-weight: 400;
  font-size: var(--text-base);
  line-height: 1.75;
  -webkit-font-smoothing: antialiased;
}

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

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

a:not([class]):hover {
  text-decoration: underline;
}

.container {
  max-width: var(--max-width);
  margin: 0 auto;
  padding: 0 1.5rem;
}

h1, h2, h3, h4, h5, h6 {
  color: var(--color-heading);
  font-family: var(--font-title);
  font-weight: 500;
  text-transform: uppercase;
  margin: 0 0 0.5em;
  line-height: 1.3;
  letter-spacing: 0.14em;
  /* Deutsche Komposita sind laenger als die Zeile eines Handys:
     "Datenschutzerklaerung" misst 424 px, "Allgemeine Geschaeftsbedingungen"
     421 px — beide sprengten bei 375 px den Bildschirm und liessen die
     ganze Seite seitlich wegschieben. hyphens trennt nach den Regeln der
     Sprache aus dem lang-Attribut; overflow-wrap greift nur, wo keine
     Trennstelle gefunden wird. */
  hyphens: auto;
  overflow-wrap: break-word;
}

/* Nur der Seitentitel (h1, genau einer pro Seite) bekommt Sage statt Slate
   — er soll als der eine Haupttitel auffallen. h2-h6 bleiben blau. Reines
   Sage erreicht bei dieser Grösse 4.76:1 auf Creme, also über AA auch für
   normalgrossen Text, nicht nur für die Grossschrift-Ausnahme (3:1). */
h1 { font-size: var(--text-3xl); color: var(--color-accent); }
h2 { font-size: var(--text-2xl); }
h3 { font-size: var(--text-xl); letter-spacing: 0.12em; }
h4 {
  font-family: var(--font-body);
  font-size: var(--text-lg);
  font-weight: 300;
  text-transform: none;
  letter-spacing: 0;
  line-height: 1.6;
  color: var(--color-text);
}

p { margin: 0 0 1.2em; }

::selection {
  background: var(--color-accent-soft);
  color: var(--color-accent-dark);
}

.screen-reader-text {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
  padding: 0;
  margin: -1px;
}

/* Nur für Suchmaschinen und Screenreader: steht im Markup, ist aber nicht
   zu sehen. Auf den Rassenseiten tragen die Titel damit weiterhin
   "Reinrassiger" und "aus der Schweiz", sichtbar bleibt der kurze Titel.

   Kein display: none und kein visibility: hidden — beides nimmt den Text
   auch aus dem Vorlesefluss und aus der Bewertung. Der Text bleibt darum ein
   1-px-Ausschnitt ausserhalb des Sichtfelds. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  left: -999px;
  top: auto;
  background: var(--color-heading);
  color: #fff;
  padding: 0.75rem 1.25rem;
  border-radius: var(--radius-s);
  z-index: 1000;
}

.skip-link:focus {
  left: 1rem;
  top: 1rem;
}

/* ---------- Header ---------- */

.site-header {
  position: sticky;
  top: 0;
  z-index: 200;
  background: rgba(247, 244, 239, 0.85);
  backdrop-filter: blur(14px) saturate(140%);
  -webkit-backdrop-filter: blur(14px) saturate(140%);
  border-bottom: 1px solid transparent;
  transition: border-color 0.3s ease, box-shadow 0.3s ease;
}

.site-header.is-scrolled {
  border-bottom-color: var(--color-border);
  box-shadow: 0 12px 30px -22px rgba(43, 50, 61, 0.38);
}

/* Das Logo behält immer dieselbe Größe — es schrumpft beim Scrollen nicht.
   Die 707px sind kein runder Wert, sondern die Breite der Menüzeile (659px)
   plus die 1.5rem Innenabstand links und rechts: so stehen Logo und Menü
   auf gleicher Breite untereinander. */
.site-header__logo {
  display: block;
  padding: 1.35rem 1.5rem 0.15rem;
  max-width: 707px;
  margin: 0 auto;
}

.site-header__logo img {
  width: 100%;
}

.site-header__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  /* Knapper als frueher: die groessere Menueschrift braucht den Platz, sonst
     faellt die Leiste zwischen 950 und 1100 px auf zwei Reihen. */
  gap: 0.75rem;
  flex-wrap: wrap;
  padding: 0.6rem 1.5rem 1.1rem;
  max-width: var(--max-width);
  margin: 0 auto;
}

.nav-toggle {
  display: none;
  background: none;
  border: 1px solid var(--color-border);
  border-radius: 999px;
  padding: 0.5rem 0.85rem;
  cursor: pointer;
  color: var(--color-heading);
}

.main-nav {
  order: 2;
}

.main-nav__list {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 0.1rem;
  margin: 0;
  padding: 0;
  justify-content: center;
}

.main-nav__item {
  position: relative;
}

/* Die Navigation stand auf --text-xs, derselben Stufe wie Bildunterschriften.
   Fuer das Hauptmenue ist das zu leise — es steht jetzt eine Stufe hoeher.
   Die Laufweite geht dabei leicht zurueck: bei groesserer Schrift wirkt
   dieselbe Sperrung breiter, und die Zeile braucht sonst zu viel Platz. */
.main-nav__link {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.6rem 0.65rem;
  font-size: var(--text-sm);
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--color-heading);
}

.main-nav__link::after {
  content: "";
  position: absolute;
  left: 0.9rem;
  right: 0.9rem;
  bottom: 0.35rem;
  height: 1px;
  background: var(--color-accent);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.3s var(--ease);
}

.main-nav__link:hover,
.main-nav__link.is-active,
.main-nav__item.is-open > .main-nav__link {
  text-decoration: none;
}

.main-nav__link:hover::after,
.main-nav__link.is-active::after {
  transform: scaleX(1);
}

.main-nav__caret {
  font-size: 0.6rem;
  opacity: 0.55;
  /* inline-block, damit sich der Pfeil drehen laesst: an einem reinen
     inline-Element greift transform nicht. */
  display: inline-block;
  transition: transform 0.2s var(--ease);
}

.main-nav__submenu {
  list-style: none;
  margin: 0;
  padding: 0.5rem;
  position: absolute;
  top: 100%;
  left: 0;
  /* Das Untermenue ist auch zugeklappt im Layout vorhanden und zaehlt zur
     Seitenbreite. Beim rechten Eintrag ragte es dadurch aus dem Fenster und
     erzeugte ein Querscrollen, ohne je sichtbar zu sein — aufgefallen bei
     900 px, nachdem es fuer die groessere Menueschrift von 210 auf 240 px
     verbreitert wurde. Die zwei rechten Eintraege haengen darum unten an
     ihrer rechten Kante statt an der linken. */
  min-width: 240px;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-m);
  box-shadow: var(--shadow-soft);
  opacity: 0;
  visibility: hidden;
  transform: translateY(6px);
  transition: opacity 0.25s var(--ease), transform 0.25s var(--ease), visibility 0.25s;
  z-index: 50;
}

.main-nav__item:nth-last-child(-n + 2) > .main-nav__submenu {
  left: auto;
  right: 0;
}

.main-nav__item.is-open > .main-nav__submenu {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}

@media (min-width: 861px) {
  .main-nav__item.has-children:hover > .main-nav__submenu,
  .main-nav__item.has-children:focus-within > .main-nav__submenu {
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
  }
}

.main-nav__submenu .main-nav__link {
  display: block;
  text-transform: none;
  letter-spacing: 0.01em;
  font-size: var(--text-sm);
  padding: 0.55rem 0.75rem;
  border-radius: var(--radius-s);
}

.main-nav__submenu .main-nav__link:hover {
  background: var(--color-accent-soft);
}

.main-nav__submenu .main-nav__link::after {
  display: none;
}

/* Die dritte Ebene, heute nur Wurfplanung > Welpenanfrage, ist
   zugeklappt (Nadine, 18.10.2026). Vorher stand sie offen im Menue,
   sobald man das Elternmenue aufklappte, und zeigte damit eine Seite,
   nach der niemand gesucht hat. Sie klappt auf, wenn der Zeiger auf
   dem Elterneintrag steht oder er mit der Tastatur angesteuert wird,
   genau wie die zweite Ebene am Hauptmenue aufklappt.

   display statt opacity: das Untermenue soll im zugeklappten Zustand
   keinen Platz brauchen, sonst bliebe die Luecke im Menue stehen.
   Am Handy ist die ganze zweite Ebene ohnehin ausgeblendet, dort
   aendert sich nichts. */
.main-nav__submenu .main-nav__submenu {
  position: static;
  border: none;
  box-shadow: none;
  padding: 0 0 0.25rem 0.75rem;
  display: none;
  opacity: 1;
  visibility: visible;
  transform: none;
}

.main-nav__submenu .main-nav__item.has-children:hover > .main-nav__submenu,
.main-nav__submenu .main-nav__item.has-children:focus-within > .main-nav__submenu {
  display: block;
}

/* Der Pfeil zeigt, ob zu oder offen. */
.main-nav__submenu .main-nav__item.has-children:hover > .main-nav__link .main-nav__caret,
.main-nav__submenu .main-nav__item.has-children:focus-within > .main-nav__link .main-nav__caret {
  transform: rotate(180deg);
}

.header-side {
  order: 1;
  display: flex;
  align-items: center;
  gap: 1.25rem;
}

.header-side:last-of-type {
  order: 3;
}

.lang-switch {
  display: flex;
  gap: 0.4rem;
  font-size: var(--text-sm);
  white-space: nowrap;
  color: var(--color-text-soft);
}

.lang-switch a.is-current {
  color: var(--color-heading);
  font-weight: 500;
}

.social-links {
  list-style: none;
  display: flex;
  gap: 0.6rem;
  margin: 0;
  padding: 0;
}

.social-links a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  border-radius: 999px;
  color: var(--color-heading);
  background: transparent;
  border: 1px solid var(--color-border);
  transition: background 0.25s ease, color 0.25s ease, transform 0.25s ease;
}

.social-links a:hover {
  background: var(--color-heading);
  color: #fff;
  transform: translateY(-2px);
}

.social-links svg {
  width: 15px;
  height: 15px;
  fill: currentColor;
}

@media (max-width: 860px) {
  .nav-toggle {
    display: inline-flex;
    order: 0;
  }

  .site-header__bar {
    justify-content: space-between;
  }

  .header-side:last-of-type {
    order: 1;
  }

  .main-nav {
    order: 4;
    flex-basis: 100%;
    display: none;
  }

  .site-header.is-nav-open .main-nav {
    display: block;
  }

  .main-nav__list {
    flex-direction: column;
    align-items: stretch;
  }

  .main-nav__link::after {
    display: none;
  }

  /* Das Hamburger-Menue zeigt nur die Hauptseiten. Die Untermenues bleiben
     hier ganz weg: ein Tipp auf "Siberian Husky" fuehrt auf die Seite, und
     die Unterseiten stehen dort im Inhalt — sie sind auf allen fuenf
     Elternseiten vollstaendig verlinkt. Vorher klappte der Tipp nur auf und
     zu, wodurch die Elternseiten am Handy unerreichbar waren. */
  .main-nav__submenu {
    display: none;
  }

  /* Ohne Untermenue zeigt der Pfeil auf nichts mehr. */
  .main-nav__caret {
    display: none;
  }

  /* Volle Tippflaeche: die Menuepunkte fuellen die Zeile und halten die
     44 px Mindesthoehe, die auf dem Touchscreen sicher zu treffen ist. */
  .main-nav__link {
    display: flex;
    align-items: center;
    min-height: 44px;
  }
}

/* ---------- Hero / splash (language chooser) ---------- */

.splash {
  position: relative;
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 2rem 1.5rem;
  background: var(--color-heading);
  color: var(--color-cream);
  overflow: hidden;
}

.splash__inner {
  position: relative;
  z-index: 2;
  max-width: 640px;
}

.splash h1 {
  color: #ffffff;
  margin-bottom: 0.3em;
}

.splash__tagline {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 400;
  font-size: var(--text-xl);
  margin-bottom: 2.75rem;
  opacity: 0.88;
}

.splash__choices {
  display: flex;
  gap: 1rem;
  justify-content: center;
  flex-wrap: wrap;
  margin-bottom: 2.75rem;
}

.splash__choice {
  border: 1px solid rgba(255, 255, 255, 0.4);
  border-radius: 999px;
  padding: 0.95rem 2.4rem;
  font-size: var(--text-2xs);
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  transition: background 0.3s ease, border-color 0.3s ease, transform 0.3s var(--ease);
}

.splash__choice:hover {
  background: var(--color-accent);
  border-color: var(--color-accent);
  transform: translateY(-2px);
  text-decoration: none;
}

.splash__credit {
  font-size: var(--text-xs);
  /* the slate backdrop is lighter than the old brown one, so this needs more
     opacity to stay readable at this size (5.7:1) */
  opacity: 0.68;
  letter-spacing: 0.03em;
}

.splash figure {
  margin: 0 0 2.25rem;
  border-radius: var(--radius-l);
  overflow: hidden;
  max-width: 400px;
}

.splash figure img {
  animation: kenburns 22s ease-in-out infinite alternate;
}

@keyframes kenburns {
  from { transform: scale(1); }
  to { transform: scale(1.08); }
}

/* ---------- 404 ---------- */
/* Reuses the .splash treatment (same dark hero, same choice-pill button) so
   a dead link still feels like the same site instead of a bare error. Two
   language blocks stacked, same reasoning as the bilingual splash above:
   nobody knows which language a broken link belongs to. */

.notfound__code {
  font-family: var(--font-display);
  font-size: var(--text-2xs);
  letter-spacing: 0.3em;
  text-transform: uppercase;
  opacity: 0.68;
  margin: 0 0 2.5rem;
}

/* h2 inherits var(--color-heading), which is the same slate the .splash
   background uses — without this it would be invisible, same reason
   .splash h1 above sets an explicit white. */
.notfound__lang h2 {
  color: #ffffff;
  margin-bottom: 0.5em;
}

.notfound__links {
  font-size: var(--text-xs);
  margin: 0 0 2.75rem;
}

.notfound__links a {
  color: var(--color-cream);
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

.notfound__links a:hover {
  color: var(--color-accent);
}

.notfound__divider {
  border: none;
  border-top: 1px solid rgba(255, 255, 255, 0.25);
  margin: 0 0 2.75rem;
}

/* ---------- Content blocks ---------- */

main {
  display: block;
}

.page-section {
  max-width: var(--max-width);
  margin: 0 auto;
  padding: 3.5rem 1.5rem 4.5rem;
}

.page-section--narrow {
  max-width: var(--max-width-narrow);
}

/* Contact stacks two sections; without this their paddings add up to a
   conspicuous hole between the copy and the form. */
.page-section + .page-section {
  padding-top: 0;
}

.content-block {
  margin: 0 0 1.75rem;
  max-width: var(--max-width-text);
  margin-left: auto;
  margin-right: auto;
}

.content-block--p,
.content-block--li {
  text-align: left;
}

.content-block--h1,
.content-block--h2 {
  text-align: center;
  max-width: 900px;
}

.content-block--h1:first-child,
.content-block--h2:first-child {
  margin-top: 0;
}

.content-block--h2 {
  margin-top: 3rem;
  position: relative;
  padding-top: 1.6rem;
}

.content-block--h2::before {
  content: "";
  position: absolute;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
  width: 46px;
  height: 3px;
  border-radius: 999px;
  /* sage into sand: both brand colours show up at every section heading */
  background: linear-gradient(90deg, var(--color-sage), var(--color-sand));
}

.content-block--h1 {
  text-align: center;
}

.content-block--h3,
.content-block--h4 {
  text-align: center;
  max-width: 760px;
}

.content-block--h3.content-block--subtitle,
.content-block--h4.content-block--subtitle,
.content-block--h1.content-block--subtitle,
.content-block--h2.content-block--subtitle {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 300;
  font-size: var(--text-xl);
  color: var(--color-text-soft);
  /* Der Untertitel ist bewusst gemischt gesetzt: Versalien direkt unter
     einem Versaltitel würden die Hierarchie einebnen. */
  text-transform: none;
  letter-spacing: 0.01em;
  margin-top: -1rem;
}

.content-block--h2.content-block--subtitle::before {
  display: none;
}

.content-block--h4 {
  opacity: 0.9;
}

/* Leading announcement line ("we're expecting a litter…") — reads as an
   orphaned grey sentence when left as plain text, so it gets a pill. */
.content-block--announce {
  display: block;
  width: fit-content;
  max-width: 100%;
  margin: 0 auto 2rem;
  padding: 0.5rem 1.25rem;
  border-radius: 999px;
  /* Helles Sage statt des sandfarbenen Bands — derselbe Ton, der auch die
     Textmarkierung (::selection) trägt, hier nur als Fläche. Der dunkle
     Sage-Text darauf bleibt bei 6.0:1 gut lesbar. */
  background: var(--color-accent-soft);
  color: var(--color-accent-dark);
  border: 1px solid var(--color-sage);
  font-family: var(--font-body);
  font-size: var(--text-2xs);
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  text-align: center;
  opacity: 1;
}

.content-block--h3 + .content-block--p,
.content-block--h4 + .content-block--p {
  margin-top: -0.6rem;
}

/* ---------- Figures & imagery ---------- */

/* Kein Rahmen um Fotos (Regel vom 18.10.2026): kein Schatten, keine helle
   Hinterlegung, kein Strich. Das Foto steht frei auf der Seite, die
   Bildunterschrift darunter im Fliesstext. */
.content-figure {
  margin: 0 auto 2rem;
  max-width: var(--max-width-narrow);
  border-radius: var(--radius-l);
  overflow: hidden;
}

.content-figure img {
  width: 100%;
  cursor: zoom-in;
}

/* Alle Fotos haben dieselbe Rundung, auf allen vier Ecken, auch wenn eine
   Unterschrift darunter steht (Nadine, 20.10.2026). Vorher rundete nur der
   Rahmen um Foto UND Unterschrift: die oberen Ecken des Fotos waren rund,
   die unteren eckig, denn die gerundeten unteren Ecken lagen an der
   Unterschrift, die keine Flaeche mehr hat. Gemessen waren das 82 Fotos.

   Das Titelbild (--hero) bleibt ausgenommen: es laeuft am Handy ueber die
   ganze Breite und hat dort bewusst keine Rundung. */
.content-figure:not(.content-figure--hero) img {
  border-radius: var(--radius-l);
}

.content-figure img:focus-visible,
.info-card__frame img:focus-visible {
  outline: 2px solid var(--color-sage);
  outline-offset: 3px;
}

.content-figure figcaption {
  font-size: var(--text-xs);
  padding: 0.75rem 1.1rem;
  color: var(--color-text-soft);
}

/* Hero figure — first stand-alone photo on a page.
   Deliberately laid out with margins only (never a transform): the
   scroll-reveal helper sets `transform: none` at a higher specificity,
   which would silently knock a transform-centred box off-centre. */

.content-figure--hero {
  position: relative;
  max-width: none;
  width: auto;
  margin: 0 -1.5rem 3rem;
  border-radius: 0;
}

/* Derselbe Rahmen wie beim Titelband: ein Format fuer alle Titelbilder. */
.content-figure--hero .content-figure__frame {
  position: relative;
  overflow: hidden;
  aspect-ratio: var(--titelbild-format);
}

.content-figure--hero img {
  width: 100%;
  height: 100%;
  /* cover statt contain: keine Balken. Ein Foto, das nicht 3 : 2 ist,
     wird in der Foto-Werkstatt zugeschnitten, nicht hier mit dunklen
     Flaechen aufgefuellt. */
  object-fit: cover;
  object-position: center;
  cursor: default;
}

.content-figure--hero::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(43, 50, 61, 0) 55%, rgba(43, 50, 61, 0.6) 100%);
  pointer-events: none;
}

.content-figure--hero figcaption {
  position: absolute;
  left: 1.5rem;
  bottom: 1.25rem;
  z-index: 2;
  color: #fff;
  background: rgba(43, 50, 61, 0.5);
  backdrop-filter: blur(6px);
  border-radius: 999px;
  padding: 0.4rem 1rem;
}

/* Wie beim Titelband: ab Tablet runde Ecken. Die Breite kommt aus der
   gemeinsamen Regel fuer alle Titelbilder. */
@media (min-width: 601px) {
  .content-figure--hero {
    border-radius: var(--radius-l);
  }

  .content-figure--hero .content-figure__frame {
    border-radius: var(--radius-l);
    overflow: hidden;
  }
}

/* Rechtliche Pflichtseiten in der Fusszeile: leise gesetzt, aber auffindbar.
   Kleiner und blasser als die uebrige Fusszeile, mit klarem Fokus- und
   Hover-Zustand — dezent heisst zurueckhaltend, nicht versteckt. */
.footer-legal {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.4rem 1.5rem;
  margin-top: 2rem;
}

.footer-legal a {
  color: inherit;
  opacity: 0.6;
  font-size: var(--text-xs);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: opacity 0.25s ease, border-color 0.25s ease;
}

.footer-legal a:hover,
.footer-legal a:focus-visible {
  opacity: 1;
  border-bottom-color: currentColor;
}

/* ---------- Seiten-Einstieg (Hero) ----------
   Der erste Eindruck jeder Seite: das Foto füllt die Fläche, Ankündigung,
   Titel, Satz und Button liegen darauf. Vorher standen die Teile untereinander
   und der Button hing zwischen Text und Bild.

   Zwei Dinge sind hier bewusst gesetzt:

   1. object-fit: cover statt contain. Eine Bildüberlagerung braucht eine
      gefüllte Fläche — die seitlichen dunklen Balken, die contain bei
      unpassendem Bildformat übrig liess, fallen damit weg.

   2. Das Foto wird NICHT verändert — kein Verlauf, keine Fläche, keine
      Abdunklung. Lesbar wird der Text allein durch seine eigene Behandlung.

      Drei Fassungen davor haben das Bild angefasst und sind daran
      gescheitert: ein Verlauf über die Bildhöhe deckte eine feste Zone ab,
      während der Textblock mal zwei, mal sechs Zeilen hoch ist; ein Verlauf
      am Textblock war lesbar, liess aber das Foto untergehen und zog eine
      sichtbare Kante quer durchs Bild; eine weichgezeichnete Fläche wirkte
      als Kasten über dem Motiv.

      Was die Schrift jetzt trägt: Gewicht 600 beim Titel, 500 im Fliesstext,
      und eine dunkle Kontur an der Buchstabenkante. `paint-order: stroke fill`
      zeichnet sie HINTER die Füllung, die Buchstabenform bleibt also
      unverändert. Die Kontur trennt die Schrift auch von einem gleich hellen
      Hintergrund, und sie tut das genau am Buchstaben — anders als ein
      Schatten dunkelt sie die Fläche daneben nicht ab. Dazu ein enger
      Schatten von 2 px für etwas Tiefe; bewusst kein weit gestreuter, der
      wäre eine Abdunklung des Bildes durch die Hintertür.

      Wer die Kontur verstärkt, macht die Schrift teigig. Wer sie wegnimmt,
      verliert die Lesbarkeit über hellen Motiven. An einem hellen UND an
      einem unruhigen Foto gegenprüfen. */

/* Bild, Ankündigung und Textblock liegen als Raster übereinander, nicht
   absolut positioniert. Der Unterschied zeigt sich auf schmalen Geräten: dort
   wächst der Titel auf fünf, sechs Zeilen, und ein absolut gesetzter
   Textblock lief oben aus dem Bild heraus und wurde vom overflow
   abgeschnitten (auf einem 320-px-Display fehlten 90 px, also Ankündigung und
   halber Titel). Als Rasterzelle schiebt der Text den Hero stattdessen
   auseinander: die Höhe unten ist eine Mindesthöhe, keine feste.

   Zwei Zeilen, nicht eine: oben die Ankündigung, darunter der Textblock, das
   Foto spannt über beide. In derselben Zelle liefen sie bei 320 px
   ineinander. */
.page-hero {
  position: relative;
  display: grid;
  grid-template-rows: auto 1fr;
  /* minmax(0, 1fr) statt der Vorgabe: ohne das waechst die Rasterspalte,
     sobald ein Knopf im Titeltext breiter ist als die Seite, und das
     Titelbild waechst mit. Auf Konas Seite war es dadurch 311 statt
     305 px breit, also 6 px breiter als auf jeder anderen Seite. */
  grid-template-columns: minmax(0, 1fr);
  isolation: isolate;
  margin: 0 -1.5rem 3rem;
  overflow: hidden;
  background: var(--color-deep);
}

.page-hero__frame {
  grid-row: 1 / 3;
  grid-column: 1;
  position: relative;
  width: 100%;
  /* align-self: start, damit der Rahmen sein Format behaelt. Ohne das
     zieht ihn die Rasterzeile in die Hoehe, sobald der Titeltext mehr
     Platz braucht als das Foto hoch ist, und das Format waere dahin. */
  align-self: start;
  aspect-ratio: var(--titelbild-format);
}

/* Absolut im Rahmen statt height: 100% — so füllt das Foto die Zelle auch
   dann, wenn der Text die Zeile höher gemacht hat als die Mindesthöhe. */
.page-hero__frame picture {
  position: absolute;
  inset: 0;
  display: block;
}

.page-hero__frame img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  cursor: default;
}

/* Obere Zeile: die Ankündigungen. Mehrere stehen untereinander, nicht
   nebeneinander — zwei volle Sätze nebeneinander sprengen jede Bildbreite. */
.page-hero__top {
  grid-row: 1;
  grid-column: 1;
  z-index: 3;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.5rem;
  max-width: 100%;
  padding: clamp(1rem, 2.5vw, 1.75rem);
  color: #fff;
  text-shadow: 0 1px 2px rgba(10, 13, 18, 0.85);
  paint-order: stroke fill;
  -webkit-text-stroke: 2px rgba(14, 18, 24, 0.5);
}

/* Untere Zeile: Textblock links, Bildnachweis rechts, beide unten bündig.
   Als Flex-Zeile mit Umbruch können sie sich nie überlagern — wird es zu
   schmal, rutscht der Nachweis unter den Button und bleibt rechtsbündig. */
.page-hero__inner {
  grid-row: 2;
  grid-column: 1;
  position: relative;
  z-index: 2;
  align-self: end;
  width: 100%;
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 0.75rem 1.5rem;
  padding: clamp(1.5rem, 4vw, 3rem);
  color: #fff;
  text-shadow: 0 1px 2px rgba(10, 13, 18, 0.9);
  paint-order: stroke fill;
  -webkit-text-stroke: 2px rgba(14, 18, 24, 0.85);
}

.page-hero__content {
  flex: 1 1 18rem;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 1rem;
  max-width: 44rem;
  text-align: left;
}

/* Die Ankuendigung ist die Werbung der Zuchtstaette — der einzige Satz auf
   der Seite, der etwas verkauft. Sie steht darum so gross wie eine
   Zwischenueberschrift und im schwersten Schnitt, den die Schrift hat.

   Kein Rand, keine Flaeche, keine Kontur, kein Schatten: Kontur und Schatten
   muessen ausdruecklich abgeschaltet werden, sonst erbt die Zeile den dunklen
   Saum der Elternregel und wuerde als schwarze Schrift schmutzig wirken.

   Damit haengt ihre Lesbarkeit allein am Foto: ueber dem hellen Himmel der
   Startseite steht sie bei 12:1, ueber einem dunklen Motiv waere sie weg.
   Wenn dort einmal ein dunkles Bild liegt, braucht diese Zeile eine andere
   Farbe — CSS kann das nicht von sich aus erkennen. */
.page-hero__pill {
  margin: 0;
  padding: 0;
  max-width: 22ch;
  color: #000;
  font-size: clamp(1.05rem, 0.8rem + 1vw, 1.6rem);
  font-weight: 700;
  letter-spacing: 0.06em;
  line-height: 1.25;
  text-transform: uppercase;
  text-wrap: balance;
  text-shadow: none;
  -webkit-text-stroke: 0;
}

.page-hero__title {
  margin: 0;
  color: #fff;
  font-family: var(--font-title);
  font-size: var(--text-3xl);
  font-weight: 600;
  letter-spacing: 0.05em;
  line-height: 1.16;
  text-transform: uppercase;
  text-wrap: balance;
  -webkit-text-stroke: 3.5px rgba(14, 18, 24, 0.85);
}

/* Zweite Zeile auf den Hundeseiten: Zuchtname unter dem Rufnamen. */
.page-hero__subtitle {
  margin: -0.5rem 0 0;
  font-size: var(--text-lg);
  font-style: italic;
  letter-spacing: 0.02em;
  opacity: 0.94;
}

.page-hero__text {
  margin: 0;
  max-width: 36rem;
  color: #fff;
  font-size: var(--text-lg);
  font-weight: 500;
  line-height: 1.6;
  text-wrap: pretty;
}

/* Der Button trägt seine eigene Fläche — dort ist die Kontur nur im Weg. */
.page-hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin: 0.35rem 0 0;
  text-shadow: none;
  -webkit-text-stroke: 0;
}

/* Der Aufruf im Hero steht auf einem Foto, nicht auf der beigen Seite. Das
   Slate hebt sich davon nur mit 2,2:1 ab — gemessen auf der Startseite, wo
   Wasser und Himmel genau in derselben Helligkeit liegen. Die Farbe bleibt
   auf Wunsch die helle der übrigen Buttons; die Sichtbarkeit tragen darum
   Ring, Schatten und Grösse:

   - der helle Ring zeichnet die Knopfkante gegen die Fläche ab (5,2:1 gegen
     den Knopf selbst) und wirkt auf hellen wie auf dunklen Fotos
   - der Schatten hebt ihn von der Bildebene ab
   - grösser als die Buttons im Fliesstext, weil er hier gegen ein ganzes
     Foto ankommen muss und nicht gegen eine ruhige beige Fläche

   Wer die Fläche wieder abdunkelt (var(--color-deep)), bekommt 5,6:1 gegen
   das Foto — messbar am besten, aber nicht die Wunschfarbe. */
.page-hero__actions .content-button {
  background: var(--color-slate);
  padding: 1.15rem 3rem;
  font-size: var(--text-sm);
  font-weight: 600;
  letter-spacing: 0.2em;
  box-shadow:
    0 0 0 2px rgba(255, 255, 255, 0.85),
    0 8px 24px rgba(10, 13, 18, 0.5);
}

.page-hero__actions .content-button:hover,
.page-hero__actions .content-button:focus-visible {
  background: var(--color-accent);
}

/* Der Bildnachweis ist eine Pflichtangabe, kein Gestaltungselement: keine
   Fläche, keine Kontur, kein Schatten — schwarze Schrift wie die Ankündigung
   oben. Kontur und Schatten müssen ausdrücklich abgeschaltet werden, sonst
   erbt er den dunklen Saum der Elternregel.

   Dieselbe Abhängigkeit wie oben: über dem hellen Sand der Startseite steht
   er gut, über einem dunklen Motiv wäre er weg.

   auto links schiebt ihn ans rechte Ende; das muss in DERSELBEN Regel stehen
   wie die übrigen Werte, eine getrennte Regel weiter oben hat ein späteres
   margin: 0 hier schon einmal stillschweigend aufgehoben. */
.page-hero__credit {
  margin: 0 0 0 auto;
  flex-shrink: 0;
  color: #000;
  font-size: var(--text-2xs);
  font-weight: 600;
  letter-spacing: 0.04em;
  line-height: 1.5;
  text-shadow: none;
  -webkit-text-stroke: 0;
}

/* Verlinkt auf die Seite der Fotografin oder des Fotografen. Unterstrichen
   erst beim Überfahren, damit der Nachweis dezent bleibt und trotzdem als
   Link erkennbar ist. */
.page-hero__credit a {
  color: inherit;
  text-decoration: none;
  border-bottom: 1px solid rgba(0, 0, 0, 0.4);
}

.page-hero__credit a:hover,
.page-hero__credit a:focus-visible {
  color: #000;
  border-bottom-color: #000;
}

/* Jedes Titelbild ist gleich breit, auch auf den schmalen Seiten (Kontakt,
   Danke), die sonst in einer 760-px-Spalte laufen. Dort war der Rahmen
   vorher 712 px breit statt 1177, also sichtbar kleiner als auf jeder
   anderen Seite.

   Die Rechnung liefert fuer beide Spaltenarten dasselbe Ergebnis: 50 %
   bezieht sich auf die Spalte, in der das Band steckt, der Rest zieht es
   von dort auf die gemeinsame Breite. In der breiten Spalte kommt null
   heraus, in der schmalen der noetige negative Rand.

   --seitenbreite setzt site.js aus clientWidth, also ohne Scrollleiste;
   100vw waere um deren Breite zu gross und erzeugte Querscrollen. Der
   Rueckfallwert 100 % ist bewusst zu schmal statt zu breit: solange das
   Skript nicht gelaufen ist, bleibt das Band lieber etwas kleiner, als
   dass die Seite seitlich wegliefe. */
@media (min-width: 601px) {
  .page-hero,
  .content-figure--hero {
    margin-left: calc(50% - min(var(--max-width), var(--seitenbreite, 100%)) / 2 + 1.5rem);
    margin-right: calc(50% - min(var(--max-width), var(--seitenbreite, 100%)) / 2 + 1.5rem);
  }
}

/* Auf dem Handy ist das 3 : 2-Band so flach, dass Titel, Text und Knopf
   darauf keinen Platz mehr haetten. Sie stehen darum unter dem Foto auf
   der dunklen Flaeche des Bandes. Dort braucht die Schrift weder Schatten
   noch Kontur: sie steht auf einer ruhigen Flaeche, nicht auf einem Foto. */
@media (max-width: 600px) {
  .page-hero {
    grid-template-rows: auto auto;
  }

  .page-hero__frame {
    grid-row: 1;
  }

  .page-hero__inner {
    grid-row: 2;
    align-self: start;
    text-shadow: none;
    -webkit-text-stroke: 0;
  }
}

/* Ab Tablet sitzt das Band buendig in derselben Spalte wie Galerie und
   Karten, damit alle Bildkanten der Seite auf denselben zwei Linien
   stehen. Die Breite kommt aus der gemeinsamen Regel weiter oben. */
@media (min-width: 601px) {
  .page-hero {
    border-radius: var(--radius-l);
  }
}

/* ---------- Collage ----------
   Ein grosses Bild links, die uebrigen rechts darunter gestapelt. Kein Foto
   wird beschnitten: jedes behaelt sein Format, und die Spaltenbreite rechnet
   Blocks.astro pro Reihe aus den Bildformaten aus — sie steht als
   grid-template-columns direkt am Element. Der Wert hier ist nur die
   Rueckfallebene, falls dieser Stil einmal ohne die Rechnung verwendet wird.

   Der Abstand von 1rem muss zu COLLAGE_ABSTAND in Blocks.astro passen: die
   Rechnung bezieht ihn mit ein, damit beide Spalten unten gleich enden. */
.mosaik {
  display: grid;
  /* Der gerechnete Wert kommt als Variable vom Element, nicht als
     grid-template-columns direkt: ein Inline-Stil wuerde die Media Query
     unten schlagen, und die Collagen blieben auf dem Handy zweispaltig mit
     99 px schmalen Bildern. */
  grid-template-columns: var(--collage-spalten, 2fr 1fr);
  gap: 1rem;
  align-items: start;
  max-width: var(--max-width);
  margin: 0 auto 2.5rem;
}

/* ---- Bildunterschriften auf eine Linie ------------------------------
   Die zwei Spalten einer Collage werden verschieden hoch: links ein Foto,
   rechts zwei mit Abstand dazwischen. Dadurch standen die Nachweise auf
   verschiedener Hoehe, was von blossem Auge als schief auffaellt.

   Erster Versuch war, den Ausgleich in den Weissraum zwischen Bild und
   Nachweis zu legen. Nadine hat das verworfen: die Luecke unter dem grossen
   Bild fiel staerker auf als die schiefe Linie.

   Jetzt traegt das UNTERSTE Bild der schmalen Spalte den Ausgleich. Es
   bekommt die Hoehe, die uebrig bleibt, und wird von oben angeschnitten —
   object-position: bottom haelt die Unterkante fest, wo der Hund steht.
   Das grosse Bild links bleibt unberuehrt.

   min-height: 0 ist noetig, damit die Figur ueberhaupt kleiner werden darf
   als ihr Inhalt; ohne das ignoriert Flexbox das flex-basis und die Spalte
   waechst wieder ueber die Zeile hinaus. */
.mosaik {
  align-items: stretch;
}

.mosaik__seite > .content-figure:last-child {
  flex: 1 1 0;
  min-height: 0;
  display: flex;
  flex-direction: column;
}

/* Der flexible Teil ist das <picture>, nicht das <img> darin — es ist das
   direkte Kind der Figur. Es nimmt den Platz, der nach der Bildunterschrift
   uebrig bleibt; das Bild darin fuellt ihn und wird oben angeschnitten. */
.mosaik__seite > .content-figure:last-child > picture {
  flex: 1 1 0;
  min-height: 0;
  display: block;
  overflow: hidden;
}

.mosaik__seite > .content-figure:last-child > picture img {
  height: 100%;
  width: 100%;
  object-fit: cover;
  object-position: bottom;
}

/* Am Handy stehen die Bilder untereinander. Dort gibt es keine zweite
   Spalte, an der sich etwas ausrichten muesste — der Zuschnitt faellt weg,
   sonst wuerde ein Foto ohne Grund beschnitten. */
@media (max-width: 700px) {
  /* Untereinander gibt es keine zweite Spalte, an der sich etwas ausrichten
     muesste — Zuschnitt und Hoehenzwang fallen weg, sonst wuerde ein Foto
     ohne Grund beschnitten. Die Selektoren muessen so genau sein wie die
     Regeln oben, sonst gewinnen jene. */
  .mosaik__seite {
    height: auto;
    min-height: 0;
  }

  .mosaik__seite > .content-figure:last-child {
    flex: 0 0 auto;
  }

  .mosaik__seite > .content-figure:last-child > picture {
    flex: 0 0 auto;
  }

  .mosaik__seite > .content-figure:last-child > picture img {
    height: auto;
    object-fit: fill;
  }
}

.mosaik__seite {
  justify-content: space-between;
}

.mosaik__seite {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  /* Die schmale Spalte darf die Zeilenhoehe nicht bestimmen, sonst richtet
     sich die Zeile nach ihr und das unterste Bild hat nichts, wogegen es
     sich kuerzen koennte. height: 0 nimmt sie aus der Rechnung,
     min-height: 100% zieht sie danach auf die Hoehe der Zeile, die jetzt
     allein vom grossen Bild links kommt. */
  height: 0;
  min-height: 100%;
}

/* Die Figuren im Mosaik tragen keinen festen Rahmen: die Hoehe kommt vom
   Bild selbst, damit nichts wegfaellt. */
.mosaik .content-figure {
  max-width: none;
  margin: 0;
}

.mosaik .content-figure img {
  width: 100%;
  height: auto;
}

/* Auf schmalen Geraeten stehen die drei Bilder untereinander — nebeneinander
   waere die rechte Spalte nur noch ein Streifen. */
@media (max-width: 700px) {
  .mosaik {
    grid-template-columns: 1fr;
  }
}

/* Gallery — runs of 2+ consecutive images.
   Every tile gets one explicit aspect ratio so a stray portrait shot
   can't stretch a whole row. Ratios lean portrait for the wider 3-up
   sets (which is how most of these dog photos are shot) and landscape
   for the roomier 2-up ones. The photo is never cropped to fill that
   shape — object-fit: contain shows the whole animal, with a plain
   border on whichever side doesn't match the tile. */

.gallery-grid {
  --tile-ratio: 3 / 4;
  max-width: var(--max-width);
  margin: 0 auto 2.5rem;
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(3, 1fr);
}

.gallery-grid[data-count="2"],
.gallery-grid[data-count="4"] {
  --tile-ratio: 4 / 3;
  grid-template-columns: repeat(2, 1fr);
}

.gallery-grid .content-figure {
  position: relative;
  max-width: none;
  margin: 0;
}

.gallery-grid .content-figure img {
  width: 100%;
  aspect-ratio: var(--tile-ratio);
  /* Randlos, auch wenn das Foto dabei beschnitten wird. Vorher entschied
     Picture.astro je nach Format zwischen cover und contain — der Rand aus
     contain war genau das, was als "blaue Seitenbalken" auffiel. */
  object-fit: cover;
  background: var(--color-bg-alt);
}

/* Bildunterschrift liegt jetzt als Verlauf über dem Foto und erscheint erst
   bei Hover/Fokus — das Foto wirkt dadurch ruhiger, der Kontext bleibt aber
   einen Wisch entfernt statt permanent unter jeder Kachel zu stehen. Ein
   Foto ohne caption (die meisten) bekommt trotzdem den Zoom, nur ohne
   Verlauf/Text darüber. */
.gallery-grid .content-figure:has(figcaption)::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(43, 50, 61, 0) 55%, rgba(43, 50, 61, 0.82) 100%);
  opacity: 0;
  transition: opacity 0.45s var(--ease);
  pointer-events: none;
}

.gallery-grid .content-figure:hover::after,
.gallery-grid .content-figure:focus-within::after {
  opacity: 1;
}

.gallery-grid .content-figure figcaption {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  margin: 0;
  padding: 0.5rem 1rem 0.85rem;
  color: #fff;
  font-size: var(--text-xs);
  transform: translateY(0.4rem);
  opacity: 0;
  transition: opacity 0.4s var(--ease), transform 0.4s var(--ease);
  pointer-events: none;
}

.gallery-grid .content-figure:hover figcaption,
.gallery-grid .content-figure:focus-within figcaption {
  transform: translateY(0);
  opacity: 1;
}

@media (hover: none) {
  /* Ohne Hover (Touch) bleibt die Bildunterschrift wie bisher sichtbar —
     sonst gäbe es keine Möglichkeit, sie überhaupt zu lesen. */
  .gallery-grid .content-figure::after,
  .gallery-grid .content-figure figcaption {
    opacity: 1;
    transform: none;
  }
  .gallery-grid .content-figure figcaption {
    position: static;
    color: var(--color-text-soft);
    padding: 0.75rem 1.1rem;
  }
  .gallery-grid .content-figure::after {
    display: none;
  }
}

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

/* ---------- Collage: Fotos in Spalten, jedes in seinem Format ----------

   Fuer Barbet und Siberian Husky (Nadine, 21.10.2026): alle Fotos in einer
   Galerie, nicht nach Thema unterteilt. Spalten statt Raster, damit hohe und
   breite Fotos ohne Zuschnitt und ohne Luecken ineinandergreifen.

   Sie teilt Beschriftung, Hover und Grossansicht mit .gallery-grid; hier
   werden nur Anordnung und Bildformat ueberschrieben. Der Selektor mit zwei
   Klassen steht NACH den Regeln oben, sonst gewaenne die feste Kachelform. */
.gallery-grid.gallery-grid--collage {
  display: block;
  column-count: 3;
  column-gap: 1rem;
}

.gallery-grid--collage .content-figure {
  break-inside: avoid;
  margin: 0 0 1rem;
}

.gallery-grid--collage .content-figure img {
  display: block;
  height: auto;
  /* Das Verhaeltnis jedes Fotos steht am Rahmen (--bild-verhaeltnis). Ein
     nacktes "auto" haette das aus Breite und Hoehe des Bildes abgeleitete
     Verhaeltnis ueberschrieben: vor dem Laden waere jedes Foto 0 px hoch,
     und die Seite spraenge beim Nachladen. */
  aspect-ratio: var(--bild-verhaeltnis, auto);
  object-fit: initial;
}

/* Zwei Spalten ab Tablet abwaerts, auch am Handy: eine einzelne Spalte waere
   eine lange Kolonne und keine Collage mehr. */
@media (max-width: 900px) {
  .gallery-grid.gallery-grid--collage {
    column-count: 2;
  }
}

@media (max-width: 560px) {
  .gallery-grid,
  .gallery-grid[data-count="2"],
  .gallery-grid[data-count="4"] {
    --tile-ratio: 4 / 3;
    grid-template-columns: 1fr;
  }

  /* Bei dieser Breite ist die Kachel immer 4/3. Randlos wie oben; die Regel
     bleibt stehen, damit die Kachelform hier vollständig beschrieben ist. */
  .gallery-grid .content-figure img {
    object-fit: cover;
  }
}

/* ---------- Gleichrangige Punkte nebeneinander ----------
   Drei kurze Unterabschnitte unter einer Abschnittsueberschrift.

   Bewusst KEINE Karten: auf derselben Seite stehen weiter oben schon zwei
   weisse Kaesten mit Bild und Button. Noch eine Kartenreihe daneben liesse
   die Seite gleichfoermig wirken, und die drei Punkte waeren nicht mehr als
   eigene Sorte erkennbar.

   Erkennbar macht sie stattdessen: ein kurzer Sage-Strich ueber jedem Titel,
   Trennlinien zwischen den Spalten und mehr Luft dazwischen als zwischen
   allem anderen auf der Seite. So liest man drei Punkte, nicht drei Karten.

   minmax(0, 1fr) statt 1fr: ohne die Null als Untergrenze waechst eine
   Spalte mit langem Text ueber ihren Anteil hinaus, und die Breiten waeren
   nicht mehr gleich. */
.spalten {
  display: grid;
  grid-template-columns: repeat(var(--spalten-anzahl, 3), minmax(0, 1fr));
  /* Zwei Zeilen fuer alle Spalten gemeinsam: Titel und Text. Die Spalten
     klinken sich per subgrid darin ein, dadurch stehen Titel und Text ueber
     alle Spalten auf derselben Hoehe — auch wenn ein Titel zweizeilig wird
     wie "Unsere wichtigsten Werte". Ohne das beginnt jeder Text woanders. */
  grid-template-rows: auto auto;
  gap: 2.5rem 0;
  max-width: var(--max-width);
  margin: 0.5rem auto 3rem;
}

.spalten[data-count="2"] {
  --spalten-anzahl: 2;
}

.spalte {
  display: grid;
  grid-template-rows: subgrid;
  grid-row: span 2;
  padding: 0 clamp(1.25rem, 2.5vw, 2.75rem);
}

/* Browser ohne subgrid bekommen dasselbe Ergebnis ueber eine Mindesthoehe
   fuer zweizeilige Titel. Nicht so genau, aber es haelt die Texte auf
   derselben Linie. */
@supports not (grid-template-rows: subgrid) {
  .spalte {
    display: block;
  }

  .spalte__titel {
    min-height: calc(1.5rem + 2.6em);
  }
}

/* Haarlinie zwischen den Spalten, nicht am Rand — darum erst ab der zweiten
   und nur, solange sie nebeneinander stehen. */
.spalte + .spalte {
  border-left: 1px solid var(--color-border);
}

/* Der Strich ueber dem Titel: dasselbe Sage wie die Trennlinie unter den
   Abschnittsueberschriften der Seite, damit er zur Seite gehoert und nicht
   als Fremdkoerper wirkt. */
.spalte__titel {
  margin: 0 0 0.9rem;
  padding-top: 1.5rem;
  position: relative;
  font-size: var(--text-lg);
  text-align: center;
}

.spalte__titel::before {
  content: "";
  position: absolute;
  top: 0;
  left: 50%;
  width: 2.5rem;
  height: 2px;
  transform: translateX(-50%);
  border-radius: 2px;
  background: var(--color-accent);
}

.spalte__text {
  margin: 0 auto;
  max-width: 34ch;
  text-align: center;
  text-wrap: pretty;
}

/* Untereinander verschwinden die senkrechten Linien — dort trennt der
   Abstand, und eine Linie links am Text saehe aus wie ein Zitat. */
@media (max-width: 800px) {
  .spalten {
    grid-template-columns: 1fr;
    gap: 2.25rem;
  }

  .spalte {
    display: block;
    padding: 0;
  }

  .spalte__titel {
    min-height: 0;
  }

  .spalte + .spalte {
    border-left: 0;
  }
}

/* ---------- Vorstellungs-Kaesten ----------
   Zwei Kaesten nebeneinander, die dasselbe vorstellen: Titel, Unterzeile,
   Text, Bild, Button.

   "Gleich gross" ist hier woertlich gemeint und braucht drei Dinge, die
   zusammenwirken: gleiche Spaltenbreite (1fr 1fr), gleiche Hoehe (das Raster
   streckt beide auf die des hoeheren) und ein Bild mit festem Seitenverhaelt-
   nis statt eigener Hoehe. Ohne das dritte waere der Kasten mit dem hoeheren
   Foto hoeher, und ohne margin-top: auto am Button stuenden die Buttons auf
   verschiedenen Hoehen, sobald die Texte unterschiedlich lang sind. */
.boxen {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1.75rem;
  max-width: var(--max-width);
  margin: 0 auto 2.5rem;
}

.box {
  display: flex;
  flex-direction: column;
  padding: 1.75rem;
  background: var(--color-surface);
  border-radius: var(--radius-l);
  box-shadow: var(--shadow-soft);
}

.box__titel {
  margin: 0 0 0.4rem;
  font-size: var(--text-xl);
  text-align: center;
}

.box__unterzeile {
  margin: 0 0 1rem;
  color: var(--color-accent-dark);
  font-size: var(--text-sm);
  font-weight: 500;
  letter-spacing: 0.06em;
  text-align: center;
  text-transform: uppercase;
}

.box__text {
  margin: 0 0 1.5rem;
  text-align: left;
}

/* 16:9, weil beide Fotos in diesem Bereich 16:9 sind (1200x675 und
   1125x633). Im vorherigen 4:3-Rahmen fielen 25 Prozent links und rechts
   weg, und die aeusseren Hunde waren angeschnitten. Mit dem passenden
   Verhaeltnis bleibt randlos und trotzdem vollstaendig.

   Werden hier andere Fotos eingesetzt, gehoert dieses Verhaeltnis geprueft:
   ein Hochformat wuerde hier wieder stark beschnitten. */
.box__bild {
  overflow: hidden;
  border-radius: var(--radius-l);
  background: var(--color-bg-alt);
  aspect-ratio: 16 / 9;
}

.box__bild img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  cursor: default;
}

/* auto oben schiebt die Buttonreihe an die Unterkante: so stehen die Buttons
   beider Kaesten auf einer Linie, auch bei unterschiedlich langen Texten.

   Der Selektor nennt bewusst .box davor: .content-buttons steht weiter unten
   im Stylesheet und setzt margin: 0 auto 2rem. Ohne die hoehere Spezifitaet
   gewinnt diese spaetere Regel, und die Buttons rutschen wieder auf
   verschiedene Hoehen. */
.box .box__aktionen {
  margin: auto 0 0;
  padding-top: 1.5rem;
  justify-content: center;
}

/* Nebeneinander lohnt sich erst ab einer gewissen Breite — darunter waeren
   Text und Bild zu schmal. */
@media (max-width: 760px) {
  .boxen {
    grid-template-columns: 1fr;
  }
}

/* Info cards — image + heading + text triples grouped side by side */

.info-card-grid {
  max-width: var(--max-width);
  margin: 0 auto 2.5rem;
  display: grid;
  gap: 1.75rem;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
}

/* Das Foto sass frueher buendig an der Oberkante, Weiss gab es nur unten um
   den Text. Die Kachel wirkte dadurch oben abgeschnitten und unten gedraengt.
   Jetzt liegt rundherum derselbe Weissraum, auch ueber dem Bild, und die
   Karte ist eine Spalte: Bild, Titel, Text, Button mit gleichen Abstaenden.
   margin-top: auto an der Buttonreihe schiebt sie ans untere Ende, damit die
   Buttons mehrerer Karten auf einer Linie stehen, auch wenn die Texte
   unterschiedlich lang sind. */
.info-card {
  display: flex;
  flex-direction: column;
  padding: 1rem;
  background: var(--color-surface);
  border-radius: var(--radius-l);
  box-shadow: var(--shadow-soft);
  transition: transform 0.4s var(--ease), box-shadow 0.4s var(--ease);
}

.info-card:hover {
  transform: translateY(-6px);
  box-shadow: var(--shadow-lift);
}

/* Quadratisch statt fester Hoehe: die Fotos folgen damit der Kachelbreite und
   wirken in jeder Spaltenzahl gleich. Vorher waren es 260 px, wodurch das
   Bild in einer breiten Zweierkachel zu einem flachen Streifen wurde und in
   einer schmalen Dreierkachel fast quadratisch — dieselbe Reihe sah je nach
   Fensterbreite anders aus. */
.info-card__frame {
  aspect-ratio: 1 / 1;
  overflow: hidden;
  border-radius: var(--radius-l);
  background: var(--color-bg-alt);
}

.info-card__frame img {
  width: 100%;
  height: 100%;
  /* Randlos, siehe .gallery-grid img weiter oben. */
  object-fit: cover;
  cursor: default;
}

/* Unter 636px räumt das auto-fit-Raster jede Karte in eine eigene Zeile
   (siehe .info-card-grid oben). Der Rahmen bleibt auch dort quadratisch und
   randlos. */
@media (max-width: 636px) {
  .info-card__frame img {
    object-fit: cover;
  }
}

.info-card__body {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 0.65rem;
  padding: 1.25rem 0.75rem 0.5rem;
}

.info-card__body h3 {
  margin: 0;
  text-align: left;
}

.info-card__body p {
  margin: 0;
  text-align: left;
}

/* Die Buttonreihe hat als einzige einen eigenen Abstand: sie soll deutlicher
   vom Text abgesetzt sein als Titel und Text voneinander. */
.info-card__body .content-buttons--card {
  margin: auto 0 0;
  padding-top: 0.6rem;
}

/* Checklists */

.content-list {
  list-style: none;
  margin: 0 auto 1.75rem;
  padding: 0;
  max-width: var(--max-width-text);
  display: grid;
  gap: 0.6rem;
}

.content-list li {
  position: relative;
  padding-left: 2.1rem;
  text-align: left;
}

.content-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.25em;
  width: 1.3em;
  height: 1.3em;
  border-radius: 999px;
  background: var(--color-accent-soft);
  border: 1px solid var(--color-accent);
}

.content-list li::after {
  content: "";
  position: absolute;
  left: 0.42em;
  top: 0.62em;
  width: 0.42em;
  height: 0.24em;
  border-left: 2px solid var(--color-accent-dark);
  border-bottom: 2px solid var(--color-accent-dark);
  transform: rotate(-45deg);
}

/* ---------- Credential panels ---------- */

/* Health results presented as documents rather than prose, and — since there
   are three per dog and the findings are dense lab shorthand — collapsed
   behind a native <details> so the page shows what was tested without
   forcing every reading to be read. The sage tick is decorative (the
   summary's own heading already says what was examined), so it is drawn in
   CSS and kept out of the accessibility tree. */
.credential-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 1.1rem;
  max-width: var(--max-width);
  margin: 0 auto 2.5rem;
}

.credential {
  background: var(--color-surface);
  border: 1px solid var(--color-sand);
  border-radius: var(--radius-m);
  box-shadow: var(--shadow-soft);
  transition: box-shadow 0.35s var(--ease);
}

/* Die Karten stehen immer offen — der Schatten des frueheren
   Aufklapp-Zustands gilt darum durchgehend. */
.credential--offen {
  box-shadow: var(--shadow-lift);
}

.credential__summary {
  list-style: none;
  display: flex;
  align-items: center;
  gap: 0.9rem;
  padding: 1.4rem 1.4rem;
}

.credential__summary::-webkit-details-marker {
  display: none;
}

.credential__summary::marker {
  content: "";
}

.credential__check {
  position: relative;
  flex-shrink: 0;
  width: 1.6rem;
  height: 1.6rem;
  border-radius: 999px;
  background: var(--color-accent-soft);
  border: 1px solid var(--color-accent);
}

.credential__check::after {
  content: "";
  position: absolute;
  top: 0.58rem;
  left: 0.42rem;
  width: 0.5rem;
  height: 0.28rem;
  border-left: 2px solid var(--color-accent-dark);
  border-bottom: 2px solid var(--color-accent-dark);
  transform: rotate(-45deg);
}

.credential__label {
  flex: 1;
  min-width: 0;
}

.credential__title {
  display: block;
  font-family: var(--font-body);
  font-size: var(--text-2xs);
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-heading);
  line-height: 1.35;
}

.credential__source {
  display: block;
  font-family: var(--font-display);
  font-size: var(--text-lg);
  color: var(--color-slate);
  line-height: 1.25;
}

.credential__chevron {
  position: relative;
  flex-shrink: 0;
  width: 1.7rem;
  height: 1.7rem;
  border-radius: 50%;
  border: 1px solid var(--color-border);
}

.credential__chevron::before {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 8px;
  height: 8px;
  margin: -5px 0 0 -5px;
  border-right: 1.5px solid var(--color-heading);
  border-bottom: 1.5px solid var(--color-heading);
  transform: rotate(45deg);
  transition: transform 0.35s var(--ease);
}

.credential[open] .credential__chevron::before {
  transform: rotate(-135deg);
  margin-top: -3px;
}

.credential__findings {
  margin: 0;
  padding: 0 1.4rem 1.4rem calc(1.4rem + 1.6rem + 0.9rem);
  font-size: var(--text-sm);
  line-height: 1.65;
  color: var(--color-text);
}

@media (max-width: 480px) {
  /* Bei sehr schmalen Karten würde der Einzug (auf Höhe des Häkchens) den
     Fliesstext zu stark einengen. */
  .credential__findings {
    padding-left: 1.4rem;
    border-top: 1px solid var(--color-border);
    padding-top: 0.9rem;
  }
}

/* ---------- Story cards (memorial entries) ---------- */

/* A private photo album read as a small set of keepsake cards instead of
   flowing text: dark ground, portrait, name and dates always visible, the
   paragraph clamped to two lines with a "read more" toggle (site.js). Text
   stays in the HTML at full length regardless of open/closed state — only
   the visual height changes — so nothing is hidden from search engines. */
/* ---------- In liebevoller Erinnerung ----------
   Zwei gleich grosse Kaesten nebeneinander: Name, Lebensdaten, Text, Foto.

   Der dunkle Rahmen ist hier kein Zierrat, sondern das, was ein Trauerrand
   seit jeher ist — er nimmt den Abschnitt aus dem uebrigen Seitenfluss
   heraus und zeigt vor dem Lesen, worum es geht. Er nutzt --color-deep und
   nicht reines Schwarz: derselbe Ton, der auch die Sprachwahlseite traegt,
   sodass er zur Seite gehoert.

   Das Bildformat kommt als Variable vom Element und wird in Blocks.astro aus
   den Bildern der jeweiligen Gruppe gerechnet: die Huskys sind 4:3, die
   Barbets 16:9. Ein gemeinsames Format wuerde eine der beiden Seiten um ein
   Viertel beschneiden. */
.erinnerung {
  display: grid;
  /* min() statt der nackten 320 px: auf einem 320-px-Geraet bleiben nach
     Abzug der Seitenraender nur 272 px, und die feste Untergrenze schob den
     Kasten 24 px ueber den Rand hinaus. Mit min() gibt die Spalte nach,
     sobald weniger als 320 px zur Verfuegung stehen. */
  grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr));
  gap: 1.75rem;
  max-width: var(--max-width);
  margin: 0 auto 2.5rem;
}

.erinnerung__karte {
  display: flex;
  flex-direction: column;
  padding: clamp(1.5rem, 3vw, 2.25rem);
  background: var(--color-surface);
  border: 2px solid var(--color-deep);
  border-radius: var(--radius-l);
}

.erinnerung__name {
  margin: 0 0 0.6rem;
  font-size: var(--text-xl);
  text-align: center;
  text-wrap: balance;
}

.erinnerung__daten {
  margin: 0 0 1.25rem;
  color: var(--color-text-soft);
  font-size: var(--text-2xs);
  letter-spacing: 0.12em;
  text-align: center;
  text-transform: uppercase;
}

.erinnerung__text {
  margin: 0 0 1.5rem;
  text-align: center;
  text-wrap: pretty;
}

/* auto oben schiebt Bild und Button an die Unterkante, damit die Fotos
   beider Kaesten auf einer Linie liegen, auch wenn ein Text laenger ist. */
.erinnerung__bild {
  margin-top: auto;
  overflow: hidden;
  border-radius: var(--radius-l);
  background: var(--color-bg-alt);
  aspect-ratio: var(--erinnerung-format, 4 / 3);
}

.erinnerung__bild img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  cursor: default;
}

.erinnerung__karte .erinnerung__aktionen {
  margin: 1.25rem 0 0;
  justify-content: center;
}

/* ---------- Call-to-action buttons ---------- */

.content-buttons {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.75rem;
  margin: 0 auto 2rem;
  max-width: var(--max-width-narrow);
}

/* Inside a card the buttons sit with the text, not centred across the page. */
.content-buttons--card {
  justify-content: flex-start;
  margin: 0.9rem 0 0;
}

.content-button {
  display: inline-block;
  /* Slate statt der fast schwarzen Überschriftfarbe: eine der drei
     Markenfarben, deutlich heller, und Weiss darauf erreicht 5.2:1. */
  background: var(--color-slate);
  color: #fff;
  text-decoration: none;
  border-radius: 999px;
  padding: 0.85rem 2.1rem;
  font-size: var(--text-2xs);
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  transition: background 0.25s ease, transform 0.3s var(--ease);
}

.content-button:hover,
.content-button:focus-visible {
  background: var(--color-accent);
  transform: translateY(-2px);
}

/* ---------- Tables ---------- */

/* Show results are wide: the wrapper scrolls on its own so the page body
   never gets a horizontal scrollbar on a phone. */
.content-table-wrap {
  /* Volle Inhaltsbreite statt der 760 px des Fliesstexts. Die
     Ausstellungstabellen haben fuenf Spalten — Resultat, Klasse, Richter/in,
     Show, Datum. In der schmalen Spalte brachen Richternamen und Shownamen
     auf zwei Zeilen um, wodurch die Zeilen unterschiedlich hoch wurden und
     das Auge die Reihe verlor. Mit der vollen Breite steht wieder eine
     Ausstellung in einer Zeile.

     Am Handy aendert das nichts: dort begrenzt ohnehin der Bildschirm, und
     der Kasten wischt mit dem Schatten am Rand weiter wie zuvor. */
  max-width: var(--max-width);
  margin: 0 auto 2rem;
  overflow-x: auto;
  border-radius: var(--radius-m);
  border: 1px solid var(--color-border);
  background: var(--color-surface);
  box-shadow: var(--shadow-soft);
}

.content-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--text-sm);
  text-align: left;
}

.content-table caption {
  padding: 0.9rem 1rem 0;
  font-family: var(--font-display);
  color: var(--color-heading);
  text-align: left;
}

.content-table th {
  background: var(--color-sand-soft);
  color: var(--color-heading);
  font-family: var(--font-body);
  font-weight: 500;
  font-size: var(--text-2xs);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  white-space: nowrap;
}

.content-table th,
.content-table td {
  padding: 0.7rem 1rem;
  border-bottom: 1px solid var(--color-border);
  vertical-align: top;
}

.content-table tbody tr:last-child td {
  border-bottom: 0;
}

.content-table tbody tr:hover td {
  background: var(--color-accent-soft);
}

/* ---------- Scroll reveal ---------- */

.will-reveal {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity 0.7s var(--ease), transform 0.7s var(--ease);
}

.will-reveal.is-visible {
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  .will-reveal {
    opacity: 1;
    transform: none;
    transition: none;
  }

  .content-figure img,
  .splash figure img {
    transition: none;
    animation: none;
  }
}

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

.lightbox {
  position: fixed;
  inset: 0;
  z-index: 500;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 3vh 4vw;
  background: rgba(43, 50, 61, 0.94);
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.3s ease, visibility 0.3s;
}

.lightbox.is-open {
  opacity: 1;
  visibility: visible;
}

.lightbox__figure {
  max-width: 100%;
  max-height: 100%;
  text-align: center;
}

.lightbox__figure img {
  max-width: 100%;
  max-height: 86vh;
  width: auto;
  margin: 0 auto;
  border-radius: var(--radius-l);
}

.lightbox__caption {
  color: rgba(255, 255, 255, 0.75);
  margin-top: 1rem;
  font-size: var(--text-sm);
}

.lightbox__close {
  position: absolute;
  top: 1.5rem;
  right: 1.75rem;
  background: rgba(255, 255, 255, 0.12);
  color: #fff;
  border: none;
  width: 42px;
  height: 42px;
  border-radius: 999px;
  font-size: var(--text-lg);
  cursor: pointer;
  transition: background 0.25s ease;
}

.lightbox__close:hover {
  background: rgba(255, 255, 255, 0.25);
}

/* ---------- Contact form ---------- */

.contact-emails {
  display: flex;
  gap: 0.75rem 1.5rem;
  flex-wrap: wrap;
  justify-content: center;
  margin: 0 0 2rem;
  font-size: var(--text-base);
  font-family: var(--font-display);
}

.contact-emails a {
  border-bottom: 1px solid var(--color-accent);
  padding-bottom: 0.1rem;
}

.contact-card {
  max-width: var(--max-width-narrow);
  margin: 0 auto;
  background: var(--color-surface);
  border-radius: var(--radius-l);
  box-shadow: var(--shadow-soft);
  padding: clamp(1.75rem, 1.4rem + 1.5vw, 3rem);
}

/* One form style for both the contact form and the puppy enquiry form.
   Labels are set in sentence case rather than uppercase micro-type: on the
   enquiry form a label is a whole question, and uppercase is unreadable
   at that length. */
.content-form {
  display: grid;
  gap: 1.15rem;
}

.content-form__section {
  font-family: var(--font-display);
  font-size: var(--text-xl);
  color: var(--color-heading);
  margin: 1.4rem 0 0;
}

.content-form__section:first-child {
  margin-top: 0;
}

.content-form label,
.content-form legend {
  display: block;
  font-size: var(--text-sm);
  line-height: 1.45;
  color: var(--color-heading);
  margin-bottom: 0.45rem;
}

.content-form input[type="text"],
.content-form input[type="email"],
.content-form textarea {
  width: 100%;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-s);
  padding: 0.8rem 1rem;
  font-family: inherit;
  font-size: var(--text-base);
  background: var(--color-bg);
  color: var(--color-heading);
  transition: border-color 0.25s ease, box-shadow 0.25s ease;
}

.content-form input:focus,
.content-form textarea:focus {
  outline: none;
  border-color: var(--color-accent);
  box-shadow: 0 0 0 3px var(--color-accent-soft);
}

.content-form textarea {
  min-height: 120px;
  resize: vertical;
}

.content-form__field--choice {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-s);
  padding: 0.9rem 1rem;
  margin: 0;
}

.content-form__option,
.content-form__field--consent {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.6rem;
  align-items: start;
  margin-bottom: 0.4rem;
  cursor: pointer;
}

.content-form__option input,
.content-form__field--consent input {
  margin-top: 0.28em;
  accent-color: var(--color-accent);
}

.content-form__field--consent {
  color: var(--color-text);
  font-size: var(--text-sm);
  line-height: 1.5;
}

.content-form button {
  justify-self: start;
  background: var(--color-slate);
  color: #fff;
  border: none;
  border-radius: 999px;
  padding: 0.85rem 2.1rem;
  font-size: var(--text-2xs);
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  font-family: var(--font-body);
  cursor: pointer;
  transition: background 0.25s ease, transform 0.3s var(--ease);
}

.content-form button:hover {
  background: var(--color-accent);
  transform: translateY(-2px);
}

/* ---------- Footer ---------- */

.site-footer {
  position: relative;
  border-top: 1px solid var(--color-border);
  padding: 3.5rem 1.5rem 3rem;
  text-align: center;
  margin-top: 3rem;
  background: var(--color-bg-alt);
}

.site-footer h2 {
  font-size: var(--text-xl);
  margin-bottom: 0.6rem;
}

.site-footer p {
  color: var(--color-text-soft);
  margin-bottom: 0;
}

.site-footer .social-links {
  justify-content: center;
  margin-top: 1.5rem;
}

/* ---------- Dark Mode: die zwei Ausnahmen ----------
   Diese beiden Regeln stehen bewusst am Dateiende und nicht oben beim
   Token-Block. Eine Media Query erhoeht die Spezifitaet nicht: stuenden sie
   oben, wuerde die spaetere .site-header-Regel sie wieder ueberschreiben —
   genau das ist beim ersten Versuch passiert, die Kopfzeile blieb im Dunkeln
   cremefarben. Alles andere im Dark Mode laeuft ueber die Farbtoken und
   braucht keine eigene Regel. */
@media (prefers-color-scheme: dark) {
  /* Die Kopfzeile liegt durchscheinend ueber dem Inhalt und braucht darum
     einen festen Wert statt eines Tokens: denselben Ton wie der Grund, nur
     mit Deckung dahinter. */
  .site-header {
    background: rgba(27, 31, 38, 0.85);
  }

  /* Das Logo ist eine schwarze Zeichnung auf durchsichtigem Grund — mittlere
     Helligkeit 23 von 255, vollstaendig unbunt. Auf dunklem Grund waere es
     unsichtbar. invert(1) macht daraus dieselbe Zeichnung in Weiss und laesst
     die weichen Kanten unberuehrt, weil die Deckung nicht mitgedreht wird.
     Eine zweite Bilddatei ist dafuer nicht noetig. */
  .site-header__logo img {
    filter: invert(1);
  }
}

/* ---------- Tippflaechen am Handy ----------

   65 % der Besucher kommen vom Handy. Eine Flaeche, die sicher zu treffen
   ist, misst rund 44 x 44 px — das ist der Wert, den sowohl Apple als auch
   die WCAG (2.5.5) nennen. Gemessen wurden vorher: Menue-Knopf 41 x 35,
   Social-Icons 30 x 30, Sprachwahl 52 x 26, Fusszeile 24 px hoch.

   Der Menue-Knopf waechst sichtbar, denn er ist das meistgetippte Element
   der Seite. Bei den Icons und den Textlinks wuerde das die Gestaltung
   verziehen — dort vergroessert ein unsichtbares ::after nur die
   Trefferflaeche, waehrend der Kreis und die Schrift bleiben, wie sie sind. */

@media (max-width: 860px) {
  .nav-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 44px;
    min-height: 44px;
    padding: 0.5rem 0.85rem;
  }

  .social-links a,
  .lang-switch a,
  .footer-legal a {
    position: relative;
  }

  .social-links a::after,
  .lang-switch a::after,
  .footer-legal a::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    min-width: 44px;
    min-height: 44px;
    width: 100%;
    height: 100%;
  }

  /* Die Fusszeilen-Links liegen dicht nebeneinander; ohne etwas Luft
     wuerden sich die vergroesserten Flaechen ueberlappen. */
  .footer-legal {
    gap: 0.4rem 1.75rem;
  }
}

/* ---------- Schriftgroessen am Handy ----------

   Die beiden kleinsten Stufen der Skala sind am Bildschirm eines Rechners
   stimmig, am Handy aber zu klein: 2xs ergab 11,8 px und traegt unter
   anderem die Buttons — also keine Randnotiz, sondern das, worauf getippt
   wird. xs ergab 13,1 px und traegt Navigation und Bildunterschriften.

   Angehoben wird die Skala selbst und nicht jede einzelne Regel: die beiden
   Stufen kommen an rund zwanzig Stellen vor, und die Abstufung soll dabei
   erhalten bleiben. Am Rechner aendert sich nichts. */

@media (max-width: 860px) {
  :root {
    --text-2xs: 0.875rem;
    --text-xs: 0.9rem;
  }
}

/* ---------- Tabellen am Handy ----------

   Die Ausstellungsergebnisse sind 496-537 px breit, das Fenster eines
   Handys 375 px. Der Kasten wischt seitlich, aber nichts zeigte das an —
   man sah zwei von vier Spalten und hielt die Tabelle fuer abgeschnitten.

   Statt eines Hinweistextes, der in beiden Sprachen gepflegt werden
   muesste, zeigt ein Schatten am Rand, dass dort noch etwas liegt. Er
   erscheint und verschwindet von selbst: die weissen Flaechen scrollen mit
   dem Inhalt mit (background-attachment: local) und schieben sich vor die
   Schatten, sobald der Rand erreicht ist. Am Anfang liegt also nur rechts
   ein Schatten, am Ende nur links — ganz ohne Skript. */

@media (max-width: 860px) {
  .content-table-wrap {
    background-color: var(--color-surface);
    background-image:
      linear-gradient(to right, var(--color-surface) 30%, transparent),
      linear-gradient(to left, var(--color-surface) 30%, transparent),
      radial-gradient(farthest-side at 0 50%, rgba(0, 0, 0, 0.16), transparent),
      radial-gradient(farthest-side at 100% 50%, rgba(0, 0, 0, 0.16), transparent);
    background-position: left center, right center, left center, right center;
    background-repeat: no-repeat;
    background-size: 42px 100%, 42px 100%, 14px 100%, 14px 100%;
    background-attachment: local, local, scroll, scroll;
  }

  /* Ohne nowrap darf der Tabellenkopf umbrechen. Das macht die Tabelle
     schmaler, es bleibt also weniger zu wischen uebrig. */
  .content-table th {
    white-space: normal;
  }
}

/* ---------- Nachtrag zu den Tabellen am Handy ----------

   Der groessere Tabellenkopf aus der Schriftanpassung hat die Tabelle
   breiter gemacht, als das Weglassen von nowrap eingespart hat. Engere
   Zellen und weniger Sperrung im Kopf holen das wieder herein — beides
   nur am Handy, wo jedes Pixel Breite zaehlt. */

@media (max-width: 860px) {
  .content-table th,
  .content-table td {
    padding: 0.6rem 0.65rem;
  }

  .content-table th {
    letter-spacing: 0.06em;
  }
}

/* ---------- Letzte zwei Tippflaechen ----------

   Der Schliessknopf der Lightbox mass 42 x 42 px und der Namenszug in der
   Fusszeile 157 x 26 px — beide knapp unter den 44 px, die sicher zu
   treffen sind. */

.lightbox__close {
  width: 44px;
  height: 44px;
}

@media (max-width: 860px) {
  .site-footer h2 a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }
}

/* ---------- Seitentitel am Handy ----------

   "Datenschutzerklaerung" ist ein Wort aus 20 Buchstaben. Bei 29,6 px und
   einer Sperrung von 0,14em misst es 424 px — mehr als jedes Handy breit
   ist. Die Sperrung allein steuert dabei rund 80 px bei.

   hyphens: auto steht weiter oben als Netz, aber darauf ist kein Verlass:
   ob ein Browser deutsche Trennmuster mitbringt, ist nicht garantiert (in
   der Testumgebung hier fehlten sie). Darum wird der Titel so bemessen,
   dass er gar nicht erst brechen muss: mit 0,06em Sperrung und einer
   Groesse, die mit dem Geraet mitwaechst, passt das Wort ab 320 px in eine
   Zeile — gemessen bei 320, 360, 375 und 414 px.

   .page-hero__title ist nicht betroffen: die Klasse setzt Groesse und
   Sperrung selbst und sticht diese Regel. Der grosse Titel ueber dem Foto
   bleibt also, wie er ist. */

@media (max-width: 600px) {
  h1 {
    font-size: clamp(1.45rem, 1.1rem + 1.9vw, 1.85rem);
    letter-spacing: 0.06em;
  }
}

/* ---------- Links im Fliesstext ----------

   Die Grundregel oben unterstreicht Links erst beim Hover. Am Handy gibt es
   keinen Hover, und dort kommen zwei von drei Besuchern her. Zusammen mit
   "color: inherit" heisst das: ein Link im Text war fuer die Mehrheit der
   Besucher von gewoehnlichem Text nicht zu unterscheiden — die E-Mail-
   Adressen im Impressum, der Verweis auf den Barbet Club, die Links in der
   Datenschutzerklaerung.

   Unterstrichen wird darum fest, aber nur im Inhalt und nur bei Links ohne
   eigene Klasse. Alles, was sich selbst gestaltet, bleibt unberuehrt:
   Buttons (.content-button), Navigation, Sprachwahl, Fusszeile und die
   Social-Icons — dort waere eine Unterstreichung falsch, und die Icons
   truegen einen Strich unter einem Bild.

   [data-content-root] umfasst alle Inhaltsbloecke, auch Listen und
   Tabellen: ein Link, der spaeter dort hinzukommt, ist damit automatisch
   mitgemeint. Die Kontaktkarte steht ausserhalb dieses Bereichs und wird
   eigens genannt.

   Der Abstand haelt die Linie von den Unterlaengen frei. */

[data-content-root] a:not([class]),
.contact-emails a:not([class]) {
  text-decoration: underline;
  text-underline-offset: 0.18em;
  text-decoration-thickness: 1px;
}

/* ---------- Abschied ----------

   Die Zeile zum Tod eines Hundes stand als gewoehnlicher Absatz zwischen
   den Befunden — sachlich richtig, aber am falschen Ort im Ton. Sie steht
   jetzt fuer sich: viel Luft darum, mittig, mit einem Kreuz darueber.

   Das Kreuz traegt --color-deep, den fast schwarzen Ton, den auch der
   Trauerrand der Erinnerungs-Kaesten nutzt. Er ist als einziger Farbwert
   der Seite im Dunkelmodus nicht neu gesetzt und waere dort auf dunklem
   Grund unsichtbar, darum die eigene Angabe weiter unten.

   Die duenne Linie darueber trennt den Abschnitt ab, ohne eine Ueberschrift
   zu brauchen: es soll leiser sein als eine, nicht lauter. */

.abschied {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.75rem;
  max-width: var(--max-width-text);
  margin: 3rem auto;
  padding-top: 2.5rem;
  border-top: 1px solid var(--color-border);
  text-align: center;
  color: var(--abschied-farbe, var(--color-deep));
}

.abschied__kreuz {
  font-family: var(--font-title);
  font-size: 2rem;
  line-height: 1;
  opacity: 0.75;
}

.abschied__text {
  font-size: var(--text-lg);
  line-height: 1.6;
  text-wrap: balance;
}

@media (prefers-color-scheme: dark) {
  .abschied {
    --abschied-farbe: var(--color-heading);
  }
}

/* ---------- Karte mit Kreuz statt Haken ----------

   Der Haken der Untersuchungskarten meint "bestanden, frei von allem" — bei
   Kona steht er neben "HD A". Auf einer Gedenkseite koennen in denselben
   Karten aber Diagnosen stehen: bei Jenna eine sekundaere Epilepsie und ein
   Wasserkopf. Dort behauptet ein gruener Haken etwas, was der Text nicht
   sagt, und der fluechtige Blick liest die Seite falsch herum.

   Darum diese Variante: derselbe Kreis, rot statt gruen, mit einem Kreuz
   aus zwei Balken. Gesetzt wird sie ueber "marker": "kreuz" am h3-Block im
   Inhalt, nicht geraten — was ein guter und was ein schlechter Befund ist,
   entscheidet niemand ausser den Besitzern.

   Die Regeln des Hakens setzen Rahmen und Verschiebung; beides wird hier
   zurueckgenommen, sonst bliebe der halbe Haken stehen. */

.credential__check--kreuz {
  background: var(--color-alert-soft);
  border-color: var(--color-alert);
}

.credential__check--kreuz::before,
.credential__check--kreuz::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 0.72rem;
  height: 2px;
  border: 0;
  background: var(--color-alert);
  transform: translate(-50%, -50%) rotate(45deg);
}

.credential__check--kreuz::before {
  transform: translate(-50%, -50%) rotate(-45deg);
}

/* ---------- Foto neben Text ----------

   Diese Abschnitte standen voll in der Breite untereinander: Ueberschrift,
   Foto, zwei Absaetze. Das liest sich als lange Kolonne, und wer scrollt,
   sieht Bild und Aussage nie zugleich. Nebeneinander sieht man beides.

   Der Block ist breiter als der uebrige Fliesstext (der bleibt bei
   --max-width-narrow, 760 px): zwei Spalten brauchen Platz, sonst wird die
   Textspalte zu schmal und bricht nach drei Woertern um.

   data-seite kommt aus Blocks.astro und wechselt von Block zu Block. Getauscht
   wird nur die Darstellung ueber grid-column, nicht die Reihenfolge im
   Markup — am Handy und beim Vorlesen kommt so immer erst das Foto, dann der
   Text, unabhaengig davon, wo das Bild am Rechner steht.

   Unter 900 px stapelt sich alles: zwei Spalten auf einem Handy waeren zwei
   zu schmale Spalten. Dort kommen zwei von drei Besuchern her. */

.nebeneinander {
  display: grid;
  gap: clamp(1.5rem, 4vw, 3rem);
  align-items: center;
  max-width: var(--max-width);
  margin: 0 auto 2.75rem;
}

.nebeneinander__bild {
  margin: 0;
  border-radius: var(--radius-l);
  overflow: hidden;
}

/* Das Bild fuellt die Spalte. Ohne diese Regel bleibt ein kleines Foto
   in seiner Naturbreite stehen und der helle Rahmen scheint daneben
   durch — auf der Trainingsseite ist ein Videostandbild nur 342 px breit.
   Fuer die grossen Fotos aendert sich nichts, sie waren schon breiter als
   die Spalte. */
.nebeneinander__bild picture,
.nebeneinander__bild img {
  display: block;
  width: 100%;
}

/* Das Foto rundet selbst. Am Handy steht die Unterschrift unter dem Foto im
   selben Rahmen und machte ihn hoeher als das Bild (360 statt 312 px): der
   Rahmen rundete dann die Unterschrift und liess das Foto unten eckig.
   Am Rechner liegt sie ueber dem Bild, dort aendert sich nichts (Nadine,
   20.10.2026). */
.nebeneinander__bild img {
  border-radius: var(--radius-l);
}

.nebeneinander__bild figcaption {
  padding: 0.6rem 0.9rem 0.8rem;
  font-size: var(--text-xs);
  color: var(--color-text-soft);
  text-align: center;
}

.nebeneinander__text > p {
  margin: 0 0 1.25rem;
}

.nebeneinander__text > p:last-child {
  margin-bottom: 0;
}

@media (min-width: 901px) {
  .nebeneinander {
    grid-template-columns: 1fr 1fr;
  }

  .nebeneinander[data-seite="bild-rechts"] .nebeneinander__bild,
  .nebeneinander[data-seite="bild-rechts"] .nebeneinander__karussell {
    grid-column: 2;
    grid-row: 1;
  }

  .nebeneinander[data-seite="bild-rechts"] .nebeneinander__text {
    grid-column: 1;
    grid-row: 1;
  }
}

/* ---------- Karussell in der Bildspalte ----------

   Statt eines einzelnen Fotos kann neben dem Text ein Karussell stehen
   (Levi auf der Barbet-Seite, Nadine 20.10.2026). Es braucht drei Dinge,
   die das einzelne Foto nicht braucht:

   min-width: 0 ist kein Zierrat. 1fr heisst minmax(auto, 1fr), und die
   Mindestbreite des Karussells ist seine Spur mit allen Folien. Ohne die
   Null sprengt sie die Spalte: gemessen nahm das Karussell 760 px von
   937, fuer den Text blieb ein Streifen von 137 px.

   max-width: none, weil die schmale Lesebreite hier die Spalte nicht
   ausfuellen wuerde, und margin: 0, weil der Abstand vom Raster kommt. */
/* Zwei Klassen im Selektor, nicht eine: .karussell deckelt die Breite
   auf die schmale Lesebreite und steht weiter unten im Stilblatt. Bei
   gleicher Genauigkeit gewaenne es, und das Karussell bliebe 760 px
   breit, auch in einer schmaleren Spalte. */
.nebeneinander .nebeneinander__karussell {
  min-width: 0;
  max-width: none;
  margin: 0;
}

/* Eine leere Folie im Karussell. Sie haelt dasselbe Format wie ein Foto,
   sonst springt die Hoehe beim Weiterblaettern. */
.karussell__folie--platz {
  display: flex;
}

.karussell .fotoplatz--karussell {
  width: 100%;
  aspect-ratio: 3 / 2;
  max-width: none;
  margin: 0;
  padding: 1.25rem;
}

/* ---------- Titel und Aufruf in der Textspalte ----------

   Ueberschrift, Text und Button stehen jetzt zusammen neben dem Foto. Die
   Ueberschriften kommen aus dem Seitenfluss, wo sie mittig stehen und volle
   Breite haben — in einer Spalte waere beides falsch. */

.nebeneinander__titel {
  text-align: left;
  max-width: none;
  margin: 0 0 0.6rem;
}

.nebeneinander__titel + .nebeneinander__titel {
  margin-top: -0.2rem;
}

/* Nach der letzten Ueberschrift etwas mehr Luft als zwischen ihnen. */
.nebeneinander__text > .nebeneinander__titel:last-of-type {
  margin-bottom: 1.1rem;
}

/* Der Aufruf sitzt am Ende der Spalte, linksbuendig statt mittig — er
   gehoert zum Text daneben und nicht in die Seitenmitte. */
.nebeneinander__aktionen {
  justify-content: flex-start;
  margin: 1.5rem 0 0;
}

/* Gestapelt wird die Spalte zur vollen Breite; dann steht der Aufruf wie
   ueberall sonst mittig unter dem Text. */
@media (max-width: 900px) {
  .nebeneinander__aktionen {
    justify-content: center;
  }

  .nebeneinander__titel {
    text-align: center;
  }
}

/* ---------- Beschriftete Listen nebeneinander ----------

   "Best Resultate" und "Champion Titel" standen untereinander und ergaben
   eine lange Kolonne, in der man den Zusammenhang verlor. Nebeneinander
   sieht man auf einen Blick, dass es zwei gleichrangige Aufstellungen sind.

   auto-fit statt fester Spaltenzahl: kaemen einmal drei Aufstellungen dazu,
   ordnen sie sich von selbst. Unter der Mindestbreite bricht jede in eine
   eigene Zeile — auf einem Handy waeren zwei Spalten zu schmal fuer Zeilen
   wie "2nd Best Bitch KMC 2025 (out of 35 Barbet bitches)".

   Die Beschriftung bleibt ein Absatz und wird keine Ueberschrift: sie steht
   nicht in der Gliederung der Seite. */

.listenspalten {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr));
  gap: 1rem 2.5rem;
  max-width: var(--max-width-text);
  margin: 0 auto 2rem;
}

.listenspalten__titel {
  margin: 0 0 0.75rem;
  color: var(--color-text-soft);
}

.listenspalten .content-list {
  margin: 0;
}

/* ---------- Zweizeiliger Tabellenkopf ----------

   Auf der Wurfseite steht das Jahr ueber zwei Spalten, darunter SH und B.
   Die Gruppenzelle bekommt eine Trennlinie nach unten, sonst schwimmen die
   beiden Zeilen ineinander und man sieht nicht, welche Spalte zu welchem
   Jahr gehoert. */

.content-table__gruppe {
  text-align: center;
  border-bottom: 1px solid var(--color-border);
}

/* Die Untergruppen mittig, damit sie unter ihrer Jahreszahl sitzen. */
.content-table thead tr + tr th {
  text-align: center;
}

/* Die Zahlenspalten ebenso — linksbuendige Ziffern unter einer mittigen
   Ueberschrift lesen sich schief. */
.content-table td:not(:first-child) {
  text-align: center;
}

/* Senkrechte Trennung zwischen den Jahresgruppen. Ohne sie laufen elf
   Zahlenspalten ineinander und man sieht nicht mehr, welches Paar zu
   welchem Jahr gehoert. Die Linie sitzt jeweils links der ersten Spalte
   einer Gruppe — im Kopf wie in den Daten. */
.content-table__trenn {
  border-left: 1px solid var(--color-border);
}

/* ---------- Namen unter den Galeriebildern ----------

   Bildunterschriften der Galerie liegen sonst als Ueberblendung auf dem Foto
   und erscheinen erst beim Hover — richtig fuer eine zurueckhaltende
   Urheberangabe, falsch fuer einen Namen. Wo die Unterschrift sagt, welcher
   Hund zu sehen ist, muss sie immer dastehen: am Rechner wie am Handy, ohne
   dass jemand mit der Maus darueberfahren muss.

   Gesetzt wird das ueber "layout": "raster" im Inhalt, das ohnehin schon
   sagt: diese Bilder sind gleichrangig und einzeln benannt. */

.gallery-grid--namen .content-figure::after {
  display: none;
}

.gallery-grid--namen .content-figure figcaption {
  position: static;
  opacity: 1;
  transform: none;
  padding: 0.75rem 0.9rem 0.9rem;
  color: var(--color-heading);
  font-size: var(--text-base);
  font-weight: 500;
  text-align: center;
  pointer-events: auto;
}


/* ---- Wurfblock: Huendin links, Text mittig, Ruede rechts ------------
   Das Muster der alten Wurfplanung. Die Mitte traegt Titel, Elterntiere
   und den Aufruf, die beiden Aussenspalten je ein beschriftetes Foto.
   Am Handy stapeln sich die drei untereinander.

   Der Rahmen fasst eine Ankuendigung zusammen: auf der Seite stehen
   mehrere Wuerfe untereinander, und ohne Rahmen laeuft der eine in den
   naechsten. Er nimmt dieselben Werte wie die uebrigen Kaesten der Seite
   — 1 px --color-border auf --color-surface, grosser Radius. */
.wurfblock {
  display: grid;
  gap: var(--gap);
  align-items: center;
  margin: calc(var(--gap) * 2) 0;
  /* Am Handy schmaler: 30 px Innenabstand kosteten dort ein Fuenftel der
     Bildbreite. 18 px reichen, damit der Rahmen als Rahmen liest. */
  padding: calc(var(--gap) * 0.75);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-l);
}

.wurfblock__seite {
  margin: 0;
}

.wurfblock__seite img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--radius-l);
}

.wurfblock__beschriftung {
  margin: 0 0 8px;
  font-weight: 600;
  text-align: left;
}

.wurfblock__seite figcaption {
  margin-top: 8px;
  font-size: var(--text-xs);
  color: var(--color-text-soft);
  text-align: left;
}

.wurfblock__mitte {
  text-align: center;
}

.wurfblock__titel {
  margin-top: 0;
}

.wurfblock__zeile {
  margin: 0 0 4px;
}

.wurfblock__aktionen {
  margin-top: var(--gap);
  justify-content: center;
}

@media (min-width: 901px) {
  .wurfblock {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr) minmax(0, 1fr);
    gap: calc(var(--gap) * 1.5);
    padding: calc(var(--gap) * 1.75);
  }
}


/* ---- Falle fuer Automaten -------------------------------------------
   Ein Feld, das kein Mensch sieht und darum auch keiner ausfuellt.
   Traegt es doch etwas, verwirft formular.php die Sendung. Es wird aus dem
   Bild geschoben statt mit display:none versteckt: manche Automaten
   ueberspringen genau das, was unsichtbar geschaltet ist. aria-hidden und
   tabindex=-1 halten es aus Vorlesesoftware und Tabreihenfolge heraus. */
.content-form__falle {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* ---------- Karussell ---------------------------------------------------
   Eine wischbare Reihe, die ein Foto auf die volle Spaltenbreite stellt.
   Ohne JavaScript bleibt sie genau das: scroll-snap sorgt dafuer, dass ein
   Wisch auf dem naechsten Foto einrastet. Pfeile, Punkte und der
   automatische Weiterlauf kommen aus site.js dazu.

   Der Rahmen kommt weiter von .content-figure; hier fallen nur der
   Aussenabstand und die Hoechstbreite weg, die dort fuer einzelne Bilder
   im Textfluss stehen. */

.karussell {
  position: relative;
  max-width: var(--max-width-narrow);
  margin: 0 auto 2rem;
}

.karussell__spur {
  display: flex;
  gap: 1rem;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  /* Die Leiste selbst bleibt unsichtbar: gewischt wird am Handy, am Rechner
     fuehren Pfeile und Punkte. Die Reihe bleibt trotzdem scrollbar. */
  scrollbar-width: none;
  -ms-overflow-style: none;
}

.karussell__spur::-webkit-scrollbar {
  display: none;
}

.karussell__folie {
  flex: 0 0 100%;
  margin: 0;
  max-width: none;
  scroll-snap-align: center;
}

/* Pfeile erst ab Tablet: am Handy wird gewischt, und zwei Knoepfe ueber
   einem 320 px breiten Foto verdecken mehr, als sie helfen. */
.karussell__pfeil {
  display: none;
}

/* Die Punkte brechen um. Mit zwei Folien passten sie immer in eine Zeile,
   mit neun nicht mehr: je 44 px Tippflaeche ergaben 396 px und damit
   Querscrollen auf jedem Handy (gemessen bei 375 px, Nadine 20.10.2026). */
.karussell__punkte {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.25rem;
  margin-top: 0.75rem;
}

/* 44 px Trefferflaeche um einen 10 px grossen Punkt: gross genug fuer den
   Daumen, ohne dass die Leiste unruhig wird. */
.karussell__punkt {
  appearance: none;
  border: 0;
  background: none;
  padding: 17px;
  cursor: pointer;
  line-height: 0;
}

.karussell__punkt::before {
  content: "";
  display: block;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--color-text-soft);
  opacity: 0.35;
  transition: opacity 0.2s ease, transform 0.2s ease;
}

.karussell__punkt[aria-current="true"]::before {
  opacity: 1;
  transform: scale(1.2);
}

.karussell__punkt:focus-visible {
  outline: 2px solid var(--color-sage);
  outline-offset: -8px;
  border-radius: 50%;
}

@media (min-width: 701px) {
  .karussell__pfeil {
    display: grid;
    place-items: center;
    position: absolute;
    top: calc(50% - 1.5rem);
    transform: translateY(-50%);
    width: 44px;
    height: 44px;
    border: 0;
    border-radius: 50%;
    background: var(--color-surface);
    box-shadow: var(--shadow-soft);
    color: var(--color-text);
    font-size: 1.75rem;
    line-height: 1;
    cursor: pointer;
    opacity: 0.9;
    transition: opacity 0.2s ease;
  }

  .karussell__pfeil:hover {
    opacity: 1;
  }

  .karussell__pfeil:focus-visible {
    outline: 2px solid var(--color-sage);
    outline-offset: 3px;
  }

  .karussell__pfeil--zurueck {
    left: 0.75rem;
  }

  .karussell__pfeil--vor {
    right: 0.75rem;
  }

  /* Am Anfang und am Ende bleibt der jeweilige Pfeil sichtbar: das
     Karussell laeuft rundherum weiter. */
}

/* Wer weniger Bewegung wuenscht, bekommt kein weiches Gleiten — und
   site.js schaltet fuer dieselbe Einstellung den automatischen Weiterlauf
   ab. */
@media (prefers-reduced-motion: reduce) {
  .karussell__spur {
    scroll-behavior: auto;
  }

  .karussell__punkt::before {
    transition: none;
  }
}

/* ---------- Plaketten ---------------------------------------------------
   Ausstellungserfolge von Levi und Joya: jeder Titel in eigenem Rahmen mit
   Rosette, statt einer Zeile mit Haken in einer langen Liste. Die Titel sind
   das Ergebnis jahrelanger Arbeit und sollen als solche zu sehen sein
   (Nadine, 16.09.2026).

   Die Plaketten stehen in einem eigenen Raster und nicht in .content-list:
   sie brauchen Rahmen, Innenabstand und eine Rosette, und ein Eintrag darf
   ueber zwei Zeilen laufen, ohne dass die Reihe auseinanderfaellt. */

/* Die Erfolge stehen als Band ueber die ganze Fensterbreite, nicht in der
   Inhaltsspalte (Nadine, 17.09.2026: "so breit wie moeglich, die ganze
   Seite"). Die eigene Flaeche traegt das Band - ohne sie haengen die
   Plaketten am Bildschirmrand, waehrend darueber und darunter alles in der
   Spalte bleibt.

   Ausgebrochen wird ueber --seitenbreite, das site.js auf die Fensterbreite
   OHNE Rollbalken setzt. Mit 100vw waere der Rollbalken mitgezaehlt, und am
   Rechner entstuende genau das Querscrollen, das es hier nie geben darf.
   Ohne JavaScript greift der Rueckfallwert 100%: dann bleibt das Band in der
   Inhaltsspalte - schmaler als gewuenscht, aber nie kaputt. */
.plaketten {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr));
  gap: 1.75rem 3rem;
  max-width: none;
  margin: 0 calc(50% - var(--seitenbreite, 100%) / 2) 2.5rem;
  padding: clamp(1.5rem, 4vw, 2.75rem) clamp(1rem, 4vw, 3rem);
  background: var(--color-bg-alt);
}

.plaketten__titel {
  margin: 0 0 0.85rem;
  font-family: var(--font-title);
  font-size: var(--text-xs);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--color-heading);
}

/* Innerhalb einer Gruppe fuellen die Plaketten die Breite in mehreren
   Unterspalten statt in einer einzigen, sehr breiten Reihe: "Deutscher
   Champion" ueber 570 px waere vor allem Luft. Unter 230 px je Plakette
   bleibt eine Spalte, am Handy also immer untereinander. */
.plaketten__liste {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 0.6rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.plakette {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  padding: 0.7rem 1rem;
  border: 1px solid var(--color-border);
  border-left: 3px solid var(--color-accent);
  border-radius: var(--radius-m, 14px);
  background: var(--color-surface);
  box-shadow: var(--shadow-soft);
}

.plakette__rosette {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  color: var(--color-accent);
}

.plakette__rosette svg {
  width: 100%;
  height: 100%;
}

.plakette__text {
  font-weight: 500;
  line-height: 1.35;
}

/* Auf dunklem Hintergrund traegt die Flaeche selbst die Auszeichnung: der
   weiche Schatten verschwindet dort ohnehin, die hellere Flaeche bleibt. */
@media (prefers-color-scheme: dark) {
  .plaketten {
    background: rgba(255, 255, 255, 0.04);
  }

  .plakette {
    background: var(--color-surface);
  }
}

/* ---------- Titel ueber die ganze Fensterbreite -------------------------
   Seitentitel (h1) und Abschnittstitel (h2) brechen aus der Textspalte aus
   und stehen ueber das ganze Fenster (Nadine, 17.09.2026). Die Breite kommt
   aus --seitenbreite, das site.js auf die Fensterbreite OHNE Rollbalken
   setzt: mit 100vw waere der Rollbalken mitgezaehlt und die Seite wuerde
   quer scrollen. Ohne JavaScript greift der Rueckfallwert 100%, dann bleibt
   der Titel in der Textspalte - schmaler, aber nie kaputt.

   Der Innenabstand haelt die Schrift bei schmalen Fenstern von der Kante
   weg; die Titel sind mittig gesetzt, darum fallen die Werte nur am Rand
   auf. Zwischentitel (h3, h4) bleiben bei der Textbreite: sie gehoeren zum
   Absatz darunter und wuerden quer ueber die Seite den Zusammenhang
   zerreissen. */
.content-block--h1,
.content-block--h2 {
  max-width: none;
  margin-inline: calc(50% - var(--seitenbreite, 100%) / 2);
  padding-inline: 1.5rem;
}

/* ---------- Zeitleiste --------------------------------------------------
   "Unsere Geschichte": oben das Neueste, unten "Wo alles beginnt" (Nadine,
   28.09.2026). Oben eine gemeinsame Achse, unten zwei getrennte Straenge,
   dazwischen der Zusammenfluss.

   Wie das Plaketten-Band nimmt die Achse die ganze Fensterbreite, ueber
   --seitenbreite aus site.js. Ohne JavaScript bleibt sie in der Spalte. */

.zeitachse {
  margin: 0 calc(50% - var(--seitenbreite, 100%) / 2) 3rem;
  padding: clamp(1.5rem, 4vw, 3rem) clamp(1rem, 4vw, 3rem);
  background: var(--color-bg-alt);
  color: var(--color-text);
}

.zeitachse ol {
  list-style: none;
  margin: 0;
  padding: 0;
}

/* Am Handy eine einzige Spur am linken Rand, alle Karten rechts davon. Zwei
   Straenge nebeneinander waeren auf 320 px zwei 130 px schmale Spalten. */
.zeitachse__eintrag {
  position: relative;
  display: grid;
  grid-template-columns: 2.5rem 1fr;
  padding-bottom: 1.5rem;
}

.zeitachse__eintrag::before {
  content: "";
  position: absolute;
  left: 0.6rem;
  top: 0.35rem;
  bottom: -0.35rem;
  width: 2px;
  background: var(--color-border);
}

/* Der letzte Eintrag eines Strangs hat keine Fortsetzung mehr. */
.zeitachse__eintrag--start::before {
  bottom: auto;
  height: 0.9rem;
}

.zeitachse__eintrag--dick::before {
  width: 5px;
  left: calc(0.6rem - 1.5px);
  background: var(--color-accent);
}

.zeitachse__punkt {
  position: absolute;
  left: 0.1rem;
  top: 0.35rem;
  width: 1rem;
  height: 1rem;
  border-radius: 50%;
  background: var(--color-surface);
  border: 2px solid var(--color-accent);
  box-shadow: var(--shadow-soft);
}

.zeitachse__eintrag--start .zeitachse__punkt {
  background: var(--color-accent);
}

/* Ein Abschied traegt dieselbe Farbe wie die Gedenkseiten. */
.zeitachse__eintrag--abschied .zeitachse__punkt {
  border-color: var(--color-slate);
  background: var(--color-slate);
}

/* Noch nicht geschehen: der Punkt bleibt offen, damit man sieht, dass hier
   etwas erwartet wird und nichts erreicht ist. */
.zeitachse__eintrag--erwartet .zeitachse__punkt {
  border-style: dashed;
  background: transparent;
  box-shadow: none;
}

/* Der Steg fuehrt vom Punkt auf der Linie zu seiner Karte. Ohne ihn
   schwebten die Karten neben der Achse, und bei zwei kurz aufeinander
   folgenden Ereignissen war nicht zu sehen, welcher Punkt zu welcher Karte
   gehoert. */
.zeitachse__eintrag::after {
  content: "";
  position: absolute;
  top: 1.05rem;
  left: 1.1rem;
  width: 1.4rem;
  height: 2px;
  background: var(--color-border);
}

.zeitachse__karte {
  grid-column: 2;
  background: var(--color-surface);
  border-radius: var(--radius-m);
  box-shadow: var(--shadow-soft);
  padding: 0.9rem 1.1rem;
}

/* Das Datum ist eine Plakette und keine zweite Ueberschrift: vorher stand
   es in derselben Schriftfamilie direkt ueber dem Titel, und man las beide
   als eine Zeile (Nadine, 28.09.2026: "man weiss nicht, wo was hingehoert").
   Jetzt traegt es eine eigene Flaeche und sitzt an der Seite, an der auch
   die Linie steht. */
.zeitachse__zeit {
  display: inline-block;
  margin: 0 0 0.45rem;
  padding: 0.15rem 0.6rem;
  border-radius: 999px;
  background: var(--color-accent-soft);
  font-family: var(--font-title);
  font-size: var(--text-xs);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-accent-dark);
}

.zeitachse__titel {
  margin: 0;
  font-size: 1.1rem;
  font-weight: 600;
  line-height: 1.25;
  color: var(--color-heading);
}

/* Der Text steht ruhiger als der Titel und ist durch eine Haarlinie von ihm
   getrennt - sonst verschwimmen Ueberschrift und Beschreibung zu einem
   Block. */
.zeitachse__text {
  margin: 0.5rem 0 0;
  padding-top: 0.5rem;
  border-top: 1px solid var(--color-border);
  line-height: 1.55;
  color: var(--color-text-soft);
}

.zeitachse__strangname {
  margin: 0 0 0.75rem 2.5rem;
  font-family: var(--font-title);
  font-size: var(--text-xs);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--color-heading);
}

.zeitachse__strang + .zeitachse__strang {
  margin-top: 2rem;
}

/* Die Gabel ergibt erst Sinn, wenn die Straenge wirklich nebeneinander
   stehen — am Handy laufen sie untereinander. */
.zeitachse__gabel {
  display: none;
}

@media (min-width: 861px) {
  /* Jede Spur liegt in der Mitte ihres Bereichs, die Karten stehen
     abwechselnd links und rechts davon - fuer die gemeinsame Achse wie fuer
     die zwei Straenge. */
  .zeitachse__eintrag {
    grid-template-columns: 1fr 3rem 1fr;
    padding-bottom: 2rem;
  }

  .zeitachse__eintrag::before {
    left: calc(50% - 1px);
  }

  .zeitachse__eintrag--dick::before {
    left: calc(50% - 2.5px);
  }

  .zeitachse__punkt {
    left: calc(50% - 0.5rem);
  }

  .zeitachse__eintrag[data-seite="links"] .zeitachse__karte {
    grid-column: 1;
    text-align: right;
  }

  .zeitachse__eintrag[data-seite="rechts"] .zeitachse__karte {
    grid-column: 3;
  }

  .zeitachse__gabel {
    display: block;
    width: 100%;
    height: 3.5rem;
    color: var(--color-border);
  }

  /* Ohne Spaltenabstand: nur dann liegen die Spaltenmitten genau bei 25 %
     und 75 % der Breite - und genau dort enden die zwei Linien der Gabel.
     Mit "gap" waeren es 24,1 % und 75,9 %, und die Gabel traefe die
     Straenge um zwoelf Pixel daneben. Der Abstand zwischen den Straengen
     kommt darum als Innenabstand. */
  .zeitachse__getrennt {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0;
  }

  .zeitachse__strang {
    padding-inline: 1.5rem;
  }

  .zeitachse__strang + .zeitachse__strang {
    margin-top: 0;
  }

  .zeitachse__strangname {
    margin-left: 0;
    text-align: center;
  }
}

/* ---------- Zeitleiste: Straenge unterscheiden -------------------------
   Selina und Andreas bekommen verschiedene Farben, damit im getrennten Teil
   auf einen Blick klar ist, welche Linie wem gehoert. Die gemeinsame Achse
   oben behaelt die Akzentfarbe. */
.zeitachse__strang[data-strang="andreas"] .zeitachse__eintrag::before,
.zeitachse__strang[data-strang="andreas"] .zeitachse__eintrag::after {
  background: var(--color-sand);
}

.zeitachse__strang[data-strang="andreas"] .zeitachse__punkt {
  border-color: var(--color-sand);
}

.zeitachse__strang[data-strang="andreas"] .zeitachse__eintrag--start .zeitachse__punkt {
  background: var(--color-sand);
}

.zeitachse__strangname {
  display: inline-block;
  padding: 0.2rem 0.7rem;
  border-radius: 999px;
  background: var(--color-accent-soft);
  color: var(--color-accent-dark);
}

.zeitachse__strang[data-strang="andreas"] .zeitachse__strangname {
  background: var(--color-sand-soft);
  color: var(--color-text);
}

@media (min-width: 861px) {
  /* Am Rechner steht die Linie zwischen den Karten: der Steg zeigt darum
     nach links oder nach rechts, je nachdem, wo die Karte steht. */
  .zeitachse__eintrag[data-seite="links"]::after {
    left: auto;
    right: calc(50% + 0.5rem);
    width: 1rem;
  }

  .zeitachse__eintrag[data-seite="rechts"]::after {
    left: calc(50% + 0.5rem);
    width: 1rem;
  }

  /* Die Plakette mit dem Datum sitzt an der Seite, an der die Linie steht. */
  .zeitachse__eintrag[data-seite="links"] .zeitachse__karte {
    text-align: right;
  }
}

/* ---------- Aktuell-Band ------------------------------------------------
   Die laufenden Meldungen der Zucht, ueber dem Einstieg der Startseite.
   Vorher standen sie als Pillen im Hero und waren das Erste, was ein
   Besucher las - noch vor dem Namen der Zuchtstaette (Nadine, 15.10.2026).

   Volle Fensterbreite wie das Plaketten-Band, ueber --seitenbreite aus
   site.js; ohne JavaScript bleibt es in der Inhaltsspalte. Weisse Schrift
   auf dem Akzentgruen ergibt rund 4,9:1 Kontrast und ist damit auch fuer
   kleine Schrift ausreichend. */

/* Das Band sitzt buendig unter der Kopfzeile: der Inhaltsbereich
   (.page-section) beginnt mit 3.5rem Innenabstand, und darin stand das Band
   mit 56 px Leerraum darueber, aber ohne Abstand zum Bild darunter - genau
   verkehrt herum (Nadine, 15.10.2026). Der negative Aussenabstand zieht es
   an die Kopfzeile, darunter folgt der Abstand zum Einstiegsbild. */
.aktuell {
  margin: -3.5rem calc(50% - var(--seitenbreite, 100%) / 2) 2rem;
  padding: 0.7rem clamp(1rem, 4vw, 3rem);
  background: var(--color-accent);
  color: #ffffff;
}

.aktuell__inhalt {
  max-width: var(--max-width);
  margin: 0 auto;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: center;
  gap: 0.35rem 1rem;
}

.aktuell__label {
  font-family: var(--font-title);
  font-size: var(--text-xs);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  opacity: 0.85;
}

.aktuell__liste {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: center;
  gap: 0.35rem 1rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Ein Trennpunkt zwischen den Meldungen, aber nicht vor der ersten und
   nicht, wenn sie am Handy untereinander stehen. */
.aktuell__eintrag + .aktuell__eintrag::before {
  content: "·";
  margin-right: 1rem;
  opacity: 0.6;
}

.aktuell__eintrag a {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 3px;
}

.aktuell__eintrag a:hover {
  text-decoration-thickness: 2px;
}

.aktuell__eintrag a:focus-visible {
  outline: 2px solid #ffffff;
  outline-offset: 3px;
}

@media (max-width: 560px) {
  .aktuell__liste {
    flex-direction: column;
    gap: 0.3rem;
  }

  .aktuell__eintrag + .aktuell__eintrag::before {
    content: none;
  }
}

/* Foto in einem Ereignis der Zeitleiste. Es steht unter dem Text in
   derselben Karte, damit Bild und Anlass zusammenbleiben. Der Platz dafuer
   wird in der JSON-Datei vorbereitet ("bild": null) und bleibt leer, bis
   ein Foto eingetragen ist (Nadine, 17.10.2026). */
/* Das Foto rundet selbst und die Unterschrift steht frei darunter, ohne
   gefuellte Flaeche. So sind die unteren Ecken des Fotos rund, auch wenn
   eine Unterschrift folgt. */
.zeitachse__foto {
  margin: 0.75rem 0 0;
}

.zeitachse__foto img {
  display: block;
  width: 100%;
  border-radius: var(--radius-l);
}

.zeitachse__foto figcaption {
  padding: 0.5rem 0.7rem;
  font-size: var(--text-xs);
  color: var(--color-text-soft);
  text-align: left;
}

/* In einer linken Karte steht der Text rechtsbuendig; die Unterschrift
   folgt dem, sonst klebt sie als einzige Zeile auf der falschen Seite. */
.zeitachse__eintrag[data-seite="links"] .zeitachse__foto figcaption {
  text-align: right;
}

/* ---------- Foto neben Text: Hoehe begrenzen -------------------------
   Hochformate tuermten sich neben zwei Zeilen Text: auf Jennas Seite stand
   ein 808 px hohes Foto neben 94 px Text, die Reihen wirkten unruhig
   (Nadine, 17.10.2026). Das Foto wird darum nicht hoeher als 28 rem.

   Beschnitten wird nichts: Das Bild behaelt sein Format, wird nur kleiner
   und steht mittig in seiner Spalte. Nur dort, wo Bild und Text wirklich
   nebeneinander stehen - untereinander am Handy darf das Foto die volle
   Breite behalten. */
@media (min-width: 901px) {
  .nebeneinander__bild {
    display: flex;
    flex-direction: column;
    align-items: center;
  }

  .nebeneinander__bild picture {
    display: flex;
    justify-content: center;
    width: auto;
    max-width: 100%;
  }

  .nebeneinander__bild img {
    width: auto;
    max-width: 100%;
    max-height: 28rem;
  }

  /* Die Unterschrift gehoert unter das Bild, nicht unter die ganze
     Spaltenbreite. */
  .nebeneinander__bild figcaption {
    align-self: stretch;
  }
}

/* ---------- Platz fuer ein fehlendes Foto -----------------------------
   Steht dort, wo das Bild hinkommt, und sagt, was es zeigen soll. Gestrichelt
   und zurueckhaltend: Es ist eine Baustelle, kein Gestaltungselement
   (Nadine, 17.10.2026). Seiten mit solchen Plaetzen gehoeren auf
   entwurf: true, damit Besucher sie nicht sehen. */

.fotoplatz {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  max-width: var(--max-width-text);
  margin: 0 auto 2rem;
  padding: clamp(1.5rem, 5vw, 3rem) 1.25rem;
  border: 2px dashed var(--color-border);
  border-radius: var(--radius-l);
  background: var(--color-bg-alt);
  text-align: center;
}

.fotoplatz__zeichen {
  display: block;
  width: 2.5rem;
  height: 2.5rem;
  color: var(--color-text-soft);
  opacity: 0.7;
}

.fotoplatz__zeichen svg {
  width: 100%;
  height: 100%;
}

.fotoplatz__text {
  margin: 0;
  font-family: var(--font-title);
  font-size: var(--text-xs);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-heading);
}

.fotoplatz__hinweis {
  margin: 0;
  max-width: 32rem;
  font-size: var(--text-xs);
  line-height: 1.5;
  color: var(--color-text-soft);
}

/* Vorbereiteter, noch leerer Fotoplatz in einem Ereignis der Zeitleiste.
   Klein und gestrichelt: Er zeigt, wo das Foto hinkommt, ohne die Karte zu
   sprengen (Nadine, 17.10.2026). */
.zeitachse__fotoplatz {
  margin: 0.6rem 0 0;
  padding: 0.5rem 0.7rem;
  border: 1px dashed var(--color-border);
  border-radius: var(--radius-l);
  font-family: var(--font-title);
  font-size: var(--text-xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-text-soft);
}
