/* ── icons-subset.css ── */
/* ══════════════════════════════════════════
   Font Awesome: kleine Schrift zuerst, volle als Rückfall
   ──────────────────────────────────────────
   Die Seite lädt auf JEDER Seite fa-solid-900.woff2 (133 KB) und
   fa-brands-400.woff2 (114 KB) — für 54 Icons aus rund 2.500. Das sind 247 KB,
   und anders als bei CSS und JSON hilft die Kompression nichts: woff2 ist
   schon gepackt. Die Subsets wiegen zusammen rund 18 KB.

   Der Kern ist die Reihenfolge in der font-family-Liste. Schrift-Rückfall gilt
   im Browser PRO ZEICHEN: steht ein Icon im Subset, kommt es aus der kleinen
   Datei; steht es nicht drin, lädt der Browser die volle Schrift nach — aber
   nur auf der Seite, wo dieses Icon vorkommt.

   Das ist der Unterschied zwischen dieser Lösung und einem stumpfen Subset.
   Icons werden im Panel als Freitext eingetragen. Wer morgen `fa-tent` tippt,
   hätte sonst ein leeres Kästchen und würde es nicht merken. So kann nichts
   still kaputtgehen, und niemand muss daran denken, das Skript zu starten.
   Wer es startet, macht die Seite schneller — wer nicht, macht nichts kaputt.

   Erzeugt von scripts/icons-subset.py. Muss NACH fontawesome.min.css geladen
   werden, sonst gewinnt deren font-family-Regel.
   ══════════════════════════════════════════ */

@font-face {
    font-family: "FA6 Solid Subset";
    font-style: normal;
    font-weight: 900;
    font-display: block;
    src: url("/webfonts/fa-solid-900-subset.woff2") format("woff2");
}
@font-face {
    font-family: "FA6 Brands Subset";
    font-style: normal;
    font-weight: 400;
    font-display: block;
    src: url("/webfonts/fa-brands-400-subset.woff2") format("woff2");
}

/* Dieselben Selektoren wie in fontawesome.min.css, nur mit dem Subset davor.
   .fa-regular und .far stehen bewusst NICHT dabei: fa-regular wird nirgends
   benutzt, und die Schrift dazu lädt der Browser deshalb auch nie. */
.fa-classic,
.fa-solid,
.fas { font-family: "FA6 Solid Subset", "Font Awesome 6 Free"; }

.fa-brands,
.fab { font-family: "FA6 Brands Subset", "Font Awesome 6 Brands"; }

/* ── themes.css ── */
/* ══════════════════════════════════════════
   DPSG DV Limburg — Dunkles Design
   ══════════════════════════════════════════
   Das helle Design ist der :root-Default in css/teil-*.css.
   Hier lebt NUR das dunkle Pendant: [data-theme="dunkel"]
   (dunkles Navy, DPSG-Rot als CTA, gleiche Struktur).
   Umgeschaltet wird per Sonne/Mond-Button (js/theme-switcher.js).
   ══════════════════════════════════════════ */

/* Die Dunkel-TOKENS (html[data-theme="dunkel"] { --… }) stehen in css/tokens.css.
   Hier nur noch Bauteil-Regeln fuer den Dunkelmodus. */

/* ── Struktur-Anpassungen (Spiegelung der hellen Basiswerte) ── */

[data-theme="dunkel"] header { box-shadow: 0 1px 0 rgba(var(--weiss-rgb), .06); }
/* Laufband: die Flaeche ist im Dunkelmodus --primary (#6FA8D2) bzw. der helle
   Akzent der Seite. Weisse Schrift kam darauf auf 2,56:1. Dieselbe Loesung wie
   beim gefuellten Button (DESIGN-SYSTEM.md §6): Farbe bleibt, Schrift wird dunkel. */
[data-theme="dunkel"] .mq-item::before { filter: brightness(0); opacity: .45; }
/* --on-accent (#14222E) kam auf dem dunklen --primary (#5A87A9) nur auf 4,22:1, die Zeile ist
   Fließtextgröße. --bg (#0A1820) hat 4,7:1 (Messung 12.11.2026). */
[data-theme="dunkel"] .mq-item { color: var(--bg); }
[data-theme="dunkel"] .marquee-scroll:focus-visible { outline-color: var(--on-accent); }
/* DV-Logo (navy) auf dunklem Header → weiß */
[data-theme="dunkel"] header .logo-dv { filter: brightness(0) invert(1); opacity: .92; }
/* Logo-Wortmarke: Farben kommen jetzt aus css/teil-01-basis.css (--text = neutral, --primary = blau)
   und passen sich hell/dunkel selbst an → „DPSG" hell-neutral, „Limburg" hellblau. */

/* Chips: Dunkelwerte stehen als --chip-x in css/tokens.css */

/* Flächen & Linien, die in der Basis feste dunkle rgba-Werte haben */
[data-theme="dunkel"] .dl-btn { background: rgba(var(--weiss-rgb), .07); }

/* Gefüllte Buttons auf getönten Seiten (Stufen/AKs): EXAKT der Akzentton der
   Seite — eine Farbe pro Stufe, kein zweiter Sonderton daneben. Weiße Schrift
   reicht auf den aufgehellten Dunkelmodus-Tönen nicht (1,5–3,4 statt 4,5),
   also dunkle Schrift; derselbe Weg wie bei der aktiven Stufen-Kachel.
   --sc statt --sc-btn, damit auch ein gesetztes --friedenslicht-fill hier nicht durchkommt.
   Hover geht deshalb HELLER: abdunkeln würde den Kontrast zur dunklen Schrift
   wieder zerstören (Rover läge bei 3,36). */
[data-theme="dunkel"] .tinted :is(.btn-fire, .dl-btn-primary) {
    background: var(--sc);
    color: var(--on-accent);
}
[data-theme="dunkel"] .tinted :is(.btn-fire, .dl-btn-primary):hover,
[data-theme="dunkel"] .tinted a.bleed-card:is(:hover, :focus-visible) .btn-fire {
    background: color-mix(in srgb, var(--sc) 85%, #fff);
    box-shadow: 0 8px 28px color-mix(in srgb, var(--sc) 35%, transparent);
}
/* Dasselbe fuer Bloecke mit eigener Akzentfarbe: im Dunkelmodus sind alle
   Akzente aufgehellt, nur --cta bleibt tief (dort traegt Weiss). */
[data-theme="dunkel"] .btn-fire.btn-akzent:not([data-akzent="cta"]) { color: var(--on-accent); }
[data-theme="dunkel"] .btn-fire.btn-akzent:not([data-akzent="cta"]):hover { background: color-mix(in srgb, var(--ac) 85%, #fff); }
/* Aktive Biber-Kachel: --stufe-biber ist im Dunkelmodus das helle Braun.
   Mit 65 % gemischt kam Weiss darauf nur auf 4,44:1. */
[data-theme="dunkel"] .stufe-nav [data-stufe="biber"] { --snc-fill: color-mix(in srgb, var(--snc) 55%, #16242e); }
/* Kontakt-Knopf in Kopfleiste und Handy-Menue: auf getoenten Seiten dieselbe
   Regel wie fuer gefuellte Knoepfe oben. Vorher weiss auf dem aufgehellten
   Akzent, Praevention 2,65:1. */
[data-theme="dunkel"] body.tinted .nav-cta { background: var(--sc); color: var(--on-accent) !important; }
[data-theme="dunkel"] body.tinted .nav-cta:hover { background: color-mix(in srgb, var(--sc) 85%, #fff) !important; }
/* Im Handy-Menue ist der Knopf auch ungetoent in --primary gefuellt, im
   Dunkelmodus also hellblau: auch dort dunkle Schrift (vorher 2,56:1). */
[data-theme="dunkel"] .mobile-nav .nav-cta { color: var(--on-accent) !important; }
[data-theme="dunkel"] .event-row { border-bottom-color: rgba(var(--weiss-rgb), .06); }
[data-theme="dunkel"] .event-row:first-child { border-top-color: rgba(var(--weiss-rgb), .06); }
[data-theme="dunkel"] .quick-grid { background: rgba(var(--weiss-rgb), .03); border-color: rgba(var(--weiss-rgb), .06); }
[data-theme="dunkel"] .sidebar-box { border-color: var(--border-card); }
[data-theme="dunkel"] .ak-info-card { border-color: var(--border-card); }
[data-theme="dunkel"] .ak-info-row { border-bottom-color: rgba(var(--weiss-rgb), .07); }
[data-theme="dunkel"] .article-share { border-top-color: rgba(var(--weiss-rgb), .09); border-bottom-color: rgba(var(--weiss-rgb), .09); }
[data-theme="dunkel"] .kl { border-right-color: rgba(var(--weiss-rgb), .06); }
[data-theme="dunkel"] .kl-divider { background: rgba(var(--weiss-rgb), .07); }
[data-theme="dunkel"] .kl-row:hover { background: rgba(var(--weiss-rgb), .07); }
[data-theme="dunkel"] .ak-member-cta { border-color: rgba(var(--weiss-rgb), .16); }
[data-theme="dunkel"] .ak-cta-icon { border-color: rgba(var(--weiss-rgb), .22); }

/* Eingaben & Filter */
[data-theme="dunkel"] .f-field input,
[data-theme="dunkel"] .f-field textarea,
[data-theme="dunkel"] .nl-input,
[data-theme="dunkel"] .stamm-search {
    background: rgba(var(--weiss-rgb), .07);
    border-color: rgba(var(--weiss-rgb), .12);
}
/* Select separat: Farbe + Pfeil in EINER background-Angabe.
   (Ein nacktes background:-Shorthand würde repeat/position des
   Chevrons zurücksetzen -> der Pfeil kachelt als Muster.) */
[data-theme="dunkel"] .f-field select {
    background: rgba(var(--weiss-rgb), .07) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%239DB6C8' stroke-width='1.5' fill='none' stroke-linecap='round'/%3E%3C/svg%3E") no-repeat right 16px center;
    border-color: rgba(var(--weiss-rgb), .12);
}
[data-theme="dunkel"] .nf-chip,
[data-theme="dunkel"] .ev-view-btn { border-color: rgba(var(--weiss-rgb), .18); }

/* Wasserzeichen-Lilie: hell auf dunklem Grund */
[data-theme="dunkel"] .pg-header::after { filter: brightness(0) invert(1); opacity: .06; }

/* Fotos auf dunklem Grund leicht dimmen (Editorial-Look) */
[data-theme="dunkel"] .news-img img { opacity: .8; }

/* ── teil-01-basis.css ── */
/* ══════════════════════════════════════════
   DPSG DV Limburg — Editorial, DPSG-CD-basiert
   ──────────────────────────────────────────
   :root = HELLES Design (Default).
   Dunkles Design: [data-theme="dunkel"] in themes.css.
   Farben nach DPSG CD: Blau #003056 (Marke/Struktur),
   Rot #810A1A→web (CTA), Gelb/Cyan als warme Akzente.
   ══════════════════════════════════════════ */

/* themes.css steht im Stylesheet-Bündel (plugins/dpsg-buendel) direkt vor
   dieser Datei, mit derselben Version wie alle anderen. Als @import trug sie (wie früher custom-icons.css) ein festes
   ?v=, und Änderungen am Dunkelmodus kamen bei wiederkehrenden Besuchern
   ein Jahr lang nicht an (Code-Review #37). */

/* ── A11y-Basics: Skip-Link + Screenreader-Utility ──────────
   Der Skip-Link ist das erste fokussierbare Element (components.js setzt ihn
   vor den <header>), springt zu <main id="inhalt"> und ist nur bei Tastatur-
   Fokus sichtbar. Farben aus var(--text)/var(--bg) → garantiert kontrastreich
   in hell UND dunkel.
   z-index über dem festen Kopf (1000) und dem Cookie-Banner (1100), unter
   Suche und Dialogen. Bis 11.11.2026 stand er auf 1000 wie der Kopf, der im
   DOM später kommt und ihn deshalb verdeckte (WCAG 2.4.1, 2.4.7). */
.skip-link {
    position: fixed; top: -60px; left: 12px; z-index: 1150;
    background: var(--text); color: var(--bg);
    padding: 10px 16px; border-radius: var(--radius-sm);
    font-family: var(--font-ui); font-weight: 700; text-decoration: none;
    transition: top .18s ease;
}
.skip-link:focus { top: 12px; }
main:focus { outline: none; }   /* programmatischer Sprungfokus → kein sichtbarer Ring */
.sr-only {
    position: absolute !important; width: 1px; height: 1px;
    padding: 0; margin: -1px; overflow: hidden;
    clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

/* Die Tokens (:root) stehen in css/tokens.css, geladen vor dieser Datei. */

*, *::before, *::after { margin:0; padding:0; box-sizing:border-box; }
html { scroll-behavior: smooth; scroll-padding-top: 108px; }   /* Anker-Sprünge stoppen unter der fixen Navbar → Eyebrow + Überschrift bleiben sichtbar */
@media (max-width: 560px) { html { scroll-padding-top: 84px; } }
/* Transitions während des initialen Theme-Ladens deaktivieren → kein FOUC */
html.no-transition *, html.no-transition *::before, html.no-transition *::after { transition: none !important; }
body {
    background: var(--bg);
    color: var(--text);
    font-family: var(--font-ui);
    line-height: 1.5;
    /* clip statt hidden: hidden macht body zu einem eigenen Scrollbereich, und
       an dem hängen dann die scroll-gesteuerten Animationen der Doodles
       (animation-timeline: view()). Er scrollt nie, also standen sie still. */
    overflow-x: clip;
}
a { color: inherit; text-decoration: none; }

/* [hidden] muss stärker sein als jede eigene display-Regel.

   Der Browser setzt [hidden] auf display:none, aber das steht in SEINEM
   Stylesheet und verliert gegen jede Regel von uns. `.blog-post` steht auf
   display:block — damit lief das `c.hidden = true` in js/neuigkeiten-liste.js
   ins Leere und der Themenfilter blendete nichts aus: „wenn ich Info auswähle,
   werden trotzdem die Newsletter angezeigt."

   Die Falle betrifft jedes Element mit eigener display-Regel, das per
   .hidden = true versteckt wird. Deshalb einmal global statt einzeln. */
[hidden] { display: none !important; }


/* ── GRAIN OVERLAY ──
   `top: 60px` statt `inset: 0` ist keine Gestaltungsfrage. Diese Schicht war
   die Ursache des Streifens über der Navbar auf iPhones, und zwar belegt:

   Safari 26 färbt die Fläche um die Statusleiste nach der `background-color`
   eines fixierten Elements im 4px-Band am oberen Rand. Diese Schicht liegt dort,
   ist volle Breite, hat z-index 9997 über allem — und hat gar keine
   `background-color`. Safari tastet also eine durchsichtige Fläche ab, und die
   Statusleiste zeigt den Seiteninhalt.

   Zwei Messreihen am Gerät (Janis, 06.08.) tragen das:
     · Ein Kandidat mit `opacity: .97` HAT gefärbt. `opacity` unter 1
       disqualifiziert also nicht — die 3 % hier ändern nichts daran, dass diese
       Schicht ein vollwertiger Kandidat ist. Genau das hatte ich zwischendurch
       falsch angenommen und den Fix zurückgenommen.
     · Auf einer Testseite mit Navbar-Nachbau färbte schon die Navbar allein.
       Dort gibt es dieses Overlay nicht. Es ist der einzige Unterschied.

   Ein erster Versuch stand auf `top: 4px`, also genau AUF der Bandgrenze, und
   war damit wirkungslos. 60 px sind klar draußen. Bei 3 % Deckkraft sieht
   niemand, dass die obersten 60 px kein Korn tragen — dort liegt ohnehin die
   deckende Kopfzeile darüber.

   NICHT auf `inset: 0` zurückdrehen. Es waren sieben Anläufe. */
body::before {
    content: '';
    position: fixed; top: 60px; right: 0; bottom: 0; left: 0;
    background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
    opacity: .03;
    pointer-events: none;
    z-index: 9997;
}
/* Auf Touch-Geräten ohne Korn: Bei 3 % sieht man es auf dem Handy nicht,
   aber Safari muss eine bildschirmgroße Ebene über allem bei jedem
   Scroll-Frame mitverrechnen (06.10.2026). Das löst nebenbei auch das
   Statusleisten-Problem oben für immer: kein fixiertes Element, kein Abtasten. */
@media (pointer: coarse) { body::before { content: none; } }

/* ══════════════════════════════════════════
   LANGE WÖRTER BRECHEN, STATT AUSZULAUFEN
   ──────────────────────────────────────────
   Deutsche Komposita sind der Dauerbrenner: „Stammesvorständekonferenz" lief
   aus der Termin-Karte, „Pfadfindertechniken" schob die Modul-Zeile unter den
   Aufklapp-Pfeil. Beides dieselbe Ursache — ein Wort ohne Trennstelle ist die
   kleinste unteilbare Einheit einer Zeile, und ist die breiter als der Kasten,
   laeuft sie hinaus.

   BEIDES zusammen, und die Reihenfolge im Kopf behalten: hyphens:auto trennt
   nach Silben und setzt dabei einen Bindestrich („Stammesvorstände-konferenz"),
   und genau so gehört es im Deutschen. Das braucht <html lang="de">, das steht
   in default.php. overflow-wrap:break-word ist nur der Rückfall für Wörter, für
   die der Browser keine Trennstelle kennt — dort bricht es ohne Strich, was
   hässlich, aber immer noch besser als ein Überlauf ist.

   break-word statt anywhere: es greift NUR, wenn ein Wort sonst überliefe. Bei
   allem anderen bleibt der Umbruch unverändert, die Regel ist also unsichtbar,
   bis sie gebraucht wird.

   Mindestens drei Buchstaben vor und nach dem Strich (02.10.2026): Ohne die
   Grenze trennte Chrome „Arbeitskrei-se" und „Gruppen-stunde" nur deshalb
   verschieden, weil die Breite zufaellig passte. Mit 3/3 bleibt kein
   Zwei-Buchstaben-Rest am Zeilenanfang stehen. Safari kennt nur die alten
   Einzelwerte, deshalb beide Schreibweisen.

   Getrennt werden nur Wörter ab zehn Buchstaben, mit vier vor und nach dem
   Strich (11.11.2026): „ande-ren" in „Kurse in anderen Diözesen" brach am
   Desktop, obwohl das Wort in jede Zeile passt. Gemeint ist die Regel für
   lange Komposita, nicht für Alltagswörter.
   ══════════════════════════════════════════ */
:is(h1, h2, h3, h4, h5, h6, .sec-title, .kl-value, .ev-modal-title, .ev-modal-desc, .card-popup-body) {
    overflow-wrap: break-word; hyphens: auto;
    hyphenate-limit-chars: 10 4 4;
    -webkit-hyphenate-limit-before: 4; -webkit-hyphenate-limit-after: 4;
}
/* Icons nie trennen. Mit hyphens:auto sucht Chrome im Icon-Font den
   Trennstrich, findet ihn im Subset nicht und lädt dafür die volle
   fa-solid-900.woff2 (134 KB) nach. Jedes Icon in einer Überschrift tat das. */
:is(.fa-solid, .fas, .fa-classic, .fa-brands, .fab) { hyphens: manual; -webkit-hyphens: manual; }

/* ── HEADER ── */
header {
    position: fixed; top: 0; left: 0; right: 0; z-index: 1000;
    padding: 22px 52px;
    /* env(...) liefert seit dem 03.08.2026 überall 0: der Viewport steht wieder
       auf Vorgabe, ohne viewport-fit=cover. Die Fläche unter der Dynamic Island
       legt damit Safari selbst an und färbt sie nach theme-color, statt dass wir
       sie bemalen (Begründung in snippets/head.php). Die Zeile bleibt, weil sie
       dann wieder greift, falls cover je zurückkommt. */
    padding-top: calc(22px + env(safe-area-inset-top));
    display: flex; justify-content: space-between; align-items: center;
    background: rgba(var(--hbg), .97);
    backdrop-filter: blur(14px);
    box-shadow: 0 1px 0 rgba(var(--tinte-rgb), .09);
    transition: background .4s;
}
header.solid {
    background: rgba(var(--hbg), .97);
    backdrop-filter: blur(14px);
}
/* Touch/Safari: backdrop-filter auf fixed = Repaint-Lag beim Scrollen (Navbar
   „schwebt"/scheint durch). Auf Touch-Geräten deshalb voll deckend, ohne Blur.

   Seit Safari 26 hat das einen zweiten, wichtigeren Grund: Der Browser färbt
   die Statusleiste nach dem obersten fixierten Element und liest dabei
   `background-color` UND `backdrop-filter`. Durchscheinend plus Weichzeichner
   heißt für Safari „Glas", und dann kommt dort Seiteninhalt durch. Deckend und
   ohne Weichzeichner ist also Pflicht, nicht Geschmack.

   Dasselbe gilt für die Mobilnavigation: sie ist fixed über den ganzen Schirm
   und würde im geöffneten Zustand abgetastet. */
@media (pointer: coarse) {
    header, header.solid { background: rgb(var(--hbg)); -webkit-backdrop-filter: none; backdrop-filter: none; transition: none; }
    .mobile-nav { background: rgb(var(--hbg)); -webkit-backdrop-filter: none; backdrop-filter: none; }
}

/* ── LILIE LOGO ── */
.logo-lilie {
    display: block;
    width: 18px; height: 18px;
    filter: brightness(0) invert(1);
    object-fit: contain;
    transform: translateY(12%);
}

.logo { display: flex; align-items: center; gap: 11px; cursor: pointer; text-decoration: none; }
/* DV-Limburg-Logo (Gebietsumriss mit Lilie) — ersetzt das alte Hex-Placeholder-Logo */
.logo-dv {
    height: 38px; width: auto; display: block; flex-shrink: 0;
    transition: transform .35s cubic-bezier(.34,1.56,.64,1);
}
.logo:hover .logo-dv { transform: scale(1.05); }
/* Wortmarke im Navbar-Kleid: gleiche Schrift/Versalien/Sperrung wie die Nav-Links */
.logo-text { font-family: var(--font-heading); font-weight: 700; font-size: 1.04rem; letter-spacing: .04em; text-transform: uppercase; color: var(--text); }
.logo-text span { font-weight: 400; color: var(--sc, var(--primary)); white-space: nowrap; }   /* bei 320px brach es als „DPSG DV“ / „LIMBURG“ */

nav { display: flex; gap: 2px; align-items: center; }
nav a {
    color: var(--text-secondary); font-size: 1rem; font-weight: 700;
    letter-spacing: .09em; text-transform: uppercase;
    padding: 8px 14px; cursor: pointer; text-decoration: none;
    transition: color .25s; position: relative;
    white-space: nowrap;
}
/* Kein Strich unter den Menüpunkten, auch kein aufziehender (Janis,
   05.11.2026): Hover und die aktuelle Seite stehen in der Seitenfarbe. */
/* Ohne Seitenfarbe (--sc, nur auf AK- und Stufenseiten) das DPSG-Rot des
   Kontakt-Knopfs: Blau war von der graublauen Navi-Schrift kaum zu
   unterscheiden, die aktuelle Seite fiel nicht auf (Janis, 07.11.2026). */
/* --ziel: Ton der Seite, auf die der Link führt (plugins/dpsg-farben, dpsg_zielton) */
nav a:hover { color: var(--ziel, var(--sc, var(--cta-text))); }
/* Der markierte Bereich zeigt den Ton der Seite, auf der man steht: auf dem
   Jupfi-AK leuchtet „Unser DV“ blau, nicht im Rot von /unser-dv (Janis, 15.11.2026). */
nav a.active { color: var(--sc, var(--cta-text)); }
.nav-cta {
    /* Akzentfarbe der Seite: auf AK- und Stufenseiten setzt das Template
       --sc-btn am <body>, ohne Tint bleibt das rote --cta. */
    background: var(--sc-btn, var(--cta)); color: var(--on-fill) !important;
    padding: 9px 20px !important; border-radius: 2px; margin-left: 10px;
}
.nav-cta::after { display: none !important; }
.nav-cta:hover { background: var(--cta-hover) !important; }
/* Getönte Seiten dunkeln aus der Akzentfarbe ab, statt --cta-hover zu nehmen.
   Zwei Gründe: --cta-hover ist ein Rotton und würde die Akzentfarbe beim Hover
   wegwischen, und --sc-btn-hover taugt nicht (nur für 2 der 9 Tints definiert,
   sonst identisch mit der Füllung = kein sichtbarer Hover). Über .tinted
   getrennt, damit ungetönte Seiten ihren aufhellenden Rot-Hover behalten. */
body.tinted .nav-cta:hover { background: color-mix(in srgb, var(--sc-btn, var(--cta)) 84%, #000) !important; }

/* Mobile hamburger */
.nav-toggle {
    display: none; background: none; border: none;
    color: var(--text); font-size: 1.4rem; cursor: pointer;
    padding: 8px; z-index: 1001;
}
/* Suche + Hell/Dunkel sichtbar neben dem Burger (nur mobil) */
.nav-actions-mobile { display: none; align-items: center; gap: 8px; }
.mobile-nav {
    display: none; position: fixed; inset: 0; z-index: 1002;
    background: rgba(var(--hbg), .98); backdrop-filter: blur(20px);
    flex-direction: column; align-items: stretch; justify-content: flex-start; gap: 4px;
    /* Die Safe-Area muss IN die Kurzschreibweise. Vorher stand darüber ein
       eigenes padding-top: env(...), das die Zeile hier stillschweigend
       überschrieben hat — mit viewport-fit=cover liefe das Menü sonst unter
       die Statusleiste. */
    overflow-y: auto;
    padding: calc(72px + env(safe-area-inset-top)) clamp(28px, 9vw, 80px) 28px;
}
/* Spacer oben/unten: zentriert, wenn alles passt — scrollt sauber, wenn nicht */
.mobile-nav::before, .mobile-nav::after { content: ''; margin: auto; flex-shrink: 0; }
.mobile-nav.open { display: flex; }
.mobile-nav-close { position: fixed; top: 22px; right: 24px; }
/* Seite hinter offenem Menü nicht mitscrollen */
/* Scroll-Sperre: Mobil-Menue (nav-locked), Termin-Popup (modal-locked) und
   Lightbox (lb-locked) nutzen getrennte Klassen, damit das Schliessen des
   einen nicht die Sperre der anderen aufhebt. Gesperrt wird, sobald eine
   aktiv ist. */
/* Scrollen sperren, ohne dass die Seite breiter wird: Fiel die Scrollleiste
   weg, verschob sich alles um ihre Breite, und jeder Filzstift-Rahmen und jedes
   Doodle zeichnete sich neu. Das war das Flackern hinter der Suche (Janis,
   10.11.2026), dasselbe bei Menü, Popup, Lightbox. --sbw (Breite der
   Scrollleiste) misst js/components.js; scrollbar-gutter greift hier nicht,
   weil html overflow-x: clip trägt. */
html.nav-locked, html.modal-locked, html.lb-locked, html.suche-locked { overflow: hidden; padding-right: var(--sbw, 0px); }

/* ── LIGHTBOX (globale Bildansicht) ── */
.lb-zoomable { cursor: zoom-in; }
/* Vergrößerbare Bilder sind Tab-Halte (js/lightbox.js). Der Ring liegt innen,
   weil Rahmen und Karussells überstehende Ränder abschneiden. */
.lb-zoomable:focus-visible { outline: 3px solid var(--sc, var(--primary)); outline-offset: -3px; }
/* In den Karussells ist das Bild größer als sein Rahmen (Zoom, Verschiebung),
   ein Ring am Bild läge außerhalb. Dort zeichnet der Rahmen den Ring. */
.gallery .lb-zoomable:focus-visible, .acx-viewport .lb-zoomable:focus-visible { outline: none; }
.acx-viewport:has(.lb-zoomable:focus-visible) { position: relative; }
.gallery:has(.lb-zoomable:focus-visible)::after, .acx-viewport:has(.lb-zoomable:focus-visible)::after {
    content: ''; position: absolute; inset: 0; z-index: 5; pointer-events: none;
    border: 3px solid var(--sc, var(--primary)); border-radius: inherit;
}
.lightbox { position: fixed; inset: 0; z-index: 3000; display: none; align-items: center; justify-content: center; padding: 5vmin; background: rgba(8,16,22,.93); opacity: 0; transition: opacity .2s ease; }
.lightbox.is-open { display: flex; opacity: 1; }
.lightbox img { max-width: 92vw; max-height: 86vh; width: auto; height: auto; object-fit: contain; border-radius: 6px; box-shadow: 0 14px 50px rgba(var(--schwarz-rgb), .55); }
/* top rechnet die Safe-Area mit, sonst liegt die Leiste auf iPhones mit Dynamic
   Island teilweise darunter. Gilt fuer beide Lightboxen, sie teilen sich diese
   Klassen. */
.lb-actions { position: fixed; top: calc(16px + env(safe-area-inset-top)); right: 16px; display: flex; gap: 10px; z-index: 3001; }
.lb-btn { width: 46px; height: 46px; border-radius: 50%; border: none; background: rgba(var(--weiss-rgb), .15); color: var(--on-photo); font-size: 1.05rem; display: inline-flex; align-items: center; justify-content: center; cursor: pointer; text-decoration: none; transition: background .2s ease, transform .2s ease; }
.lb-btn:hover, .lb-btn:focus-visible { background: rgba(var(--weiss-rgb), .32); transform: translateY(-2px); }
.lb-btn:focus-visible { outline: 2px solid var(--on-photo); outline-offset: 2px; }
/* Lightbox-Blaettern (nur bei Bildgruppen: Collage, Karussell, Material-Grid) */
.lb-nav { position: fixed; top: 50%; transform: translateY(-50%); width: 48px; height: 48px; border-radius: 50%; border: 1px solid rgba(var(--weiss-rgb), .25); background: rgba(var(--weiss-rgb), .15); color: var(--on-photo); font-size: 1.1rem; display: grid; place-items: center; cursor: pointer; transition: background .2s ease; z-index: 3001; }
.lb-nav:hover, .lb-nav:focus-visible { background: rgba(var(--weiss-rgb), .34); }
.lb-nav:focus-visible { outline: 2px solid var(--on-photo); outline-offset: 2px; }
.lb-prev { left: clamp(12px, 3vw, 34px); }
.lb-next { right: clamp(12px, 3vw, 34px); }
.lb-nav[hidden] { display: none; }
.lb-count { position: fixed; bottom: 24px; left: 50%; transform: translateX(-50%); color: rgba(var(--weiss-rgb), .82); font-family: var(--font-ui); font-size: .92rem; z-index: 3001; }
.lb-count[hidden] { display: none; }
/* Fotograf*in, unten links und leiser als die Bildzahl in der Mitte */
.lb-credit { position: fixed; bottom: 24px; left: 24px; color: rgba(var(--weiss-rgb), .7); font-family: var(--font-ui); font-size: .85rem; z-index: 3001; max-width: calc(50vw - 60px); }
.lb-credit[hidden] { display: none; }

/* ── Zurueck-nach-oben-Button (js/to-top.js), unten rechts in der Ecke ── */
.to-top {
    position: fixed; right: 20px; bottom: 24px; z-index: 200;
    width: 50px; height: 50px; border: none; border-radius: 50%; cursor: pointer;
    /* Akzentfarbe der Seite, wie .btn-fire und .dl-btn-primary: auf AK- und
       Stufenseiten setzt das Template --sc-btn am <body>, sonst greift das rote
       --cta. Der Button hängt per position:fixed am body, erbt also mit. */
    background: var(--sc-btn, var(--cta)); color: var(--on-fill);
    display: grid; place-items: center;
    box-shadow: 0 10px 26px rgba(var(--schwarz-rgb), .24);
    opacity: 0; visibility: hidden; transform: translateY(12px);
    transition: opacity .25s ease, transform .25s ease, visibility .25s ease, background .2s ease;
}
.to-top.is-visible { opacity: 1; visibility: visible; transform: none; }
/* Hover NICHT über --sc-btn-hover, siehe .dl-btn-primary weiter unten: die
   Variable ist nur für 2 der 9 Tints definiert und fiele sonst auf die
   Füllfarbe zurück, also gar kein sichtbarer Hover. Abdunkeln klappt überall. */
.to-top:hover { background: color-mix(in srgb, var(--sc-btn, var(--cta)) 84%, #000); }
.to-top:focus-visible { outline: 2px solid var(--sc, var(--primary)); outline-offset: 3px; }
.to-top .wz { width: 26px; height: 26px; transform: rotate(-90deg); }
@media (max-width: 768px) { .to-top { width: 46px; height: 46px; bottom: 20px; } }
@media (prefers-reduced-motion: reduce) { .to-top { transition: opacity .2s ease, visibility .2s ease; transform: none; } }

/* ── „Seite bearbeiten“ (snippets/bearbeiten.php), nur für Angemeldete ──
   Unten links, gegenüber dem Nach-oben-Knopf. Rahmen in der Tinte, kein
   Akzent: Das ist Werkzeug, nicht Teil der Seite. */
.bearbeiten-stift {
    position: fixed; left: 20px; bottom: 24px; z-index: 200;
    display: inline-flex; align-items: center; gap: 8px;
    padding: 10px 16px; border-radius: 999px;
    background: var(--bg-mid); color: var(--text);
    border: 1px solid color-mix(in srgb, var(--text) 28%, transparent);
    box-shadow: 0 10px 26px rgba(var(--schwarz-rgb), .18);
    font-family: var(--font-ui); font-size: .95rem; text-decoration: none;
    transition: background .2s ease;
}
.bearbeiten-stift:hover { background: color-mix(in srgb, var(--text) 8%, var(--bg-mid)); }
.bearbeiten-stift:focus-visible { outline: 2px solid var(--sc, var(--primary)); outline-offset: 3px; }
@media (max-width: 768px) {
    .bearbeiten-stift { bottom: 20px; padding: 0; width: 46px; height: 46px; justify-content: center; }
    .bearbeiten-stift span { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
}
@media print { .bearbeiten-stift { display: none; } }
@media (prefers-reduced-motion: reduce) { .lightbox, .lb-btn { transition: none; } }

/* ── Wegzeichen-Lightbox (Zeichen groß anzeigen, js/wegzeichen.js) ── */
.wz-item { cursor: pointer; }
.wz-item:focus-visible { outline: 2px solid var(--sc, var(--primary)); outline-offset: 4px; border-radius: 8px; }
/* Das Zeichen wächst beim Überfahren leicht, wie die Icons in Linkkarten.
   Kein Wackeln mehr (Janis, 05.11.2026). Sitzt auf dem Rahmen, nicht auf dem
   SVG: die Hintergrund-Doodles bringen eigene transform-Animationen mit, die
   sich sonst gegenseitig überschreiben. */
.wz-item .wz-item-sign { transition: transform .3s ease; }
.wz-item:is(:hover, :focus-visible) .wz-item-sign { transform: scale(1.08); }
/* Ein Doodle in der Lightbox: .dood-svg ist für den Hintergrund gebaut (absolut
   positioniert, eigene Farbe über --dood-c) und muss hier die Fläche füllen und
   die Farbe der Lightbox erben. */
.wz-lb-sign .dood-svg { position: static; width: 100%; height: 100%; color: inherit; opacity: 1; }
.wz-lightbox { position: fixed; inset: 0; z-index: 3000; display: none; align-items: center; justify-content: center; padding: 7vmin; background: rgba(8,16,22,.93); opacity: 0; transition: opacity .2s ease; }
.wz-lightbox.is-open { display: flex; opacity: 1; }
/* Bedienelemente: die Wegzeichen-Lightbox nutzt seit dem 03.08. dieselben
   Klassen wie die Bilder-Lightbox (.lb-actions, .lb-btn, .lb-nav, siehe oben).
   Vorher standen hier eigene Regeln mit denselben Werten in Kopie — eine
   Doodle-Regel hat dann position:relative daruebergelegt und alle drei Knoepfe
   aus ihrer Verankerung gerissen. Zwei Stellen fuer dieselbe Sache, das war die
   eigentliche Ursache. */
.wz-lb-inner { text-align: center; color: var(--on-photo); max-width: 440px; }
.wz-lb-sign { width: min(64vw, 300px); height: min(64vw, 300px); margin: 0 auto 20px; color: var(--on-photo); }
.wz-lb-sign .wz { width: 100%; height: 100%; }
.wz-lb-name { display: block; font-family: var(--font-heading); font-size: 1.5rem; margin-bottom: 6px; }
.wz-lb-hint { color: rgba(var(--weiss-rgb), .82); font-family: var(--font-ui); font-size: 1.02rem; line-height: 1.5; }
@media (prefers-reduced-motion: reduce) { .wz-lightbox { transition: none; } }
/* Theme-Anpassung: Light-Mode = helle Flaeche + Navy-Zeichen, Dark-Mode = dunkel + weiss */
html:not([data-theme="dunkel"]) .wz-lightbox { background: rgba(var(--papier-rgb), .96); }
html:not([data-theme="dunkel"]) .wz-lb-inner { color: var(--text); }
html:not([data-theme="dunkel"]) .wz-lb-sign { color: var(--sc, var(--primary)); }
html:not([data-theme="dunkel"]) .wz-lb-name { color: var(--text); }
html:not([data-theme="dunkel"]) .wz-lb-hint { color: var(--text-secondary); }
/* Im Hellmodus ist die Lightbox-Fläche hell, die geteilten .lb-Knöpfe sind aber
   auf Weiß-auf-Dunkel ausgelegt. Deshalb hier umgedreht — inklusive der
   Umrandung von .lb-nav, die sonst weiß auf hell und damit unsichtbar wäre. */
html:not([data-theme="dunkel"]) .wz-lightbox :is(.lb-btn, .lb-nav) { background: rgba(0,32,58,.1); color: var(--text); border-color: rgba(0,32,58,.22); }
html:not([data-theme="dunkel"]) .wz-lb-close, html:not([data-theme="dunkel"]) .wz-lb-nav, html:not([data-theme="dunkel"]) .wz-lb-dl { background: rgba(0,32,58,.1); color: var(--text); }
html:not([data-theme="dunkel"]) .wz-lb-close:hover, html:not([data-theme="dunkel"]) .wz-lb-close:focus-visible, html:not([data-theme="dunkel"]) .wz-lb-nav:hover, html:not([data-theme="dunkel"]) .wz-lb-nav:focus-visible, html:not([data-theme="dunkel"]) .wz-lb-dl:hover, html:not([data-theme="dunkel"]) .wz-lb-dl:focus-visible { background: rgba(0,32,58,.18); }
.mobile-nav a {
    color: var(--text-secondary); font-size: 1.125rem; font-weight: 700;
    letter-spacing: .09em; text-transform: uppercase;
    padding: 11px 0; text-decoration: none;
    transition: color .25s;
}
.mobile-nav a:hover { color: var(--text); }
.mobile-nav a.active { color: var(--sc, var(--cta-text)); }   /* wie in der Navbar oben (07.11.2026) */
/* Unterseiten-Gruppe: eingerückt mit Führungslinie */
.mnav-group { display: flex; flex-direction: column; }
.mnav-subs {
    display: flex; flex-direction: column;
    margin: 0 0 6px 4px; padding-left: 16px;
    border-left: 2px solid color-mix(in srgb, var(--text) 16%, transparent);
}
.mobile-nav .nav-cta {
    background: var(--sc, var(--primary)); color: var(--on-accent);
    padding: 13px 26px; border-radius: 2px; margin: 14px 0 0;
    align-self: flex-start;
}


/* ── teil-02-geruest.css ── */
/* ── PAGE SYSTEM ── */
.page { display: none; min-height: 100vh; animation: pfIn .45s ease both; }
.page.active { display: block; }
@keyframes pfIn { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: translateY(0); } }
@keyframes fadeUp { from { opacity: 0; transform: translateY(28px); } to { opacity: 1; transform: translateY(0); } }

/* ── SCROLL REVEAL ──
   Verstecken nur wenn JS aktiv ist (html.js wird im <head>-Inline-Script gesetzt).
   Ohne JS bleiben alle .reveal-Inhalte sichtbar → kein "leerer" Inhalt bei JS-Fehler. */
/* Kurz und knapp (06.10.2026): vorher .55 s plus bis zu .3 s Verzögerung, 24px
   Weg. Beim zügigen Scrollen kam der Inhalt fast eine Sekunde nach dem Daumen,
   und die Seite wirkte langsam. js/reveal.js löst dazu etwas VOR dem Rand aus. */
.js .reveal { opacity: 0; transform: translateY(10px); transition: opacity .3s ease-out, transform .3s ease-out; }
.js .reveal.visible { opacity: 1; transform: translateY(0); }
.reveal-delay-1 { transition-delay: .05s; }
.reveal-delay-2 { transition-delay: .1s; }
.reveal-delay-3 { transition-delay: .15s; }
@media (prefers-reduced-motion: reduce) { .js .reveal { opacity: 1; transform: none; transition: none; } }

/* ── UTILITY ── */
/* iOS/Safari bläht Text in breiten Blöcken (z.B. Marquee) automatisch auf → aus */
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
.wrap { max-width: 1240px; margin: 0 auto; padding: 0 52px; }
/* 90px waren zu viel: auf /ak/ausbildung/woodbadge summierten sich die
   Sektionspolster auf 1710px, also 21% der Seitenhöhe, und damit auf mehr als
   alle neun Trennlinien zusammen. Die 72px hier wirken auf allen 97 Seiten;
   für die 74 ohne Kasten-Abschnitt sind sie am Desktop die einzige Änderung,
   denn dort erreicht das clamp() der Trennlinie fast wieder ihre alte Größe.
   Tablet (60px) und Handy (48px) bleiben, wie sie sind: dort war es nie zu
   luftig, und die Trennlinie ist mobil schon von 114 auf 64px geschrumpft. */
.sec { padding: 72px 0 48px; }   /* unten 48 (Janis, 10.11.2026: Abstände ein Drittel kleiner), siehe --abschnitt-abstand */
/* Ein Kasten, den der Satz davor ankündigt, gehört an diesen Satz. Ohne das
   standen 90px Polster, eine Trennlinie und noch einmal 90px dazwischen, die
   doodles.js zum Zentrieren setzt — rund 300 Pixel zwischen einem Doppelpunkt
   und dem, worauf er zeigt. :has() greift auf den VORIGEN Abschnitt zu,
   deshalb keine negativen Außenabstände. */
.sec:has(+ .sec--anschluss) { padding-bottom: 28px; }
.sec--anschluss { padding-top: 0; }
/* Oben ohne Polster, sonst wie .sec. Für neue Abschnitte statt
   style="padding-top:0" (scripts/inline-check.mjs zählt Inline-Styles). */
.sec-oben-buendig { padding-top: 0; }
.sec-sm { padding: 60px 0; }

/* ── ANBAU: ein Abschnitt, der nur aus einem Kasten besteht ──────────────────
   Ein solcher Abschnitt macht kein neues Thema auf, er hängt an dem, was
   darüber steht. Die volle Zeremonie — 90px Polster, Trennlinie, 90px Polster
   — behandelt ihn aber wie eines. Auf /ak/ausbildung/woodbadge standen fünf
   davon hintereinander: 213 Wörter auf 2380px, also fast drei Bildschirme.
   Gemessen am 29.08.2026, dieselbe Seite kam auf 8027px bei 1440×900.

   Seit 05.11.2026 gibt es keine Trennlinien mehr, Abschnitte trennt Luft
   (doodles.css, „ABSCHNITTE OHNE WELLEN“). Dort steht dieselbe Bedingung
   noch einmal, damit ein solcher Kasten nicht die volle Luft bekommt.

   Ob ein Kasten wirklich am Thema darüber hängt, weiß nur, wer den Text
   geschrieben hat. Deshalb ist es im Panel einstellbar (fields/naehe.yml):
   `.sec--thema` nimmt den Abschnitt hier wieder heraus und holt die Linie
   zurück. „Häufige Fragen" gefolgt von „Das Friedenslicht" ist so ein Fall.

   Das !important ist nötig und nicht bequem: die Block-Snippets schreiben
   `style="padding-top:0"` direkt ins Markup, damit ein Block oben anstößt.
   Bisher hat doodles.js das beim Setzen der Trennlinie wieder hochgezogen —
   fällt die Linie weg, fällt auch der Ausgleich weg, und der Kasten klebte
   am vorigen Abschnitt. Im CSS gelöst hält es auch ohne JavaScript.
 */
.sec:not(.sec--thema):has(> .wrap > .bleed-card:only-child) { padding-top: 34px !important; }
/* Aufruf ohne Box (blocks/cta.php, bg „divider“), heute auf /ak, /staemme und
   /wegzeichen jeweils der letzte Block: Er steht mittig zwischen dem Inhalt
   darüber und dem Footer. Oben stehen der Abschnittsabstand und die 48px
   Unterkante des Abschnitts davor, unten bekommt er dasselbe (Janis, 16.11.2026; vorher 44px zusätzlich oben und
   nur 48px unten). */
.sec.sec--abschluss { padding-bottom: calc(var(--abschnitt-abstand, var(--section-space, clamp(64px, 8vw, 96px))) + 48px); }
/* Nach unten wird nur da eng, wo direkt der nächste Kasten folgt. Steht
   danach ein neues Thema, kommt dort wieder eine Trennlinie, und die braucht
   ihren Anlauf — sonst spart man am falschen Ende. Der Nachbarschafts-
   Selektor erledigt das von selbst: liegt eine Trennlinie dazwischen, ist die
   nächste Sektion nicht mehr der direkte Nachbar und die Regel greift nicht. */
.sec:not(.sec--thema):has(> .wrap > .bleed-card:only-child):has(+ .sec:not(.sec--thema) > .wrap > .bleed-card:only-child) { padding-bottom: 34px; }

/* ── BREADCRUMBS ("Du bist hier", injiziert von components.js) ──
   Die a-Overrides neutralisieren die globale nav-a-Regel (uppercase/
   bold/padding/Unterstrich-Animation) — sonst sähen die Links anders
   aus als die aktuelle Seite. */
.breadcrumbs { font-family: var(--font-ui); font-size: .9rem; margin-bottom: 20px; }
/* Im Seitenkopf mehr Luft zwischen Krume und Titel: 20px wirkten gedrängt, und
   weil .page-hero seine Höhe aus dem Inhalt zieht (min-height ist nur die
   Untergrenze), bekommt das Hero-Foto dadurch gleich mehr Fläche. Skaliert mit,
   damit es auf dem Handy nicht auseinanderfällt. */
:is(.page-hero, .ak-hero, .pg-header) .breadcrumbs { margin-bottom: clamp(26px, 3vw, 38px); }
.breadcrumbs ol { list-style: none; display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; margin: 0; padding: 0; }
.breadcrumbs li { display: inline-flex; align-items: center; gap: 10px; color: var(--text-muted); }
/* „Freund/Feind"-Wegzeichen rahmen verspielte Seiten ein: Spielbeginn oben,
   Spielende unten. Dezente, mittige Kreide-Marke. */
.wz-frame { text-align: center; padding: 12px 0 2px; }
.wz-frame .wz { width: 44px; height: 44px; opacity: .38; color: var(--text-muted); }
.wz-frame-end { padding: 26px 0 12px; }

/* KEINE eigene Farbe: der Pfeil ist ein Wegzeichen-SVG und zeichnet mit
   currentColor. Setzte er hier --text-muted (#566A7D, ein Schieferblau), erbte
   er NICHT das Weiss, das .page-hero .breadcrumbs li setzt — auf dem dunklen
   Hero-Foto stand dann ein blauer Pfeil zwischen weissen Woertern, mit
   entsprechend schlechtem Kontrast. So nimmt er immer die Farbe des <li>, also
   dieselbe wie das Wort links davon. */
.breadcrumbs .bc-sep { display: inline-flex; align-items: center; }
/* Kein opacity-Abschlag: der Pfeil erbt die Farbe des <li> und war mit .55
   dunkler als die Wegmarken, zwischen denen er steht — er sah aus wie ein
   deaktiviertes Element statt wie ein Trennzeichen. */
.breadcrumbs .bc-wz { width: 16px; height: 16px; }
.breadcrumbs a {
    color: inherit; text-decoration: none; transition: color .2s;
    text-transform: none; font-weight: 400; font-size: inherit; letter-spacing: 0; padding: 0;
}
.breadcrumbs a::after { display: none; }
.breadcrumbs a:hover { color: var(--text); text-decoration: underline; text-underline-offset: 3px; }
.breadcrumbs [aria-current="page"] { color: var(--text-secondary); font-weight: 700; }

/* ── Schmale Schirme: Mitte einklappen ──────────────────────────────────────
   Sichtbar bleiben Start, die direkte Elternebene und die aktuelle Seite. Was
   dazwischen liegt, steckt hinter einem „…"-Knopf — antippen zeigt den ganzen
   Pfad. Der Trenner sitzt IM <li>, verschwindet also mit seiner Krume und
   hinterlässt kein einzelnes Wegzeichen in der Luft. */
.breadcrumbs .bc-more { display: none; }
.breadcrumbs .bc-more button {
    font: inherit; color: inherit; background: none; border: 0; cursor: pointer;
    padding: 0 4px; line-height: 1; letter-spacing: .06em;
}
.breadcrumbs .bc-more button:hover { color: var(--text); }
@media (max-width: 560px) {
    /* Beides ist Kleinschrift in Grossbuchstaben mit weiter Laufweite — auf dem
       Handy zusammen mit dem geringeren Kontrast von Grau auf Foto zu wenig.
       Ein Schritt hoch, nicht zwei: die Brotkrume soll die h1 nicht bedraengen. */
    .breadcrumbs { font-size: 1rem; }
    .hero-tag    { font-size: .9rem;  letter-spacing: .12em; }
    .breadcrumbs .bc-wz { width: 18px; height: 18px; }
    .breadcrumbs:not(.bc-offen) .bc-mid  { display: none; }
    .breadcrumbs:not(.bc-offen) .bc-more { display: inline-flex; }
    /* Lange Titel (Beitragsüberschriften) kappen statt umbrechen — der voll-
       ständige Titel steht direkt darunter als Überschrift. */
    .breadcrumbs [aria-current="page"] { max-width: 58vw; }
    .breadcrumbs [aria-current="page"] > span {
        overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    }
}

/* Auf Foto-/Farb-Heroes hell (page-hero UND ak-hero) */
.page-hero .breadcrumbs li, .ak-hero .breadcrumbs li { color: rgba(var(--weiss-rgb), .9); }
.page-hero .breadcrumbs a:hover, .ak-hero .breadcrumbs a:hover { color: var(--on-photo); }
.page-hero .breadcrumbs [aria-current="page"], .ak-hero .breadcrumbs [aria-current="page"] { color: rgba(var(--weiss-rgb), .95); }
/* Typo-Skala: h1 (Seitentitel) klar über h2 (Abschnittstitel) —
   Unterseiten sollen ruhig wirken, nicht jede Sektion gleich laut. */
h1.sec-title {
    font-family: var(--font-heading);
    font-size: clamp(2.4rem,4.6vw,3.6rem);
    color: var(--text); line-height: 1.06; margin-bottom: 14px;
}
h2.sec-title {
    font-family: var(--font-heading);
    font-size: clamp(1.55rem,2.6vw,2.15rem);
    color: var(--text); line-height: 1.14; margin-bottom: 12px;
}
/* Hervorhebung heißt immer kursiv UND eingefärbt, nie eins ohne das andere
   (Janis, 15.11.2026). Farbe: Seitenton, sonst --akzent (website-tokens.css). */
.sec-title em { color: var(--sc, var(--akzent)); font-style: italic; }
main :is(p, li, dd, td, blockquote, figcaption, .sec-sub) em { color: var(--sc, var(--akzent)); font-style: italic; }
.ak-hero .sec-title em { color: inherit; } /* Foto-Hero: Akzent = Titelweiß statt grellem Ton auf Dunkel */
.sec-sub {
    color: var(--text-secondary); font-size: 1rem; line-height: 1.72;
    max-width: 560px; margin-bottom: 44px;
}
/* Die 44px sind fuer einen echten Abschnittswechsel gedacht: Vorspann, dann
   Karten, Listen oder ein Termin-Gitter. Folgt darauf aber nur WEITERER Text,
   liest sich der Abstand wie zwei Leerzeilen mitten im Absatz — der Vorspann
   ist dann optisch vom Text abgeschnitten, zu dem er gehoert. In dem Fall der
   normale Absatzabstand (18px, wie .article-prose p). */
.sec-sub:has(+ .article-prose) { margin-bottom: 18px; }
/* Und derselbe Fall braucht auch denselben Satzspiegel. Der Vorspann brach bei
   560px um, der Absatz direkt darunter erst bei 1136 — eine Spalte, zwei
   Zeilenlaengen, und der Text sprang beim Weiterlesen nach rechts weg. Auf
   /spiritualitaet gemeldet (Janis, 07.08.2026), betrifft sechs Abschnitte plus
   den AK-Vorspann. Abschnitte OHNE Vorspann bleiben so breit wie bisher.
   Breite 720 statt 560px (Janis, 04.11.2026): Auf großen Bildschirmen stand die
   gemeinsame Spalte schmal und verloren neben breiten Kästen. 720px sind gut
   80 Zeichen, die Obergrenze für bequemes Lesen. */
.sec-sub:has(+ .article-prose),
.sec-sub + .article-prose,
.sec-sub + .article-prose.is-narrow { max-width: 720px; }
/* Die schmale Variante des Fliesstext-Blocks. Stand vorher als inline-style im
   Snippet und haette jede Regel hier ueberstimmt — auch die Zeile darueber. */
.article-prose.is-narrow { max-width: 780px; }
/* Lesespalte des Fließtext-Blocks (snippets/blocks/richtext.php). Innen füllen
   Einleitung und Text die Spalte, damit beide dieselbe Zeilenlänge haben.
   Linksbündig an der Kante der Überschriften darüber und darunter: mittig
   gesetzt stand die Spalte eingeschoben zwischen linksbündigen Abschnitten
   (Janis, 04.11.2026, auf /ak/praevention). */
.lesespalte { max-width: 780px; }
.lesespalte .sec-sub, .lesespalte .article-prose, .lesespalte .article-prose.is-narrow { max-width: none; }

.btn {
    display: inline-flex; align-items: center; gap: 9px;
    padding: 13px 26px; border-radius: var(--button-radius);
    font-family: var(--font-ui); font-weight: 700; font-size: 1rem;
    letter-spacing: .04em; cursor: pointer;
    /* Durchsichtiger Rahmen statt keinem: .btn-outline hat 1px Rahmen, .btn-fire
       hatte keinen. Bei gleicher Polsterung war der gefuellte Knopf dadurch 2px
       niedriger (50 gegen 52, klein 42 gegen 44), und nebeneinander sassen die
       Kanten versetzt. */
    border: 1px solid transparent;
    transition: all .25s; text-transform: uppercase; text-decoration: none;
    /* Zeilenhöhe MUSS hier stehen, sonst sind <a class="btn"> und
       <button class="btn"> unterschiedlich hoch: der Link erbt die 1.5 vom
       Body, der Button bekommt vom Browser "normal" (ca. 1.2). Das sind rund
       5px Unterschied, sichtbar sobald beide nebeneinander stehen. Mit einem
       festen Wert hängt die Komponente nicht mehr am Umfeld. */
    line-height: 1.5;
}
.btn-fire { background: var(--sc-btn, var(--cta)); color: var(--on-fill); }
.btn-fire:hover { background: var(--sc-btn-hover, var(--cta-hover)); transform: translateY(var(--button-lift)); box-shadow: 0 8px 28px color-mix(in srgb, var(--sc-btn, var(--cta)) 35%, transparent); }
.btn-outline { background: transparent; color: var(--text); border: 1px solid color-mix(in srgb, var(--text) 28%, transparent); }
.btn-outline:hover { background: color-mix(in srgb, var(--text) 7%, transparent); border-color: color-mix(in srgb, var(--text) 50%, transparent); transform: translateY(var(--button-lift)); }
/* Outline-Buttons IM Hero liegen auf dunklem Foto → hell */
.hero .btn-outline { border-color: rgba(var(--weiss-rgb), .45); color: rgba(var(--weiss-rgb), .9); }
.hero .btn-outline:hover { background: rgba(var(--weiss-rgb), .14); border-color: rgba(var(--weiss-rgb), .8); color: var(--on-photo); }
/* Zweiter und jeder weitere interne Link einer Knopfreihe (plugins/dpsg-knoepfe,
   Regel seit 05.11.2026): Textlink mit Pfeil statt noch eines roten Knopfs. Er ersetzt
   auch den Unterstrich-Link .btn-ghost (Designsystem, Knopf).
   Gleiche Höhe wie ein Knopf, damit die Reihe auf einer Linie bleibt; das
   Icon fällt weg, der Pfeil sagt „weiter“. */
.btn-text, .dl-btn-text {
    background: transparent; color: var(--sc, var(--primary));
    border-color: transparent; padding-left: 6px; padding-right: 6px;
}
.btn-text i[class*="fa-"], .dl-btn-text i[class*="fa-"] { display: none; }
.btn-text::after, .dl-btn-text::after { content: '→'; display: inline-block; transition: transform .25s; }
.btn-text:hover, .dl-btn-text:hover { background: transparent; color: var(--sc, var(--primary)); transform: none; }
.btn-text:hover::after, .dl-btn-text:hover::after { transform: translateX(5px); }
@media (prefers-reduced-motion: reduce) { .btn-text::after, .dl-btn-text::after { transition: none; } }
.btn-sm { padding: 9px 18px; font-size: 1rem; }
/* Gefuellter Knopf in der Akzentfarbe eines Blocks (Splitcard). Vorher inline
   background, im Dunkelmodus dann weiss auf hellem Gold (2,19:1). */
.btn-fire.btn-akzent { background: var(--ac); }
/* Ganze Karte als Link mit Knopf darin (AK-Verweis auf den Stufenseiten). Die
   Buehne selbst hebt bewusst nicht ab (KARTEN-HOVER-SYSTEM), also zeigt der Knopf,
   dass die Flaeche reagiert. Vorher tat sich beim Ueberfahren der Karte nichts. */
a.bleed-card:is(:hover, :focus-visible) .btn-fire { background: var(--sc-btn-hover, var(--cta-hover)); transform: translateY(var(--button-lift)); }

/* ── FOCUS STATES (WCAG) ── */
/* Grundregel fuer alles ohne eigenen Fokusstil. Vorher trugen Kopf, Footer,
   Galerie, Brotkrumen und Textlinks den Standardring des Browsers, Karten und
   Knoepfe 2px in --sc: sichtbar beides, einheitlich nicht. Niedrigste
   Spezifitaet (0-1-0), damit jede vorhandene Regel gewinnt. Kontrast des
   Rings gegen die Seite: hell Navy auf Creme 13:1, dunkel Hellblau 7,6:1. */
:focus-visible { outline: 2px solid var(--sc, var(--primary)); outline-offset: 2px; }
.btn-fire:focus-visible, .btn-outline:focus-visible, .btn-text:focus-visible,
.nf-chip:focus-visible, .ev-view-btn:focus-visible, .ev-cal-nav-btn:focus-visible,
.dl-btn:focus-visible {
    outline: 2px solid var(--sc, var(--primary)); outline-offset: 3px;
}
a.news-card:focus-visible, a.srv-card:focus-visible, a.ak-card:focus-visible,
a.int-card:focus-visible, a.blog-post:focus-visible,
a.stat-c:focus-visible, a.qc:focus-visible, a.hero-door:focus-visible,
a.stufe-mini:focus-visible, a.mat-card:focus-visible, a.ak-member:focus-visible,
a.dl-person:focus-visible, .card-popup-close:focus-visible { outline: 2px solid var(--sc, var(--primary)); outline-offset: 2px; }

/* Globaler reduced-motion-Fallback: kürzt ALLE Animationen/Transitions/Scroll
   für bewegungsempfindliche Nutzer (deckt auch neue Elemente wie Popup und
   Doodle-Wackeln ab; komponentenspezifische Regeln bleiben zusätzlich bestehen). */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: .01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .01ms !important;
        scroll-behavior: auto !important;
    }
}

.chip {
    display: inline-block; padding: 4px 11px; border-radius: 2px;
    font-family: var(--font-ui); font-size: .8rem; font-weight: 700;
    letter-spacing: .1em; text-transform: uppercase;
}
/* Chip-Farben aus den Tokens (--chip-x, --chip-x-flaeche), hell und dunkel,
   geprueft in wcag-check. Vorher hier und in themes.css als feste Werte. */
.chip-blue { background: var(--chip-blue-surface); color: var(--chip-blue); }
.chip-green { background: var(--chip-green-surface); color: var(--chip-green); }
.chip-orange { background: var(--chip-orange-surface); color: var(--chip-orange); }
.chip-purple { background: var(--chip-purple-surface); color: var(--chip-purple); }
.chip-teal { background: var(--chip-teal-surface); color: var(--chip-teal); }
.chip-red { background: var(--chip-red-surface); color: var(--chip-red); }
.chip-leiter { background: var(--chip-leitende-surface); color: var(--chip-leitende); }
.chip-white { background: var(--chip-neutral-surface); color: var(--chip-neutral); }
.chip-stamm { background: var(--chip-stamm-surface); color: var(--chip-stamm); }

.dl-row { display: flex; flex-wrap: wrap; gap: 7px; }
.dl-btn {
    display: inline-flex; align-items: center; gap: 7px;
    padding: 7px 14px; border-radius: var(--radius);
    font-size: 1rem; font-weight: 700; letter-spacing: .07em;
    text-transform: uppercase; cursor: pointer; border: none;
    background: rgba(var(--tinte-rgb), .07); color: var(--text);
    transition: background .2s, transform .2s, box-shadow .2s;
}
.dl-btn:hover { background: var(--sc, var(--primary)); color: var(--on-accent); transform: translateY(var(--button-lift)); }
/* Roter Primär-Download-Button: für Karten, die auf eine eigene DV-Seite führen */
.dl-btn-primary { background: var(--sc-btn, var(--cta)); color: var(--on-fill); }
/* Hover NICHT über --sc-btn-hover: diese Variable ist nur für 2 der 9 Tints und
   nur im Dunkelmodus definiert. Sonst fiel sie auf dieselbe Farbe wie die
   Füllung zurück → gar kein sichtbarer Hover (Bug bis 07/2026). Stattdessen aus
   der tatsächlichen Füllfarbe abdunkeln — klappt für jeden Tint, hell + dunkel. */
.dl-btn-primary:hover {
    background: color-mix(in srgb, var(--sc-btn, var(--cta)) 82%, #000); color: var(--on-fill);
    box-shadow: 0 6px 20px color-mix(in srgb, var(--sc-btn, var(--cta)) 32%, transparent);
}


/* ── teil-03-startseite.css ── */
/* ── HERO ── */
.hero {
    position: relative; height: 100vh; height: 100svh; min-height: 580px;
    overflow: clip; display: flex; align-items: flex-end;   /* clip, nicht hidden: s. body */
}
.hero-inner {
    position: relative; z-index: 2;
    width: 100%; max-width: 1240px; margin: 0 auto;
    padding: 0 52px 80px;
    display: grid; grid-template-columns: 1fr 1fr;
    align-items: flex-end; gap: 40px;
}
/* Das Feuer liegt unter 72 bis 97 % Overlay, deshalb WebP mit wenig Qualität:
   quer 210 KB statt 890 KB als JPEG. Bis 768px ein Hochkant-Ausschnitt (960px
   breit), denn mehr zeigt cover auf dem Handy ohnehin nicht. Pfade absolut:
   relative url() in Variablen lösen Browser verschieden auf. */
.hero { --hero-foto: url('/img/hero-campfire-quer.webp'); }
@media (max-width: 768px) { .hero { --hero-foto: url('/img/hero-campfire-hoch.webp'); } }
.hero-bg {
    position: absolute; inset: 0; z-index: 0;
    /* Die Schicht liegt nur hinter dem Text (links), rechts bleibt das Foto
       unverdeckt (Janis, 05.11.2026; vorher 94 bis 38 % über die ganze Breite,
       das Feuer wirkte milchig). */
    background: linear-gradient(100deg, rgba(var(--overlay-rgb),.94) 0%, rgba(var(--overlay-rgb),.8) 30%, rgba(var(--overlay-rgb),.25) 58%, rgba(var(--overlay-rgb),0) 82%),
    var(--hero-foto) center/cover;
}
.hero-bg::after {
    content: ''; position: absolute; inset: 0;
    background: radial-gradient(ellipse at 72% 50%,
        color-mix(in srgb, var(--highlight) 15%, transparent) 0%, transparent 68%);
}
.hero-lines {
    position: absolute; right: 0; top: 0; width: 52%; height: 100%;
    z-index: 1; pointer-events: none; overflow: hidden;
    display: flex; align-items: center; justify-content: center;
}
.hero-lilie-wm {
    width: 90%; height: 90%;
    object-fit: contain;
    opacity: .07;
    transform: translateX(8%);
    filter: brightness(0) invert(1);
}
/* Auf dem Handy stand die Lilie mittig genau hinter der Zeile
   „Diözesanverband Limburg" — heller Umriss unter hellgrauer Kleinschrift, das
   war kaum zu lesen. Kleiner und nach oben aus dem Textbereich heraus. */
@media (max-width: 760px) {
    .hero-lilie-wm {
        width: 58%; height: 58%;
        opacity: .05;
        transform: translate(10%, -26%);
    }
}
.hero-left { position: relative; z-index: 2; }
/* Hero-Text immer hell — der Hero liegt in beiden Modi auf dunklem Foto-Overlay */
.hero-tag {
    display: inline-flex; align-items: center; gap: 10px;
    font-family: var(--font-ui); font-size: .85rem; font-weight: 700;
    color: rgba(var(--weiss-rgb), .72); letter-spacing: .15em; text-transform: uppercase;
    margin-bottom: 22px;
}
.hero-tag::before { content: ''; width: 28px; height: 1px; background: rgba(var(--weiss-rgb), .72); }
.hero h1 {
    font-family: var(--font-heading);
    font-size: clamp(2.7rem,4.8vw,4.3rem); line-height: 1.06;
    color: var(--on-photo); margin-bottom: 22px;
}
/* Ortsname: gleiche Größe, Hellblau; sehr lange Orte trennen per Silbentrennung */
.hero h1 em { color: #8FC0E4; font-style: italic; hyphens: auto; overflow-wrap: break-word; }
@media (max-width: 430px) { .hero h1 { font-size: 2.45rem; } }
.hero-p { font-size: 1rem; color: rgba(var(--weiss-rgb), .78); max-width: 460px; line-height: 1.72; margin-bottom: 36px; }
.hero-btns { display: flex; gap: 14px; flex-wrap: wrap; }
.hero-right {
    position: relative; z-index: 2;
    display: flex; flex-direction: column; align-items: flex-end; gap: 14px;
}
.stat-c {
    background: color-mix(in srgb, var(--bg-mid) 75%, transparent); backdrop-filter: blur(18px);
    border: 1px solid color-mix(in srgb, var(--highlight) 22%, transparent); border-radius: 12px;
    padding: 18px 26px; text-align: right;
    animation: floatY 6s ease-in-out infinite;
}
.stat-c:nth-child(2) { animation-delay: -2s; }
.stat-c:nth-child(3) { animation-delay: -4s; }
a.stat-c { transition: transform .25s, border-color .25s, box-shadow .25s; }
/* Die Karten liegen in beiden Modi auf dunklem Foto -> Hover-Akzent fest hell
   (var(--sc, var(--primary)) war im hellen Modus Navy-auf-Navy und kaum sichtbar) */
a.stat-c:hover {
    border-color: #8FC0E4;
    background: color-mix(in srgb, var(--bg-mid) 94%, transparent);
    transform: translateY(-6px) scale(1.045);
    box-shadow: 0 18px 40px rgba(0, 12, 24, .5);
}
.stat-n { font-family: var(--font-heading); font-size: 2.6rem; color: var(--sc, var(--primary)); line-height: 1; }
.stat-l { font-size: 1rem; color: var(--text-secondary); text-transform: uppercase; letter-spacing: .1em; margin-top: 3px; }
@keyframes floatY { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-7px); } }
/* Eckverlauf auch hier — fest hell, da die Karten auf dunklem Foto liegen */
.stat-c { position: relative; overflow: hidden; }
.stat-c::before {
    content: ''; position: absolute; inset: 0;
    background: linear-gradient(to top right, rgba(var(--weiss-rgb), .12) 0%, transparent 46%);
    opacity: 0; transition: opacity .5s ease; pointer-events: none;
}
a.stat-c:hover::before { opacity: 1; }

/* ── Startseiten-Hero freundlicher im Light-Mode: helle Transparenz + dunkle Schrift.
      Dark-Mode bleibt unveraendert (dunkles Overlay + helle Schrift). ── */
html:not([data-theme="dunkel"]) .hero-bg {
    background: linear-gradient(100deg, rgba(var(--papier-rgb), .94) 0%, rgba(var(--papier-rgb), .82) 30%, rgba(var(--papier-rgb), .28) 58%, rgba(var(--papier-rgb), 0) 82%),
    var(--hero-foto) center/cover;
}
html:not([data-theme="dunkel"]) .hero-tag { color: var(--cta); }
html:not([data-theme="dunkel"]) .hero-tag::before { background: var(--cta); }
html:not([data-theme="dunkel"]) .hero h1 { color: var(--text); }
html:not([data-theme="dunkel"]) .hero h1 em { color: var(--sc, var(--akzent)); }
html:not([data-theme="dunkel"]) .hero-p { color: var(--text-secondary); }
html:not([data-theme="dunkel"]) .scroll-cue { color: var(--text-secondary); }
html:not([data-theme="dunkel"]) .scroll-cue i { color: var(--text-muted); }
html:not([data-theme="dunkel"]) .hero .btn-outline { border-color: color-mix(in srgb, var(--sc, var(--primary)) 45%, transparent); color: var(--sc, var(--primary)); }
html:not([data-theme="dunkel"]) .hero .btn-outline:hover { background: color-mix(in srgb, var(--sc, var(--primary)) 8%, transparent); border-color: var(--sc, var(--primary)); color: var(--sc, var(--primary)); }
html:not([data-theme="dunkel"]) .hero .stat-c { background: color-mix(in srgb, var(--bg-mid) 92%, transparent); border-color: var(--border-card); box-shadow: 0 10px 28px rgba(0,32,58,.10); }
/* Mobile: der 120deg-Verlauf laesst den Text auf dem transparenten Teil liegen.
   Darum hochkant ein nach unten deckendes Overlay (dort sitzt der Hero-Text). */
@media (max-width: 768px) {
    html:not([data-theme="dunkel"]) .hero-bg {
        background: linear-gradient(to bottom, rgba(var(--papier-rgb), .1) 0%, rgba(var(--papier-rgb), .35) 30%, rgba(var(--papier-rgb), .9) 55%, rgba(var(--papier-rgb), .97) 100%),
        var(--hero-foto) center/cover;
    }
    html[data-theme="dunkel"] .hero-bg {
        background: linear-gradient(to bottom, rgba(var(--overlay-rgb),.1) 0%, rgba(var(--overlay-rgb),.35) 30%, rgba(var(--overlay-rgb),.9) 55%, rgba(var(--overlay-rgb),.97) 100%),
        var(--hero-foto) center/cover;
    }
}
.scroll-cue {
    position: absolute; bottom: 28px; left: 50%; transform: translateX(-50%);
    z-index: 3; display: flex; flex-direction: column; align-items: center; gap: 7px;
    font-family: var(--font-ui); font-size: .9rem;
    color: rgba(var(--weiss-rgb), .5); letter-spacing: .15em; text-transform: uppercase;
    animation: bounce 2.2s ease-in-out infinite;
}
.scroll-cue i { color: rgba(var(--weiss-rgb), .65); font-size: 1rem; }
.tw-caret { display: inline-block; width: 3px; height: 1em; margin-left: 3px; background: currentColor; vertical-align: -0.08em; animation: tw-blink 1.05s step-end infinite; }
@keyframes tw-blink { 0%, 100% { opacity: 1; } 50% { opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .tw-caret { display: none; } }
@keyframes bounce { 0%,100%{transform:translateX(-50%) translateY(0)} 50%{transform:translateX(-50%) translateY(7px)} }

/* ── HERO: Zwei Türen (Startseite) ── */
.hero--split { height: auto; min-height: 100vh; align-items: center; }
.hero-split-inner {
    position: relative; z-index: 2;
    width: 100%; max-width: 1240px; margin: 0 auto;
    padding: 124px 52px 92px;
}
.hero-intro { max-width: 640px; margin-bottom: 44px; }
.hero--split h1 { font-size: clamp(2.4rem, 4.6vw, 3.7rem); line-height: 1.05; }
.hero-doors { display: grid; grid-template-columns: 1fr 1fr; gap: 22px; align-items: stretch; }
.hero-door {
    position: relative; overflow: hidden;
    display: flex; flex-direction: column;
    background: color-mix(in srgb, var(--bg-mid) 72%, transparent);
    backdrop-filter: blur(16px);
    border: 1px solid var(--border-card);
    border-radius: var(--radius-lg);
    padding: 36px 34px 32px;
    transition: transform .3s, border-color .3s, background .3s, box-shadow .3s;
}
.hero-door::before {
    content: ''; position: absolute; inset: 0;
    background: linear-gradient(to top right, color-mix(in srgb, var(--hd-c, var(--sc, var(--primary))) 16%, transparent) 0%, transparent 46%);
    opacity: 0; transition: opacity .5s ease; pointer-events: none;
}
.hero-door--join   { --hd-c: var(--sc, var(--primary)); }
.hero-door--portal { --hd-c: var(--highlight); }
/* Die Tür selbst ist kein Link, nur ihre Knöpfe: kein Hover auf der Fläche. */
.hero-door-icon { font-size: 30px; margin-bottom: 18px; display: block; width: fit-content; transition: transform .25s ease; }
.hero-door--join .hero-door-icon   { color: var(--sc, var(--primary)); }
.hero-door--portal .hero-door-icon { color: var(--highlight); }
.hero-door-eyebrow { font-family: var(--font-ui); font-size: 1rem; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: var(--text-muted); margin-bottom: 10px; }
.hero-door h2 { font-family: var(--font-heading); font-size: clamp(1.4rem, 2vw, 1.75rem); line-height: 1.1; color: var(--text); margin-bottom: 12px; }
.hero-door p { font-size: 1rem; color: var(--text-secondary); line-height: 1.6; margin-bottom: 26px; max-width: 40ch; }
.hero-door-actions { margin-top: auto; display: flex; align-items: center; gap: 20px; flex-wrap: wrap; }
/* .hero-door-more: Stil wie .btn-text, siehe „Links mit Pfeil“ am Dateiende. */

@media (max-width: 860px) {
    .hero-doors { grid-template-columns: 1fr; gap: 16px; }
    .hero-split-inner { padding: 104px 24px 64px; }
    .hero-intro { margin-bottom: 30px; }
}

/* ── MARQUEE ── */
.marquee-bar { background: var(--sc, var(--primary)); position: relative; overflow: hidden; }
.marquee-bar::before, .marquee-bar::after { content: ''; position: absolute; top: 0; bottom: 0; width: 64px; z-index: 2; pointer-events: none; }
.marquee-bar::before { left: 0;  background: linear-gradient(to right, var(--sc, var(--primary)), transparent); }
.marquee-bar::after  { right: 0; background: linear-gradient(to left,  var(--sc, var(--primary)), transparent); }
.marquee-scroll { overflow-x: auto; overflow-y: hidden; padding: 16px 0; cursor: grab; touch-action: pan-x; scrollbar-width: none; -ms-overflow-style: none; }
.marquee-scroll::-webkit-scrollbar { display: none; }
/* Mobil hat der Banner keinen sichtbaren Scrollbalken und (im Doodle-Look)
   keine seitlichen Fades. Ein beidseitiger Rand-Fade zeigt, dass er scrollt. */
@media (max-width: 760px) {
    .marquee-scroll {
        -webkit-mask-image: linear-gradient(to right, transparent 0, #000 8%, #000 92%, transparent 100%);
        mask-image: linear-gradient(to right, transparent 0, #000 8%, #000 92%, transparent 100%);
    }
}
.marquee-scroll.is-grabbing { cursor: grabbing; }
.marquee-scroll:focus-visible { outline: 2px solid var(--on-accent); outline-offset: -4px; }
.marquee-inner { display: flex; gap: 0; width: max-content; white-space: nowrap; }
/* Laufband als Transform-Animation (js/app.js setzt .laeuft und --mq-dauer).
   Der Inhalt steht doppelt drin, -50 % ist also genau ein Durchlauf. */
.marquee-inner.laeuft { animation: laufband var(--mq-dauer, 60s) linear infinite; will-change: transform; }
.marquee-scroll:hover .marquee-inner, .marquee-scroll.is-grabbing .marquee-inner, .marquee-inner.steht { animation-play-state: paused; }
@keyframes laufband { to { transform: translateX(-50%); } }
@media (prefers-reduced-motion: reduce) { .marquee-inner.laeuft { animation: none; } }
.mq-item {
    display: flex; align-items: center; gap: 18px;
    margin-right: 50px;
    font-family: var(--font-heading); font-size: 1rem;
    color: var(--on-accent); flex-shrink: 0;
}
.mq-item::before {
    content: '';
    display: block;
    width: .8em; height: .8em;
    flex-shrink: 0;
    background: url('../img/lilie-fill.svg') center/contain no-repeat;
    filter: brightness(0) invert(1);
    opacity: .5;
}
/* ── QUICK NAV ── */
/* Karten-Raster brechen nach fester Mindestbreite um (auto-fit) —
   mobil dadurch automatisch einspaltig, ganz ohne Media-Query.
   min(100%, Xpx) verhindert Überlauf auf sehr schmalen Geräten. */
.quick-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr)); gap: 14px; }
/* Raster der Wegekarten (Block wegekarten). Die Spaltenzahl folgt der
   Kartenzahl, nicht nur der Breite: Mit auto-fit standen vier Karten bei
   mittlerer Breite als 3 + 1 da, eine Karte allein in der zweiten Reihe
   (Janis, 06.10.2026). Jetzt: 4 Karten = 4, 2 oder 1 Spalte; 3 Karten = 3
   oder 1; 2 Karten = 2 oder 1. Andere Zahlen wie bisher automatisch. */
.qc-grid { display: grid; gap: 18px; grid-template-columns: repeat(auto-fit, minmax(min(100%, 230px), 1fr)); }
.qc-grid:is(.qc-n2, .qc-n3, .qc-n4) { grid-template-columns: 1fr; }
@media (min-width: 600px) {
    .qc-grid:is(.qc-n2, .qc-n4) { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 760px) {
    .qc-grid.qc-n3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
/* Vier Spalten erst ab 1180 px: darunter waren es je 214 px, und die Titel
   „Für Kinder & Eltern“ und „Leiter*in werden“ brachen zweizeilig um
   (gemessen am 06.10.2026, ab 1180 px einzeilig). */
@media (min-width: 1180px) {
    .qc-grid.qc-n4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
/* Vier schmale Spalten: Innenabstand etwas knapper, sonst bricht der Titel */
/* Kacheln sind normale Karten (Hover kommt zentral aus dem Karten-System) */
.qc {
    background: var(--bg-mid); padding: 38px 32px;
    border: 1px solid var(--border-card); border-radius: var(--radius-lg);
}

.qc-icon {
    font-size: 26px; color: var(--sc, var(--primary)); margin-bottom: 18px; display: block;
    width: fit-content;   /* Box = Glyphe -> scale/rotate um die eigene Mitte, kein Links-Wandern */
    transition: transform .25s ease;
}
.qc-title { font-family: var(--font-heading); font-size: 1.375rem; color: var(--text); margin-bottom: 9px; }
.qc-desc { color: var(--text-secondary); font-size: 1rem; line-height: 1.62; margin-bottom: 26px; }
.qc-link {
    color: var(--sc, var(--primary)); font-size: 1rem; font-weight: 700;
    letter-spacing: .1em; text-transform: uppercase;
    display: inline-flex; align-items: center; gap: 8px;
    transition: color .2s;
}

/* ── NEWS STRIP / CARDS ── */
.news-strip { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr)); gap: 20px; }
.news-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr)); gap: 20px; }
.news-card {
    background: var(--bg-mid); border: 1px solid var(--border-card);
    border-radius: var(--radius-lg); overflow: hidden;
    transition: transform .3s, border-color .3s; cursor: pointer;
}
.news-img { height: 160px; overflow: hidden; position: relative; }
.news-img img {
    width: 100%; height: 100%; object-fit: cover; object-position: center 20%;
    transition: transform .4s;
}
.news-card:hover .news-img img { transform: scale(1.04); }
.news-body { padding: 20px 22px; }
.news-date { font-family: var(--font-ui); font-size: 1rem; color: var(--text-muted); letter-spacing: .1em; margin-bottom: 7px; }
.news-title { font-family: var(--font-heading); font-size: 1.125rem; color: var(--text); margin-bottom: 7px; line-height: 1.25; }
.news-excerpt { font-size: 1rem; color: var(--text-secondary); line-height: 1.6; }
/* Reihen-Label auf der Startseite: trennt sichtbar „Aktuelles" (Blog) von „Termine" */
.home-row-label { font-family: var(--font-ui); font-size: .9rem; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--text-secondary); margin: 4px 0 16px; display: flex; align-items: center; gap: 9px; }
.home-row-label i { color: var(--sc, var(--primary)); font-size: .95rem; }

/* ── PHOTO STRIP ── */
.photo-strip { display: grid; grid-template-columns: 1.6fr 1fr 1fr; gap: 3px; height: 320px; border-radius: var(--radius-lg); overflow: hidden; }
.ps-item { position: relative; overflow: hidden; cursor: pointer; }
.ps-item img { width: 100%; height: 100%; object-fit: cover; transition: transform .5s, filter .4s; }
.ps-item:hover img { transform: scale(1.05); filter: brightness(1.1); }
.ps-item::after { content: ''; position: absolute; inset: 0; background: linear-gradient(to top, rgba(var(--overlay-rgb),.72) 0%, transparent 55%); }
.ps-cap span, .ps-cap small { color: var(--on-photo); }
.ps-cap small { color: rgba(var(--weiss-rgb), .75); }
.ps-cap { position: absolute; bottom: 0; left: 0; right: 0; padding: 14px 16px; z-index: 2; }
.ps-cap span { font-family: var(--font-heading); font-size: 1.125rem; color: var(--text); }
.ps-cap small { display: block; font-family: var(--font-ui); font-size: 1rem; color: var(--text-secondary); letter-spacing: .1em; text-transform: uppercase; margin-bottom: 3px; }

/* ── VERANSTALTUNGEN ── */
.events-layout { display: grid; grid-template-columns: 1fr 320px; gap: 28px; }
.event-row {
    display: grid; grid-template-columns: 80px minmax(0, 1fr) auto; gap: 24px;
    align-items: start; padding: 26px 0;
    border-bottom: 1px solid rgba(var(--tinte-rgb), .08); transition: border-color .3s;
}
.event-row:first-child { border-top: 1px solid rgba(var(--tinte-rgb), .08); }
.event-row:hover { border-bottom-color: color-mix(in srgb, var(--sc, var(--primary)) 25%, transparent); }
.ev-date { text-align: center; background: var(--bg-mid); border-radius: 10px; padding: 10px 6px; }
.ev-day { font-family: var(--font-heading); font-size: 2.4rem; color: var(--sc, var(--primary)); line-height: 1; }
.ev-month { font-family: var(--font-ui); font-size: 1rem; color: var(--text-secondary); letter-spacing: .1em; text-transform: uppercase; margin-top: 3px; }
.ev-name { font-family: var(--font-heading); font-size: 1.8rem; color: var(--text); margin-bottom: 6px; }
.ev-meta { font-size: 1rem; color: var(--text-secondary); display: flex; gap: 18px; flex-wrap: wrap; }
.ev-meta span { display: flex; align-items: center; gap: 5px; }
/* Orts-Link → Google Maps (Liste + Modal). Klick öffnet Maps, nicht das Popup. */
.ev-loc { display: inline-flex; align-items: center; gap: 5px; color: inherit; text-decoration: none; transition: color .2s; cursor: pointer; }
.ev-loc:hover { color: var(--sc, var(--primary)); text-decoration: underline; text-underline-offset: 2px; }
/* Status als Text statt Pill — hebt sich klar von Buttons/Chips ab */
.ev-status { font-family: var(--font-ui); font-size: .9rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; }
/* Dasselbe Rot wie Fehlermeldungen (Designsystem), wechselt im Dunkelmodus selbst.
   Vorher Rover-Rot hell und Chip-Rot dunkel (Janis, 13.11.2026). */
.ev-status-cancelled { color: var(--status-error); }
.ev-status-full { color: var(--text-muted); }
.ev-desc { color: var(--text-secondary); font-size: 1rem; line-height: 1.55; margin-top: 8px; max-width: 64ch; }
/* Einklappbare Beschreibung: sanfte Hoehen-Animation + Fade am unteren Rand */
.ev-desc-collapsible .ev-desc-text {
    overflow: hidden; max-height: 4.9em;
    transition: max-height .42s cubic-bezier(.22,.61,.36,1);
    -webkit-mask-image: linear-gradient(to bottom, #000 62%, transparent);
            mask-image: linear-gradient(to bottom, #000 62%, transparent);
}
.ev-desc-collapsible.is-open .ev-desc-text { max-height: 60em; -webkit-mask-image: none; mask-image: none; }
.ev-more {
    display: inline-flex; align-items: center; gap: 6px; margin-top: 10px;
    padding: 0; border: 0; background: none; color: var(--sc, var(--primary));
    font: inherit; font-size: 1rem; font-weight: 600; cursor: pointer;
}
.ev-more-ic { font-size: .8em; transition: transform .35s cubic-bezier(.22,.61,.36,1); }
.ev-desc-collapsible.is-open .ev-more-ic { transform: rotate(180deg); }
@media (prefers-reduced-motion: reduce) {
    .ev-desc-collapsible .ev-desc-text, .ev-more-ic { transition: none; }
}


/* ── teil-04-overlays.css ── */
/* ── GLOBALE SUCHE (Overlay) ── */
.nav-search { background: color-mix(in srgb, var(--text) 5%, transparent); border: 1px solid var(--border-card); color: var(--text); cursor: pointer; font-size: 1rem; width: 38px; height: 38px; justify-content: center; border-radius: 10px; display: inline-flex; align-items: center; margin-left: 2px; transition: color .2s, background .2s, border-color .2s; }
.nav-search:hover { color: var(--on-accent); background: var(--sc, var(--primary)); border-color: var(--sc, var(--primary)); }
/* Abstand Menue -> Lupe: Die Knoepfe sind eine eigene Gruppe und brauchen mehr
   Luft als zwischen zwei Menuepunkten. Vorher 18px vom Text „Service“ bis zur
   Lupe bei 30px zwischen den Punkten, das las sich wie ein weiterer Punkt
   (Janis, 05.11.2026). Jetzt 34px, in der kompakten Zone unten 26px. */
@media (min-width: 1251px) {
    .nav-main .nav-search:not(.js-mode-toggle) { margin-left: 18px; }
}
/* Ohne Weichzeichner: backdrop-filter über die ganze Seite, dazu eingeblendet,
   war teuer und flimmerte (Janis, 10.11.2026). Dafür etwas dunkler. */
#search-overlay { position: fixed; inset: 0; height: 100dvh; z-index: 1400; display: none; padding: 12vh 20px 20px; background: color-mix(in srgb, #000 62%, transparent); }
#search-overlay.is-open { display: block; animation: search-fade .18s ease; }
@keyframes search-fade { from { opacity: 0; } to { opacity: 1; } }
.search-box { max-width: 600px; margin: 0 auto; background: var(--bg-mid); border: 1px solid var(--border-card); border-radius: var(--radius-lg); box-shadow: 0 24px 60px rgba(var(--schwarz-rgb), .4); overflow: hidden; animation: search-pop .22s cubic-bezier(.22,.61,.36,1); }
@keyframes search-pop { from { transform: translateY(-12px); opacity: 0; } to { transform: translateY(0); opacity: 1; } }
.search-bar { display: flex; align-items: center; gap: 12px; padding: 16px 18px; border-bottom: 1px solid var(--border-card); color: var(--text-secondary); }
.search-bar > i { font-size: 1.1rem; }
.search-bar input { flex: 1; background: none; border: 0; outline: none; color: var(--text); font: inherit; font-size: 1.125rem; }
#search-input::-webkit-search-cancel-button, #search-input::-webkit-search-decoration { -webkit-appearance: none; appearance: none; }
.search-close { background: none; border: 0; color: var(--text-secondary); cursor: pointer; font-size: 1.15rem; padding: 4px 9px; border-radius: 8px; line-height: 1; transition: color .2s, background .2s; }
.search-close:hover { color: var(--sc, var(--primary)); background: color-mix(in srgb, var(--sc, var(--primary)) 12%, transparent); }
.search-foot { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px 12px; padding: 13px 22px; border-top: 1px solid var(--border-card); color: var(--text-muted); font-size: .9rem; }
.sf-item { display: inline-flex; align-items: center; gap: 7px; }
.sf-keys { display: inline-flex; align-items: center; gap: 3px; }
.search-foot kbd { display: inline-flex; align-items: center; justify-content: center; height: 26px; min-width: 26px; padding: 0 7px; font-size: .9rem; color: var(--text-secondary); border: 1px solid var(--border-card); border-radius: 6px; line-height: 1; }
/* Symbol-Tasten (Pfeile/⌘): quadratisch & ohne Seitenpolster → Glyph sitzt
   optisch mittig. Etwas Kopffreiheit (kleinerer Glyph), weil Unicode-Pfeile
   tief im Em-Feld sitzen und sonst nach unten versetzt wirken. */
.search-foot .ksym, .search-foot .kcmd { width: 26px; min-width: 26px; padding: 0; }
.search-foot .ksym { font-size: 1rem; }
.search-foot .kcmd { font-size: 1.2rem; }
/* Enter-Taste ist keine quadratische Symboltaste, sondern eine breitere,
   rechteckige „echte" Enter-Taste (wie auf einer Tastatur). */
.search-foot .kenter { width: auto; min-width: 44px; padding: 0 12px; }
.kplus { color: var(--text-muted); font-size: .9rem; }
@media (max-width: 700px) { .search-foot { display: none; } }
.search-results { max-height: 56vh; overflow-y: auto; padding: 8px; }
.search-hint { padding: 24px 16px; color: var(--text-secondary); text-align: center; }
.search-group { padding: 12px 14px 4px; font-size: .8rem; text-transform: uppercase; letter-spacing: .08em; color: var(--text-muted); }
/* Markierung in --text: im Ausschnitt geerbtes --text-muted kam auf der Toenung
   auf 2,8:1. Die Regel stand ausserdem doppelt (zweite Kopie unter .search-result-snip). */
.search-result-title mark, .search-result-snip mark { background: color-mix(in srgb, var(--sc, var(--primary)) 22%, transparent); color: var(--text); border-radius: 3px; padding: 0 2px; }
.search-result { display: flex; align-items: center; gap: 12px; padding: 12px 14px; border-radius: 10px; text-decoration: none; color: var(--text); }
.search-result > i { color: var(--text-secondary); width: 18px; text-align: center; }
.search-result-main { display: flex; flex-direction: column; flex: 1; min-width: 0; gap: 2px; }
.search-result-title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.search-result-snip { font-size: .9rem; color: var(--text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.search-result-type { font-size: .8rem; color: var(--text-muted); text-transform: uppercase; letter-spacing: .06em; }
/* Auf der getoenten aktiven Zeile reicht --text-muted nicht (3,1:1). */
.search-result:is(.is-active, :hover) .search-result-type { color: var(--text-secondary); }
.search-result.is-active, .search-result:hover { background: color-mix(in srgb, var(--sc, var(--primary)) 16%, transparent); }
/* „alle N zeigen" und die „Meintest du …?"-Wörter: Knöpfe, die wie Text
   aussehen. Kein Button-Stil, damit sie in der Liste nicht wichtiger wirken als
   die Treffer selbst. */
.search-mehr { display: block; width: 100%; text-align: left; padding: 8px 14px 12px 44px; border: 0;
    background: none; color: var(--text-muted); font: inherit; font-size: .9rem; cursor: pointer; }
.search-mehr:hover, .search-mehr:focus-visible { color: var(--sc, var(--primary)); text-decoration: underline; }
.search-meinte { display: inline-block; margin-top: 8px; font-size: .9rem; }
.search-vorschlag { border: 0; background: none; padding: 0 2px; font: inherit; cursor: pointer;
    color: var(--sc, var(--primary)); text-decoration: underline; }
@media (prefers-reduced-motion: reduce) { #search-overlay.is-open, .search-box { animation: none; } }

/* ── COOKIE-CONSENT-BANNER ── */
#consent-banner { position: fixed; left: 0; right: 0; bottom: 0; z-index: 1100; display: none; padding: 16px; }
#consent-banner.is-open { display: block; animation: consent-up .3s cubic-bezier(.22,.61,.36,1); }
@keyframes consent-up { from { transform: translateY(110%); } to { transform: translateY(0); } }
/* Solange der Banner offen ist, hält die Seite unten seinen Platz frei, damit
   er kein fokussiertes Element verdeckt (WCAG 2.4.11). --consent-h misst
   js/consent.js. */
html.consent-offen { scroll-padding-bottom: var(--consent-h, 0px); }
html.consent-offen body { padding-bottom: var(--consent-h, 0px); }
.consent-inner { max-width: 940px; margin: 0 auto; background: var(--bg-mid); border: 1px solid var(--border-card); border-radius: var(--radius-lg); box-shadow: 0 14px 44px rgba(var(--schwarz-rgb), .4); padding: 20px 24px; display: flex; gap: 22px; align-items: center; flex-wrap: wrap; }
.consent-text { flex: 1; min-width: 260px; color: var(--text-secondary); font-size: 1rem; line-height: 1.6; }
.consent-text strong { color: var(--text); }
.consent-text a { color: var(--sc, var(--primary)); }
/* ── Einstellungen: dieselbe Schale wie das Banner, aber mittig und mit einer
   Zeile je Dienst. Deshalb erbt #consent-prefs die Banner-Regeln ueber die
   gemeinsame .consent-inner und setzt hier nur die Abweichungen. */
#consent-prefs { position: fixed; inset: 0; z-index: 1110; display: none; padding: 16px;
    background: rgba(var(--schwarz-rgb), .45); overflow-y: auto; }
#consent-prefs.is-open { display: flex; align-items: center; justify-content: center; }
#consent-prefs .consent-inner { flex-direction: column; align-items: stretch; max-width: 560px; gap: 16px; }
/* Die Zeilen sind <label> um eine Checkbox: damit schaltet auch der Text, nicht
   nur das kleine Kaestchen — auf dem Handy der Unterschied zwischen benutzbar
   und nicht. */
.consent-row { display: flex; gap: 12px; align-items: flex-start; cursor: pointer;
    color: var(--text-secondary); font-size: .9rem; line-height: 1.55; }
/* Kästchen (Designsystem, Kaestchen, Janis 05.11.2026): Rahmen und Haken im
   Filzstift. Das echte <input> bleibt, unsichtbar über dem gezeichneten Kasten
   (appearance: none), damit Tastatur, Formular und Screenreader wie gewohnt
   gehen. Den Rahmen legt js/filz.js um .kasten, den Haken macht es aus dem
   Pfad mit data-filz-strich. Gewählt ist der Kasten gefüllt und dann ohne
   Rahmen. Markup: js/consent.js. */
.kasten { position: relative; flex: none; width: 20px; height: 20px; margin-top: 2px; border-radius: 5px; --filz-breite: 1.8px; }
.kasten > .filz { inset: 0; }
.kasten:has(input:checked) > .filz { opacity: 0; }
.kasten input { appearance: none; -webkit-appearance: none; position: absolute; inset: 0; width: 100%; height: 100%;
    margin: 0; border: 0; border-radius: 5px; background: transparent; cursor: pointer; }
.kasten > svg { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; overflow: visible; }
.kasten .fuellung { fill: var(--filz-tinte); opacity: 0; }
.kasten .haken { color: var(--bg); opacity: 0; }
.kasten:has(input:checked) :is(.fuellung, .haken) { opacity: 1; }
.kasten:has(input:focus-visible) { outline: 2px solid var(--sc, var(--primary)); outline-offset: 4px; border-radius: 6px; }
.kasten input:focus-visible { outline: none; }
.consent-row strong { color: var(--text); }
#consent-prefs .consent-btns { display: flex; gap: 10px; justify-content: flex-end; }
.consent-btns { display: flex; gap: 10px; flex-shrink: 0; }
@media (prefers-reduced-motion: reduce) { #consent-banner.is-open { animation: none; } }

/* ── GLOSSAR (Abkürzungs-Tooltips) ── */
/* Feine graue Punkte unter dem Wort, beim Hover in der Seitenfarbe (Janis,
   05.11.2026, statt der Wellenlinie). */
.gloss {
    cursor: help; position: relative;
    text-decoration: underline dotted 1px; text-underline-offset: 4px;
    text-decoration-color: color-mix(in srgb, var(--text) 45%, transparent);
}
.gloss:hover { text-decoration-color: var(--sc, var(--primary)); }
/* Glossarbegriffe sind mit tabIndex=0 anspringbar, also Bedienelemente. Hier stand
   `outline: none`, und sichtbar blieb allein eine andere FARBE an der gepunkteten
   Linie — eine reine Farbunterscheidung, und die genügt für einen Fokus nicht
   (2.4.7, Stufe AA). Dazu :focus statt :focus-visible, es griff also auch bei der
   Maus. Jetzt derselbe Ring wie überall sonst auf der Seite. */
.gloss:focus-visible {
    border-bottom-color: var(--sc, var(--primary));
    outline: 2px solid var(--sc, var(--primary)); outline-offset: 3px; border-radius: 3px;
}
/* Der Tooltip liegt als EINZELNES Element am <body> (js/glossar.js portiert den
   Inhalt dorthin), damit ihn weder overflow:hidden NOCH ein transform der Karten
   (Hover-Lift macht die Karte zum Containing-Block für position:fixed)
   abschneiden kann. .gloss-pop im Wort ist nur versteckter Datenhalter. */
.gloss .gloss-pop { display: none; }
.gloss-tip {
    position: fixed; z-index: 2000; width: max-content; max-width: 280px;
    background: var(--bg-mid); color: var(--text);
    border: 1px solid var(--border-card); border-radius: 10px; padding: 9px 13px;
    font-size: .9rem; line-height: 1.45; font-weight: 400; box-shadow: 0 10px 30px rgba(var(--schwarz-rgb), .32);
    opacity: 0; visibility: hidden; transition: opacity .15s; pointer-events: none;
}
.gloss-tip strong { font-weight: 700; }   /* Begriff fett, Erklärung normal */
.gloss-tip.is-on { opacity: 1; visibility: visible; }
@media (prefers-reduced-motion: reduce) { .gloss-tip { transition: none; } }
.sidebar-box {
    background: var(--bg-mid); border: 1px solid rgba(var(--tinte-rgb), .08);
    border-radius: var(--radius-lg); padding: 28px; margin-bottom: 18px;
}
.sidebar-box :is(h2, h4) { font-family: var(--font-heading); font-size: 1.125rem; color: var(--text); margin-bottom: 14px; }
.sidebar-box p { color: var(--text-secondary); font-size: 1rem; line-height: 1.65; margin-bottom: 16px; }


/* ── teil-05-bereiche.css ── */
/* ── AUSBILDUNG ── */
.ab-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 2px; border-radius: var(--radius-lg); overflow: hidden; }
.ab-block { background: var(--bg-mid); padding: 46px 40px; position: relative; overflow: hidden; }
.ab-block.dark { background: var(--bg); }
.ab-glow { display: none; }
.ab-block h3 { font-family: var(--font-heading); font-size: 1.8rem; color: var(--text); margin-bottom: 12px; }
.ab-block p { color: var(--text-secondary); font-size: 1rem; line-height: 1.68; margin-bottom: 22px; }

/* ── ACCORDION (Prävention) ── */
.accord { margin-bottom: 12px; background: var(--bg-mid); border-radius: var(--radius-lg); overflow: hidden; border: 1px solid var(--border-card); }
.accord-head { padding: 20px 26px; display: flex; justify-content: space-between; align-items: center; cursor: pointer; }
.accord-head :is(h2, h3, h4) { font-family: var(--font-heading); font-size: 1.375rem; color: var(--text); }
.accord-head i { color: var(--sc, var(--primary)); transition: transform .3s; font-size: 1rem; }
.accord.open .accord-head i { transform: rotate(180deg); }
.accord-body { display: none; padding: 0 26px 24px; color: var(--text-secondary); font-size: 1rem; line-height: 1.68; }
.accord.open .accord-body { display: block; }

/* ── SERVICE ── */
.service-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr)); gap: 18px; --mehr-zeilen: 4; }   /* Kartentext auf vier Zeilen gekürzt, js/karten-mehr.js */
/* Genau 4 Karten: sauber 2×2 statt 3+1 (keine einzelne Karte allein in der
   letzten Zeile). Ab 5 Karten greift wieder das normale auto-fit.
   :not(.as-list) ist Pflicht — die Listenansicht ist IMMER einspaltig, und
   diese Regel gewinnt sonst gegen .service-grid.as-list (:has zaehlt bei der
   Spezifitaet mit). */
@media (min-width: 700px) {
    .service-grid:not(.as-list):has(> .srv-card:nth-child(4):last-child) { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
/* Festes 2-Spalten-Raster (z.B. Mehrwert-Karten), einspaltig auf schmal */
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }
@media (max-width: 680px) { .grid-2 { grid-template-columns: 1fr; } }
.srv-card {
    background: var(--bg-mid); border: 1px solid var(--border-card);
    border-radius: var(--radius-lg); padding: 30px 28px;
    transition: all .3s; position: relative; overflow: hidden;
    display: flex; flex-direction: column;
}
/* Button-Reihe unten in der Karte, mit Abstand zum Text (statt direkt drunter) */
.srv-card .dl-row { margin-top: auto; padding-top: 20px; }
/* Mit Text darüber (der Normalfall) griff stattdessen die spätere Regel
   .article-prose + .dl-row (22px), und die Knöpfe standen in jeder Karte
   auf anderer Höhe (Janis, 11.11.2026, /ak/praevention/schulungen). Höhere
   Spezifität, damit die Reihe unten bündig bleibt; den Abstand zum Text gibt
   padding-top. */
.srv-card .article-prose + .dl-row { margin-top: auto; }
.srv-icon {
    transition: transform .25s ease;
    width: 50px; height: 50px; background: color-mix(in srgb, var(--sc, var(--primary)) 12%, transparent); border-radius: 10px;
    display: flex; align-items: center; justify-content: center;
    font-size: 20px; color: var(--sc, var(--primary)); margin-bottom: 18px;
}
.srv-card :is(h2, h3) { font-family: var(--font-heading); font-size: 1.375rem; color: var(--text); margin-bottom: 10px; }
.srv-card p { color: var(--text-secondary); font-size: 1rem; line-height: 1.62; margin-bottom: 22px; }
.srv-text > p:last-child { margin-bottom: 0; }

/* ── DV (ÜBER UNS) ── */
.dv-split { display: grid; grid-template-columns: 1fr 1fr; }
.dv-left { background: var(--bg-mid); padding: 80px 52px; display: flex; flex-direction: column; justify-content: center; }
.dv-right { position: relative; padding: 80px 52px; overflow: hidden; display: flex; flex-direction: column; justify-content: flex-end; cursor: pointer; min-height: 480px; }
.dv-right-bg { position: absolute; inset: 0; background: url('../img/fotos/lagerplatz.jpg') center/cover; opacity: .22; transition: opacity .4s; }
.dv-right:hover .dv-right-bg { opacity: .38; }
.dv-right-overlay { position: absolute; inset: 0; background: linear-gradient(to top, rgba(var(--overlay-rgb),.95) 30%, rgba(var(--overlay-rgb),.4) 100%); }
.dv-right-content { position: relative; z-index: 2; }
.dv-ak-list {
    list-style: none; margin-top: 16px;
    display: grid; grid-template-columns: 1fr 1fr; gap: 13px 28px;
}
.dv-ak-list li {
    font-size: 1rem; color: var(--text-secondary);
    display: flex; align-items: center; gap: 9px;
}
.contact-row { display: flex; align-items: flex-start; gap: 14px; margin-bottom: 20px; }
.contact-row i { width: 22px; color: var(--sc, var(--primary)); font-size: 16px; flex-shrink: 0; margin-top: 2px; }
.contact-row span { color: var(--text-secondary); font-size: 1rem; line-height: 1.6; }
.contact-row a { color: var(--text-secondary); text-decoration: none; transition: color .2s; }
.contact-row a:hover { color: var(--sc, var(--primary)); }

/* Vorstand cards */
.vorstand-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 230px), 1fr)); gap: 18px; margin-top: 40px; }
.vs-card {
    background: var(--bg-mid); border-radius: var(--radius-lg);
    padding: 26px 24px; border: 1px solid var(--border-card); text-align: center;
}
.vs-avatar {
    width: 64px; height: 64px; border-radius: 50%;
    background: var(--bg-card); border: 2px solid color-mix(in srgb, var(--sc, var(--primary)) 30%, transparent);
    margin: 0 auto 14px; display: flex; align-items: center; justify-content: center;
    font-family: var(--font-heading); font-size: 1.4rem; color: var(--sc, var(--primary));
}
.vs-name { font-family: var(--font-heading); font-size: 1.125rem; color: var(--text); margin-bottom: 5px; }
.vs-role { font-family: var(--font-ui); font-size: 1rem; color: var(--text-muted); letter-spacing: .1em; text-transform: uppercase; }
.vs-email { font-size: 1rem; color: var(--sc, var(--primary)); margin-top: 8px; display: block; text-decoration: none; }
.vs-email:hover { color: var(--link-hover); }

/* DiLei grid */
.dilei-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 230px), 1fr)); gap: 14px; margin-top: 28px; }
.dl-person { background: var(--bg-mid); border-radius: 10px; padding: 18px 16px; border: 1px solid var(--border-card); text-align: center; }
.dl-person .vs-avatar { width: 48px; height: 48px; font-size: 1rem; }
.dl-person .vs-name { font-size: 1rem; }

/* ── AK ÜBERSICHT ── */
.ak-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr)); gap: 16px; }
.ak-card {
    background: var(--bg-mid); border-radius: var(--radius-lg);
    padding: 26px; border: 1px solid var(--border-card); transition: all .3s;
    position: relative; overflow: hidden;
    display: flex; flex-direction: column;
}
/* „Mehr erfahren" an der Kartenunterkante halten — sonst klebt der Button je
   nach Textlänge unterschiedlich hoch am Absatz (Reihe wirkt unruhig).
   align-self, damit der Button nicht auf Kartenbreite gezogen wird. */
.ak-card .qc-link { margin-top: auto; align-self: flex-start; }
/* Titel in der AK-Farbe. --akc ist im Panel immer ein --ak-*-Ton, und die sind als
   Textfarbe in beiden Modi auf AA geprueft: gemessen 4,96 bis 9,38 auf der Karte
   (02.10.2026). Eine --stufe-*-Farbe haette hier nichts zu suchen (DESIGN-SYSTEM.md §8). */
.ak-card :is(h2, h3) { font-family: var(--font-heading); font-size: 1.375rem; color: var(--akc, var(--text)); margin-bottom: 7px; }
/* Gefüllte Lilie mit Filzstift-Kante für Stufen- und AK-Zeichen (Janis,
   06.11.2026): Form der offiziellen Lilie, Kante wie #filz-tinte auf den
   Icons. Der Filter steckt in der Datei selbst, weil ein CSS-Filter auf einem
   maskierten Element vor der Maske wirkt und die Kante glatt bliebe.
   --lilie-mask (Designsystem) bleibt für kleine Listenhaken. */
/* Zeichen über dem Titel (blocks/akgrid.php): Stufenlilie oder Icon in der
   AK-Farbe. Die Lilie ist die gefüllte Filzstift-Lilie (img/logo/lilie-filz.svg, aus dem Designsystem),
   so folgt sie hell und dunkel der aufgehellten AK-Farbe. */
.ak-card-icon { display: block; width: 40px; height: 40px; margin-bottom: 14px; color: var(--akc, var(--primary)); font-size: 2rem; line-height: 40px; }
.ak-card-lilie { background-color: var(--akc, var(--primary)); -webkit-mask: url('/img/logo/lilie-filz.svg') left center/contain no-repeat; mask: url('/img/logo/lilie-filz.svg') left center/contain no-repeat; }
.ak-card p { color: var(--text-secondary); font-size: 1rem; line-height: 1.6; margin-bottom: 18px; }

/* ── AK DETAIL ── */
.ak-hero { position: relative; height: 48vh; min-height: 320px; overflow-x: clip; overflow-y: visible; display: flex; align-items: flex-end; }   /* y frei: das AK-Zeichen ragt über die Unterkante */
.ak-hero::after {
    content: '';
    position: absolute;
    right: -4%; top: -8%;
    width: 340px; height: 340px;
    background: url('../img/lilie-fill.svg') center/contain no-repeat;
    opacity: .04;
    pointer-events: none;
    z-index: 1;
}
/* object-position kommt als style vom Fokuspunkt (plugins/dpsg-bildgroessen), sonst Mitte */
.ak-hero-bg { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: center; display: block; }
.ak-hero-ov { position: absolute; inset: 0; background: linear-gradient(to right, rgba(var(--overlay-rgb),.95) 0%, rgba(var(--overlay-rgb),.5) 100%); }
.ak-hero-c { position: relative; z-index: 2; width: 100%; padding-bottom: 40px; }
.ak-intro-grid { display: grid; grid-template-columns: 1fr 280px; gap: 48px; align-items: start; }
/* Personen-Block mit Info-Karte: Personen so breit wie ihre Karten, die
   Info-Karte füllt den Rest (--pers-spalten setzt blocks/personen.php). */
@media (min-width: 961px) {
    .pers-mit-info { grid-template-columns: auto minmax(280px, 1fr); }
    .pers-mit-info .ak-members { grid-template-columns: repeat(var(--pers-spalten, 3), minmax(200px, 260px)); }
}
/* Ueberschrift im Infokasten. Sie ersetzt seit dem 23.08. den Kicker „Auf einen
   Blick": ohne ihn waere der Kasten eine Liste aus drei Zeilen ohne Anlass.
   Masse wie bei .sidebar-box, damit Kaesten gleich aussehen. */
.ak-info-card :is(h2, h3, h4) {
    font-family: var(--font-heading); font-size: 1.125rem; color: var(--text);
    margin-bottom: 14px;
}
.ak-info-card { background: var(--bg-mid); border: 1px solid rgba(var(--tinte-rgb), .12); border-radius: var(--radius-lg); padding: 24px; }
.ak-info-row { display: flex; align-items: center; gap: 10px; min-height: var(--control-height); box-sizing: border-box; padding: 10px 0; border-bottom: 1px solid rgba(var(--tinte-rgb), .09); font-size: 1rem; color: var(--text-secondary); }
.ak-info-row:last-child { border-bottom: none; padding-bottom: 0; }
/* Kurzer Text unter dem Titel der Info-Karte (Feld sidecardtext im Personen-
   Baustein), z. B. „Kommt gerne vorbei" neben der Anschrift des DiBü. */
.ak-info-text { font-size: 1rem; line-height: 1.55; color: var(--text-secondary); margin: 0 0 8px; }
.ak-info-row i { width: 16px; text-align: center; color: var(--sc, var(--primary)); flex-shrink: 0; }
/* Aufgaben als Lilien-Aufzählung (zweispaltig), nicht als Kästchen-Reihe: als
   Einzelkarten wirkte die Liste unruhig und die Kästen versprachen Interaktion,
   die es nicht gibt. */
/* Zwei Spalten, die jede für sich fließen. Als Raster war jede Zeile so hoch
   wie ihr längster Eintrag, ein langer Satz rechts riss links eine Lücke auf
   (Janis, 11.11.2026, /ak/oekologie). */
.ak-tasks { columns: 2; column-gap: 44px; }
.ak-tasks > .ak-task { break-inside: avoid; margin-bottom: 8px; }
.ak-task { display: flex; align-items: flex-start; gap: 12px; padding: 0; background: none; border: 0; font-size: var(--font-size-reading); color: var(--text-secondary); line-height: 1.62; }
.ak-task i { color: var(--sc, var(--primary)); margin-top: .34em; flex-shrink: 0; }
/* Größe in rem, NICHT in em: das Element hatte font-size:0 (um die FA-Glyphe zu
   unterdrücken), womit .85em = 0px ergab — die Lilie war unsichtbar. Die Glyphe
   blendet ohnehin ::before aus, also braucht es font-size:0 nicht. */
.ak-task .fa-check { width: .8rem; height: .8rem; display: inline-block; background-color: var(--sc, var(--primary)); -webkit-mask: var(--lilie-mask) center/contain no-repeat; mask: var(--lilie-mask) center/contain no-repeat; }
.ak-task .fa-check::before { display: none; }
/* auto-fill statt auto-fit: Seit die Fotos quadratisch sind, würden zwei
   Karten in einer Reihe sonst auf die halbe Breite gedehnt und als Quadrat
   riesig (gemessen 397px beim Diözesanbüro). So bleibt jede Karte eine Spalte. */
.ak-members { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 230px), 1fr)); gap: 14px; }
/* Handy: zwei Spalten, sonst wäre jedes quadratische Foto so breit wie der
   Bildschirm und eine Teamliste mehrere Bildschirme lang */
@media (max-width: 560px) { .ak-members { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; } }
.ak-member { background: var(--bg-mid); border-radius: var(--radius-lg); overflow: hidden; border: 1px solid var(--border-card); transition: all .3s; }
/* Quadratisch statt 140px hoch (Janis, 04.11.2026): Im 2:1-Streifen fehlte bei
   jedem Porträt oben oder unten etwas, Kinn oder Haaransatz. Die Fotos unter
   img/team/ sind dafür quadratisch zugeschnitten, Kopf in der oberen Hälfte. */
.ak-mimg { aspect-ratio: 1 / 1; overflow: hidden; position: relative; }
.ak-mimg img { width: 100%; height: 100%; object-fit: cover; object-position: center 30%; filter: grayscale(15%); transition: filter .3s, transform .4s; }
.ak-member:hover .ak-mimg img { filter: grayscale(0%); transform: scale(1.05); }
.ak-mbody { padding: 14px; }
.ak-mname { font-family: var(--font-heading); font-size: 1rem; color: var(--text); margin-bottom: 3px; }
.ak-mrole { font-family: var(--font-ui); font-size: 1rem; color: var(--akc,var(--sc, var(--primary))); letter-spacing: .07em; text-transform: uppercase; }
.ak-dls { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 280px), 1fr)); gap: 12px; --mehr-zeilen: 2; }
.ak-dl { background: var(--bg-mid); border-radius: var(--radius-lg); padding: 18px; border: 1px solid var(--border-card); display: flex; align-items: stretch; gap: 12px; cursor: pointer; transition: all .25s; }
.ak-dl-ico { align-self: flex-start; width: 40px; height: 40px; border-radius: 8px; background: color-mix(in srgb,var(--sc, var(--primary)) 12%,transparent); display: flex; align-items: center; justify-content: center; font-size: 16px; color: var(--sc, var(--primary)); flex-shrink: 0; }
/* Kompakt, weil die höchste Kachel die Höhe für alle vorgibt (js/karten-mehr.js):
   Titel höchstens zwei Zeilen, „Auf der Seite“ einzeilig mit „Mehr anzeigen“
   rechts daneben (Janis, 15.11.2026). Der volle Titel steht im title-Attribut
   und für Vorlesehilfen ohnehin im Link. */
/* Textspalte über die volle Kachelhöhe, die Fußzeile („Auf der Seite“,
   „Mehr anzeigen“) unten am Rand. Sonst stand sie eingeklappt höher als
   aufgeklappt, und unter ihr blieb die Fläche der gemeinsamen Mindesthöhe
   leer (Janis, 15.11.2026). */
.ak-dl-text { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
/* „Mehr anzeigen“ in eigener Zeile über „Auf der Seite“: nebeneinander
   schnitt der Knopf die Seitenangabe ab („AK Ök…“, Janis 15.11.2026). */
.ak-dl-fuss { margin-top: auto; padding-top: 6px; display: flex; flex-direction: column; align-items: flex-start; gap: 2px; }
.ak-dl-fuss:empty { display: none; }
.ak-dl-name {
    display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden;
    font-size: 1rem; font-weight: 700; color: var(--text); text-decoration: none;
}
/* Der Titel ist der Link und deckt die ganze Kachel ab (snippets/dateiliste.php) */
.ak-dl-name::after { content: ''; position: absolute; inset: 0; z-index: 1; }
.ak-dl-name:focus-visible { outline: none; }
.ak-dl:has(.ak-dl-name:focus-visible) { outline: 2px solid var(--sc, var(--primary)); outline-offset: 3px; }
.ak-dl-meta { font-size: 1rem; color: var(--text-muted); }
/* Optionale Beschreibung unter Name und Groesse. Das Icon sitzt immer oben. */
.ak-dl-desc { font-size: var(--font-size-reading); color: var(--text-secondary); line-height: 1.5; margin-top: 5px; }
/* Seit 15.11.2026 dieselben Kacheln überall, wo es Dateien gibt
   (snippets/dateiliste.php): AK-Seiten, Baustein „Dateien“, Übersicht unter
   /service/downloads. Dort steht zusätzlich, auf welcher Seite die Datei
   verlinkt ist. */
.ak-dl-auf { max-width: 100%; font-size: 1rem; color: var(--text-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ak-dl-fuss > .mehr-knopf { order: -1; margin: 0; padding: 0; }
.dl-gruppe + .dl-gruppe { margin-top: 36px; }
.dl-gruppe-titel { font-family: var(--font-heading); font-size: 1.25rem; color: var(--text); margin: 0 0 14px; }
/* Das Suchfeld nimmt die Breite: Neben sechs Chips blieben ihm am Desktop
   rund 130 px, und der Platzhalter war abgeschnitten. Die Rubriken klappt
   js/filterleiste.js damit ins Auswahlfeld daneben. */
.dl-filter { margin-bottom: 28px; flex-wrap: wrap; }
.dl-filter .fb-search { flex: 1 1 100%; }
.dl-block .sec-sub { margin-bottom: 24px; }
.dl-block .dl-row { margin-top: 18px; }
/* Dateien aus der Knopfzeile eines Fließtexts (blocks/richtext.php) */
.dl-im-text { margin-top: 22px; }
.dl-im-text + .dl-row { margin-top: 18px; }

/* ── STUFEN ── */
.stufen-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 330px), 1fr)); gap: 16px; }
.stufen-card { border-radius: var(--radius-lg); padding: 30px 24px; border: 1px solid var(--border-card); border-bottom: 3px solid var(--sc); overflow: hidden; position: relative; transition: transform .3s, box-shadow .3s; cursor: pointer; }
.stufen-card-bg { position: absolute; inset: 0; background: color-mix(in srgb, var(--sc) 6%, var(--bg-mid)); }
.stufen-card-content { position: relative; z-index: 1; }
.stufen-card h3 { font-family: var(--font-heading); font-size: 1.375rem; color: var(--text); margin-bottom: 6px; hyphens: auto; overflow-wrap: break-word; }
.stufen-card .age { font-family: var(--font-ui); font-size: .8rem; font-weight: 700; text-transform: uppercase; color: var(--sc); letter-spacing: .12em; margin-bottom: 10px; }
.stufen-card p { color: var(--text-secondary); font-size: 1rem; line-height: 1.6; }

/* ── STÄMME ── */
.stamm-search {
    /* --control-height ist die Hoehe JEDES Bedienelements (DESIGN-SYSTEM.md §6). Das Feld
       stand auf 13px Innenabstand und war damit 47px hoch, drei Pixel ueber dem
       Biber-Chip daneben — in der breiten Leiste kaum zu sehen, in der schmalen
       Spalte des Finders sofort. */
    width: 100%; height: var(--control-height); padding: 0 22px;
    background: rgba(var(--tinte-rgb), .08); border: 1px solid rgba(var(--tinte-rgb), .16);
    border-radius: 999px; color: var(--text);
    font-family: var(--font-ui); font-size: 1rem;
    transition: border-color .3s;
}
/* Suche mit Treffer-Zähler im Feld (Stammesfinder) */
.stamm-search-wrap { position: relative; flex: 1; min-width: 240px; display: flex; align-items: center; }
.stamm-search-wrap .stamm-search { margin: 0; padding-right: 105px; }
.stamm-count {
    position: absolute; right: 20px;
    color: var(--text-muted); font-size: .9rem; white-space: nowrap;
    pointer-events: none;
}
.stamm-search:focus-visible {
    /* Vorher outline:none, sichtbar war nur eine andere Rahmenfarbe auf 1px.
       Der Ring kommt dazu, die weiche Färbung bleibt. */
    outline: 2px solid var(--sc, var(--primary)); outline-offset: 2px;
    border-color: var(--sc, var(--primary));
    background: color-mix(in srgb, var(--sc, var(--primary)) 5%, transparent);
}
.stamm-search::placeholder { color: var(--text-muted); }
/* ── STAMMESFINDER: Suchspalte und Karte nebeneinander ───────────────────────
   Vorher lag die Karte oben ueber die volle Breite und darunter ein Raster aus
   32 Kacheln — Suche und Karte waren nie gleichzeitig zu sehen. Jetzt teilen
   sie sich eine feste Hoehe: die Liste scrollt in sich, die Karte steht.

   Die Hoehe ist bewusst an den Bildschirm gebunden und nach oben gedeckelt.
   Ohne 74vh waere die Liste auf einem Laptop laenger als das Fenster, ohne die
   680px waere die Karte auf einem grossen Monitor ein Plakat. */
.stammfinder {
    display: grid;
    grid-template-columns: minmax(290px, 370px) 1fr;
    grid-template-rows: auto 1fr;
    grid-template-areas: "kopf karte" "liste karte";
    gap: 16px 22px;
    height: min(74vh, 680px);
}
/* Suche immer auf voller Breite, Filter darunter. Nebeneinander passt es in der
   schmalen Spalte nur knapp — und „knapp" heisst, dass es je nach Beschriftung
   des Filters mal umbricht und mal nicht. */
.sf-kopf { grid-area: kopf; display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }
.sf-kopf .stamm-search-wrap { flex: 1 1 100%; }
/* Der Filter neben einem 44px-Suchfeld in einer 370er-Spalte war zu wuchtig.
   Kleiner und mit demselben runden Abschluss wie das Feld darueber — er ist
   ein Zusatz zur Suche, keine zweite Hauptsache. Nur hier: die vier anderen
   Filterleisten der Seite behalten die Systemhoehe. */
.sf-kopf .nf-chip-klein {
    height: 34px; padding: 0 14px; font-size: .9rem; font-weight: 600;
    border-radius: 999px;
}
.sf-karte { grid-area: karte; min-height: 0; display: flex; flex-direction: column; gap: 8px; }
/* Quellenangabe unter der Karte statt in ihrer Ecke — Begruendung im Template. */
.sf-quelle { margin: 0; font-size: .8rem; line-height: 1.5; color: var(--text-muted); }
.sf-quelle a { color: inherit; text-decoration: underline; text-underline-offset: 2px; }
.sf-quelle a:hover { color: var(--sc, var(--primary)); }

/* „Wo bin ich" — sitzt unter der Zoom-Leiste und uebernimmt deren Form, damit
   die drei Knoepfe als eine Gruppe gelesen werden. Leaflet liefert Rahmen und
   Groesse ueber .leaflet-bar; hier kommt nur das Icon dazu. */
.sf-ortung a { display: flex !important; align-items: center; justify-content: center; }
/* color: inherit, nicht --primary. Sonst steht ein blaues Fadenkreuz neben
   einem weissen Plus und Minus — im Doodle-Look faerbt --filz-tinte alle drei. */
.sf-ortung i { font-size: .95rem; color: inherit; }
.sf-ortung.is-suchend i { animation: sf-ortung-dreh 1s linear infinite; }
@keyframes sf-ortung-dreh { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
    /* Ohne Drehung braucht es trotzdem ein Zeichen, dass gerade gesucht wird. */
    .sf-ortung.is-suchend i { animation: none; opacity: .45; }
}
/* FLEX, NICHT GRID — und das ist keine Geschmacksfrage.

   Als Grid mit fester Hoehe schrumpften die 32 Zeilen auf 5,65px zusammen:
   (429 − 31×8 Abstand) / 32. Sichtbar blieb von jeder Karte ein Strich, der
   Rest lag unter `overflow: hidden`. Genau so hat Janis es gemeldet.

   Der Grund ist eine Kombination aus zwei Dingen, die einzeln richtig sind:
   die Liste hat eine feste Hoehe (sie soll ja in sich scrollen), und `.stamm`
   erbt `overflow: hidden` aus dem Karten-Hover-System. Ein Grid-Item mit
   overflow ungleich visible hat die automatische Mindesthoehe 0 — es DARF
   unter seinen Inhalt schrumpfen, und bei knappem Platz tut es das auch.

   Flex hat dieselbe Falle (flex-shrink ist standardmaessig 1), deshalb steht
   unten `flex: none`. Wer hier wieder auf Grid geht, braucht
   `grid-auto-rows: min-content`. */
.sf-liste {
    grid-area: liste;
    list-style: none; margin: 0; padding: 0 2px 0 0;
    overflow-y: auto; min-height: 0;
    display: flex; flex-direction: column; gap: 8px;
    /* scrollbar-gutter haelt die Breite konstant: ohne ihn ruckt die Liste beim
       Filtern seitlich, sobald sie kurz genug fuer keinen Balken wird. */
    scrollbar-gutter: stable;

    /* Weicher Rand statt harter Kante. Die beiden Werte setzt js/staemme.js je
       nach Scrollstand: oben nur, wenn schon gescrollt wurde, unten nur,
       solange noch etwas kommt. Steht die Liste am Ende, ist der Verlauf weg —
       sonst sieht die letzte Karte dauerhaft angeschnitten aus. */
    --fade-oben: 0px;
    --fade-unten: 0px;
    mask-image: linear-gradient(to bottom,
        transparent 0, #000 var(--fade-oben),
        #000 calc(100% - var(--fade-unten)), transparent 100%);
}
.sf-liste > li { flex: none; }


