/* =========================================================================
   Land der Hildegard — Grundlagen
   Farben nach dem Corporate Design des Hildegard-Netzwerks.
   Atlantic Blue wird bewusst nicht verwendet.
   ========================================================================= */

:root {
  /* --- Palette ------------------------------------------------------- */
  --color-ivory: #e6e3dc;    /* Hellelfenbein — die Grundfläche der Seite */
  --color-taupe: #bc987e;    /* nur Flächen und Zierlinien, nie Text auf Hell */
  --color-moss: #287126;     /* Moosgrün — zweite Akzentfarbe */
  --color-bordeaux: #780231; /* Bordeaux — Leitfarbe */
  --color-white: #ffffff;
  --color-ink: #241f1d;      /* warmes Dunkelbraun für Lesetext */
  --color-mauve: #b3768e;    /* Altrosa aus dem Roll-Up — nur Fläche, 2,79:1 */

  /* --- Semantische Zuordnung ------------------------------------------
     Kontraste nachgerechnet (04.08.2026): Bordeaux auf Elfenbein 8,85:1
     (AAA), Moosgrün auf Elfenbein 4,71:1 (AA — nur 0,21 Luft zur
     Schwelle 4,5, beim Nachdunkeln von Elfenbein aufpassen), Weiß auf
     Bordeaux 11,34:1 (AAA), Dunkelbraun auf Elfenbein 12,71:1.
     Taupe erreicht auf hellem Grund nur 2,07:1 und ist deshalb
     ausschließlich Flächenfarbe.                                        */
  --color-background: var(--color-ivory);
  --color-surface: var(--color-white);
  --color-text: var(--color-ink);
  --color-text-muted: #5c5148;
  --color-primary: var(--color-bordeaux);
  --color-accent: var(--color-moss);
  --color-line: rgba(36, 31, 29, 0.16);
  --color-focus: var(--color-moss);

  /* --- Maße ----------------------------------------------------------- */
  --content-width: 72rem;
  --content-width-text: 44rem;
  --padding: clamp(1.25rem, 0.7rem + 2.6vw, 3rem);
  --padding-vertical: clamp(3rem, 2.1rem + 3.6vw, 6rem);
  --border-radius: 0.5rem;
  /* Zwei Werte, die auseinandergehalten werden müssen:

     --header-min  ist eine reine Layout-Vorgabe: So hoch ist der
                   Kopfbereich mindestens. Fest, wird nie überschrieben.
     --header-height  ist die GEMESSENE Höhe. animationen.js schreibt sie
                   nach jedem Umbruch der Navigation neu. Sie steuert
                   ausschließlich scroll-margin-top.

     Sie dürfen nicht zusammenfallen. Steuert der gemessene Wert auch das
     Layout, vergrößert jede Messung das, was sie misst — der
     Kopfbereich wächst dann in einer Rückkopplung ins Unendliche. Genau
     das ist am 04.08. passiert (siehe 04-Analyse/A11y-Pruefung.md, F1). */
  --header-min: 4.5rem;
  --header-height: 4.5rem;

  /* --- Schrift --------------------------------------------------------
     Die beiden Familien-Token stehen bewusst NICHT hier, sondern in
     assets/css/schriften.css — dort liegen auch die Schriftdateien und
     die drei zur Auswahl stehenden Kombinationen. Ein Ort für alles,
     was mit Schriftwahl zu tun hat.                                     */

  --font-size-body: clamp(1.0625rem, 1.02rem + 0.2vw, 1.1875rem);
  --font-size-body-sm: 0.9375rem;
  --font-size-body-xs: 0.8125rem;
  --font-size-lead: clamp(1.1875rem, 1.1rem + 0.5vw, 1.5rem);
  --font-size-h1: clamp(2.25rem, 1.5rem + 3.2vw, 4.5rem);
  --font-size-h2: clamp(1.75rem, 1.5rem + 1.1vw, 2.625rem);
  --font-size-h3: clamp(1.25rem, 1.15rem + 0.45vw, 1.625rem);
  /* 15 px statt 16. Gemessen am 07.08.2026 (Rückmeldung Carlo bei
     1078 px): Die neun Navigationspunkte brauchen einzeilig 744 px,
     im Kopf standen bei 1000 px Innenbreite nur 950 px abzüglich
     Wortmarke und Abständen zur Verfügung — es fehlten 88 px, und die
     Navigation brach um. Eine Stufe kleiner spart rund 35 px, der
     engere Abstand (siehe .nav__list) noch einmal 64 px.

     Es ist dieselbe Stufe, die --font-size-body-sm trägt; die
     Trefferfläche bleibt mit 29 × 35 px weit über den geforderten
     24 × 24 (WCAG 2.5.8), weil sie am padding-block hängt und nicht an
     der Schriftgröße. */
  --font-size-nav: 0.9375rem;

  /* --- Laufweite der Überschriften ------------------------------------
     Rückmeldung 2026-08-13-1057-5xda28: „Laufweite in den Headlines
     etwas verringern."

     Bis dahin stand an h1, h2 und h3 gar kein `letter-spacing` — sie
     liefen also in den Werkseinstellungen von Spectral. Die sind für
     Fließtextgrößen ausgelegt; bei 72 px wirkt dieselbe relative Fuge
     zu weit. Das ist keine Geschmacksfrage, sondern die übliche
     optische Regel: Je größer die Schrift, desto enger darf sie laufen,
     weil die Fugen mitwachsen und ab einer gewissen Größe auseinander-
     fallen.

     Deshalb eine Staffel und kein einzelner Wert — je größer die Stufe,
     desto mehr Minus:

       h1  36–72 px   -0.02em    bei 72 px = -1,44 px je Fuge
       h2  28–42 px   -0.015em   bei 42 px = -0,63 px je Fuge
       h3  20–26 px   -0.01em    bei 26 px = -0,26 px je Fuge

     ⚠ Unterhalb von h3 wird NICHTS enger gestellt. Bei 20 px und
     darunter kostet engere Laufweite Lesbarkeit, statt Ruhe zu
     bringen — h3 ist mit 20 px Mindestgröße die letzte Stufe, die es
     verträgt, und bekommt deshalb auch nur ein Drittel des Werts von h1.

     ⚠ Die Wortmarke im Kopfbereich (`.header__titel`) ist bewusst NICHT
     dabei. Sie steht auf +0.03em, und dieser Wert ist hergeleitet: Der
     Bold-Schnitt bringt mehr Fläche mit, dadurch rücken die Buchstaben
     optisch zusammen — dort wurde die Laufweite absichtlich GEÖFFNET.
     Sie hier mitzuziehen hieße, eine begründete Entscheidung
     versehentlich rückgängig zu machen, und der Kopfbereich muss bei
     980 px einzeilig bleiben. Begründung steht bei `.header__titel`. */
  --laufweite-h1: -0.02em;
  --laufweite-h2: -0.015em;
  --laufweite-h3: -0.01em;

  --line-height-body: 1.6;
  --line-height-heading: 1.15;

  --shadow-soft: 0 1px 2px rgba(36, 31, 29, 0.06), 0 8px 24px rgba(36, 31, 29, 0.08);

  /* --- Farbtonleiter der Abschnitte ------------------------------------
     Fünf helle Stufen, die sich abwechseln und der langen Seite Rhythmus
     geben. Alle tragen denselben dunklen Lesetext (Kontrast > 9:1),
     die Reihenfolge ist deshalb frei wählbar. Taupe erscheint nur als
     aufgehellte Fläche — nie als Textfarbe.                             */
  --ton-1: var(--color-ivory);   /* #e6e3dc — Grundfläche */
  --ton-2: var(--color-white);
  --ton-3: #f1ece3;              /* Sand, eine Spur heller als Elfenbein */
  --ton-4: #dfcdbd;              /* Taupe auf Elfenbein aufgehellt */
  /* --ton-5 ist --ton-1 um 50 % Richtung Weiß aufgehellt — Sarahs Vorgabe
     vom 13.08.2026: „von dem Grau, was jetzt gesetzt ist, 50 Prozent
     nochmal weggezogen". Gerechnet im sRGB-Kanal, nicht geschätzt:
     #e6e3dc = rgb(230, 227, 220), je Kanal die Mitte zu 255 ergibt
     rgb(242,5 | 241 | 237,5) → #f2f1ee.
     Er trägt genau zwei Flächen — den Einführungsbereich unter dem
     Titelbild und den Kontaktbereich über der Fußzeile. Die übrigen
     Bänder bleiben beim Wechsel Weiß ↔ Elfenbein.
     Kontraste auf #f2f1ee (13.08.2026 gerechnet): Dunkelbraun #241f1d
     14,43:1, gedämpfter Text #5c5148 6,82:1, Bordeaux #780231 10,04:1,
     Moosgrün #287126 5,34:1 — alle über AA.                            */
  --ton-5: #f2f1ee;              /* Elfenbein, 50 % Richtung Weiß */

  /* Höhe des Wellenbands. Auf dem Telefon flach, am Schreibtisch
     ausgeprägter — so bleibt der Kopfbereich mobil kompakt.            */
  --welle-hoehe: clamp(1.5rem, 5vw, 5.5rem);
}

/* =========================================================================
   Grundgerüst
   ========================================================================= */

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

* {
  margin: 0;
  padding: 0;
}

html {
  font-size: 100%;
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
}

body {
  font-family: var(--font-family-body);
  font-size: var(--font-size-body);
  line-height: var(--line-height-body);
  color: var(--color-text);
  background: var(--color-background);
  -webkit-font-smoothing: antialiased;
}

/* Sprungziele nicht unter dem festen Kopfbereich verstecken.

   Der Zuschlag über der gemessenen Kopfhöhe ist bewusst nicht fest:
   Auf einem 1200 px hohen Fenster sind 1,5rem Luft angenehm, auf einem
   600 px hohen verschenken sie spürbar Sichtfläche. `svh` und nicht
   `vh`, weil die Adressleiste auf dem Telefon sonst mitrechnet und der
   Wert beim Scrollen wandert.

   Zwei Zeilen, nicht eine: Ein Browser, der `svh` nicht kennt, verwirft
   die zweite Deklaration und behält die erste — ohne sie stünde er ganz
   ohne Abstand da.

   --header-height ist der von animationen.js GEMESSENE Wert. Er darf
   ausschliesslich hier stehen und niemals Layout steuern (A11y-Prüfung
   F1, siehe auch der Hinweis an :root). */
[id] {
  scroll-margin-top: calc(var(--header-height) + 1rem);
  scroll-margin-top: calc(var(--header-height) + clamp(0.5rem, 3svh, 1.5rem));
}

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

img {
  height: auto;
}

h1,
h2,
h3 {
  font-family: var(--font-family-heading);
  /* „Barrierefreiheitserklärung" passt bei 320 px sonst nicht in die
     Zeile und schiebt die Seite waagerecht auf. lang="de" steht am
     <html>, die Silbentrennung greift also. */
  overflow-wrap: break-word;
  hyphens: auto;
  line-height: var(--line-height-heading);
  font-weight: 600;
  text-wrap: balance;
  color: var(--color-primary);
}

/* Größe und Laufweite gehören zusammen und stehen deshalb Zeile für
   Zeile nebeneinander — wer eine Stufe verschiebt, sieht die andere
   Angabe sofort. Herleitung der Staffel: :root, `--laufweite-h1`. */
h1 { font-size: var(--font-size-h1); letter-spacing: var(--laufweite-h1); }
h2 { font-size: var(--font-size-h2); letter-spacing: var(--laufweite-h2); }
h3 { font-size: var(--font-size-h3); letter-spacing: var(--laufweite-h3); }

p {
  text-wrap: pretty;
}

a {
  color: var(--color-primary);
  text-underline-offset: 0.15em;
}

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

/* =========================================================================
   Barrierefreiheit
   ========================================================================= */

/* Ein sichtbarer Fokusring auf allem, was bedienbar ist */
:focus-visible {
  outline: 3px solid var(--color-focus);
  outline-offset: 3px;
  border-radius: 2px;
}

.skip-link {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 100;
  padding: 0.75rem 1.25rem;
  background: var(--color-primary);
  color: var(--color-white);
  text-decoration: none;
  transform: translateY(-120%);
}

.skip-link:focus {
  transform: translateY(0);
}

/* Nur für Screenreader */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* =========================================================================
   Layout-Hilfen
   ========================================================================= */

.wrap {
  width: 100%;
  max-width: var(--content-width);
  margin-inline: auto;
  padding-inline: var(--padding);
}

.wrap--text {
  max-width: calc(var(--content-width-text) + 2 * var(--padding));
}

.section {
  padding-block: var(--padding-vertical);
}

/* =========================================================================
   Wellenband und Farbbänder

   Jeder Abschnitt sitzt in einem Band mit eigener Grundfarbe, davor ein
   Wellentrenner. Die Trennlinie zwischen den Abschnitten entfällt damit —
   die Welle übernimmt ihre Aufgabe.
   ========================================================================= */

.band {
  background: var(--band-farbe, var(--ton-1));
}

.band--ton-1 { --band-farbe: var(--ton-1); }
.band--ton-2 { --band-farbe: var(--ton-2); --karten-farbe: var(--ton-3); }
.band--ton-3 { --band-farbe: var(--ton-3); }
.band--ton-4 { --band-farbe: var(--ton-4); }
.band--ton-5 { --band-farbe: var(--ton-5); }

/* overflow: hidden, weil die Kurve fuer die Varianz breiter gezogen wird
   als das Band (siehe --welle-dehnung). Was seitlich hinausragt, ist der
   Vorrat, aus dem der Ausschnitt geschoben wird. */
/* Die Haarlinie an der Unterkante — und warum sie so hartnaeckig war.

   Die Bandhoehe faellt fast nie auf ein volles Geraetepixel: Sie kommt
   aus clamp() und wird zusaetzlich mit --welle-mass multipliziert (0,90
   bis 1,24). Der Browser zeichnet die unterste Zeile des SVG deshalb
   halb deckend. Weil dort die Zierbahn unter der deckenden Bahn liegt,
   mischen sich beide zu einem hellen Streifen in Zierfarbe — sichtbar
   an drei Sektionsgrenzen und ueber der Fusszeile, je nach Fensterbreite.

   Ein negativer margin half NICHT, obwohl der folgende Abschnitt
   dieselbe Farbe hat: Ein SVG ist ersetzter Inhalt und wird in der
   Malreihenfolge NACH den Hintergruenden nachfolgender Block-Elemente
   gezeichnet. Das SVG malt also ueber den Abschnitt, der es zudecken
   soll — nicht umgekehrt.

   Deshalb wird die Kante abgeschnitten statt zugedeckt: Der Container
   bekommt die Sollhoehe, das SVG zwei Pixel mehr, und overflow: hidden
   nimmt den Rest weg. Was unten sichtbar bleibt, ist voll deckende
   Bahnfarbe. Beim Hero loest `bottom: -1px` das anders, dort liegt die
   Welle absolut im Bild. */
.welle {
  --welle-hoehe-ist: calc(var(--welle-hoehe) * 1.423 * var(--welle-mass, 1));

  line-height: 0;
  height: var(--welle-hoehe-ist);
  overflow: hidden;
  background: var(--welle-von, transparent);
}

/* Die Bandhoehe traegt den Faktor 212/149: Die viewBox ist oben um 21
   Einheiten gewachsen, damit die Zierbahn am Rand nicht abgeschnitten
   wird, und unten um dieselben 21, damit sie an der Bandkante nicht als
   Keil stehen bleibt (Begruendung im Snippet). Ohne diesen Ausgleich
   wuerde dieselbe Kurve um 42 % flacher gestaucht. Die unteren 21
   Einheiten sind reine Flaeche in der Farbe des folgenden Abschnitts —
   das Band ist rechnerisch hoeher, zu sehen ist davon nichts.
   --welle-mass variiert die Hoehe je Ausschnitt leicht, damit die
   Abschnitte nicht im Gleichmass folgen. */
.welle svg {
  display: block;
  width: 100%;
  height: calc(var(--welle-hoehe-ist) + 2px);
  fill: var(--welle-nach, var(--ton-1));
  transform: translateX(var(--welle-schub, 0))
             scaleX(calc(var(--welle-dehnung, 1) * var(--welle-richtung, 1)));
}

/* Der Zierstreifen ist die Farbe der Seite.

   Er ist dieselbe Kurve, nur 21 Einheiten höher, und schaut deshalb als
   schmales Band über der deckenden Bahn hervor — genau wie im Druck. Weil
   er zwischen zwei hellen Flächen liegt und keinen Text trägt, dürfen hier
   auch die kräftigen CD-Farben stehen: Bordeaux trägt, Moosgrün setzt
   Akzente, Taupe und Altrosa sind die Atempausen.

   Ohne Farbklasse läuft er halbtransparent mit der Bahn mit und deutet nur
   eine Kante an (so unter dem Titelbild und über der Fußzeile). */
.welle__zier {
  fill: var(--welle-zier, var(--welle-nach, var(--ton-1)));
  opacity: var(--welle-zier-deckung, 0.45);
}

.welle--zier-bordeaux { --welle-zier: var(--color-bordeaux); --welle-zier-deckung: 1; }
.welle--zier-moos     { --welle-zier: var(--color-moss);     --welle-zier-deckung: 1; }
.welle--zier-taupe    { --welle-zier: var(--color-taupe);    --welle-zier-deckung: 1; }
.welle--zier-mauve    { --welle-zier: var(--color-mauve);    --welle-zier-deckung: 1; }

/* Eine Kurve, zwei Richtungen. Die Spiegelung laeuft ueber ein Vorzeichen
   in --welle-richtung, damit sie sich mit Dehnung und Schub in EINEM
   transform vertraegt — zwei transform-Regeln wuerden einander ersetzen,
   nicht ergaenzen. */
.welle--gespiegelt {
  --welle-richtung: -1;
}

.welle--nach-1 { --welle-nach: var(--ton-1); }
.welle--nach-2 { --welle-nach: var(--ton-2); }
.welle--nach-3 { --welle-nach: var(--ton-3); }
.welle--nach-4 { --welle-nach: var(--ton-4); }
.welle--nach-5 { --welle-nach: var(--ton-5); }
.welle--nach-taupe    { --welle-nach: var(--color-taupe); }
.welle--nach-bordeaux { --welle-nach: var(--color-bordeaux); }

.welle--von-1 { --welle-von: var(--ton-1); }
.welle--von-2 { --welle-von: var(--ton-2); }
.welle--von-3 { --welle-von: var(--ton-3); }
.welle--von-4 { --welle-von: var(--ton-4); }
.welle--von-5 { --welle-von: var(--ton-5); }
.welle--von-taupe    { --welle-von: var(--color-taupe); }
.welle--von-bordeaux { --welle-von: var(--color-bordeaux); }

/* Unter dem Titelbild liegt die Welle im Bild, nicht darunter —
   sonst schöbe sie das Foto nach oben. Ein Pixel Überstand nach unten
   verhindert die Haarlinie, die manche Browser sonst zeichnen. */
.welle--hero {
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px;
  z-index: 1;
}


/* Eine Zeile für Überschrift und Werkzeug (heute nur „Alle Einträge
   öffnen"), darunter über die volle Breite die Einleitung.

   `baseline` statt `center`: Der kleine Schalter soll auf derselben
   Schriftlinie sitzen wie die Überschrift, nicht auf deren Mitte.
   Die Einleitung erzwingt mit `flex-basis: 100%` ihre eigene Zeile und
   behält dort ihre 44rem — der Kopf selbst läuft über die vollen 72rem
   der Sektion, damit der Schalter die rechte Kartenkante trifft.

   `row-gap` ersetzt den früheren `margin-top` der Einleitung: derselbe
   Abstand wie bisher, und wenn der Schalter auf schmalen Schirmen unter
   die Überschrift umbricht, hat er dort ohne Zutun dieselbe Luft.
   Umgebrochen steht er links — `space-between` setzt das einzige
   Element einer Zeile an deren Anfang. */
.section__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  column-gap: 1.5rem;
  row-gap: 0.75rem;
  margin-bottom: 2rem;
}

.section__intro {
  flex-basis: 100%;
  max-width: var(--content-width-text);
  color: var(--color-text-muted);
}

/* =========================================================================
   Kopfbereich
   ========================================================================= */

/* Der Kopfbereich klebt — aber nicht bedingungslos.

   Ohne JavaScript steht die Burger-Navigation dauerhaft offen (die
   Begründung steht weiter unten bei `.nav-mobil`). Gemessen am
   13.08.2026 bei 390 px Breite ist der Kopf dann 533 px hoch. Klebend
   verdeckte er auf jedem Telefon fast den ganzen Schirm — die Seite
   wäre ohne JavaScript unbenutzbar, statt nur schlichter zu sein.

   Er klebt deshalb genau dort, wo er flach bleibt: wenn JavaScript
   läuft und das Menü zuklappbar ist, oder ab 61.25rem, wo es das
   mobile Menü gar nicht gibt. Die Grundstellung ist „klebt nicht" —
   Browser, die `scripting` nicht kennen, fallen damit in den
   bedienbaren Zustand statt in den verdeckten.
   ⚠ 61.25rem ist dieselbe Umbruchgrenze wie bei `.nav` weiter unten. */
.header {
  position: static;
  top: 0;
  z-index: 50;
  background: var(--color-ivory);
  border-bottom: 1px solid var(--color-line);
}

@media (scripting: enabled) {
  .header {
    position: sticky;
  }
}

@media (min-width: 61.25rem) {
  .header {
    position: sticky;
  }
}

.header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  /* Der feste Wert, NICHT der gemessene — sonst entsteht eine
     Rückkopplung mit kopfhoeheMessen() in animationen.js. */
  min-height: var(--header-min);
}

.header__brand {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  font-family: var(--font-family-heading);
  font-size: 1.25rem;
  color: var(--color-primary);
  text-decoration: none;
}

/* Der Markenname trägt als einzige Stelle Spectral 700. Überschriften
   stehen auf 600 — so setzt sich der Kopf ab, ohne die Hierarchie zu
   verschieben. Die feinen Serifen wirkten bei 400 auf Elfenbein
   ausgezehrt.

   Zur Laufweite: Ein fetterer Schnitt bringt mehr Fläche mit, dadurch
   rücken die Buchstaben optisch zusammen. Zwei Stellschrauben, die
   verschiedene Dinge tun und deshalb beide hier stehen:

   `font-kerning: normal` schaltet die Kernpaare der Schrift scharf —
   das sind die paarweisen Feinkorrekturen, die Spectral selbst
   mitbringt (etwa „La" und „He" im Namen). Browser machen das bei
   OpenType zwar meist von sich aus, aber nicht garantiert; explizit
   gesetzt bleibt es auch dann erhalten, wenn ein Wert wie
   `font-feature-settings` an anderer Stelle dazwischenfunkt.

   `letter-spacing` öffnet zusätzlich die Laufweite über alle Buchstaben
   gleichmäßig. Der Wert ist die Stellschraube, an der sich das Schriftbild
   am schnellsten regeln lässt: höher = luftiger. */
.header__titel {
  font-weight: 700;
  font-kerning: normal;
  letter-spacing: 0.03em;

  /* Der Zeilenabstand der Wortmarke — gezielt hier, NICHT am Token.

     Bis zum 07.08.2026 erbte die Wortmarke `--line-height-body` (1,6)
     vom `body`: bei 20 px Schrift also 32 px Grundlinienabstand. Bricht
     „Land der Hildegard" neben dem Signet um, standen die zwei Zeilen
     damit 32 px auseinander und der Block war 64 px hoch — Carlo:
     „müsste auch deutlich niedriger sein, sodass es fein aussieht".

     1,1 ist nachgerechnet, nicht geschätzt. Gemessen mit
     `TextMetrics.actualBoundingBox…` an Spectral 700, 20 px:
     Unterlänge von „Land der" 0,2 px, Oberlänge von „Hildegard" 15,0 px
     — zusammen 15,2 px Tinte. Bei 1,1 sind es 22 px Grundlinienabstand,
     also 6,8 px Luft. Selbst 1,0 wäre kollisionsfrei (4,8 px); 1,1
     lässt Reserve, falls die Wortmarke im Panel je länger wird.

     ⚠ Nicht `--line-height-heading` (1,15) benutzen: Das Token trägt
     jede h2 und h3 auf allen Seiten. Hier soll genau eine Stelle
     enger werden. */
  line-height: 1.1;
}

/* Trägt das eingebettete SVG genauso wie ein hochgeladenes Bild.
   Beim Vektor bestimmt die Breite die Größe, die Höhe folgt dem
   Seitenverhältnis aus der viewBox. */
.header__signet {
  display: block;
  width: 2.25rem;
  height: auto;
  color: var(--color-primary);
}

.header__signet svg {
  width: 100%;
  height: auto;
}

.nav {
  display: none;
}

/* Der waagerechte Abstand war bis zum 07.08.2026 1.25rem (20 px).
   Carlo: „Der Abstand bei der Navigation könnte schmaler sein" — und er
   war zugleich die Hälfte des Umbruchproblems: 8 Fugen × 8 px sparen
   64 px. Die senkrechte Fuge bleibt bei 0.25rem; sie greift nur, wenn
   doch einmal umgebrochen wird, und ist dort kein Gestaltungsmittel,
   sondern eine Notmaßnahme. */
.nav__list {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem 0.75rem;
  list-style: none;
}

/* Keine Unterkante hier: Den Strich zeichnet die animierte ::after-Linie
   in animationen.css (wächst von links auf). Eine zusätzliche
   border-bottom ergäbe zwei Linien übereinander. Sie diente auch nicht
   als Platzhalter — sie war in beiden Zuständen 2 px hoch und hat nur
   die Navigation um 2 px höher gemacht. */
.nav__link {
  display: inline-block;
  padding-block: 0.35rem;
  font-size: var(--font-size-nav);
  color: var(--color-text);
  text-decoration: none;
}

.nav__link:hover,
.nav__link:focus-visible {
  color: var(--color-primary);
}

/* Der Bereich, in dem man gerade steht (gesetzt von animationen.js).
   Nur die Farbe wechselt, KEINE Schriftstärke: Ein fetterer Text wäre
   breiter, die Navigation bräche anders um, der Kopf würde höher — und
   damit spränge bei jedem Bereichswechsel die halbe Seite. Den Strich
   darunter zieht animationen.css, dieselbe Linie wie beim Überfahren.
   Bordeaux auf Elfenbein steht bei 8,85:1. */
.nav__link[aria-current] {
  color: var(--color-primary);
}

/* Die waagerechte Navigation erscheint ab 61.25rem (980 px) statt ab
   60rem (960 px). Zwei Schritte Unterschied, und sie schließen die
   letzte Lücke: Mit den engeren Abständen und der Stufe kleinerer
   Schrift passen die neun Punkte ab 980 px einzeilig — bei 960 und 970
   fehlten weiterhin wenige Pixel. Dort greift jetzt die aufklappbare
   Navigation, die es ohnehin gibt, statt einer zweizeiligen Leiste.
   ⚠ Der Gegenwert steht weiter unten bei `.nav-burger` / `.nav-mobil`; beide
   Grenzen müssen zusammenbleiben, sonst stehen zwei Navigationen
   nebeneinander oder keine. */
@media (min-width: 61.25rem) {
  .nav {
    display: block;
  }
}

/* =========================================================================
   Burger-Navigation auf schmalen Bildschirmen (13.08.2026)
   Loest die Aufklappzeile „Bereiche dieser Seite" ab.

   Die Grundstellung dieses Blocks ist der Zustand OHNE JavaScript:
   kein Knopf, Navigation offen und lesbar. Alles, was den Knopf
   sichtbar macht und die Liste zuklappt, steht in
   `@media (scripting: enabled)`. Browser ohne Kenntnis dieser Abfrage
   landen damit automatisch im bedienbaren Zustand — genau die richtige
   Richtung fuer einen Rueckfall.
   ========================================================================= */

.nav-burger {
  display: none;
}

/* Drei Balken, gebaut statt geladen. `currentColor` haelt sie an der
   Textfarbe des Knopfes; damit stimmt der Kontrast automatisch mit dem
   Wort daneben ueberein.

   Masse: 3 x 2 px Balken, 4 px Fuge = 14 px hoch. Daraus ergeben sich
   die 6 px Versatz im Kreuz weiter unten (halbe Gesamthoehe minus halbe
   Balkenhoehe) — wer die Fuge aendert, muss sie mitziehen. */
.nav-burger__icon {
  display: grid;
  gap: 4px;
  width: 1.375rem;
}

.nav-burger__icon span {
  display: block;
  height: 2px;
  background: currentColor;
  border-radius: 1px;
  transition:
    transform 180ms ease-out,
    opacity 120ms ease-out;
}

/* Geoeffnet wird aus dem Burger ein Kreuz. Der Zustand haengt an
   `aria-expanded` und nicht an einer eigenen Klasse: So kann das Bild
   gar nicht auseinanderlaufen mit dem, was angesagt wird. */
.nav-burger[aria-expanded="true"] .nav-burger__icon span:nth-child(1) {
  transform: translateY(6px) rotate(45deg);
}

.nav-burger[aria-expanded="true"] .nav-burger__icon span:nth-child(2) {
  opacity: 0;
}

.nav-burger[aria-expanded="true"] .nav-burger__icon span:nth-child(3) {
  transform: translateY(-6px) rotate(-45deg);
}

/* Der Ruhemodus ist bereits global geregelt: Der Block
   `@media (prefers-reduced-motion: reduce)` ganz oben setzt
   `transition-duration` auf 0.01ms fuer *, ::before und ::after. Das
   Kreuz erscheint dann sofort statt zu drehen — es verschwindet nicht.
   Deshalb steht hier keine zweite Ausnahme. */

.nav-mobil {
  border-top: 1px solid var(--color-line);
  background: var(--color-ivory);
}

.nav-mobil__list {
  padding-block: 0.5rem 1rem;
  list-style: none;
  display: grid;
  gap: 0.25rem;
}

/* Groessere Trefferflaeche als in der Kopfleiste: 0.65rem oben und
   unten ergeben mit der Zeilenhoehe rund 45 px — ueber den 44 px, die
   als Fingermass gelten, und weit ueber WCAG 2.5.8 (24 px).
   `inline-block` bleibt bewusst stehen: Der wachsende Unterstrich aus
   animationen.css spannt sonst ueber die volle Panelbreite statt unter
   das Wort. */
.nav-mobil .nav__link {
  padding-block: 0.65rem;
}

@media (scripting: enabled) {
  .nav-burger {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    flex: none;
    /* Trefferflaeche: gemessen 89 x 44 px. Die 44 kommen aus
       `min-height`, nicht aus dem Innenabstand — Symbol und Wort sind
       zusammen nur rund 16 px hoch, und ein Innenabstand, der das
       ausgleicht, wuerde beim naechsten Schriftwechsel wieder
       daneben liegen. WCAG 2.5.8 verlangt 24 x 24; 44 ist das
       gebraeuchliche Fingermass und hier ohne Folgen fuer die
       Kopfhoehe (--header-min steht auf 72 px).

       Der negative Aussenabstand nimmt den Innenabstand rechts wieder
       heraus, damit der Knopf optisch buendig mit dem Seitenrand
       abschliesst, die Trefferflaeche aber darueber hinausreicht. */
    min-height: 2.75rem;
    padding: 0.6rem 0.65rem;
    margin-inline-end: -0.65rem;
    border: 0;
    border-radius: var(--border-radius);
    background: none;
    font-family: var(--font-family-body);
    font-size: var(--font-size-nav);
    /* Bordeaux auf Elfenbein: 8,85:1 — dieselbe Rechnung wie bei der
       Kopfnavigation, siehe :root. */
    color: var(--color-primary);
    cursor: pointer;
  }

  /* Zugeklappt ist die Grundstellung, sobald JavaScript laeuft. Kein
     `hidden`-Attribut im HTML, sondern hier im CSS: Sonst haette die
     Seite ohne JavaScript eine dauerhaft versteckte Navigation, und
     mit JavaScript blitzte die offene Liste auf, bis das Skript sie
     zuklappt (`defer` laeuft nach dem Aufbau des Dokuments). */
  .nav-mobil {
    display: none;
    /* Ausgeklappt legt sich das Menue UEBER die Seite, statt sie nach
       unten zu schieben. Zwei Gruende: Der Inhalt springt nicht weg,
       und die gemessene Kopfhoehe (--header-height, Grundlage von
       scroll-margin-top) bleibt konstant — die Rueckkopplung aus F1
       kann so gar nicht erst entstehen. Der klebende `.header` ist ein
       positioniertes Element und damit bereits der Bezugsrahmen. */
    position: absolute;
    inset-inline: 0;
    top: 100%;
    /* Zehn Punkte passen auf jedes Telefon; wird die Seite laenger,
       rollt das Menue in sich statt aus dem Bild zu laufen. `dvh`
       rechnet die eingeblendete Browserleiste mit. */
    max-height: calc(100dvh - var(--header-min) - 1rem);
    overflow-y: auto;
    overscroll-behavior: contain;
    box-shadow: 0 10px 24px rgba(36, 31, 29, 0.16);
  }

  .nav-mobil.is-offen {
    display: block;
  }
}

@media (min-width: 61.25rem) {
  /* Knopf und Menue verschwinden gemeinsam — sonst bliebe eine zweite,
     gleichnamige Navigationslandmarke neben der echten stehen (M2)
     oder ein Knopf ohne Aufgabe.
     ⚠ Dieselbe Grenze wie oben bei `.nav` — siehe die Begründung dort.
     `.is-offen` muss mitgenannt werden: Wer das Menue schmal oeffnet
     und dann das Fenster aufzieht, haette sonst beide Navigationen. */
  .nav-burger,
  .nav-mobil,
  .nav-mobil.is-offen {
    display: none;
  }
}

/* =========================================================================
   Titelbild
   ========================================================================= */

.hero {
  position: relative;
  background: var(--color-taupe);

  /* Wo die SICHTBARE Welle unter dem Titelbild beginnt, gemessen vom
     unteren Rand des Kopfbereichs.

     Das ist nicht dasselbe wie --welle-hoehe, und genau daran ist der
     Bildnachweis in die Welle gerutscht (Feedback 2026-08-05-2310-o92829).
     Zwei Änderungen haben das Band wachsen lassen, ohne dass der Kasten
     davon erfahren hat:

       cc5a1da  gab der Hero-Welle „form 3" mit mass 1.10
       a9a67a7  zog die viewBox auf 212 statt 149 Einheiten (Faktor 1.423)

     Das Band ist seither --welle-hoehe × 1.423 × 1.10 = 1,565 mal so
     hoch wie sein Name sagt. Von dieser Bandhöhe sind die oberen rund
     30 % durchsichtig — dort liegt beim Titelbild das Foto, denn die
     Zierbahn beginnt erst darunter. Gemessen am rechten Bildrand, wo
     der Kasten hängt und die Kurve am höchsten läuft: 33,4 % bei
     320 px, 29,7 % bei 1400 px, dazwischen gleichmäßig fallend.

     1,565 × 0,70 = 1,096 — aufgerundet 1,1. Diese eine Zahl beschreibt
     also die Oberkante der sichtbaren Welle, und sie trägt über die
     ganze Breitenspanne: der Abstand darüber bleibt konstant, statt von
     +4 px auf −2 px zu kippen.

     ⚠ Wer in site/snippets/hero.php die „form" der Welle ändert, ändert
     das mass und damit diese Zahl. Die fünf Formen stehen in
     site/snippets/welle.php unter $formen. */
  --hero-wellenkante: calc(var(--welle-hoehe) * 1.1);
}

/* `width: 100%` ist hier keine Selbstverständlichkeit, sondern die
   Reparatur eines echten Fehlers (05.08.2026):

   Ein Block mit `aspect-ratio`, dessen Breite `auto` ist, gilt dem
   Browser in BEIDEN Achsen als automatisch bemessen. Greift dann die
   `max-height`, rechnet er die Breite über das Seitenverhältnis
   zurück — der Kasten wird SCHMALER statt nur flacher und steht
   linksbündig im Band. Sichtbar wird das, sobald das Fenster breiter
   ist als 70vh × 21/9, also etwa ab dem 1,63-fachen seiner Höhe. Auf
   einem 4K-Schirm in voller Breite fehlten so rund 570 px rechts
   (gemessen: 2515 statt 3008 px bei 3008 × 1540).

   Mit einer ausdrücklichen Breite ist die Inline-Achse fest, das
   Verhältnis wirkt nur noch in eine Richtung, und die `max-height`
   deckelt ausschliesslich die Höhe. Die Breite bleibt voll — genau so
   soll der Kopfbereich auf grossen Schirmen laufen.

   Die 70vh sind die Obergrenze, damit der Kopfbereich auf hohen
   Schirmen nicht die ganze Seite verschluckt: Es bleiben immer 30 vh
   für den Anfang des Einstiegstextes. Auf üblichen Fenstern bindet
   sie gar nicht, dort gibt das Seitenverhältnis die Höhe vor. */
/* Das Seitenverhältnis wächst mit, je schmaler das Fenster wird.
 *
 * Der Bildnachweis ist ein Kasten fester Größe — rund 258 × 65 px, drei
 * Zeilen Text, die nicht kleiner werden dürfen. Das Titelbild dagegen
 * schrumpft mit der Fensterbreite: Bei 16/9 sind auf einem 320 px
 * breiten Schirm nur noch 180 px Höhe übrig, und der Kasten deckte davon
 * 29 % der Fläche zu. Gemessen: 29,3 % bei 320 px, 19,7 % bei 390 px.
 *
 * Ein festes Verhältnis kann das nicht auffangen, weil der Kasten eben
 * nicht mitskaliert. Deshalb wird das Bild nach unten hin hochformatiger
 * — 4/3 auf dem Telefon, 3/2 auf dem Tablet, 21/9 am Schreibtisch. Die
 * Bildwirkung bleibt in jeder Stufe die eines Panoramas, nur der
 * Ausschnitt ist enger. `max-height: 70vh` deckelt weiterhin. */
.hero__media {
  position: relative;
  width: 100%;
  aspect-ratio: 4 / 3;
  max-height: 70vh;
  overflow: hidden;
}

@media (min-width: 30rem) {
  .hero__media {
    aspect-ratio: 3 / 2;
  }
}

/* `object-position` setzt site/snippets/hero.php aus dem im Panel
   gepflegten Fokuspunkt — hier steht nur der Rückfall für den Fall,
   dass keiner hinterlegt ist. Kirbys eigener Fokus greift beim
   Zuschneiden der Datei (`crop`), unsere Titelbilder werden aber nur
   skaliert und erst im Browser beschnitten. Deshalb dieser Weg. */
.hero__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 50%;
}

/* Der Bildnachweis sitzt über der Welle, nicht dahinter */
.hero__credit {
  position: absolute;
  z-index: 2;
  right: 0.5rem;
  /* Über der sichtbaren Wellenkante, nicht über der nominellen
     Bandhöhe — Herleitung bei --hero-wellenkante oben. Hier stand bis
     zum 07.08.2026 `calc(var(--welle-hoehe) + 0.25rem)`; das war
     richtig, solange das Band genau --welle-hoehe hoch war (Stand
     c6a9e10), und ist seit cc5a1da/a9a67a7 zu tief.

     0.5rem statt der früheren 0.25rem: Carlo hat ausdrücklich „genug
     Abstand" verlangt, und der Kasten steht über einem Foto, nicht über
     einer ruhigen Fläche. Ergibt gemessen 9 bis 11 px Luft bis zur
     Zierbahn — bei jeder Breite von 320 bis 1600 px. */
  bottom: calc(var(--hero-wellenkante) + 0.5rem);
  /* Das Innenmaß steht bewusst NICHT hier, sondern in bildnachweis.css —
     der Kasten trägt seit dem 05.08.2026 zwei Zeilen und braucht mehr
     Luft. Eine Angabe an beiden Orten hätte die hiesige wirkungslos
     gemacht (bildnachweis.css lädt später). */
  font-size: var(--font-size-body-xs);
  color: var(--color-white);
  /* Deckend statt halbtransparent: Das Titelbild wird gewuerfelt, und
     ueber hellen Bildstellen kam der Kasten nur auf 4,3:1. Bordeaux
     liefert unabhaengig vom Foto 11,3:1 und passt zum Erscheinungsbild. */
  background: var(--color-bordeaux);
  border-radius: 3px;
}

/* --- Pfeile zum Durchblättern (13.08.2026) -------------------------------

   Entscheidung aus dem Call: „Nur Pfeile (links/rechts), kein
   Punkte-Indikator; automatisches Shuffeln bleibt aktiv." Der Grund ist
   der schmale Schirm — Punkte UND Pfeile überladen ein Bildband, unter
   dem ohnehin schon der Nachweiskasten hängt.

   Ohne JavaScript stünden hier zwei Knöpfe ohne Wirkung: Das Blättern
   tauscht `src`, `srcset`, `alt` und `object-position` am einzigen
   <img>. Die Grundstellung ist deshalb `display: none`, sichtbar werden
   sie erst in `@media (scripting: enabled)` — dieselbe Bauweise wie
   beim Burgermenü weiter oben.                                          */

.hero__pfeil {
  display: none;
}

@media (scripting: enabled) {
  .hero__pfeil {
    position: absolute;
    z-index: 2;
    display: flex;
    align-items: center;
    justify-content: center;

    /* Senkrecht mittig im Bildband, NICHT unten: Dort liegen der
       Bildnachweis (rechts) und die Welle (über die volle Breite).
       Bei 320 px ist das Band 240 px hoch, die Mitte also 120 px —
       weit über der Wellenkante. */
    top: 50%;
    transform: translateY(-50%);

    /* 44 × 44 px, das gebräuchliche Fingermaß; WCAG 2.5.8 verlangt
       24 × 24. Eine Größe für alle Breiten: Der Knopf soll auf dem
       Telefon nicht kleiner sein als am Schreibtisch — dort wird er
       mit dem Daumen getroffen, hier mit der Maus. */
    width: 2.75rem;
    height: 2.75rem;
    padding: 0;
    border: 0;
    border-radius: 50%;

    /* Deckendes Bordeaux statt eines durchscheinenden Knopfes — dieselbe
       Begründung wie beim Bildnachweis darunter: Das Titelbild wird
       gewürfelt, über hellen Bildstellen bliebe von einem
       halbtransparenten Knopf nichts übrig. Weiß auf #780231 sind
       11,34:1, unabhängig davon, welches Foto gerade läuft. */
    background: var(--color-bordeaux);
    color: var(--color-white);
    cursor: pointer;
    transition: filter 150ms ease-out;
  }

  .hero__pfeil:hover {
    filter: brightness(1.3);
  }

  /* Der globale Fokusring ist Moosgrün mit 3 px Abstand — er läge damit
     auf dem Foto, und wie gut er dort zu sehen ist, entscheidet das
     zufällig gewürfelte Bild. Der weiße Innenring macht die Sache
     bildunabhängig: Weiß auf Bordeaux 11,34:1, Weiß auf Moosgrün
     5,35:1. Beide Kanten sind damit immer da. */
  .hero__pfeil:focus-visible {
    outline-offset: 2px;
    box-shadow: 0 0 0 2px var(--color-white);
  }

  .hero__pfeil--zurueck {
    left: 0.5rem;
  }

  .hero__pfeil--vor {
    right: 0.5rem;
  }
}

/* Auf Papier gibt es nichts zu blättern. */
@media print {
  .hero__pfeil {
    display: none;
  }
}

@media (min-width: 48rem) {
  .hero__media {
    aspect-ratio: 21 / 9;
  }
}

/* =========================================================================
   Einstiegstext
   ========================================================================= */

.intro {
  padding-block: var(--padding-vertical);
}

/* Die Hauptüberschrift der Startseite. Der Umbruch nach „Das Land der
   Hildegard" kommt aus dem <span>, das site/templates/home.php um
   „von Bingen" legt — nicht aus einer geratenen Breite in ch. */
.intro__h1 {
  /* Optischer Randausgleich für das „D".

     Gemessen am 07.08.2026 (Feedback 2026-08-05-2309-7zwf5k): Spectral
     600 legt vor das „D" eine Seitenlage von 0,052 em — bei jeder
     Schriftgröße gleich, geprüft von 36 bis 72 px. Die Überschrift
     beginnt damit sichtbar weiter rechts als alles darunter: bei
     1280 px Fensterbreite 3,38 px vom Rand des Textblocks, während der
     Absatz darunter (Archivo) bei 2,00 px anfängt und die zweite
     Zeile „von Bingen" sogar 2,00 px nach LINKS übersteht — das „v"
     hat eine negative Seitenlage von 0,031 em. Zwischen den beiden
     Zeilen der Überschrift lagen also 5,4 px. Das ist das
     „aus der Reihe tanzen".

     Die Zahl ist nicht geraten: Sie IST die gemessene Seitenlage. Damit
     steht die Tinte des „D" genau auf der Kante des Textblocks — also
     2 px links vom Absatz und 2 px rechts vom „v" der zweiten Zeile,
     mittig zwischen seinen beiden Nachbarn.

     `text-indent` und nicht `margin`: Die Korrektur gilt nur der ersten
     Zeile. Ein negativer Rand zöge „von Bingen" mit und schöbe die
     Zeile, die ohnehin schon übersteht, noch weiter hinaus.

     In em, damit es mit clamp() mitwächst. Bei 320 px sind das 1,87 px
     bei 16 px Innenabstand des Textblocks — es entsteht kein Überlauf,
     nachgemessen in 20er-Schritten von 320 bis 1600 px.

     07.08.2026, Carlos Nachjustierung: -0.072em statt -0.052em. */
  text-indent: -0.072em;

  /* Engere Zeilen, nur hier.

     Carlo hat 1,05 am 06.08.2026 selbst ausprobiert und „deutlich
     angenehmer" gefunden (Meldung 2026-08-06-2328-wize6o). Nachgerechnet
     für Spectral 600 bei 72 px, kritischste Paarung mit den Umlautpunkten
     auf „ä": Grundlinienabstand 75,6 px, Luft zwischen der Tinte
     20,9 px — kollisionsfrei.

     ⚠ Gezielt hier und NICHT am Token `--line-height-heading`. Das Token
     trägt jede h2 und h3 auf allen Seiten, also auch die 21
     Eintragsüberschriften. Carlo ausdrücklich: „für die Hauptseite NUR
     die Lineheit setzen". Ob die Rechtstextseiten sie auch bekommen
     sollen, ist offen — dort war von Abstand und Randausgleich die Rede,
     nicht von der Zeilenhöhe. */
  line-height: 1.05;

  /* „Hildegard" darf nirgends getrennt werden, auch mobil nicht.
     Die allgemeine Regel für h1–h3 setzt hyphens: auto — hier nicht. */
  hyphens: manual;
  /* text-wrap: balance verteilt die Zeilen gleichmäßig und arbeitet
     damit gegen den gesetzten Umbruch. */
  text-wrap: wrap;
}

@media (min-width: 60rem) {
  .intro__h1-zeile {
    display: block;

    /* Ab hier wird „von Bingen" ein eigener Block — und erbt damit das
       text-indent der Überschrift, rückt also mit ein. Genau das soll
       der Ausgleich nicht: Er gilt allein dem „D" der ersten Zeile.
       Das „v" bringt seine eigene (negative) Seitenlage schon mit. */
    text-indent: 0;
  }
}

.intro__teaser {
  margin-top: 1.5rem;
  font-size: var(--font-size-lead);
  color: var(--color-primary);
  max-width: var(--content-width-text);
}

.intro__text {
  margin-top: 1.5rem;
  max-width: var(--content-width-text);
}

.intro__text > * + * {
  margin-top: 1rem;
}

/* =========================================================================
   Ausklapp-Einträge
   ========================================================================= */

.entries {
  display: grid;
  gap: 0.75rem;
}

/* Der Halter der Abkürzung „Alle Einträge öffnen". Er sitzt im
   `.section__head` und wird dort von `space-between` an die rechte
   Kante gestellt — an dieselbe, an der auch die Karten enden. Abstände
   regelt der Kopf (`row-gap`), hier steht bewusst keiner. */
.entries__werkzeuge {
  display: flex;
}

/* Der Knopf ist bewusst zurückhaltend: eine Abkürzung für Geübte, kein
   Aufruf zum Handeln. Er trägt KEINE Klasse `extern` — er führt nirgends
   hin und dürfte deshalb auch keinen Pfeil tragen (siehe Abschnitt
   „Ausgehende Links" weiter unten).

   Das Innenmaß bringt die Zielfläche über die 24 px aus WCAG 2.2
   (2.5.8): 15 px Schrift × 1,6 Zeilenhöhe = 24 px, plus 2 × 0,35rem
   Innenabstand. Wer die Schriftgröße hier ändert, rechnet das nach. */
.alle-oeffnen {
  background: none;
  border: 0;
  padding-inline: 0;
  padding-block: 0.35rem;
  font-family: inherit;
  font-size: var(--font-size-body-sm);
  line-height: 1.6;
  color: var(--color-primary);
  text-decoration: none;
  cursor: pointer;
}

/* Feste Unterstreichung beim Überfahren statt der aufwachsenden Linie
   aus animationen.css. Grund: Diese Linie hängt dort an einer Liste von
   Selektoren, und jeder weitere Eintrag koppelt eine Datei mehr an die
   Ladereihenfolge — genau das hat heute schon beim Widerrufsknopf in der
   Fußzeile Ärger gemacht. Hier bleibt alles in einer Datei. */
.alle-oeffnen:hover {
  text-decoration: underline;
  text-underline-offset: 0.15em;
  text-decoration-thickness: 2px;
}

/* Die Karten heben sich vom Band ab. Auf weißem Grund wechseln sie
   deshalb auf den Sandton — sonst verschwände die Kante. */
.entry {
  background: var(--karten-farbe, var(--color-surface));
  /* Kraeftiger als die allgemeine Linienfarbe (0,16 = 1,4:1): 20 Karten
     untereinander verschwimmen sonst zu einem Block. 0,35 ergibt rund
     2,3:1 und laesst die einzelne Karte erkennen (M5). */
  border: 1px solid rgba(36, 31, 29, 0.35);
  border-radius: var(--border-radius);
  overflow: hidden;
}

.entry[open] {
  box-shadow: var(--shadow-soft);
}

/* ── Dauerhaft offener Eintrag ──────────────────────────────────────────
   Entsteht, wenn eine Sektion im Panel auf „dauerhaft offen" steht (seit
   dem Teamtermin 05.08.2026, gewollt fuer „Wer war Hildegard von Bingen?").

   Hier faellt die Kartenoptik weg: keine Flaeche, keine Kante, kein Radius,
   kein Schatten. Der Abschnitt soll wie Fliesstext weiterlaufen, nicht wie
   ein geschlossener Kasten wirken — genau das war der Grund fuer die
   Umstellung. Was bleibt, ist der Rhythmus: derselbe Abstand nach unten wie
   zwischen zwei Karten, damit die Sektion nicht aus dem Raster faellt.

   `overflow: hidden` wird ebenfalls zurueckgenommen. Es gehoerte zur
   Kartenkante; ohne Kante schneidet es nur noch Fokusringe ab. */
.entry--offen {
  background: none;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  overflow: visible;
}

/* Ohne Kante muss der Abstand die Trennung allein tragen.
 *
 * Gemessen im iframe von 320 bis 1600 px: Zwischen zwei Eintraegen lagen
 * ueberall genau 12 px — der `gap` von .entries. Zwischen zwei Karten ist
 * das richtig, dort trennt zusaetzlich die Kante. Bei den daueroffenen
 * Eintraegen gibt es keine Kante, und was unmittelbar vor der naechsten
 * Ueberschrift steht, ist je nach Breite der Weiterleitungsknopf (Text
 * links, Bild rechts) oder die Bildunterschrift (alles untereinander).
 * Genau diese zwei Faelle sind aufgefallen — es ist derselbe Fehler, nur
 * von zwei Seiten gesehen.
 *
 * Der Zuschlag kommt als margin-top ZUSAETZLICH zum gap: So wird der
 * Abstand groesser und an keiner Stelle kleiner. 0,75rem + 1,5rem
 * ergeben 36 px zwischen den Eintraegen, waehrend die Karten in den
 * Ausklapp-Sektionen bei ihren 12 px bleiben. */
.entry--offen + .entry--offen {
  margin-top: 1.5rem;
}

/* Die Ueberschrift traegt hier, was sonst im <summary> steckt — dieselbe
   Schrift und Groesse, damit beide Darstellungen als eine Familie lesbar
   bleiben. Ohne den Innenabstand des Kastens, aber mit Luft nach unten. */
.entry__titel {
  margin: 0 0 0.75rem;
  font-family: var(--font-family-heading);
  font-size: var(--font-size-h3);
  /* Gleiche Größe, gleiche Laufweite — siehe :root, `--laufweite-h1`. */
  letter-spacing: var(--laufweite-h3);
  color: var(--color-primary);
}

/* Der Rumpf sass im Kasten und brauchte deshalb ringsum Innenabstand.
   Ohne Kasten waere er eine willkuerliche Einrueckung. */
.entry--offen .entry__body {
  padding: 0;
}

.entry__summary {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 1rem 1.25rem;
  font-family: var(--font-family-heading);
  font-size: var(--font-size-h3);
  /* Gleiche Größe, gleiche Laufweite — siehe :root, `--laufweite-h1`. */
  letter-spacing: var(--laufweite-h3);
  color: var(--color-primary);
  cursor: pointer;
  list-style: none;
}

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

/* Der Ortsname steckt in einem <h3> — das ist eine Frage der Vorlesbarkeit,
   nicht der Optik. Die Ueberschrift erbt deshalb alles vom Summary. */
.entry__summary h3 {
  font: inherit;
  color: inherit;
  margin: 0;
}

.entry__summary::after {
  content: "";
  flex: none;
  margin-left: auto;
  width: 0.7rem;
  height: 0.7rem;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg) translate(-0.15em, -0.15em);
  transition: transform 0.2s ease;
}

.entry[open] .entry__summary::after {
  transform: rotate(225deg) translate(-0.1em, -0.1em);
}

.entry__summary:hover {
  background: rgba(120, 2, 49, 0.04);
}

/* Ist der Eintrag offen, trägt die Kopfzeile dieselbe Fläche wie der
   Inhalt darunter (.entry__body hat keinen eigenen Hintergrund, es
   scheint also .entry durch). Sonst legte sich beim Überfahren ein
   Bordeaux-Schleier nur über die Kopfzeile und die Karte zerfiele
   optisch in zwei Hälften. Geschlossen bleibt der Hover als
   Klick-Einladung unverändert. */
.entry[open] > .entry__summary,
.entry[open] > .entry__summary:hover {
  background: transparent;
}

.entry__logo {
  flex: none;
  width: 3rem;
  height: 3rem;
  object-fit: contain;
}

.entry__body {
  display: grid;
  gap: 1.5rem;
  padding: 0 1.25rem 1.5rem;
}

/* Derselbe Rumpf, aber ohne Karte drumherum — die eigenstaendige
   Textsektion (sektion-text.php, zurzeit der Pilgerwanderweg). Der
   seitliche Innenabstand oben gehoert zur Kartenkante; frei im Abschnitt
   ist er eine Einrueckung ohne Anlass. Gemessen am 05.08.2026: Der Text
   stand bei 996 px, die eigene Ueberschrift bei 976 px — 20 px
   auseinander, ohne dass etwas diese Stufe erklaert haette.

   Das ist dieselbe Ruecknahme, die `.entry--offen .entry__body` fuer den
   dauerhaft offenen Eintrag macht. Der Abstand nach unten bleibt: Er
   trennt den Text vom naechsten Abschnitt und haengt nicht an der Karte.

   Steht bewusst NACH `.entry__body` — gleiche Spezifitaet, es entscheidet
   die Reihenfolge. Wer die Regel nach oben schiebt, schaltet sie ab. */
.entry__body--frei {
  padding-inline: 0;
}

.entry__text > * + * {
  margin-top: 0.75rem;
}

@media (min-width: 48rem) {
  .entry__body {
    grid-template-columns: 1fr 1fr;
    align-items: start;
  }

  .entry__body--single {
    grid-template-columns: 1fr;
    max-width: var(--content-width-text);
  }
}

/* --- Papier ---------------------------------------------------------------
   Geschlossene Ausklapper drucken leer. Auf Papier gibt es kein
   Aufklappen, also steht alles offen da.

   Das hier ist die Grundlage, die auch ohne JavaScript wirkt.
   animationen.js legt zusätzlich vor dem Druck alle <details> auf und
   stellt die Fotos von `lazy` auf `eager` — ohne das blieben die
   Bildflächen weiß, weil nie geladene Bilder auch nicht gedruckt werden.

   Zwei Regeln, weil die Browser den verborgenen Inhalt verschieden
   lösen: ältere über die Anzeige des Kindelements, neuere über das
   Pseudoelement ::details-content. Getrennt notiert — ein Selektor, den
   ein Browser nicht kennt, macht sonst die ganze Regel ungültig. */
@media print {
  .entry:not([open]) > .entry__body {
    display: block;
  }

  .entry::details-content {
    content-visibility: visible;
    display: block;
  }

  /* Der Schalter ist auf Papier sinnlos. */
  .entries__werkzeuge {
    display: none;
  }
}

/* =========================================================================
   Bilder mit Nachweis
   ========================================================================= */

.figure {
  margin: 0;
  position: relative;
}

/* Unscharfe Farbvorschau (LQIP), bis das Foto geladen ist: ein 24 px
   breites WebP als Data-URI, das der Browser weich hochskaliert — rund
   290 Byte pro Bild, erzeugt in site/plugins/ldh-bilder.

   Warum als ::before an der <figure> und nicht als background am <img>:
   Beim Einfaden setzt .img--fade (animationen.css) das gesamte <img> auf
   opacity 0 — damit wäre auch dessen Hintergrund unsichtbar, und zwar
   genau in dem Moment, in dem die Vorschau gebraucht wird. Gemessen an
   der Startseite: alle 20 Bilder tragen .img--fade, keines ist geladen.

   Ohne JavaScript entstehen weder .reveal noch .img--fade; das Foto ist
   dann von Anfang an deckend und verdeckt die Vorschau. Es bleibt also
   nie ein Platzhalter über dem Bild stehen.

   background-color ist der Rückfall, wenn kein LQIP vorliegt (Taupe auf
   Elfenbein aufgehellt — CD-Farbe, reine Fläche, nie Textfarbe).

   WEICHZEICHNER (05.08.2026): 24 Pixel Breite auf rund 500 Pixel
   gezogen macht aus jedem Bildpunkt ein Kästchen von etwa 20 Pixeln.
   Der Browser interpoliert zwar, aber die Kästchen bleiben sichtbar —
   es sah nach kaputtem Bild aus statt nach „lädt noch". `blur` legt
   sich darüber, ohne dass Farbaufbau und Bildaufteilung verlorengehen.

   Die zwei Zeilen darunter sind kein Beiwerk, sondern der Grund, warum
   das sauber aussieht:

   `box-shadow` mit Streuung malt die Rückfallfarbe rings um die
   Fläche. Der Weichzeichner rechnet sonst mit dem Nichts jenseits der
   Kante und die Vorschau franst nach aussen durchsichtig aus — als
   weicher Schleier über dem Farbband. Mit dem Schatten liegt dort
   Material, in das hinein gerechnet werden kann. Die Streuung muss
   grösser sein als die Reichweite des Weichzeichners (etwa das
   Dreifache seines Wertes), sonst bleibt ein Rest Durchsichtigkeit.

   `clip-path` schneidet das Ergebnis wieder exakt auf die Bildkante
   zurück — mit derselben Rundung wie das Foto darüber und, weil
   `inset(0)` immer die eigene Rahmenbox meint, unabhängig vom
   Seitenverhältnis. Es greift NACH dem Weichzeichner (so ist die
   Reihenfolge in der Filter-Spezifikation), schneidet also den
   Schatten und die weiche Kante zusammen ab. */
.figure--vorschau::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  aspect-ratio: var(--lqip-verhaeltnis);
  background-color: var(--ton-4);
  background-image: var(--lqip, none);
  background-size: cover;
  background-position: center;
  border-radius: var(--border-radius);
  box-shadow: 0 0 0 3rem var(--ton-4);
  /* 8 Pixel sind knapp die halbe Kantenlänge eines hochgezogenen
     LQIP-Punktes (rund 15 bis 20 Pixel, je nach Bildbreite). Das
     reicht, um das Raster verschwinden zu lassen, und ist wenig genug,
     dass Bildaufteilung und Farben erhalten bleiben. Mehr — probiert
     mit 14 — wäscht das Bild zu einem blassen Nebel aus. */
  filter: blur(0.5rem);
  clip-path: inset(0 round var(--border-radius));
  pointer-events: none;
}

/* `position: relative` bringt das Foto in der Malreihenfolge über das
   absolut gesetzte ::before — ohne z-index, allein über die
   Dokumentreihenfolge. */
.figure img {
  position: relative;
  width: 100%;
  border-radius: var(--border-radius);
}

/* Auf Papier gibt es keinen Ladevorgang, den die Vorschau überbrücken
   könnte: animationen.js stellt die Fotos für den Druck von `lazy` auf
   `eager`, sie sind also da. Eine unscharfe Farbfläche im Ausdruck sähe
   nach Druckfehler aus und kostet nur Farbe.

   Der andere @media-print-Block (Zeile 727, „Alle öffnen") klappt die
   Einträge auf und blendet den Schalter aus. Beide greifen auf
   verschiedene Selektoren und widersprechen einander nicht. */
@media print {
  .figure--vorschau::before {
    display: none;
  }
}

/* Signet anstelle eines Fotos (Schalter `signet_statt_foto` am Eintrag,
   siehe site/snippets/eintrag.php).

   Das Seitenverhältnis ist nicht geschätzt: Von den 20 Eintragsfotos
   stehen 13 auf genau 3/2, der Median aller 20 liegt ebenfalls bei 1,50.
   Die Fläche ist damit so hoch wie ein übliches Foto an derselben
   Stelle — der Rumpf behält seinen Zweispalter, und die Zeile reißt
   nicht auf.

   Das Signet füllt sie NICHT aus. Es ist eine Grafik mit eigenem
   Freiraum und würde formatfüllend beschnitten oder verzerrt wirken;
   `height: 70%` lässt oben und unten je 15 % Luft. `object-fit: contain`
   ist die Rückversicherung für den Fall, dass `max-width` greift —
   dann darf das Bild schmaler werden, aber nicht verzerren.

   ⚠ `border-radius: 0` hebt die Rundung aus `.figure img` auf: Sie
   gehört zur Fotokante, hier gibt es keine Fläche, die eine Kante
   hätte. */
.figure--signet {
  display: grid;
  place-items: center;
  aspect-ratio: 3 / 2;
}

.figure--signet img {
  width: auto;
  height: 70%;
  max-width: 80%;
  object-fit: contain;
  border-radius: 0;
}

.figure__caption {
  margin-top: 0.5rem;
  font-size: var(--font-size-body-sm);
  color: var(--color-text-muted);
}

.figure__credit {
  font-size: var(--font-size-body-xs);
  color: var(--color-text-muted);
}

/* =========================================================================
   Schaltflächen und Linklisten
   ========================================================================= */

.buttons {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: 1.25rem;
}

.button {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.65rem 1.15rem;
  font-size: var(--font-size-body-sm);
  font-weight: 600;
  color: var(--color-white);
  background: var(--color-primary);
  border: 2px solid var(--color-primary);
  border-radius: var(--border-radius);
  text-decoration: none;
}

.button:hover {
  background: var(--color-white);
  color: var(--color-primary);
}

.button--secondary {
  color: var(--color-primary);
  background: transparent;
}

.button--secondary:hover {
  background: var(--color-primary);
  color: var(--color-white);
}

.linklist {
  display: grid;
  gap: 0.75rem;
  list-style: none;
  max-width: var(--content-width-text);
}

/* Die ganze Karte ist der Knopf — wie beim Ausklapper weiter oben
   (.entry__summary). Technisch bleibt es aber ein Link um den Titel:
   Das <li> in ein <a> zu packen würde den Beschreibungstext in den
   Linknamen ziehen und ihn im Screenreader unbrauchbar lang machen.
   Stattdessen legt der Titel-Link ein unsichtbares Feld über die Karte
   (siehe .linklist__link::before). */
/* Flaeche und Kante wie bei .entry (Sektion „Institutionen") — seit dem
   13.08.2026. Sarah im Termin: Die Kacheln unter „Angebote" seien weiss
   in weiss und heben sich nicht ab; die Institutionen-Kaesten sind das
   Vorbild.

   Deshalb dieselben zwei Werte wie dort, nicht nachempfundene:
   `--karten-farbe` setzt `.band--ton-2` auf den Sandton --ton-3 #f1ece3,
   auf allen anderen Baendern bleibt es bei Weiss — genau wie bei den
   Ausklapp-Karten. Betroffen sind damit die drei Link-Sektionen
   Angebote, Veranstaltungen und Unterkuenfte; sie teilen sich ein
   Snippet (sektion-links.php) und sind identisch aufgebaut.
   Die Kante steigt von --color-line (0,16 = 1,4:1) auf 0,35 (rund
   2,3:1) — der gleiche Wert, der bei .entry begruendet ist (M5). */
.linklist__item {
  position: relative;
  padding: 1rem 1.25rem;
  background: var(--karten-farbe, var(--color-surface));
  border: 1px solid rgba(36, 31, 29, 0.35);
  border-radius: var(--border-radius);
  cursor: pointer;
}

/* Dieselbe Anmutung wie .entry__summary:hover. Als `background-image`
   und nicht als `background`, weil die Grundfläche der Karte erhalten
   bleiben muss — sonst schiene das Farbband der Sektion durch und der
   Schleier fiele viel dunkler aus als beim Ausklapper. */
.linklist__item:hover {
  background-image: linear-gradient(rgba(120, 2, 49, 0.04), rgba(120, 2, 49, 0.04));
}

/* Der Fokusring umschließt die ganze Karte, nicht nur den Titel — sonst
   zeigte die Tastatur ein kleineres Ziel an, als der Klick trifft.
   `:focus-visible` und nicht `:focus-within`: bei der Maus soll kein
   Ring aufblitzen. Werte wie im globalen Ring, nur der Radius bleibt
   der der Karte.

   Die zwei Regeln stehen bewusst getrennt: Kennt ein Browser `:has()`
   nicht, verfällt nur die zweite — der Link behält dann seinen eigenen
   Ring, statt dass gar keiner erscheint. */
.linklist__item:has(.linklist__link:focus-visible) {
  outline: 3px solid var(--color-focus);
  outline-offset: 3px;
}

.linklist__item:has(.linklist__link:focus-visible) .linklist__link {
  outline: none;
}

.linklist__link {
  font-family: var(--font-family-heading);
  font-size: var(--font-size-h3);
  /* Gleiche Größe, gleiche Laufweite — siehe :root, `--laufweite-h1`. */
  letter-spacing: var(--laufweite-h3);
  text-decoration: none;
  /* Bei 320 px faellt die Zeile auf 22 px zusammen (M8). */
  display: inline-block;
  padding-block: 0.15rem;
}

/* Das Klickfeld über der ganzen Karte. `::before`, nicht `::after` —
   das trägt bei diesen Links schon den Pfeil nach draußen.
   PREIS DIESER LÖSUNG: Der Beschreibungstext liegt darunter und lässt
   sich nicht mehr mit der Maus markieren. Bewusst so entschieden — die
   ganze Fläche klickbar zu machen war der ausdrückliche Wunsch. */
.linklist__link::before {
  content: "";
  position: absolute;
  inset: 0;
}

/* Unterstreichung und Pfeil reagieren jetzt auf die ganze Karte, nicht
   nur auf den Titel (der Pfeil in „Ausgehende Links" weiter unten). */
.linklist__item:hover .linklist__link {
  text-decoration: underline;
}

.linklist__description {
  margin-top: 0.25rem;
  font-size: var(--font-size-body-sm);
  color: var(--color-text-muted);
}

/* =========================================================================
   Ausgehende Links

   Diese Seite ist ein Wegweiser — die meisten Links führen vom Hof. Wer
   klickt, soll das vorher sehen. Jeder Link nach draußen trägt deshalb
   die Klasse `extern` und dahinter denselben Pfeil nach rechts oben.
   Gesetzt wird die Klasse an drei Stellen: in weiterleitung.php, in
   sektion-links.php und — für Links mitten im Text — von der
   Feldmethode `externeLinks()` aus site/plugins/ldh-links.

   Warum ein SVG als Maske und kein „↗" im `content`:

     1. Ein Unicode-Zeichen sieht je nach Schrift und Betriebssystem
        anders aus; auf manchen Systemen wird daraus ein buntes Emoji.
     2. `content`-Text wird von einigen Screenreadern vorgelesen. Der
        gesprochene Hinweis kommt bereits aus dem `sr-only`-Text im
        Link — er darf sich nicht verdoppeln. Eine Maske hat keinen
        Text, den irgendjemand vorlesen könnte.
     3. Über `mask-image` + `background-color: currentColor` läuft der
        Pfeil in jedem Farbkontext automatisch mit der Textfarbe mit:
        weiß auf Bordeaux (Knopf, Fußzeile), Bordeaux auf Weiß
        (Linkliste, Knopf im Hover), Dunkelbraun auf Taupe
        (Kontaktbereich). Ein `background-image` wäre in jedem dieser
        Fälle eine eigene Datei.
   ========================================================================= */

:root {
  --extern-pfeil-form: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 10' fill='none' stroke='%23000' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M1.8 8.2 8.2 1.8'/%3E%3Cpath d='M3.7 1.8h4.5v4.5'/%3E%3C/svg%3E");

  /* Drei Stufen, gleiche Form. Groß auf den Knöpfen, weil die die
     eigentliche Handlungsaufforderung sind; mittel in den Linklisten;
     klein im Fließtext, wo der Pfeil den Lesefluss nicht stören soll.
     Gemessen: 18,4 px — 15,2 px — 12 px. */
  --extern-pfeil-gross: 1.15rem;
  --extern-pfeil-mittel: 0.95rem;
  --extern-pfeil-klein: 0.75rem;
}

.extern::after {
  content: "";
  display: inline-block;
  /* Eine Größe, drei Stufen — gesetzt wird nur diese eine Eigenschaft.
     Der Standardwert ist die kleine Stufe für Links im Fließtext. */
  width: var(--extern-pfeil, var(--extern-pfeil-klein));
  height: var(--extern-pfeil, var(--extern-pfeil-klein));
  margin-inline-start: 0.3em;
  /* Etwas über die Grundlinie heben, damit der Pfeil optisch in der
     Mitte der Kleinbuchstaben sitzt und nicht am Boden klebt. */
  vertical-align: 0.02em;
  background-color: currentColor;
  mask-image: var(--extern-pfeil-form);
  mask-repeat: no-repeat;
  mask-position: center;
  mask-size: contain;
  -webkit-mask-image: var(--extern-pfeil-form);
  -webkit-mask-repeat: no-repeat;
  -webkit-mask-position: center;
  -webkit-mask-size: contain;
  transition: transform 0.15s ease-out;
}

.button.extern {
  --extern-pfeil: var(--extern-pfeil-gross);
}

.linklist__link.extern {
  --extern-pfeil: var(--extern-pfeil-mittel);
}

/* Der Knopf ist ein Flex-Container: Der Abstand kommt dort schon aus
   `gap`, ein zusätzlicher Rand würde ihn verdoppeln. */
.button.extern::after {
  margin-inline-start: 0;
  flex: none;
}

/* Eine Andeutung von Bewegung — der Pfeil geht ein Stück in die
   Richtung, in die er zeigt. Mehr nicht.

   Die zweite Zeile zieht denselben Effekt auf die ganze Karte der
   Linkliste hoch: Dort ist die komplette Fläche klickbar, also muss sie
   sich auch komplett angesprochen fühlen. */
.extern:hover::after,
.linklist__item:hover .extern::after {
  transform: translate(0.1em, -0.1em);
}

@media (prefers-reduced-motion: reduce) {
  .extern:hover::after,
  .linklist__item:hover .extern::after {
    transform: none;
  }
}

/* =========================================================================
   Kontakt und Fußzeile
   ========================================================================= */

/* Seit dem 13.08.2026 traegt der Kontaktbereich den neuen hellen Grauton
   --ton-5 statt des Taupe. Sarah im Termin: das Gold/Taupe soll raus.

   Damit fallen die zwei Sonderregeln weg, die nur wegen des Taupe
   bestanden — beide sind hier bewusst dokumentiert, damit niemand sie
   „wiederherstellt":

   - Fokusring: Moosgruen #287126 erreicht auf #f2f1ee 5,34:1 (auf Taupe
     waren es 2,28:1 und der Ring fiel durch). Der Bereich braucht deshalb
     keinen eigenen --color-focus mehr, der globale Moosgruen-Ring gilt.
   - Links: Bordeaux #780231 erreicht auf #f2f1ee 10,04:1 (auf Taupe
     4,28:1, knapp unter AA — deshalb standen sie dort in Dunkelbraun).
     Sie laufen jetzt wieder in der Leitfarbe wie im Rest der Seite.
     Die Unterstreichung bleibt: Sie ist WCAG 1.4.1 (Use of Color) und
     haengt nicht am Untergrund.

   Ueberschrift und Lesetext: Dunkelbraun #241f1d auf #f2f1ee 14,43:1. */
.contact {
  background: var(--ton-5);
  padding-block: var(--padding-vertical);
}

.contact h2 {
  color: var(--color-ink);
}

.contact a {
  color: var(--color-primary);
  text-decoration: underline;
}

.contact__body {
  margin-top: 1rem;
  max-width: var(--content-width-text);
}

.contact__body > * + * {
  margin-top: 0.75rem;
}

.footer {
  padding-block: 2.5rem;
  background: var(--color-bordeaux);
  color: var(--color-white);
  /* Moosgruen auf Bordeaux ergibt 1,9:1 — der Fokusring waere hier
     praktisch unsichtbar. Weiss liefert 11,3:1. */
  --color-focus: var(--color-white);
}

.footer a {
  color: var(--color-white);
  /* WCAG 2.2 (2.5.8) und EN 301 549 wollen mindestens 24 x 24 px
     Zielflaeche. Die Zeilenhoehe allein ergibt hier 18 px (M8). */
  display: inline-block;
  padding-block: 0.25rem;
}

.footer__inner {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem 2rem;
  justify-content: space-between;
  align-items: center;
}

.footer__links {
  display: flex;
  flex-wrap: wrap;
  gap: 1.25rem;
  list-style: none;
  font-size: var(--font-size-body-sm);
}

/* =========================================================================
   Rechtliche Seiten
   ========================================================================= */

.legal {
  padding-block: var(--padding-vertical);
}

/* Die Überschrift der Rechtstextseiten — drei Korrekturen aus dem
   Rückmeldewerkzeug, Meldung 2026-08-06-2328-wize6o.

   Bewusst hier unter `.legal` und NICHT in der allgemeinen h1-Regel
   weiter oben: Dort träfe jede Änderung auch Überschriften, über die
   niemand gesprochen hat. Die Startseite hat ihre eigene Regel
   (`.intro__h1`) und bleibt davon ebenfalls unberührt. */
.legal h1 {
  /* 1 — Abstand zum Text darunter.
     Gemessen war er exakt 0 px, über die ganze Breitenreihe: Die globale
     h1-Regel setzt keinen unteren Rand, und `.legal__text` beginnt
     unmittelbar an der Unterkante. Auf der Startseite sind es 24 px
     (`.intro__teaser { margin-top: 1.5rem }`), und Carlo dazu: „da finde
     ich den Abstand nach unten gut". Also derselbe Wert, damit beide
     Seiten denselben Takt haben. */
  margin-bottom: 1.5rem;

  /* 2 — Optischer Randausgleich, dieselbe Korrektur wie auf der
     Startseite (`.intro__h1`, hergeleitet in d770078).

     Der Wert ist NICHT geraten und auch nicht Carlos „minus 0,08 oder
     sowas" aus dem Diktat: 0,072 em IST die gemessene Seitenlage von
     Spectral 600 vor einer Versalie, bei jeder Schriftgröße gleich.
     Geometrisch stehen Überschrift und Fließtext ohne die Korrektur
     beide auf derselben Kante — die Tinte der großen Versalie beginnt
     aber sichtbar weiter rechts. In em, damit es mit clamp() mitwächst.

     Kein Überlauf: über 320–1600 px in 20er-Schritten nachgemessen,
     waagerechter Überstand des Dokuments überall 0 px. */
  text-indent: -0.072em;

  /* 3 — Silbentrennung wieder zulassen (Firefox).
     ⚠ Diese Zeile ist ein begründeter Verdacht, KEINE Messung: Carlo
     sieht in Firefox 153 „Barrierefrei | heitserklärung" — zwei Zeilen
     mitten im Wort OHNE Bindestrich. `hyphens: auto` ist gesetzt und
     greift in Chrome einwandfrei (dort: mit Bindestrich). Die
     naheliegende Erklärung ist, dass Firefox die Trennung unterdrückt,
     solange es die Zeilen ausbalanciert.

     `wrap` statt `balance` nimmt ihm diesen Grund. In Chrome ändert es
     an der Zeilenverteilung nichts — über die ganze Breitenreihe
     dasselbe Zeilenprofil, nachgemessen. Die Startseite hat aus einem
     anderen Grund längst `text-wrap: wrap` (dort arbeitet balance gegen
     den gesetzten Umbruch).

     ⚠ In Firefox UNGEPRÜFT — diese Umgebung fährt Chrome. Wirkt es
     dort nicht, ist der robuste Weg ein weiches Trennzeichen im Titel
     (`&shy;`), das jede Engine befolgt. */
  text-wrap: wrap;
}

.legal__text {
  max-width: var(--content-width-text);
}

.legal__text > * + * {
  margin-top: 1rem;
}

/* Sicherheitsnetz: Sollte doch einmal eine rohe Adresse als Linktext
   im Text landen, schiebt sie die Seite auf schmalen Bildschirmen nicht
   mehr waagerecht auf. */
.legal__text a {
  overflow-wrap: break-word;
  /* Zielflaeche auf 24 px bringen (M8) — inline-block waere hier falsch,
     weil ein Link im Fliesstext dann nicht mehr umbricht. */
  padding-block: 0.25rem;
}

.legal__text h2 {
  margin-top: 2.5rem;
  font-size: var(--font-size-h3);
  /* Gleiche Größe, gleiche Laufweite — siehe :root, `--laufweite-h1`. */
  letter-spacing: var(--laufweite-h3);
}

.legal__text ul,
.legal__text ol {
  padding-left: 1.5rem;
}

.legal__date {
  margin-top: 2.5rem;
  font-size: var(--font-size-body-sm);
  color: var(--color-text-muted);
}
