/* ERZEUGTE DATEI — NICHT BEARBEITEN.
 *
 * Zusammengesetzt aus data/css-parts/ durch bin/build_overrides.php.
 * Änderungen gehören in den passenden Teil; danach das Skript mit
 * --schreiben laufen lassen. Wer hier direkt editiert, verliert es beim
 * nächsten Build.
 *
 * Teile in dieser Reihenfolge:
 *   - 00-foundation-navigation.css
 *   - 10-module.css
 *   - 20-header-vorlagen-utilities.css
 *   - 90-schutzebene.css
 */

/**
 * SWS Foundation CSS — generisch, theme-neutral.
 *
 * Wird vom sws_starter-Addon beim install nach assets/css/sws-overrides.css
 * kopiert. Projekt-spezifische Anpassungen NICHT direkt hier — eigene CSS
 * in einer projekt-spezifischen Override-Datei (z. B. sws-overrides-project.css)
 * ergänzen oder im Tailwind-Manager über Tokens steuern.
 *
 * Section-Marker: ### === Bereich === ### — pro Bereich eine zusammen-
 * gehörige CSS-Sektion.
 *
 * Hex-Defaults sind Tailwind-Palette (blue-600 / amber-500 / slate-900) — Projekt
 * überschreibt via Tokens (--color-primary, --color-accent, --section-link-bg etc.)
 * aus dem Tailwind-Manager.
 */

/*
 * sws-overrides.css
 *
 * Utilities, die Tailwind v4 nicht automatisch aus `@theme`-Tokens mit nicht-standardisierten
 * Shade-Suffixen (wie -70, -50, -30) erzeugt. Werden hier manuell definiert.
 * Wirkt ohne Tailwind-Rebuild.
 */

/* Horizontalen Overflow global unterdruecken.
   Hintergrund: Dekorationen wie `.m-news-section::before` (Welle) sind bewusst
   10 px breiter als ihre Sektion, um Subpixel-Gaps an den Sektion-Kanten zu
   eliminieren. Der 5-px-Ueberstand rechts erzeugt aber `scrollWidth > clientWidth`,
   wodurch die Seite bei allen Viewports minimal horizontal scrollbar wird.
   `overflow-x: clip` auf html + body blockt das Scrollen, ohne einen Scroll-Container
   anzulegen (wie `overflow-x: hidden` es taete) — `position: sticky` bleibt intakt.

   ACHTUNG, DIE KEHRSEITE: Genau weil `clip` KEINEN Scroll-Container anlegt, ist
   Inhalt, der breiter sein muss als der Viewport, nicht „abgeschnitten, aber
   erreichbar" — er ist weg. Kein Rollbalken, kein Wischen, keine Meldung.

   Wer breiten Inhalt hat (Tabellen, Code-Blöcke, weite Diagramme), braucht
   deshalb einen EIGENEN Scroll-Container. Dafür gibt es `.m-table-wrap` (siehe
   unten); redaktionelle Tabellen aus dem Editor bekommen ihn automatisch.

   Gemeldet aus HGK-Events (16.08.2026): Deren Preistabelle war bei 382 px
   Viewport 466 px breit — 84 px lagen unerreichbar außerhalb, zwei komplette
   Spalten. Die Vorfahrenkette bis `html` war durchgehend `overflow-x: visible`,
   es gab also nichts, was hätte schieben können. */
html, body { overflow-x: clip; }

/* Scroll-Container für breiten Inhalt — die Gegenstelle zur Sperre oben.
 *
 * `overscroll-behavior-x: contain` verhindert, dass das Wischen am Ende der
 * Tabelle auf die Seite überspringt (auf Touchgeräten sonst der Normalfall:
 * Man scrollt die Tabelle zu Ende und die Seite wandert seitlich mit).
 *
 * `-webkit-overflow-scrolling: touch` stammt aus dem Hausmuster von HGK-Events
 * (`.aiKbArticleTableWrap` im Cockpit, der tabellenlastigsten Anwendung dort).
 * Es schaltet auf iOS das Schwungscrollen ein — aber nur bis iOS 12: seit
 * iOS 13 ist Schwungscrollen der Default und die Eigenschaft wirkungslos. Sie
 * steht trotzdem hier, weil sie auf allem anderen folgenlos ist und alte Geräte
 * ohne sie am Finger kleben. */
.m-table-wrap {
    overflow-x: auto;
    overscroll-behavior-x: contain;
    -webkit-overflow-scrolling: touch;
    max-width: 100%;
}

/* Spaltenköpfe einzeilig — ebenfalls aus dem HGK-Hausmuster.
 *
 * Zur Herleitung, weil die Meldung sie anders begründet hat („umbrechende
 * Spaltenköpfe machen die Tabelle noch breiter"): Umbrechen macht eine Spalte
 * NICHT breiter, sondern ist gerade das, was sie schmal werden lässt — die
 * Mindestbreite einer Spalte ist ihr längstes unteilbares Wort. Der Gewinn liegt
 * woanders: Ohne `nowrap` bricht der Browser bevorzugt die kurzen Kopfzeilen um
 * und lässt die Datenzeilen einzeilig, die Kopfzeile wird also zum mehrzeiligen
 * Türmchen über einer ruhigen Tabelle. Weil der Wrapper die Mehrbreite auffängt,
 * ist die einzeilige Kopfzeile hier gratis zu haben — ohne Scroll-Container wäre
 * dieselbe Regel schädlich.
 *
 * Bewusst NUR am Opt-in-Wrapper, nicht an der Editor-Regel unten: Dort würde die
 * Vorgabe bestehende redaktionelle Tabellen auf allen Sites verbreitern und
 * manche erst dadurch schiebbar machen. Wer `.m-table-wrap` setzt, entscheidet
 * das bewusst; wer eine Tabelle in den Editor stellt, hat nichts entschieden. */
.m-table-wrap thead th { white-space: nowrap; }

/* Redaktionelle Tabellen bekommen den Scroll-Container ohne Zutun.
 *
 * Ein Redakteur, der im Editor eine Tabelle einfügt, kann kein Markup um sie
 * herumlegen — er würde den Fehler also unvermeidlich auslösen. `display: block`
 * macht die Tabelle selbst zum Scroll-Container; sie wächst dann mit ihrem
 * Inhalt statt sich auf die Containerbreite zu quetschen, und das ist hier
 * gewollt: Eine Tabelle, die nicht passt, soll schiebbar sein, nicht gestaucht.
 *
 * `:where()` hält die Spezifität bei (0,0,1) — eine Site überschreibt das mit
 * einer einzigen Klasse (siehe .claude/rules/css-spezifitaet-ist-ein-vertrag.md). */
:where(.m-bg-text, .m-bb-text, .m-tis-text, .m-tis-body-col, .m-tis-body-single,
       .m-news-detail-text, .m-news-card-text, .m-ap-vita, .m-ap-body,
       .m-kachel-body, .m-dl-tile-body, .m-abt-text, .m-bg-infobox-body) table {
    display: block;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    max-width: 100%;
}

/* === Foundation · Layout-Engine (Page Composer) === */
/*
 * Projekt-Konfiguration. Werte werden von den universellen Layout-Klassen aus dem
 * Page-Composer-Addon konsumiert (siehe sws_page_composer/assets/css/sws-layouts.css).
 * Wenn ein anderes
 * Projekt andere Content-Breiten/Gaps braucht, hier überschreiben oder selektiv auf
 * Section-Ebene neu setzen.
 */
/* 3-Zonen-Modell der Layout-Breiten:
     --max-w       Content-Zone (Text, reguläre Inhalte)
     --max-w-ext   Extended/Bleed-Zone (Hero, Splitter, Overflow-Bilder)
     > --max-w-ext Randbereich — keine Content-Elemente, nur Section-Hintergründe
     --gutter      Mindestabstand zum Viewport-Rand in der Padding-Formel

   Diese drei Variablen werden NICHT hier gesetzt, sondern vom Token-Generator je
   Breakpoint nach `assets/css/sws-breakpoints.css` geschrieben (Backend → Page
   Composer → Tailwind Manager → Tokens: `site-max-w`, `site-max-w-ext`,
   `site-gutter`). Sie sind damit backend-pflegbar und haben genau eine Quelle.

   Bis 2026-08-09 standen hier stattdessen `--sws-max-w`, `--sws-max-w-ext` und
   `--sws-gap` — unter anderem Namen als dem, den die Regeln unten abfragen. Es
   griffen ausnahmslos die var()-Fallbacks, die gepflegte Container-Breite wirkte
   auf nichts, und wer den Wert hier änderte, sah keine Wirkung. Gemeldet aus
   HGK-Events (F-12 / A2). Die Fallbacks in den Regeln bleiben als Sicherheitsnetz
   für Sites, deren Token-Tabelle die Zeilen (noch) nicht hat. */
:root {
    --sws-bp-sm:     40rem;                                   /* 640 px */
    --sws-bp-md:     48rem;                                   /* 768 px */
    --sws-bp-lg:     64rem;                                   /* 1024 px */
}

.bg-primary-70       { background-color: var(--color-primary-70); }
.bg-primary-50       { background-color: var(--color-primary-50); }
.bg-primary-30       { background-color: var(--color-primary-30); }
/* Hinweis: Klassen wie .bg-u70 werden jetzt automatisch aus dem Page-Composer-
 * Dropdown ("CSS-Klassen → Sektion-Hintergründe") generiert. Source ist
 * sws_section_config::getBgClassesCss(); injiziert per OUTPUT_FILTER ins
 * <head>. Hier nur eintragen, wenn zusätzliche Properties (z. B. eigene
 * --section-…-Variablen) nötig sind. */

.text-primary-70     { color: var(--color-primary-70); }
.text-primary-50     { color: var(--color-primary-50); }
.text-primary-30     { color: var(--color-primary-30); }

.border-primary-70   { border-color: var(--color-primary-70); }
.border-primary-30   { border-color: var(--color-primary-30); }

.hover\:text-primary-70:hover { color: var(--color-primary-70); }

/* === Foundation · Helper-Klassen === */
/*
 * Die Werte (Höhe, Breite, Schrift, Padding) werden aus der Datenbank verwaltet:
 * Backend → Page Composer → Tailwind Manager → Responsive Tokens.
 * Generierte Regeln stehen in `assets/css/sws-breakpoints.css` und wirken je Breakpoint.
 *
 * Hier bleiben nur die Nicht-responsiven Layout-Helfer.
 */

/* .m-max-w: die Auto-Margin ist nicht responsiv und steht deshalb hier; die
   max-width kommt weiter unten aus `--max-w` (Token `site-max-w`).
   Pattern (moderner Agentur-Ansatz): Body/Hintergründe fließen full-width,
   der INHALT jeder Sektion wird via .m-max-w gekappt + zentriert. */
.m-max-w { margin-left: auto; margin-right: auto; }

/* Responsive Edge-Paddings: Pufferzone um .m-max-w (max-width 1485 px).
   Die Grenze liegt bei 1564 px, damit bei Viewport = 1485 noch 40 px Rand-Padding
   wirksam sind (= 1485 + 2×40). Erst ab 1565 fällt das Padding auf 0, weil dann
   durch margin:auto mind. 40 px natürliche Luft links/rechts entsteht. */
.m-hero-text { left: 0; }
@media (max-width: 1564px) {
    .m-px-edge { padding-left: 2.667rem; padding-right: 2.667rem; }  /* ~40 px @15 / 37 @14 */
    .m-hero-text { left: 2.667rem; }
}
@media (max-width: 1023px) {
    .m-px-edge { padding-left: 2rem; padding-right: 2rem; }          /* ~28 px @14 / 26 @13 */
    .m-hero-text { left: 2rem; }
}
@media (max-width: 759px) {
    .m-px-edge { padding-left: 1.5rem; padding-right: 1.5rem; }      /* ~20 px @13 / 18 @12 */
    .m-hero-text { left: 1.5rem; }
}

/* --edge-pad: spiegelt den jeweils aktiven m-px-edge-Wert pro Breakpoint.
 * Wird für Elemente außerhalb von m-max-w-Wrappern genutzt (Logo absolute,
 * weitere), damit sie auf der GLEICHEN Inhalts-Linie starten wie m-max-w-
 * Sektionen. Ohne diese Variable haben Sektionen ohne m-px-edge-Wrapper
 * eine andere Sprung-Schwelle (siehe altes Issue „bei 1565 springen nur
 * einige Sektionen nach innen"). */
:root { --edge-pad: 0px; }
@media (max-width: 1564px) { :root { --edge-pad: 2.667rem; } }
@media (max-width: 1023px) { :root { --edge-pad: 2rem; } }
@media (max-width: 759px)  { :root { --edge-pad: 1.5rem; } }

/* Nav-Items nicht intern umbrechen (Einzelworte bleiben auf einer Zeile).
   Breakpoint-gebundene Größe/Gap laufen über Tokens. */
.m-nav-text { white-space: nowrap; }

/* === News-Ansicht · Übersicht + Detail === */
/*
   Wird vom Modul news_view gerendert und bedient zwei Darstellungen im
   selben Template. Siehe auch .m-news-card* (gemeinsamer Teaser-Kachel-Stil
   mit dem Startseiten-News-Teaser-Modul).

   Farb-Konzept (getrennte Schemata):
     Sektion (bg_class): --nv-bg, --nv-fg, --nv-heading, --nv-muted
     Box (box_class):    --card-bg, --card-fg, --card-heading, --card-muted,
                         --card-link-bg, --card-link-fg
*/
.m-news-view-section:not(.m-news-view-section--detail),
.m-news-section.m-news-view-more {
    padding-top: 2rem;
    padding-bottom: 2rem;
}
@media (min-width: 64em) {
    .m-news-view-section:not(.m-news-view-section--detail),
    .m-news-section.m-news-view-more {
        padding-top: 3rem;
        padding-bottom: 3rem;
    }
}
@media (min-width: 112.5em) {
    .m-news-view-section:not(.m-news-view-section--detail),
    .m-news-section.m-news-view-more {
        padding-top: 5rem;
        padding-bottom: 5rem;
    }
}
.m-news-view-section--detail {
    padding-top: 0;
    padding-bottom: 0;
}

.m-news-view-section--detail > .m-max-w.m-px-edge {
    max-width: none;
    margin-left: 0;
    margin-right: 0;
    padding-left:  max(var(--gutter, 1.5rem), calc((min(100vw, var(--max-w-ext, 1920px)) - var(--max-w, 1485px)) / 2));
    padding-right: max(var(--gutter, 1.5rem), calc((min(100vw, var(--max-w-ext, 1920px)) - var(--max-w, 1485px)) / 2));
}
.m-news-view-wrap { color: var(--nv-fg, var(--section-fg, var(--color-primary))); }

.m-news-view--themed { background-color: var(--nv-bg, transparent); color: var(--nv-fg, inherit); }
.m-news-view--themed .m-news-view-header-h1,
.m-news-view--themed .m-news-view-header-h2 { color: var(--nv-heading, var(--nv-fg, inherit)); }

.m-news-card--themed { background-color: var(--card-bg, #ffffff); color: var(--card-fg, #1e293b); }.m-news-card--themed .m-news-card-title { color: var(--card-heading, var(--card-fg, inherit)); }
.m-news-card--themed .m-news-card-date { color: var(--card-muted, var(--card-fg, inherit)); }
.m-news-card--themed .m-news-card-text { color: var(--card-fg, inherit); }
.m-news-card--themed .m-news-card-btn {
    background-color: var(--card-link-bg, var(--section-link-bg, #2563eb));    color: var(--card-link-fg, var(--section-link-fg, #ffffff));
}

.m-news-view-header-titles { margin-bottom: 1.5rem; }
/* `display: block` seit 2026-09-01: Die beiden Zeilen sind jetzt `<span>` in
   EINER `<h1>` statt `<h2>` und `<h3>` nebeneinander — zwei Überschriften für
   eine Ueberschrift waren semantisch falsch, und die Listenseite hatte dadurch
   keine Hauptüberschrift. Größe, Stärke und Abstaende standen hier schon
   ausgeschrieben; ergänzt ist allein die Blockdarstellung, die die Elemente
   vorher von selbst mitbrachten. */
.m-news-view-header-titles-h { margin: 0; font-size: inherit; font-weight: inherit; }
.m-news-view-header-h1 { display: block; font-size: 1.889rem; font-weight: 300; line-height: 1.15; margin: 0 0 0.25rem 0; }
.m-news-view-header-h2 { display: block; font-size: 1.889rem; font-weight: 800; line-height: 1.15; margin: 0; text-transform: uppercase; letter-spacing: 0.02em; }
.m-news-view-header-body { font-size: 1rem; line-height: 1.55; }
.m-news-view-header-body p { margin: 0 0 1rem 0; break-inside: avoid; }
.m-news-view-header-body p:last-child { margin-bottom: 0; }
.m-news-view-cols-1 { columns: 1; }
@media (min-width: 1024px) {
    .m-news-view-cols-2 { columns: 2; column-gap: 2.5rem; }
    .m-news-view-cols-3 { columns: 3; column-gap: 2rem; }
}

.m-news-detail-back-nav { margin-top: 2.222rem; margin-bottom: 0; }
.m-news-detail-back-nav--bottom { margin-top: 0; margin-bottom: 1.111rem; }
@media (min-width: 64em) {
    .m-news-detail-back-nav { margin-top: 3rem; }
    .m-news-detail-back-nav--bottom { margin-top: 0; margin-bottom: 1.5rem; }
}
@media (min-width: 112.5em) {
    .m-news-detail-back-nav { margin-top: 5rem; }
    .m-news-detail-back-nav--bottom { margin-top: 0; margin-bottom: 2.5rem; }
}

.box-element > .text.m-news-detail-text,
.box-element > .bild.m-news-detail-bild {
    padding-top: 2.222rem;
    padding-bottom: 2.222rem;
}

.m-news-detail-back {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.5rem 1rem;
    background-color: var(--section-link-bg, var(--color-primary));
    color: var(--section-link-fg, #ffffff);
    font-size: 1rem;
    font-weight: 300;
    letter-spacing: 0.02em;
    text-transform: uppercase;
    text-decoration: none;
    border-radius: 0.222rem;
    transition: filter 0.2s;
}
.m-news-detail-back:hover { filter: brightness(0.92); }
.m-news-detail-back .m-news-detail-back-icon {
    color: var(--color-accent, #f59e0b);    width: 1.111em;
    height: 1.111em;
    flex: 0 0 auto;
    display: inline-block;
}
.m-news-detail-back .m-news-detail-back-icon svg { width: 100%; height: 100%; display: block; }

.m-news-detail-text .box-title-line1 {
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.02em;
    color: var(--section-heading, var(--nv-heading, inherit));
}

.box-element .box-title-line2 {
    text-transform: uppercase;
    letter-spacing: 0.02em;
}
.m-news-detail-text .box-title-line2 {
    font-weight: 300;
    color: var(--section-muted, var(--nv-muted, inherit));
}

.m-news-detail-text .m-news-detail-date {
    font-size: 1rem;
    line-height: 1.55;
    font-weight: 400;
    color: var(--section-muted, var(--nv-muted, inherit));
    margin: 0 0 1rem 0;
}
/* Ohne `!important` — es trat gegen nichts an.
 *
 * Gemeldet aus HGK-Events (15.08.2026) mit der Vermutung, hier sei dasselbe
 * passiert wie bei ihnen: zwei Regeln für dasselbe Element, Gleichstand, und ein
 * `!important` als Abkürzung. Nachgesehen: `.box-title` kommt in dieser gesamten
 * Foundation-CSS nur an DIESER Stelle vor, und keine der vier Sites (demo,
 * demo1, BCL, ProLahn) trägt eine konkurrierende Regel — weder im Tailwind-Build
 * noch in `sws-managed.css`. Auch Inline-Styles rendert kein Modul auf dieses
 * Element. Das `!important` hat also nie etwas geschlagen; es war ein Relikt.
 *
 * Wer hier künftig eines setzen will, nennt vorher den Gegner. Ein `!important`
 * ohne benannten Gegner ist eine Vermutung, keine Lösung — und es nimmt jeder
 * Site die Möglichkeit, den Wert zu ändern. */
.m-news-detail-text .box-title { margin-bottom: 0.5rem; }

.m-news-detail-bild { display: flex; flex-direction: column; gap: 2.5rem; }

.box-element.c11 > .m-news-detail-text,
.box-element.c11 > .m-news-detail-bild { min-width: 0; }
.m-news-detail-bild .m-slider,
.m-news-detail-bild .m-slider .swiper,
.m-news-detail-bild .m-slider .swiper-wrapper { min-width: 0; max-width: 100%; }
.m-news-detail-image { margin: 0; }
.m-news-detail-image img { display: block; width: 100%; height: auto; border-radius: 0.333rem; }
.m-news-detail-image-caption {
    margin-top: 0.5rem;
    font-size: 1rem;
    font-weight: 300;
    line-height: 1.35;
    color: var(--section-fg, #666);
}

.m-news-grid--overview { margin-bottom: 2.5rem; }

.m-news-overview-empty { text-align: center; padding: 3rem 1rem; color: var(--section-fg, #888); font-size: 1.111rem; }

.m-news-pagination {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
    justify-content: center;
    align-items: center;
    margin-top: 1rem;
}
.m-news-pagination-link {
    display: inline-block;
    padding: 0.4rem 0.85rem;
    background-color: #ffffff;
    color: #2563eb;    border: 1px solid #d1d5db;
    border-radius: 0.25rem;
    text-decoration: none;
    font-size: 0.944rem;
    font-weight: 500;
    transition: background-color 0.15s, color 0.15s;
}
.m-news-pagination-link:hover { background-color: #2563eb; color: #ffffff; }.m-news-pagination--current { background-color: #2563eb; color: #ffffff; border-color: #2563eb; cursor: default; }.m-news-pagination--disabled { color: #9ca3af; cursor: not-allowed; }
.m-news-pagination--disabled:hover { background-color: #ffffff; color: #9ca3af; }

.m-kontakt-h {
    display: flex;
    align-items: center;
    /* Struktur, nicht Wert: Die Höhe ist frei, der Token-Wert ist die Untergrenze.
       Erlaubte Ausnahme nach token-kanal.md, Pflicht 3. */
    height: auto;
    min-height: var(--tok-m-kontakt-h-height, 6.667rem);
    padding-top: 1.5rem;
    padding-bottom: 1.5rem;
}
.m-kontakt-h > * { width: 100%; }

.m-kontakt-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 1rem 2rem;
    align-items: start;
}
@media (min-width: 640px) { .m-kontakt-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 768px) { .m-kontakt-grid { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 1430px) {
    .m-kontakt-grid { grid-template-columns: minmax(17.5rem, 1.5fr) repeat(5, minmax(0, 1fr)); }
}

.m-link-icon { width: 1.111rem; height: 1.111rem; flex-shrink: 0; }

.m-hero-images-wrap {
    position: absolute;
    inset: 0;
    max-width: 1920px;
    margin-left: auto;
    margin-right: auto;
    overflow: hidden;
}

/* Hero-Welcome-Block. Farben über CSS-Variablen (--card-bg etc.) überschreibbar. */
.m-hero-box {
    background-color: #2563eb;    color: #ffffff;
    padding: 1rem;
    border-radius: 0.333rem;
    font-size: 2.222rem;
    line-height: 1.1;
    margin-top: 11.111rem;
    display: block;
    width: fit-content;
}
.m-hero-box-line1 { display: block; font-weight: 300; }
.m-hero-box-line2 { display: block; font-weight: 800; text-transform: uppercase; letter-spacing: 0.02em; }

.m-hero-link {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    background-color: #ffffff;
    color: #909090;
    font-size: 1rem;
    padding: 0.667rem 1rem;
    border-radius: 0.333rem;
    margin-top: 0.667rem;
    text-decoration: none;
    transition: background-color 0.2s;
}
.m-hero-link:hover { background-color: #f5f5f5; }
.m-hero-link-icon {
    width: 1.111rem;
    height: 1.111rem;
    color: var(--color-accent);
    flex-shrink: 0;
}

.m-hero-dot {
    width: 1.333rem;
    height: 1.333rem;
    border-radius: 9999px;
    border: 1px solid #ffffff;
    background-color: #ffffff;
    padding: 0;
    cursor: pointer;
    transition: background-color 0.2s;
}
.m-hero-dot:hover { background-color: #e5e7eb; }
.m-hero-dot.is-active { background-color: #2563eb; }.m-hero-dot.is-active:hover { background-color: #2563eb; }
.m-footer-bar { background-color: #1e40af; display: flex; align-items: center; }.m-footer-bar > * { width: 100%; }

.m-footer-main { display: flex; align-items: flex-start; line-height: 1.4; }
.m-footer-main > * { width: 100%; }
.m-footer-main ul { list-style: none; padding: 0; margin: 0; }

/* FUSSZEILEN-LISTEN OHNE ABSTAND — und warum es zwei Selektoren braucht.
 *
 * Der erste ist die Ausnahme, wie sie immer dastand. Sie hat die Spezifität
 * (0,1,2) — und genau so viel hat auch die allgemeine Regel `.m-bg-text ul > li`
 * in `10-module.css`, die den Punkten `margin-bottom: 0.222rem` gibt. Bei
 * Gleichstand entscheidet die Position, und `10-module.css` wird NACH dieser
 * Datei angehängt. Die Ausnahme war also da und wirkte nicht — jede Site, die
 * ihren Footer mit Textblöcken baut, bekam die Abstände trotzdem.
 *
 * Der zweite Selektor deckt genau die Überschneidung ab und gewinnt dort mit
 * (0,2,2). Der erste bleibt UNVERÄNDERT stehen: Er greift auch für Fusszeilen-
 * Listen ausserhalb eines Textblocks, und seine Spezifität ist ein Vertrag mit
 * den Sites (siehe `.claude/rules/css-spezifitaet-ist-ein-vertrag.md`) — wer ihn
 * anhebt, entscheidet für jede Site neu, ob ihre Gegenregel noch trägt.
 *
 * Gemessen vor der Änderung: Eine einzige Site hält eine Gegenregel
 * (Frauennotruf Westerburg, `.m-footer-main .m-bg-text ul > li`, ebenfalls
 * (0,2,2)). Sie lädt nach der Foundation und gewinnt damit weiterhin — und setzt
 * ohnehin denselben Wert. BCL und ProLahn: keine Gegenregel. */
.m-footer-main ul li,
.m-footer-main .m-bg-text ul > li { margin: 0; }

.m-footer-main ul a {
    display: inline-flex;
    align-items: flex-start;
    gap: 0.5rem;
}
.m-footer-main ul a .m-link-icon { margin-top: 0.15rem; }

.m-footer-contact {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.m-footer-bar-divider {
    display: inline-block;
    width: 1px;
    height: 1em;
    background-color: currentColor;
    opacity: 0.6;
    margin: 0 1rem;
}
/* === Foundation · Sektion-Anker für no-wrapper-Module === */
/* Das Universal-Template gibt bei no-wrapper einen <span class="site-section-anchor"
   id="..."></span> vor der Modul-Section aus, damit Mega-Menu-Sprünge funktionieren.
   scroll-margin-top kompensiert den sticky Header (155 px). */
.site-section-anchor {
    display: block;
    width: 0;
    height: 0;
    scroll-margin-top: 9rem;
}

/* Links grundsätzlich ohne Unterstrich. Greift auf alle <a> im Fließtext und in
   Modulen. Wenn ein einzelner Link doch unterstrichen sein soll, kann der Redakteur
   via TinyMCE im inline style="text-decoration:underline" überschreiben. */
a { text-decoration: none; }
a:hover, a:focus { text-decoration: none; }

/* === News-Teaser-Section · No-Wrapper === */
/* REGEL: BG-Klasse kommt aus der Section-Config — hier KEIN background-color. */
.m-news-section {
    color: var(--section-fg, var(--color-primary));
    position: relative;
    padding-top: 0;
    padding-bottom: 0;
}

/* === Foundation · Sektion-Top-Decor (generisch) === */
/*
   Greift auf jeder <section> mit dem Attribut [data-section-top-decor].
   Werte werden in der Section-Config gewählt; sws_section_config setzt
   pro Sektion folgende Custom Properties als Inline-Style:
     --section-top-decor-mask        URL des SVG-Masks
     --section-top-decor-aspect      Aspect-Ratio (z.B. 1920 / 102)
     --section-top-decor-color       Sektion-BG (= Welle-Farbe)
     --section-top-decor-prev-color  Vorgelagerte-Sektion-BG (für Sockel-Bänder)

   Render-Modell: Welle wird per ::before in der EIGENEN Sektion-Farbe ÜBER die
   Sektion-Oberkante hinaus in die Vorgänger-Sektion gerendert. Sichtbar wird
   die Welle dadurch, dass der nicht-mask-Bereich transparent ist und den
   Vorgänger-BG durchscheinen lässt (Welle = eigene Farbe wächst in fremde).

   Damit der Welle-Bereich KEINEN Vorgänger-Inhalt überdeckt, bekommt die
   Vorgänger-Sektion automatisch ein padding-bottom = Welle-Höhe via
   `:has(+ [data-section-top-decor])`-Selektor (modern browsers).
   Pflege der Decor-Varianten unter Page Composer → CSS-Klassen → Sektion-Decor. */
[data-section-top-decor]:not([data-section-top-decor=""]):not([data-section-top-decor="none"]) {
    position: relative;
}
[data-section-top-decor]:not([data-section-top-decor=""]):not([data-section-top-decor="none"])::before {
    content: '';
    position: absolute;
    bottom: 100%;
    left: 50%;
    transform: translateX(-50%);
    width: 100%;
    max-width: 1920px;
    aspect-ratio: var(--section-top-decor-aspect, 1920 / 184);
    margin-bottom: -1px;
    background: var(--section-top-decor-color, var(--color-accent));
    mask-image: var(--section-top-decor-mask);
    mask-repeat: no-repeat;
    mask-position: bottom center;
    mask-size: 100% 100%;
    -webkit-mask-image: var(--section-top-decor-mask);
    -webkit-mask-repeat: no-repeat;
    -webkit-mask-position: bottom center;
    -webkit-mask-size: 100% 100%;
    pointer-events: none;
    z-index: 2;
}
/* Sockel-Bänder seitlich der Welle (bei Viewport > 1930 px sichtbar). */
[data-section-top-decor]:not([data-section-top-decor=""]):not([data-section-top-decor="none"])::after {
    content: '';
    position: absolute;
    bottom: 100%;
    left: 50%;
    transform: translateX(-50%);
    width: 100vw;
    height: calc(min(100vw, 1920px) * var(--section-top-decor-h-frac, 0.0958));
    margin-bottom: -1px;
    background:
        linear-gradient(
            to bottom,
            var(--section-top-decor-prev-color, transparent) 0%,
            var(--section-top-decor-prev-color, transparent) var(--section-top-decor-edge-y-left, var(--section-top-decor-edge-y, 50%)),
            var(--section-top-decor-color, transparent) var(--section-top-decor-edge-y-left, var(--section-top-decor-edge-y, 50%)),
            var(--section-top-decor-color, transparent) 100%
        ) left top no-repeat,
        linear-gradient(
            to bottom,
            var(--section-top-decor-prev-color, transparent) 0%,
            var(--section-top-decor-prev-color, transparent) var(--section-top-decor-edge-y-right, var(--section-top-decor-edge-y, 50%)),
            var(--section-top-decor-color, transparent) var(--section-top-decor-edge-y-right, var(--section-top-decor-edge-y, 50%)),
            var(--section-top-decor-color, transparent) 100%
        ) right top no-repeat;
    background-size:
        calc((100vw - min(100vw, 1920px)) / 2 + 5px) 100%,
        calc((100vw - min(100vw, 1920px)) / 2 + 5px) 100%;
    pointer-events: none;
    z-index: 1;
}
/* Vorgänger-Sektion bekommt automatisch padding-bottom = Welle-Höhe. */
section:has(+ [data-section-top-decor]:not([data-section-top-decor=""]):not([data-section-top-decor="none"])),
section:has(+ style + [data-section-top-decor]:not([data-section-top-decor=""]):not([data-section-top-decor="none"])) {
    padding-bottom: clamp(60px, 9.583vw, 184px) !important;
}
/* Detail-Section-Override für unterschiedliche Welle-Höhen. */
section.m-news-view-section--detail:has(+ .m-news-view-more[data-section-top-decor="welle"]) {
    padding-bottom: calc(min(100vw, 1920px) * 0.053125) !important;
}
section.m-news-view-section--detail:has(+ .m-news-view-more[data-section-top-decor="welle-mit-boot"]) {
    padding-bottom: calc(min(100vw, 1920px) * 0.0958) !important;
}

/* === Foundation · Decor-Section Standard-Padding === */
/*
 * Sections mit Welle-Decor (Top oder Bottom) brauchen kein zusätzliches
 * Tailwind-Section-Padding (`py-20 lg:py-28` = 126 px), weil die Welle
 * visuell die Section-Grenze ist und der Inhalt direkt darunter beginnen
 * soll.
 *
 * Selector matcht nur Sections mit der Standard-Wrapper-Padding-Klasse
 * `py-20` (= Page-Composer-Section-Default). No-wrapper-Module wie
 * `.m-news-section`, `.m-bg-section` (`py-0`) bleiben unverändert.
 */
section[data-section-top-decor]:not([data-section-top-decor=""]):not([data-section-top-decor="none"])[class~="py-20"] {
    padding-top: 2.5rem !important;
    padding-bottom: 2.5rem !important;
}
section[data-section-bottom-decor]:not([data-section-bottom-decor=""]):not([data-section-bottom-decor="none"])[class~="py-20"] {
    padding-bottom: 2.5rem !important;
}

.m-news-wrap { position: relative; z-index: 1; }
.m-news-head {
    text-align: center;
    margin-bottom: 2.222rem;
}
.m-news-eyebrow {
    font-weight: 300;
    font-size: 1.889rem;
    line-height: 1.15;
    margin: 0;
    color: var(--section-heading, var(--color-primary));
}
.m-news-title {
    font-weight: 800;
    font-size: 1.889rem;
    text-transform: uppercase;
    line-height: 1.15;
    margin: 0;
    color: var(--section-heading, var(--color-primary));
}

/* News-Teaser-Cards: Equal-Height per Subgrid. */
.m-news-grid,
.m-news-grid--overview {
    display: grid;
    grid-template-columns: 1fr;
    grid-template-rows: auto auto auto 1fr auto;
    column-gap: 2rem;
    row-gap: 2rem;
}
@media (min-width: 40rem)  { .m-news-grid, .m-news-grid--overview { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 56rem)  { .m-news-grid, .m-news-grid--overview { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 72rem)  { .m-news-grid, .m-news-grid--overview { grid-template-columns: repeat(4, 1fr); } }
.m-news-card {
    background-color: var(--card-bg, var(--section-box-bg, #ffffff));
    color: var(--card-fg, var(--section-box-fg, var(--color-primary)));
    display: grid;
    grid-template-rows: subgrid;
    grid-row: span 5;
    row-gap: 0;
    overflow: hidden;
    border-radius: 0.222rem;
    width: 100%;
    min-width: 0;
}
.m-news-card-heading {
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
    padding: 1rem 1.111rem 0 1.111rem;
}
.m-news-card-img {
    width: 100%;
    aspect-ratio: 340 / 185;
    overflow: hidden;
}
.m-news-card-img img {
    width: 100%; height: 100%; object-fit: cover; display: block;
}
.m-news-card-title {
    color: var(--section-box-fg, var(--color-primary));
    font-weight: 800;
    font-size: 1.167rem;
    text-transform: uppercase;
    line-height: 1.2;
    margin: 0 0 0.333rem 0;
    /* Deutsche Komposita sprengen die Kartenspalte. Gemessen am 31.08.2026 auf
       frauennotruf.msm.de: „30-JAEHRIGES JUBILAEUM DES KUNSTHANDWERKERINNEN-
       MARKTES" braucht 346 px in 286 px — und die Karte traegt `overflow:
       hidden` (für den Eckenradius), also war die Ueberschrift still
       abgeschnitten, ohne Auslassungszeichen und ohne Rollbalken.
       Dasselbe Mittel wie bei `.m-footer-heading-text` und `.m-mm-panel-title`;
       `hyphens: auto` greift, weil das Template `lang="de"` setzt. */
    overflow-wrap: break-word;
    hyphens: auto;
}
.m-news-card-date {
    color: var(--section-box-fg, var(--color-primary));
    font-weight: 400;
    font-size: 1.167rem;
    margin: 0;
    line-height: 1.25;
}
.m-news-card-published {
    color: var(--section-box-fg, var(--color-primary));
    opacity: 0.65;
    font-weight: 400;
    font-size: 0.778rem;
    line-height: 1.2;
    margin: 0.667rem 0 0 0;
    padding: 0 1.111rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.m-news-card-text {
    color: var(--section-box-fg, var(--color-primary));
    font-weight: 400;
    font-size: 0.944rem;
    line-height: 1.4;
    margin: 0.333rem 0 0 0;
    padding: 0 1.111rem;
}
.m-news-card-btn {
    display: inline-flex; align-items: center; gap: 0.5rem;
    align-self: flex-start;
    background-color: #2563eb;    color: #ffffff;
    font-size: 1rem;
    font-weight: 400;
    padding: 0.389rem 0.889rem;
    border-radius: 0.222rem;
    text-decoration: none;
    text-transform: uppercase;
    letter-spacing: 0.02em;
    margin: 1rem 1.111rem 1.222rem 1.111rem;
    transition: filter 0.2s;
}
.m-news-card-btn:hover { filter: brightness(0.95); }
.m-news-btn-icon { width: 1.111rem; height: 1.111rem; color: var(--color-accent); flex-shrink: 0; }

/* CTA-Linkbox unten ("ALLE NEWS ANSEHEN") — im 130-px-Block unter dem News-Grid. */
.m-news-cta-wrap {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 7.222rem;
    margin-top: 0;
}
.m-news-cta {
    display: inline-flex; align-items: center; gap: 0.5rem;
    background-color: var(--section-link-bg, #2563eb);    color: var(--section-link-fg, #ffffff);
    font-weight: 400;
    font-size: 1rem;
    padding: 0.389rem 0.889rem;
    border-radius: 0.222rem;
    text-decoration: none;
    text-transform: uppercase;
    letter-spacing: 0.02em;
    transition: filter 0.2s;
}
.m-news-cta:hover { filter: brightness(0.95); }

/* Mobile (< 40rem): Subgrid abschalten. */
@media (max-width: 39.999rem) {
    .m-news-grid,
    .m-news-grid--overview {
        display: block;
    }
    .m-news-card {
        display: block;
        grid-row: auto;
        grid-template-rows: none;
        margin-bottom: 1.333rem;
    }
    .m-news-card:last-child { margin-bottom: 0; }
}

/* === Utility · Responsive-Overrides < 1024 px === */
/*
   Unter Tailwind-Breakpoint lg stacked das Grid (1 oder 2 Spalten). Die bei XL fixierten
   Sektions-Hoehen (Kontakt 120, Footer 440) reichen dann nicht mehr für den stacked Inhalt.
   Fix: height → auto, zugleich etwas Padding für Atmung. */
@media (max-width: 1429px) {
    .m-kontakt-h {
        height: auto;
        padding-top: 1.5rem;
        padding-bottom: 1.5rem;
    }
}
/* Desktop (≥ 1430 px): mehr Atmung als Mobile. */
@media (min-width: 1430px) {
    .m-kontakt-h {
        padding-top: 2rem;
        padding-bottom: 2rem;
    }
}
/* Großbild / 2xl (≥ 1800 px): noch mehr Padding für 4K-Monitore. */
@media (min-width: 112.5em) {
    .m-kontakt-h {
        padding-top: 3rem;
        padding-bottom: 3rem;
    }
}
@media (max-width: 1023px) {
    .m-footer-main {
        height: auto;
        padding-top: 2.5rem;
        padding-bottom: 2.5rem;
    }
    .m-footer-bar {
        height: auto;
        padding-top: 1rem;
        padding-bottom: 1rem;
    }
}
@media (min-width: 1024px) {
    .m-footer-main {
        height: auto;
        /* Struktur wie bei .m-kontakt-h: frei nach oben, Token als Untergrenze. */
        min-height: var(--tok-m-footer-main-height, 24.444rem);
        padding-bottom: 2.5rem;
    }
}

.m-footer-heading-text {
    overflow-wrap: break-word;
    hyphens: auto;
}
@media (min-width: 1024px) and (max-width: 1279px) {
    .m-footer-heading-text {
        font-size: 1rem;
    }
}
/* === Mega-Menü · Desktop === */
/* Phase 1 — Hover/Fokus-Dropdown unter dem Header. */
.m-nav-root { position: static; }
.m-nav-offset { margin-left: 3.889rem; }
.m-nav-item { position: relative; display: flex; align-items: center; }
.m-nav-item .m-nav-link { display: inline-flex; align-items: center; padding: 0.5rem 0; }

.m-megamenu-viewport {
    display: none;
    position: absolute;
    top: 100%; left: 0; right: 0;
    z-index: 40;
    pointer-events: none;
    max-height: 0;
    overflow: hidden;
    transition: max-height 0.2s ease;
}
@media (min-width: 1024px) {
    .m-megamenu-viewport { display: block; }
}
.m-megamenu-viewport.is-open { max-height: 52rem; overflow: visible; }
.m-megamenu-viewport.is-open .m-megamenu.is-open { pointer-events: auto; }

.m-megamenu { display: none; padding: 0; }
.m-megamenu.is-open { display: block; }
.m-megamenu > .m-max-w { background: transparent; box-shadow: none; border: 0; }

.m-megamenu > .m-max-w { background: transparent; border-top: 0; box-shadow: none; }
.m-megamenu { padding: 0; }
.m-megamenu-inner {
    max-width: 90.833rem;
    margin-left: calc(12.333rem + 3.889rem);
    margin-right: max(0px, calc((100% - 82.5rem) / 2));
    margin-top: -1.25rem;
    display: grid;
    grid-template-columns: minmax(0, 1fr) 12rem;     /* Panels 1fr, Linkleiste 180-216 px (Headline+wenige Links reichen — bei 18.889rem hat links zu wenig Platz für 2 Card-Cols auf Laptop) */
    gap: 3.333rem;
    align-items: start;
    background: #ffffff;
    box-shadow: 0 0.5rem 1.25rem rgba(0, 0, 0, 0.08);
    padding: 2.222rem;
    position: relative;
    z-index: 41;
}
@media (max-width: 1564px) {
    .m-megamenu-inner { margin-right: 2.667rem; }
}
@media (max-width: 1023px) {
    .m-megamenu-inner { margin-left: 2rem; margin-right: 2rem; grid-template-columns: 1fr; gap: 2rem; }
}
@media (max-width: 759px) {
    .m-megamenu-inner { margin-left: 1.5rem; margin-right: 1.5rem; padding: 1.5rem; }
}

.m-megamenu-col-title,
.m-megamenu-side-title {
    font-weight: 800;
    font-size: 1.5rem;
    line-height: 1.15;
    color: #2563eb;    margin: 0 0 1.333rem 0;
    text-transform: uppercase;
    letter-spacing: 0.02em;
}

.m-megamenu-main { min-width: 0; }
.m-megamenu-panels {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 1.667rem 2.222rem;
    min-width: 0;
}
.m-mm-panel { min-width: 0; }
.m-mm-panel-title,
.m-mm-panel-desc,
.m-mm-panel-links a {
    min-width: 0;
    /* hyphens:auto trennt an deutschen Silbengrenzen (lang="de" auf <html>);
     * word-break/break-word entfernt — würde mitten im Wort schneiden. */
    overflow-wrap: break-word;
    hyphens: auto;
    -webkit-hyphens: auto;
}
.m-mm-panel {
    display: flex;
    flex-direction: column;
}

.m-mm-panel-img {
    display: block;
    width: 100%;
    aspect-ratio: 460 / 160;
    background: #2563eb;    margin-bottom: 0.889rem;
    transition: opacity 0.15s;
    overflow: hidden;
    position: relative;
}
.m-mm-panel-img:hover { opacity: 0.85; }
.m-mm-panel-img > img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center;
}

.m-mm-panel-title {
    font-weight: 700;
    font-size: 1.222rem;
    line-height: 1.2;
    text-transform: uppercase;
    letter-spacing: 0.02em;
    margin-bottom: 0.667rem;
    color: #505050;
    text-decoration: none;
    transition: opacity 0.15s;
}
.m-mm-panel-title:hover { opacity: 0.75; }

.m-mm-panel-desc {
    font-weight: 300;
    font-size: 1.222rem;
    line-height: 1.35;
    color: #505050;
}
.m-mm-panel-desc p { margin: 0 0 0.444rem 0; }
.m-mm-panel-desc p:last-child { margin-bottom: 0; }
.m-mm-panel-desc a { color: #2563eb; }.m-mm-panel-desc strong { font-weight: 700; }
.m-mm-panel-desc em { font-style: italic; }

.m-mm-panel-links {
    list-style: none; padding: 0; margin: 0;
}
.m-mm-panel-links li,
.m-megamenu-side-list li { margin: 0; }
.m-mm-panel-links a,
.m-megamenu-side-list a {
    display: inline-flex; align-items: flex-start;
    gap: 0.556rem;
    font-weight: 300;
    font-size: 1.222rem;
    line-height: 1.4;
    color: #505050;
    text-decoration: none;
    transition: opacity 0.15s;
}
.m-mm-panel-links a:hover,
.m-megamenu-side-list a:hover { opacity: 0.7; }

.m-mm-arrow-icon {
    width: 0.889rem; height: 0.889rem;
    color: #2563eb;    flex-shrink: 0;
    display: inline-block;
    margin-top: 0.411rem;
}

.m-megamenu-side-list { list-style: none; padding: 0; margin: 0; }

/* Laptop-Range (1024-1279 px): Title/Desc-Schrift kleiner, damit lange dt.
 * Komposita (z. B. SPORTBOOTFÜHRERSCHEIN) in die ~250-px-Karten des 2-Col-
 * Layouts passen. Ab 1280 px wieder Standard-Schrift (Karten dann breit
 * genug). Position NACH den Default-Defs damit die Cascade gewinnt. */
@media (min-width: 64em) and (max-width: 79.99em) {
    .m-mm-panel-title { font-size: 1rem; }
    .m-mm-panel-desc  { font-size: 1rem; line-height: 1.4; }
}

/* === Mega-Menü · Mobile (Accordion) === */
.m-mobile-nav { padding: 0.5rem 0; }
.m-mobile-nav-item { border-bottom: 1px solid rgba(15, 23, 42, 0.08); }.m-mobile-nav-item:last-child { border-bottom: 0; }
.m-mobile-nav-toggle,
.m-mobile-nav-link {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    padding: 1rem 1.5rem;
    background: transparent;
    border: 0;
    color: var(--color-primary);
    font-family: inherit;
    font-weight: 400;
    text-transform: uppercase;
    letter-spacing: 0.02em;
    text-align: left;
    text-decoration: none;
    cursor: pointer;
}
.m-mobile-nav-toggle.is-active,
.m-mobile-nav-link.is-active { color: var(--color-accent); }
.m-mobile-nav-chevron { transition: transform 0.2s ease; flex-shrink: 0; }
.m-mobile-nav-toggle[aria-expanded="true"] .m-mobile-nav-chevron { transform: rotate(180deg); }

.m-mobile-nav-panel {
    display: none;
    padding: 0 1.5rem 1.25rem 1.5rem;
    background: rgba(15, 23, 42, 0.025);}
.m-mobile-nav-panel.is-open { display: block; }
.m-mobile-nav-section-link {
    display: inline-block;
    padding: 0.5rem 0 1rem 0;
    color: var(--color-primary);
    font-weight: 700;
    text-decoration: none;
}

.m-mobile-nav-panel .m-megamenu-inner {
    display: block;
    max-width: none;
    margin: 0;
    padding: 0;
    background: transparent;
    box-shadow: none;
}
.m-mobile-nav-panel .m-megamenu-main { margin-bottom: 1.25rem; }
.m-mobile-nav-panel .m-megamenu-panels {
    display: grid;
    grid-template-columns: 1fr;
    gap: 1.25rem;
}
.m-mobile-nav-panel .m-megamenu-col-title,
.m-mobile-nav-panel .m-megamenu-side-title {
    font-size: 1.125rem;
    margin-bottom: 0.75rem;
}
.m-mobile-nav-panel .m-mm-panel {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
}
.m-mobile-nav-panel .m-mm-panel-img {
    width: 100%;
    max-width: 13.333rem;
    height: auto;
    aspect-ratio: 460 / 160;
    margin-bottom: 0.5rem;
}
.m-mobile-nav-panel .m-mm-panel-title {
    font-size: 1rem;
    margin-bottom: 0.375rem;
}
.m-mobile-nav-panel .m-mm-panel-desc,
.m-mobile-nav-panel .m-mm-panel-links a,
.m-mobile-nav-panel .m-megamenu-side-list a {
    font-size: 0.9375rem;
    line-height: 1.4;
}
.m-mobile-nav-panel .m-megamenu-side {
    margin-top: 1.25rem;
    padding-top: 1rem;
    border-top: 1px solid rgba(15, 23, 42, 0.1);}
.m-mobile-nav-panel .m-mm-arrow-icon {
    width: 0.75rem; height: 0.75rem;
    margin-top: 0.28rem;
}

/* === Flyouts · Pegel + Schneller Kontakt === */
/*
 * Desktop: fixed rechts, mittig, Click-to-open
 * Mobile : schlanke Leiste am unteren Rand
 */
.m-flyout {
    position: fixed;
    right: 0;
    top: 11.111rem;
    z-index: 45;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    /* Abstand zwischen den Kacheln. Vorgabe 0.556rem = 10 px bei 18-px-Wurzel,
     * der Wert, mit dem die Flyouts seit jeher ausgeliefert werden. Als Custom
     * Property, damit eine Site ihn setzen kann, ohne die Regel nachzubauen —
     * wie bei --flyout-icon, --flyout-title und --flyout-akzent. */
    gap: var(--flyout-gap, 0.556rem);
    pointer-events: none;
}
.m-flyout-item {
    pointer-events: auto;
    display: flex;
    flex-direction: row;
    align-items: flex-start;
    filter: drop-shadow(0 0.278rem 0.667rem rgba(0, 0, 0, 0.15));
}

.m-flyout-tile {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 5rem;
    height: 5rem;
    background: #ffffff;
    border: none;
    border-radius: 0.333rem 0 0 0.333rem;
    cursor: pointer;
    color: #2563eb;    transition: background-color 0.18s;
    position: relative;
    z-index: 2;
    margin-right: 0;
}
.m-flyout-item.is-open .m-flyout-tile {
    margin-right: -0.333rem;
}
.m-flyout-tile:hover,
.m-flyout-tile[aria-expanded="true"] { background: #ffffff; }

.m-flyout-icon {
    width: auto;
    height: 3.889rem;
    display: block;
}
.m-flyout-icon,
.m-flyout-icon * { fill: #2563eb !important; }.m-flyout-tile:hover .m-flyout-icon,
.m-flyout-tile:hover .m-flyout-icon *,
.m-flyout-tile[aria-expanded="true"] .m-flyout-icon,
.m-flyout-tile[aria-expanded="true"] .m-flyout-icon * { fill: #0f172a !important; }

/* Kachel-Icon für STRICH-Icons (Lucide via sws_icon).
 *
 * Warum eine zweite Klasse und nicht `.m-flyout-icon`: Dort steht
 * `fill: <farbe> !important` auf dem Element UND allen Kindern. Das war für
 * hochgeladene Flächen-SVGs gemacht (BCL: icon-pegel, icon-hafenmeister) und
 * ist dort richtig. Ein Lucide-Icon besteht aus Pfaden ohne Füllung, die ihre
 * Form allein aus `stroke` beziehen — die Füll-Regel macht daraus einen
 * geschlossenen Klumpen. Beide Icon-Sorten brauchen deshalb je eine Klasse.
 *
 * Die Geometrie ist bewusst identisch zu `.m-flyout-icon`, damit beide Sorten
 * dieselbe Kachel füllen. Farbe über `color`/`currentColor`, damit eine Site
 * sie mit einer gewöhnlichen Regel ändern kann — ohne `!important`-Wettlauf. */
.m-flyout-icon-line {
    width: auto;
    height: 3.889rem;
    display: block;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.5;
    color: var(--flyout-icon, #2563eb);
}
.m-flyout-tile:hover .m-flyout-icon-line,
.m-flyout-tile[aria-expanded="true"] .m-flyout-icon-line {
    color: var(--flyout-icon-aktiv, #0f172a);
}
.m-flyout-panel {
    order: 2;
    flex-shrink: 0;
    width: 16rem;
    max-width: 0;
    padding: 0.556rem 0;
    background: #ffffff;
    overflow: hidden;
    border-radius: 0.333rem 0 0 0.333rem;
    pointer-events: none;
    position: relative;
    z-index: 1;
    /* Das geschlossene Panel darf zur Hoehe des Eintrags NICHTS beitragen.
     *
     * `.m-flyout-item` ist ein Flex-Container in Zeilenrichtung; seine Hoehe ist
     * die des hoechsten Kindes. `max-width: 0` nimmt dem Panel nur die Breite —
     * die Hoehe bleibt, und zwar in einer Groesse, die niemand vorhersieht: Bei
     * Breite 0 bricht jedes Wort einzeln um, das Panel wird also umso hoeher, je
     * mehr Text darin steht.
     *
     * Folge vor dieser Zeile: Der `gap` wirkt zwischen den EINTRAEGEN, sichtbar
     * ist aber der Abstand zwischen den KACHELN — und der ist um den Ueberhang
     * groesser. Gemessen am 05.09.2026: demo.msm.de Ueberhang 56 px (Panel 146,
     * Kachel 90), bei eingestellten 30 px `gap` also 86 px sichtbar, fast eine
     * ganze Kachelhoehe. Auf bcl-lahn.de betrug derselbe Ueberhang 6 px — der
     * Unterschied ist allein der Panel-Inhalt.
     *
     * `100vh` im offenen Zustand statt `none`, damit die Hoehe mit animiert.
     * Nachgemessen: BCLs laengstes Panel braucht 425 px, demo 90 px. */
    max-height: 0;
    transition: max-width 0.28s ease-out, max-height 0.28s ease-out, padding 0.28s ease-out;
}
.m-flyout-item.is-open .m-flyout-panel {
    max-width: 16rem;
    max-height: 100vh;
    padding: 0.556rem 0.667rem 0.556rem 1rem;
    pointer-events: auto;

    /* Nie niedriger als die Kachel. Der Wert ist keine Setzung, sondern eine
     * Ableitung: `.m-flyout-tile` misst 5rem × 5rem, also ist 5rem genau die
     * Schwelle, ab der die Kachel nicht mehr unter dem Panel hervorsteht.
     *
     * Bis 0.51.0 stand diese Zeile nur in der Regel für `[data-flyout="pegel"]`
     * — sie galt damit für ein Flyout auf einer Site, obwohl das Problem jedes
     * Panel betrifft, dessen Inhalt kürzer als die Kachel ist. Gemeldet am
     * 03.09.2026 an einem Kontakt-Flyout mit zwei Textzeilen: Kachel 90 px,
     * Panel 69 px, 21 px Überstand.
     *
     * Auf bcl-lahn.de gemessen, bevor die Regel verallgemeinert wurde: Pegel
     * 90 px, Kontakt 425 px — beide bereits über der Schwelle, dort ändert sich
     * also nichts. */
    min-height: 5rem;
}

.m-flyout-title {
    font-size: 1rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.02em;
    color: var(--flyout-title, #2563eb);    line-height: 1.2;
}
.m-flyout-item[data-flyout="pegel"].is-open .m-flyout-panel {
    padding-top: 0.389rem;
    padding-bottom: 0.389rem;
    min-height: 5rem;
}
.m-flyout-list {
    list-style: none;
    margin: 0;
    padding: 0;
}
.m-flyout-list li + li { margin-top: 0; }
.m-flyout-list a {
    display: inline-flex;
    align-items: baseline;
    gap: 0.389rem;
    font-size: 1rem;
    font-weight: 300;
    color: #505050;
    text-decoration: none;
    line-height: 1.4;
}
.m-flyout-list a:hover { color: #0f172a; }.m-flyout-arrow {
    width: 0.75rem;
    height: 0.75rem;
    color: var(--flyout-akzent, #d97706);    flex-shrink: 0;
    transform: translateY(0.1rem);
}

.m-flyout-kontakt {
    list-style: none;
    margin: 0;
    padding: 0;
}
.m-flyout-kontakt li + li { margin-top: 0.5rem; }
.m-flyout-role {
    font-size: 1rem;
    font-weight: 700;
    color: #2563eb;    margin: 0;
    line-height: 1.2;
}
.m-flyout-name {
    font-size: 0.889rem;
    font-weight: 300;
    color: #505050;
    margin: 0;
    line-height: 1.3;
}
.m-flyout-tel {
    display: inline-flex;
    align-items: center;
    gap: 0.278rem;
    font-size: 0.889rem;
    font-weight: 300;
    color: #505050;
    text-decoration: none;
    line-height: 1.3;
    margin-top: 0;
}
.m-flyout-tel:hover { color: #0f172a; }.m-flyout-tel-icon {
    width: 0.833rem;
    height: 0.833rem;
    color: var(--flyout-akzent, #d97706);    flex-shrink: 0;
}

@media (max-width: 1023px) {
    .m-flyout {
        top: auto;
        bottom: 0;
        right: 0;
        left: 0;
        transform: none;
        flex-direction: row;
        align-items: stretch;
        justify-content: stretch;
        gap: 0;
        background: #ffffff;
        box-shadow: 0 -0.167rem 0.833rem rgba(0, 0, 0, 0.1);
    }
    .m-flyout-item {
        flex: 1 1 50%;
        filter: none;
    }
    .m-flyout-tile {
        width: 100%;
        height: 3rem;
        border-radius: 0;
        border-top: 1px solid rgba(37, 99, 235, 0.12);        margin: 0;
    }
    .m-flyout-item.is-open .m-flyout-tile {
        margin-right: 0;
        background: #f6f7f9;
    }
    .m-flyout-icon { width: auto; height: 2rem; }
    .m-flyout-icon-line { width: auto; height: 2rem; }

    .m-flyout-panel {
        position: fixed;
        left: 0;
        right: 0;
        bottom: 3rem;
        top: auto;
        width: auto;
        max-width: none;
        /* Zurueckgenommen: Unter 1024 px liegt das Panel `position: fixed` und
           traegt schon deshalb nichts zur Eintragshoehe bei. Eine Deckelung
           wuerde es hier nur unsichtbar machen. */
        max-height: none;
        min-width: 0;
        padding: 1rem 1.333rem;
        border-radius: 0.667rem 0.667rem 0 0;
        overflow: visible;
        clip-path: none;
        transform: translateY(calc(100% + 3rem));
        transition: transform 0.28s ease-out;
        pointer-events: none;
        background: #ffffff;
        box-shadow: 0 -0.167rem 0.833rem rgba(0, 0, 0, 0.12);
    }
    .m-flyout-item.is-open .m-flyout-panel {
        max-width: none;
        padding: 1rem 1.333rem;
        min-height: 0;
        transform: translateY(0);
        pointer-events: auto;
    }
    .m-flyout-item[data-flyout="pegel"].is-open .m-flyout-panel {
        padding: 1rem 1.333rem;
        min-height: 0;
    }
    body { padding-bottom: 3rem; }
}
/* === Modul Box-Element · Abgerundete Ecken === */
/*
 * Abgerundete Ecken für freistehende Bilder (8 px = 0.444rem @ 18-px-Root).
 * Greift bei Bild- und BildTextBox-Boxen — explizit NICHT bei c11.overflow-l/-r
 * (dort soll das Bild scharf an die Viewport-Kante laufen).
 */
.box-element:not(.overflow-l):not(.overflow-r) > .bild img,
.box-element:not(.overflow-l):not(.overflow-r) > .bildtextbox .box-img img {
    border-radius: 0.444rem;
}
.box-element:not(.overflow-l):not(.overflow-r) > .bild picture,
.box-element:not(.overflow-l):not(.overflow-r) > .bildtextbox .box-img picture {
    border-radius: 0.444rem;
    overflow: hidden;
    display: block;
}

/* === Modul Box-Element · Mehrfach-Blöcke === */
/*
 * Mehrere Box-Element-Blöcke innerhalb derselben CType-Tab.
 * Wenn ein Tab mehrere Box-Element-Slices enthält, sollen sie wie ein
 * durchlaufender Block wirken (= 1× Padding zwischen den Blöcken statt 2×).
 */
@media (min-width: 64em) {
    .box-section--continuation:not([data-section-top-decor]) > .box-wrap > .box-element > .text,
    .box-section--continuation:not([data-section-top-decor]) > .box-wrap > .box-element > .bild,
    .box-section--continuation:not([data-section-top-decor]) > .box-wrap > .box-element > .infobox,
    .box-section--continuation:not([data-section-top-decor]) > .box-wrap > .box-element > .bildtextbox,
    .box-section--continuation:not([data-section-top-decor]) > .box-wrap > .box-element > .kachel,
    .box-section--continuation:not([data-section-top-decor]) > .box-wrap > .box-element > .html,
    .box-section--continuation:not([data-section-top-decor]) > .box-wrap > .box-element > .galerie,
    .box-section--continuation:not([data-section-top-decor]) > .box-wrap > .box-element > .slide {
        padding-top: 0;
    }
}

.box-element .bildtextbox .box-img + .box-text {
    margin-top: 1rem;
}
@media (min-width: 64em) {
    .box-element.c11:has(> .bildtextbox) > .bild:not(.bild-h-stretch),
    .box-element.c11:has(> .bildtextbox) > .bildtextbox:not(.bild-h-stretch) {
        align-self: start;
        min-height: 0;
    }
    .box-element.c11:has(> .bildtextbox) > .bild:not(.bild-h-stretch) img,
    .box-element.c11:has(> .bildtextbox) > .bildtextbox:not(.bild-h-stretch) .box-img img {
        height: auto;
    }
}

@media (min-width: 64em) {
    .box-element > .bild.bild-h-stretch,
    .box-element > .bildtextbox.bild-h-stretch {
        align-self: stretch;
        min-height: 0;
        overflow: hidden;
        position: relative;
    }
    .box-element > .bild.bild-h-stretch img,
    .box-element > .bildtextbox.bild-h-stretch .box-img img {
        position: absolute;
        inset: 3rem 0;
        width: 100%;
        height: calc(100% - 6rem);
        object-fit: cover;
    }
    .box-element > .bild.bild-h-natural,
    .box-element > .bildtextbox.bild-h-natural {
        align-self: start;
        min-height: 0;
    }
    .box-element > .bild.bild-h-natural img,
    .box-element > .bildtextbox.bild-h-natural .box-img img {
        height: auto;
    }
}
@media (min-width: 112.5em) {
    .box-element > .bild.bild-h-stretch img,
    .box-element > .bildtextbox.bild-h-stretch .box-img img {
        inset: 5rem 0;
        height: calc(100% - 10rem);
    }
}

/* Linkbox am Ende eines Box-Slots — nutzt die Sektion-Linkbox-Farben. */
.box-element .text a.m-box-link-btn,
.box-element .bildtextbox a.m-box-link-btn,
.box-element .infobox a.m-box-link-btn,
.box-element .html a.m-box-link-btn {
    display: inline-flex; align-items: center; gap: 0.5rem;
    align-self: flex-start;
    margin-top: 1rem;
    background-color: var(--section-link-bg, #2563eb);    color: var(--section-link-fg, #ffffff);
    font-weight: 400;
    font-size: 1rem;
    padding: 0.389rem 0.889rem;
    border-radius: 0.222rem;
    text-decoration: none;
    text-transform: uppercase;
    letter-spacing: 0.02em;
    transition: filter 0.2s;
}
.box-element .text a.m-box-link-btn:hover,
.box-element .bildtextbox a.m-box-link-btn:hover,
.box-element .infobox a.m-box-link-btn:hover,
.box-element .html a.m-box-link-btn:hover { filter: brightness(0.95); }
.m-box-link-icon,
.m-kachel-btn-icon {
    width: 1.111rem; height: 1.111rem;
    color: var(--color-accent);
    flex-shrink: 0;
}

/* === Modul Box-Element · Inhaltstyp Kachel === */
.box-element .kachel { display: flex; flex-direction: column; }
.m-kachel {
    display: flex; flex-direction: column;
    overflow: hidden;
    border-radius: 0.222rem;
    background-color: #ffffff;
    color: var(--color-primary);
    height: auto;
}
.box-element > .kachel { align-self: start; }
.box-element:not(:has(> :not(.kachel))) > .kachel { align-self: stretch; }
.box-element:not(:has(> :not(.kachel))) > .kachel .m-kachel { height: 100%; }
.m-kachel--themed {
    background-color: var(--card-bg, #ffffff);
    color: var(--card-fg, var(--color-primary));
}
.m-kachel-img {
    width: 100%;
    aspect-ratio: 340 / 185;
    overflow: hidden;
}
.m-kachel-img img,
.m-kachel-img picture {
    width: 100%; height: 100%; object-fit: cover; display: block;
}
.m-kachel-body {
    padding: 1rem 1.111rem 1.222rem 1.111rem;
    display: flex; flex-direction: column;
    flex: 1;
}
.m-kachel-line1 {
    font-weight: 300;
    font-size: 1.167rem;
    line-height: 1.25;
    margin: 0 0 0.333rem 0;
    color: var(--card-muted, var(--card-fg, inherit));
}
.m-kachel-line2 {
    font-weight: 800;
    font-size: 1.167rem;
    line-height: 1.2;
    text-transform: uppercase;
    margin: 0 0 0.667rem 0;
    color: var(--card-heading, var(--card-fg, inherit));
}
.m-kachel-text {
    font-weight: 400;
    font-size: 0.944rem;
    line-height: 1.4;
    margin: 0 0 1rem 0;
    flex: 1;
    color: var(--card-fg, inherit);
}
.m-kachel-text > :first-child { margin-top: 0; }
.m-kachel-text > :last-child  { margin-bottom: 0; }
.m-kachel-btn {
    display: inline-flex; align-items: center; gap: 0.5rem;
    align-self: flex-start;
    background-color: var(--card-link-bg, var(--section-link-bg, #2563eb));    color: var(--card-link-fg, var(--section-link-fg, #ffffff));
    font-weight: 400;
    font-size: 1rem;
    padding: 0.389rem 0.889rem;
    border-radius: 0.222rem;
    text-decoration: none;
    text-transform: uppercase;
    letter-spacing: 0.02em;
    transition: filter 0.2s;
}
.m-kachel-btn:hover { filter: brightness(0.95); }

/* === Modul Box-Element · Inhaltstyp Symbolliste === */
.m-symbolliste {
    list-style: none;
    margin: 0; padding: 0;
    display: grid;
    grid-template-columns: 1fr;
    gap: 0.667rem 1.111rem;
}
.m-symbolliste.cols-2 { grid-template-columns: 1fr 1fr; }
.m-symbolliste.cols-3 { grid-template-columns: 1fr 1fr 1fr; }
@media (max-width: 47.99em) {
    .m-symbolliste.cols-3 { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 31.99em) {
    .m-symbolliste.cols-2,
    .m-symbolliste.cols-3 { grid-template-columns: 1fr; }
}
.m-symbolliste-item {
    display: flex; align-items: center; gap: 0.667rem;
    color: var(--card-fg, var(--section-fg, inherit));
    font-size: 1rem;
    line-height: 1.3;
}
.m-symbolliste--themed .m-symbolliste-item {
    background-color: var(--card-bg, transparent);
    color: var(--card-fg, inherit);
    padding: 0.5rem 0.667rem;
    border-radius: 0.222rem;
}
.m-symbolliste-icon-wrap {
    flex: 0 0 auto;
    width: 1.778rem; height: 1.778rem;
    display: inline-flex; align-items: center; justify-content: center;
    color: var(--card-heading, var(--section-link-bg, var(--color-accent)));
}
.m-symbolliste-icon-wrap > svg { width: 100%; height: 100%; display: block; }
.m-symbolliste-label { flex: 1 1 auto; }

/* === Modul Box-Element · Padding-Erweiterung Galerie + Slide === */
.box-element > .galerie,
.box-element > .slide,
.box-element > .kachel {
    padding-top: 2rem;
    padding-bottom: 2rem;
    min-width: 0;
}
.box-element > .galerie,
.box-element > .slide {
    align-self: start;
}
@media (max-width: 63.99em) {
    .box-element > .galerie,
    .box-element > .slide,
    .box-element > .kachel {
        padding-inline: max(var(--gutter, 1.5rem), calc((100% - var(--max-w, 1485px)) / 2));
    }
}
@media (min-width: 64em) {
    .box-element > .galerie,
    .box-element > .slide,
    .box-element > .kachel {
        padding-top: 3rem;
        padding-bottom: 3rem;
    }
    .box-element.c11 > .galerie:first-child,
    .box-element.c11 > .slide:first-child,
    .box-element.c11 > .kachel:first-child {
        padding-left: max(var(--gutter, 1.5rem), calc((min(100vw, var(--max-w-ext, 1920px)) - var(--max-w, 1485px)) / 2));
        padding-right: 2.222rem;
    }
    .box-element.c11 > .galerie:last-child,
    .box-element.c11 > .slide:last-child,
    .box-element.c11 > .kachel:last-child {
        padding-right: max(var(--gutter, 1.5rem), calc((min(100vw, var(--max-w-ext, 1920px)) - var(--max-w, 1485px)) / 2));
        padding-left: 2.222rem;
    }
}
@media (min-width: 112.5em) {
    .box-element > .galerie,
    .box-element > .slide,
    .box-element > .kachel {
        padding-top: 5rem;
        padding-bottom: 5rem;
    }
}

/* === Modul Box-Element · Inhaltstyp Galerie === */
.box-element .galerie .m-galerie,
.box-element .slide   .m-slider { display: block; width: 100%; }
.m-galerie-header {
    display: block;
    width: 100%;
    margin-bottom: 0.667rem;
}
.m-galerie-header a,
.m-galerie-header img,
.m-galerie-header picture { display: block; width: 100%; height: auto; }
.m-galerie-header img,
.m-galerie-header picture { border-radius: 0.444rem; overflow: hidden; }
.m-galerie-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(7rem, 1fr));
    gap: 0.667rem;
}
.m-galerie-grid-item a,
.m-galerie-grid-item img,
.m-galerie-grid-item picture {
    display: block; width: 100%; height: auto;
    border-radius: 0.222rem; overflow: hidden;
}
.m-galerie-grid-item a { transition: filter 0.2s; }
.m-galerie-grid-item a:hover { filter: brightness(0.92); }

/* === Modul Box-Element · Inhaltstyp Slide === */
.m-slider { width: 100%; max-width: 100%; }
.m-slider .swiper {
    width: 100%; max-width: 100%;
    aspect-ratio: 4 / 3;
    overflow: hidden;
    position: relative;
    border-radius: 0.444rem;
    background: rgba(0,0,0,0.04);
}
.box-element.c1111 .m-slider .swiper { aspect-ratio: 5 / 4; }
.box-element.c11111 .m-slider .swiper { aspect-ratio: 1 / 1; }
.m-slider .swiper-slide {
    box-sizing: border-box;
    overflow: hidden;
}
.m-slider .swiper-slide img,
.m-slider .swiper-slide picture {
    display: block;
    width: 100% !important;
    height: 100% !important;
    object-fit: cover;
}
.m-slider .swiper-slide-caption {
    margin-top: 0.5rem;
    font-size: 0.944rem;
    color: var(--section-muted, var(--section-fg, inherit));
    text-align: center;
}
.m-slider .swiper-pagination {
    position: absolute;
    left: 0; right: 0; bottom: 1rem;
    z-index: 5;
    display: flex; justify-content: center; gap: 0.444rem;
    pointer-events: none;
}
.m-slider .swiper-pagination-bullet {
    pointer-events: auto;
    width: 1.333rem;
    height: 1.333rem;
    border-radius: 9999px;
    border: 1px solid #ffffff;
    background-color: #ffffff;
    opacity: 1;
    margin: 0;
    transition: background-color 0.2s;
    cursor: pointer;
}
.m-slider .swiper-pagination-bullet:hover { background-color: #e5e7eb; }
.m-slider .swiper-pagination-bullet-active { background-color: #2563eb; }.m-slider .swiper-pagination-bullet-active:hover { background-color: #2563eb; }
.m-slider .swiper-button-prev,
.m-slider .swiper-button-next { color: #ffffff; text-shadow: 0 1px 3px rgba(0,0,0,0.5); }
.m-slider .swiper-button-prev::after,
.m-slider .swiper-button-next::after { font-size: 1.5rem; }
/* === Modul · Anmeldung-Form (Termin-Anmeldung) === */
/*
 * Header oben (H1/H2 + Intro-Body), darunter 2-spaltiges Form-Grid mit
 * Pflichtfeld-Markierung, Validierungs-Errors, Submit-Button mit Pfeil-Icon.
 * Farben kommen aus der Section-Config (--section-fg/-heading/-muted).
 */
.m-anmeldung-section { color: var(--section-fg, inherit); }
.m-anmeldung-header { margin-bottom: 2.222rem; text-align: center; }
.m-anmeldung-title  { font-size: 1.889rem; line-height: 1.15; margin: 0 0 1rem 0; color: var(--section-heading, var(--section-fg, inherit)); }
.m-anmeldung-h1     { display: block; font-weight: 300; color: var(--section-muted, var(--section-fg, inherit)); }
.m-anmeldung-h2     { display: block; font-weight: 800; text-transform: uppercase; letter-spacing: 0.02em; }
.m-anmeldung-intro  { color: var(--section-fg, inherit); }
.m-anmeldung-intro p { margin: 0 0 1rem 0; }
.m-anmeldung-intro p:last-child { margin-bottom: 0; }

.m-anmeldung-form { max-width: 50rem; margin: 0 auto; }
.m-anmeldung-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1rem 1.333rem;
}
@media (max-width: 47.99em) { .m-anmeldung-grid { grid-template-columns: 1fr; } }

.m-anmeldung-field { display: flex; flex-direction: column; gap: 0.333rem; }
.m-anmeldung-field--full { grid-column: 1 / -1; }
.m-anmeldung-field--plz  { grid-column: span 1; }
.m-anmeldung-field--ort  { grid-column: span 1; }
@media (min-width: 48em) {
    .m-anmeldung-grid > .m-anmeldung-field--plz { grid-column: 1 / span 1; max-width: 12rem; }
    .m-anmeldung-grid > .m-anmeldung-field--ort { grid-column: 2 / span 1; }
}

.m-anmeldung-field label {
    font-size: 0.889rem;
    font-weight: 400;
    color: var(--section-fg, inherit);
}
.m-anmeldung-field input[type="text"],
.m-anmeldung-field input[type="email"],
.m-anmeldung-field input[type="tel"],
.m-anmeldung-field input[type="date"],
.m-anmeldung-field select,
.m-anmeldung-field textarea {
    width: 100%;
    padding: 0.5rem 0.778rem;
    font-size: 1rem;
    line-height: 1.4;
    color: #0f172a;    background: #ffffff;
    border: 1px solid rgba(0,0,0,0.15);
    border-radius: 0.222rem;
    box-sizing: border-box;
    transition: border-color 0.15s, box-shadow 0.15s;
}
.m-anmeldung-field input:focus,
.m-anmeldung-field select:focus,
.m-anmeldung-field textarea:focus {
    outline: none;
    border-color: var(--color-accent, #f59e0b);    box-shadow: 0 0 0 3px rgba(245, 158, 11, 0.25);}
.m-anmeldung-field textarea { resize: vertical; min-height: 5rem; }

.m-anmeldung-field--checkbox label {
    display: flex; align-items: flex-start; gap: 0.5rem;
    font-size: 0.889rem; font-weight: 400;
    cursor: pointer;
}
.m-anmeldung-field--checkbox input[type="checkbox"] {
    margin-top: 0.222rem;
    flex: 0 0 auto;
}

.m-anmeldung-field.has-error input,
.m-anmeldung-field.has-error select,
.m-anmeldung-field.has-error textarea {
    border-color: #dc2626;
}
.m-anmeldung-field-error {
    color: #dc2626;
    font-size: 0.833rem;
    margin: 0;
}
.m-anmeldung-error {
    background: rgba(220,38,38,0.08);
    border: 1px solid #dc2626;
    color: #dc2626;
    padding: 0.778rem 1rem;
    border-radius: 0.333rem;
    margin-bottom: 1.333rem;
}
.m-anmeldung-error ul { margin: 0.444rem 0 0 1.333rem; padding: 0; }

.m-anmeldung-submit { margin-top: 1.667rem; text-align: center; }
.m-anmeldung-cta {
    display: inline-flex; align-items: center; gap: 0.5rem;
    padding: 0.667rem 1.667rem;
    background-color: var(--section-link-bg, var(--color-primary, #0f172a));    color: var(--section-link-fg, #ffffff);
    font-size: 1rem; font-weight: 400;
    text-transform: uppercase; letter-spacing: 0.02em;
    border: 0; border-radius: 0.222rem;
    cursor: pointer;
    transition: filter 0.2s;
}
.m-anmeldung-cta:hover { filter: brightness(0.92); }
.m-anmeldung-cta-icon  { color: var(--color-accent, #f59e0b); width: 1.111em; height: 1.111em; flex: 0 0 auto; }.m-anmeldung-cta-icon svg { width: 100%; height: 100%; display: block; }

.m-anmeldung-thanks {
    max-width: 50rem; margin: 0 auto;
    padding: 2rem;
    background: rgba(34,197,94,0.08);
    border: 1px solid rgba(34,197,94,0.4);
    border-radius: 0.444rem;
    color: var(--section-fg, inherit);
}
.m-anmeldung-thanks p { margin: 0 0 1rem 0; }
.m-anmeldung-thanks p:last-child { margin-bottom: 0; }

/* === Modul · Kontakt-Form === */
/*
 * Analog Anmeldung-Form, ohne Termin-Bezug.
 * Pattern und Styles gespiegelt aus .m-anmeldung-* — gleiche Form-UI,
 * eigene Klasse zur Unterscheidung in Layout-Overrides + Backend-Routing.
 */
.m-kontakt-section { color: var(--section-fg, inherit); }
.m-kontakt-header { margin-bottom: 2.222rem; text-align: center; }
.m-kontakt-title  { font-size: 1.889rem; line-height: 1.15; margin: 0 0 1rem 0; color: var(--section-heading, var(--section-fg, inherit)); }
.m-kontakt-h1     { display: block; font-weight: 300; color: var(--section-muted, var(--section-fg, inherit)); }
.m-kontakt-h2     { display: block; font-weight: 800; text-transform: uppercase; letter-spacing: 0.02em; }
.m-kontakt-intro  { color: var(--section-fg, inherit); }
.m-kontakt-intro p { margin: 0 0 1rem 0; }
.m-kontakt-intro p:last-child { margin-bottom: 0; }

.m-kontakt-form { max-width: 50rem; margin: 0 auto; }
.m-kontakt-form .m-kontakt-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1rem 1.333rem;
}
@media (max-width: 47.99em) { .m-kontakt-form .m-kontakt-grid { grid-template-columns: 1fr; } }

.m-kontakt-field { display: flex; flex-direction: column; gap: 0.333rem; }
.m-kontakt-field--full { grid-column: 1 / -1; }
.m-kontakt-field--plz  { grid-column: span 1; }
.m-kontakt-field--ort  { grid-column: span 1; }
@media (min-width: 48em) {
    .m-kontakt-form .m-kontakt-grid > .m-kontakt-field--plz { grid-column: 1 / span 1; max-width: 12rem; }
    .m-kontakt-form .m-kontakt-grid > .m-kontakt-field--ort { grid-column: 2 / span 1; }
}

.m-kontakt-field label {
    font-size: 0.889rem;
    font-weight: 400;
    color: var(--section-fg, inherit);
}
.m-kontakt-field input[type="text"],
.m-kontakt-field input[type="email"],
.m-kontakt-field input[type="tel"],
.m-kontakt-field select,
.m-kontakt-field textarea {
    width: 100%;
    padding: 0.5rem 0.778rem;
    font-size: 1rem;
    line-height: 1.4;
    color: #0f172a;    background: #ffffff;
    border: 1px solid rgba(0,0,0,0.15);
    border-radius: 0.222rem;
    box-sizing: border-box;
    transition: border-color 0.15s, box-shadow 0.15s;
}
.m-kontakt-field input:focus,
.m-kontakt-field select:focus,
.m-kontakt-field textarea:focus {
    outline: none;
    border-color: var(--color-accent, #f59e0b);    box-shadow: 0 0 0 3px rgba(245, 158, 11, 0.25);}
.m-kontakt-field textarea { resize: vertical; min-height: 6rem; }

/* KEIN FLEX AM EINWILLIGUNGS-LABEL — berichtigt am 01.09.2026.
 *
 * Hier stand `display: flex; align-items: flex-start; gap: 0.5rem`. Das ist
 * falsch, sobald der Einwilligungstext einen Verweis enthält — und das tut er
 * immer, denn er verlinkt die Datenschutzerklärung. Flex macht aus JEDEM
 * zusammenhängenden Textstück ein eigenes Element:
 *
 *     [Kästchen] ["Ich habe die"] [Verweis] ["gelesen und … Anfrage. *"]
 *
 * Mit `nowrap` stehen die vier nebeneinander und schrumpfen, bis jedes FUER
 * SICH umbricht. Gemessen auf frauennotruf.msm.de am 01.09.2026:
 *
 *     1600 px   Zeile 1: „Ich habe … Anfrage."   Zeile 2: „die *"
 *      390 px   drei Zeilen, die Wörter stehen in SPALTEN untereinander:
 *                 „Ich / habe / die" links, der Rest rechts daneben
 *
 * Der Satz lässt sich so nicht lesen. Stattdessen ein Hängeeinzug: Das Label
 * ist ein normaler Block, das Kästchen sitzt absolut im Einzug. Der Satz
 * fließt dann als EIN Absatz, und jede Zeile behält denselben Einzug —
 * nachgemessen 18/18 px bei 390 px Breite.
 *
 * Die naheliegende Alternative, das Kästchen schwimmen zu lassen, ist geprüft
 * und fällt durch: Dort rutscht die zweite Zeile auf 0 px Einzug und läuft
 * unter das Kästchen.
 *
 * Der Einzug 1.5rem = Kästchenbreite (13 px) + die bisherige `gap`-Stufe
 * (0.5rem = 8 px), aufgerundet auf die nächste halbe rem-Stufe.
 */
.m-kontakt-field--checkbox label {
    display: block;
    position: relative;
    padding-left: 1.5rem;
    font-size: 0.889rem; font-weight: 400;
    cursor: pointer;
}
.m-kontakt-field--checkbox input[type="checkbox"] {
    position: absolute;
    left: 0;
    top: 0.222rem;
    margin-top: 0;
}
.m-kontakt-field--checkbox a {
    color: var(--section-link-bg, var(--color-accent, #f59e0b));}

.m-kontakt-field.has-error input,
.m-kontakt-field.has-error select,
.m-kontakt-field.has-error textarea {
    border-color: #dc2626;
}
.m-kontakt-field-error {
    color: #dc2626;
    font-size: 0.833rem;
    margin: 0;
}

/* Abhängige Auswahlfelder des Kontaktformulars (Slot 9).
 *
 * `[hidden]` bekommt hier ausdrücklich `display: none`: Die Formularfelder
 * darüber sind Flex- bzw. Grid-Kinder, und in beiden Kontexten setzt der
 * Browser das `hidden`-Attribut wirkungslos — das Feld bliebe sichtbar, obwohl
 * das Skript es versteckt hat. Ohne diese Zeile sieht ein Besucher die Felder
 * abgewählter Gruppen weiter, und der Fehler wäre allein am JavaScript nicht zu
 * finden.
 *
 * Die Einrückung markiert die Zugehörigkeit zur angekreuzten Gruppe — ohne JS
 * stehen alle Felder untereinander, und ohne diesen Hinweis wäre nicht
 * erkennbar, welches Feld zu welcher Ankreuzoption gehört. */
.m-kontakt-abhaengig[hidden] { display: none; }
.m-kontakt-abhaengig {
    padding-left: 1.333rem;
    border-left: 2px solid color-mix(in srgb, var(--section-fg, currentColor) 20%, transparent);
}
.m-kontakt-error {
    background: rgba(220,38,38,0.08);
    border: 1px solid #dc2626;
    color: #dc2626;
    padding: 0.778rem 1rem;
    border-radius: 0.333rem;
    margin-bottom: 1.333rem;
}
.m-kontakt-error ul { margin: 0.444rem 0 0 1.333rem; padding: 0; }

.m-kontakt-submit { margin-top: 1.667rem; text-align: center; }
.m-kontakt-cta {
    display: inline-flex; align-items: center; gap: 0.5rem;
    padding: 0.667rem 1.667rem;
    background-color: var(--section-link-bg, var(--color-primary, #0f172a));    color: var(--section-link-fg, #ffffff);
    font-size: 1rem; font-weight: 400;
    text-transform: uppercase; letter-spacing: 0.02em;
    border: 0; border-radius: 0.222rem;
    cursor: pointer;
    transition: filter 0.2s;
}
.m-kontakt-cta:hover { filter: brightness(0.92); }
.m-kontakt-cta-icon  { color: var(--color-accent, #f59e0b); width: 1.111em; height: 1.111em; flex: 0 0 auto; }.m-kontakt-cta-icon svg { width: 100%; height: 100%; display: block; }

.m-kontakt-thanks {
    max-width: 50rem; margin: 0 auto;
    padding: 2rem;
    background: rgba(34,197,94,0.08);
    border: 1px solid rgba(34,197,94,0.4);
    border-radius: 0.444rem;
    color: var(--section-fg, inherit);
}
.m-kontakt-thanks p { margin: 0 0 1rem 0; }
.m-kontakt-thanks p:last-child { margin-bottom: 0; }
/* === Modul · Downloads (Liste + Kacheln) === */
/*
 * Module Download-Liste + Download-Kacheln (gemeinsamer Wrapper).
 * Liste:    kompakte Linkliste (Kategorie-Anker oben,
 *           Titel + Größe + Seitenanzahl pro Eintrag)
 * Kacheln:  Grid mit Vorschaubild, Titel, Seiten, Download-Button.
 */
.m-dl-section { color: var(--section-fg, inherit); }
.m-dl-header { margin-bottom: 2.222rem; text-align: left; }
.m-dl-header--align-left   { text-align: left; }
.m-dl-header--align-center { text-align: center; }
.m-dl-header--align-right  { text-align: right; }
.m-dl-header--align-center .m-dl-intro { margin-left: auto; margin-right: auto; }
.m-dl-header--align-right  .m-dl-intro { margin-left: auto; margin-right: 0; }
.m-dl-title  { font-size: 1.889rem; line-height: 1.15; margin: 0 0 1rem 0; color: var(--section-heading, var(--section-fg, inherit)); }
.m-dl-h1     { display: block; font-weight: 300; color: var(--section-muted, var(--section-fg, inherit)); }
.m-dl-h2     { display: block; font-weight: 800; }
.m-dl-intro  { color: var(--section-fg, inherit); max-width: 50rem; }
.m-dl-intro p { margin: 0 0 1rem 0; }
.m-dl-intro p:last-child { margin-bottom: 0; }
.m-dl-intro--cols-2,
.m-dl-intro--cols-3 { max-width: none; }
@media (min-width: 64em) {
    .m-dl-intro--cols-2 { columns: 2; column-gap: 1.778rem; }
    .m-dl-intro--cols-3 { columns: 3; column-gap: 1.444rem; }
    .m-dl-intro--cols-2 p,
    .m-dl-intro--cols-3 p { break-inside: avoid; }
}

.m-dl-toc {
    display: flex; flex-wrap: wrap; gap: 0.444rem;
    margin-bottom: 2.222rem; padding-bottom: 1.111rem;
    border-bottom: 1px solid rgba(0,0,0,0.08);
}
.m-dl-toc-link {
    display: inline-block;
    padding: 0.333rem 0.889rem;
    background: var(--section-link-bg, var(--color-primary, #0f172a));    color: var(--section-link-fg, #ffffff);
    font-size: 0.833rem; font-weight: 500;
    border-radius: 9999px;
    text-decoration: none;
    transition: filter 0.15s;
}
.m-dl-toc-link:hover { filter: brightness(1.1); text-decoration: none; }

.m-dl-group { margin-bottom: 2.667rem; scroll-margin-top: 5rem; }
.m-dl-group:last-child { margin-bottom: 0; }
.m-dl-group-title {
    font-size: 1.389rem; font-weight: 800;
    margin: 0 0 1rem 0;
    color: var(--section-heading, var(--section-fg, inherit));
    padding-bottom: 0.444rem;
    border-bottom: 2px solid var(--color-accent, #f59e0b);}

/* === Modul · Download-Liste === */
.m-dl-list { list-style: none; padding: 0; margin: 0; }
.m-dl-item {
    display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.667rem;
    padding: 0.444rem 0;
    border-bottom: 1px solid rgba(0,0,0,0.06);
}
.m-dl-item:last-child { border-bottom: 0; }
.m-dl-link {
    color: var(--section-link-bg, var(--color-primary, #0f172a));    text-decoration: none;
    font-size: 1rem; font-weight: 500;
    flex: 1 1 auto;
}
.m-dl-link:hover { /* kein Underline */ }
.m-dl-meta {
    color: var(--section-muted, #6b7280);
    font-size: 0.833rem; font-weight: 300;
    display: inline-flex; gap: 0.667rem;
    flex: 0 0 auto;
}
.m-dl-meta .m-dl-size + .m-dl-pages::before {
    content: '·'; margin-right: 0.667rem; color: rgba(0,0,0,0.25);
}
.m-dl-desc {
    flex: 1 1 100%;
    margin-top: 0.333rem;
    color: var(--section-muted, #6b7280);
    font-size: 0.875rem; line-height: 1.5; font-weight: 300;
}
.m-dl-desc > :first-child { margin-top: 0; }
.m-dl-desc > :last-child  { margin-bottom: 0; }
.m-dl-desc p { margin: 0 0 0.444rem; }
.m-dl-desc p:last-child { margin-bottom: 0; }

/* === Modul · Download-Kacheln === */
.m-dl-grid {
    display: grid; gap: 1.333rem;
    grid-template-columns: 1fr;
}
@media (min-width: 40em) { .m-dl-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 64em) {
    .m-dl-grid--cols-2 { grid-template-columns: repeat(2, 1fr); }
    .m-dl-grid--cols-3 { grid-template-columns: repeat(3, 1fr); }
    .m-dl-grid--cols-4 { grid-template-columns: repeat(4, 1fr); }
    .m-dl-grid--cols-5 { grid-template-columns: repeat(5, 1fr); }
}

.m-dl-tile {
    display: flex; flex-direction: column;
    background: var(--section-box-bg, #ffffff);
    color: var(--section-box-fg, var(--color-primary, #0f172a));    border: 1px solid rgba(0,0,0,0.08);
    border-radius: 0.444rem;
    overflow: hidden;
    transition: box-shadow 0.15s, transform 0.15s;
}
.m-dl-tile--themed {
    background: var(--card-bg, var(--section-box-bg, #ffffff));
    color: var(--card-fg, var(--section-box-fg, inherit));
}
.m-dl-tile--themed .m-dl-tile-title,
.m-dl-tile--themed .m-dl-tile-title a {
    color: var(--card-heading, var(--card-fg, var(--section-box-fg, inherit)));
}
.m-dl-tile--themed .m-dl-tile-meta {
    color: var(--card-fg, var(--section-box-fg, inherit));
    opacity: 0.7;
}
.m-dl-tile--themed .m-dl-tile-btn {
    background: var(--card-link-bg, var(--section-link-bg, var(--color-primary, #0f172a)));    color: var(--card-link-fg, var(--section-link-fg, #ffffff));
}
.m-dl-tile:hover {
    box-shadow: 0 4px 16px rgba(0,0,0,0.08);
    transform: translateY(-2px);
}
/* DAS BILDFORMAT IST EINSTELLBAR. 4:3 bleibt die Vorgabe — für Bildschirmfotos
   und breite Dokumente richtig. Sites, deren Downloads Hochformate sind
   (Flyer, Broschueren), setzen `--dl-tile-ratio`: Ein `object-fit: cover` in
   einem Querrahmen schneidet aus einem A4-Titelbild sonst einen Streifen heraus,
   und vom Titel bleibt nichts uebrig. Aufgefallen beim Auftritt Frauennotruf
   Westerburg, dessen zehn Downloads samt Titelbild alle hochkant sind. */
.m-dl-tile-img {
    display: block; aspect-ratio: var(--dl-tile-ratio, 4 / 3); background: #f3f4f6; overflow: hidden;
}
.m-dl-tile-img img { width: 100%; height: 100%; object-fit: cover; display: block; }
.m-dl-tile-img--placeholder {
    display: flex; align-items: center; justify-content: center;
    background: linear-gradient(135deg, #f3f4f6, #e5e7eb);
}
.m-dl-tile-icon { width: 2.667rem; height: 2.667rem; color: rgba(0,0,0,0.3); }
.m-dl-tile-icon svg { width: 100%; height: 100%; display: block; }
.m-dl-tile-body { padding: 0.889rem; display: flex; flex-direction: column; flex: 1 1 auto; gap: 0.444rem; }
.m-dl-tile-title {
    font-size: 1rem; font-weight: 600; line-height: 1.3;
    margin: 0;
    color: var(--section-box-fg, var(--color-primary, #0f172a));}
.m-dl-tile-title a {
    color: inherit; text-decoration: none;
}
.m-dl-tile-title a:hover { /* kein Underline */ }
.m-dl-tile-meta {
    margin: 0; font-size: 0.833rem; color: rgba(0,0,0,0.5); font-weight: 300;
}
.m-dl-tile-desc {
    margin: 0.222rem 0 0;
    font-size: 0.875rem; line-height: 1.5; font-weight: 300;
    color: rgba(0,0,0,0.65);
}
.m-dl-tile-desc > :first-child { margin-top: 0; }
.m-dl-tile-desc > :last-child  { margin-bottom: 0; }
.m-dl-tile-desc p { margin: 0 0 0.444rem; }
.m-dl-tile-desc p:last-child { margin-bottom: 0; }
.m-dl-tile--themed .m-dl-tile-desc {
    color: var(--card-fg, var(--section-box-fg, inherit));
    opacity: 0.8;
}
.m-dl-tile-btn {
    margin-top: auto;
    display: inline-flex; align-items: center; gap: 0.444rem;
    padding: 0.444rem 0.889rem;
    background: var(--section-link-bg, var(--color-primary, #0f172a));    color: var(--section-link-fg, #ffffff);
    font-size: 0.889rem; font-weight: 500;
    text-transform: uppercase; letter-spacing: 0.02em;
    border-radius: 0.222rem;
    text-decoration: none;
    transition: filter 0.15s;
    align-self: flex-start;
}
.m-dl-tile-btn:hover { filter: brightness(0.92); text-decoration: none; }
/* `margin-left: auto` schiebt den Pfeil an die rechte Kante, sobald der Knopf
   breiter ist als sein Inhalt. Bei der Vorgabe (inline-flex, auf Inhaltsbreite)
   bleibt es wirkungslos — die Regel kostet dort nichts und erspart der Site,
   die zwei Kanten selbst auszurichten. */
/* `inherit`, NICHT `--color-accent`: Das Zeichen sitzt IM Knopf, dessen Grund
   aus dem Kartenschema kommt (`--card-link-bg`). Die Akzentfarbe kennt diesen
   Grund nicht — auf einem violetten Knopf (#6c1f7f) misst ein oranges Zeichen
   2,87:1 und verfehlt die 3:1, die WCAG für Bildzeichen verlangt, waehrend die
   Beschriftung daneben bei 9,81 liegt. Geerbt wird `--card-link-fg`, also genau
   die Farbe, die für diesen Grund gewaehlt wurde. */
.m-dl-tile-btn-icon { width: 1em; height: 1em; flex: 0 0 auto; margin-left: auto; color: inherit; }.m-dl-tile-btn-icon svg { width: 100%; height: 100%; display: block; }

/* === Modul · Ansprechpartner-Grid === */
/*
 * Personen-Karten-Layout, Modul-Klasse `m-ap`.
 * Foto + Name + Position + Kontaktdaten als Karte. Hover-Foto optional.
 */
.m-ap-section { color: var(--section-fg, inherit); }

/* Inner-Wrap-Padding für full-bleed-Module (analog .m-bg-col).
 * Da die Module im full_bleed_module_keys-Register kein Section-Padding
 * rendern (siehe py-0-Hardcode in mod_box_grid + den fünf Form-/Listen-
 * Modulen), kommt das vertikale Spacing aus dem Inner-Wrap. Symmetrisch,
 * pro Breakpoint identisch zu .m-bg-col. */
.m-ap-wrap,
.m-dl-wrap,
.m-anmeldung-wrap,
.m-kontakt-wrap {
    width: 100%;
    padding-top: 2rem;
    padding-bottom: 2rem;
}
@media (min-width: 64em) {
    .m-ap-wrap,
    .m-dl-wrap,
    .m-anmeldung-wrap,
    .m-kontakt-wrap { padding-top: 3rem; padding-bottom: 3rem; }
}
@media (min-width: 112.5em) {
    .m-ap-wrap,
    .m-dl-wrap,
    .m-anmeldung-wrap,
    .m-kontakt-wrap { padding-top: 3.5rem; padding-bottom: 3.5rem; }
}

.m-ap-header { margin-bottom: 2.222rem; text-align: left; }
.m-ap-header--align-left   { text-align: left; }
.m-ap-header--align-center { text-align: center; }
.m-ap-header--align-right  { text-align: right; }
.m-ap-header--align-center .m-ap-intro { margin-left: auto; margin-right: auto; }
.m-ap-header--align-right  .m-ap-intro { margin-left: auto; margin-right: 0; }
.m-ap-title  { font-size: 1.889rem; line-height: 1.15; margin: 0 0 1rem 0; color: var(--section-heading, var(--section-fg, inherit)); }
.m-ap-h1     { display: block; font-weight: 300; color: var(--section-muted, var(--section-fg, inherit)); }
.m-ap-h2     { display: block; font-weight: 800; }
.m-ap-intro  { color: var(--section-fg, inherit); max-width: 50rem; }
.m-ap-intro p { margin: 0 0 1rem 0; }
.m-ap-intro p:last-child { margin-bottom: 0; }
.m-ap-intro--cols-2,
.m-ap-intro--cols-3 { max-width: none; }
@media (min-width: 64em) {
    .m-ap-intro--cols-2 { columns: 2; column-gap: 1.778rem; }
    .m-ap-intro--cols-3 { columns: 3; column-gap: 1.444rem; }
    .m-ap-intro--cols-2 p,
    .m-ap-intro--cols-3 p { break-inside: avoid; }
}

.m-ap-toc {
    display: flex; flex-wrap: wrap; gap: 0.667rem;
    margin: 0 0 2rem; padding: 0;
}
.m-ap-toc-link {
    display: inline-block;
    padding: 0.444rem 0.889rem;
    background: var(--section-link-bg, var(--color-primary, #0f172a));    color: var(--section-link-fg, #ffffff);
    border-radius: 999px;
    font-size: 0.889rem; font-weight: 500;
    text-decoration: none;
    transition: filter 0.15s;
}
.m-ap-toc-link:hover { filter: brightness(1.15); text-decoration: none; }

.m-ap-group { margin-bottom: 3rem; scroll-margin-top: 5rem; }
.m-ap-group:last-child { margin-bottom: 0; }
.m-ap-group-title {
    font-size: 1.444rem; font-weight: 800;
    margin: 0 0 1.333rem;
    padding-bottom: 0.444rem;
    border-bottom: 2px solid var(--color-accent, #f59e0b);    color: var(--section-heading, var(--section-fg, inherit));
}

.m-ap-grid {
    display: grid; gap: 1.333rem;
    grid-template-columns: 1fr;
}
@media (min-width: 40em) and (max-width: 63.99em) {
    .m-ap-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 64em) {
    .m-ap-grid--cols-2 { grid-template-columns: repeat(2, 1fr); }
    .m-ap-grid--cols-3 { grid-template-columns: repeat(3, 1fr); }
    .m-ap-grid--cols-4 { grid-template-columns: repeat(4, 1fr); }
    .m-ap-grid--cols-5 { grid-template-columns: repeat(5, 1fr); }
}

.m-ap-card {
    display: flex; flex-direction: column;
    overflow: hidden;
    background: #ffffff;
    border-radius: 0.444rem;
    box-shadow: 0 1px 3px rgba(0,0,0,0.06);
    transition: box-shadow 0.2s, transform 0.2s;
}
.m-ap-card:hover {
    box-shadow: 0 4px 14px rgba(0,0,0,0.10);
    transform: translateY(-2px);
}
.m-ap-card--themed {
    background: var(--card-bg, var(--section-box-bg, #ffffff));
    color: var(--card-fg, var(--section-box-fg, inherit));
}

.m-ap-photo {
    position: relative;
    aspect-ratio: 4 / 5;
    overflow: hidden;
    background: rgba(0,0,0,0.04);
}
.m-ap-photo-primary,
.m-ap-photo-hover {
    position: absolute; inset: 0;
}
.m-ap-photo-primary img,
.m-ap-photo-hover img {
    width: 100%; height: 100%; object-fit: cover; display: block;
}
.m-ap-photo-hover {
    opacity: 0;
    transition: opacity 0.4s ease;
}
.m-ap-card:hover .m-ap-photo-hover { opacity: 1; }

.m-ap-photo--placeholder {
    display: flex; align-items: center; justify-content: center;
    color: rgba(0,0,0,0.25);
}
.m-ap-photo-icon { width: 3rem; height: 3rem; }
.m-ap-photo-icon svg { width: 100%; height: 100%; display: block; }

.m-ap-body {
    display: flex; flex-direction: column; gap: 0.444rem;
    padding: 1rem 1.111rem 1.222rem;
    flex: 1 1 auto;
}
.m-ap-name {
    margin: 0;
    font-size: 1.111rem; font-weight: 700;
    line-height: 1.2;
    color: var(--card-heading, var(--section-heading, var(--section-fg, inherit)));
}
.m-ap-card--themed .m-ap-name {
    color: var(--card-heading, var(--card-fg, var(--section-box-fg, inherit)));
}
.m-ap-position {
    margin: 0;
    font-size: 0.889rem; font-weight: 500;
    color: rgba(0,0,0,0.55);
    text-transform: uppercase; letter-spacing: 0.02em;
    /* Positionsbezeichnungen sind deutsche Komposita und stehen in einer
       schmalen Karte. Gemessen am Auftritt Frauennotruf Westerburg
       (28.08.2026): „Alphabetisierung/Grundbildungskurse" braucht 336 px in
       einem 295 px breiten Kasten — bei DREI von zehn Personen, und der
       Ueberhang wurde vom `overflow: hidden` der Karte abgeschnitten.

       `overflow-wrap` ist der tragende Teil: Es verhindert den Beschnitt.
       `hyphens` steht daneben als Zugabe — nachgemessen hat es im Pruefbrowser
       NICHTS bewirkt (mit und ohne identisch: zwei Zeilen, 38 px), weil dort
       kein deutsches Trennwoerterbuch geladen ist. Wo eines vorhanden ist,
       trennt es sauber statt hart; verlassen darf man sich nicht darauf.

       Der Schraegstrich ist für den Umbruch KEINE Trennstelle. Wer ihn als
       solche will, setzt ein schmales Leerzeichen ohne Breite (U+200B) hinter
       den Strich — das ist Inhalt und gehoert in die Daten, nicht hierher. */
    overflow-wrap: break-word;
    hyphens: auto;
}
.m-ap-card--themed .m-ap-position {
    color: var(--card-fg, var(--section-box-fg, inherit));
    opacity: 0.7;
}
.m-ap-vita {
    font-size: 0.889rem; line-height: 1.5; font-weight: 300;
    color: rgba(0,0,0,0.7);
}
.m-ap-card--themed .m-ap-vita {
    color: var(--card-fg, var(--section-box-fg, inherit));
    opacity: 0.85;
}
.m-ap-vita > :first-child { margin-top: 0; }
.m-ap-vita > :last-child  { margin-bottom: 0; }
.m-ap-vita p { margin: 0 0 0.444rem; }
.m-ap-vita p:last-child { margin-bottom: 0; }

.m-ap-contact {
    list-style: none;
    margin: 0.222rem 0 0;
    padding: 0;
    display: flex; flex-direction: column; gap: 0.333rem;
    font-size: 0.889rem;
}
/* Kontaktzeilen nebeneinander statt untereinander — Option im Modul (Feld 10).
 * Umbruch erlaubt, damit vier Angaben auf schmalen Karten nicht überlaufen.
 * Der waagerechte Abstand ist größer als der senkrechte (1rem gegen 0.333rem),
 * weil nebeneinanderstehende Zeilen sonst als ein Text gelesen werden. */
.m-ap-contact--inline {
    flex-direction: row; flex-wrap: wrap;
    column-gap: 1rem; row-gap: 0.333rem;
}

.m-ap-contact-row {
    display: flex; align-items: center; gap: 0.5rem;
    color: var(--card-fg, var(--section-fg, inherit));
}
.m-ap-contact-row a {
    color: inherit; text-decoration: none;
    transition: color 0.15s;
}
.m-ap-contact-row a:hover {
    color: var(--card-link-bg, var(--section-link-bg, var(--color-primary, #0f172a)));}
.m-ap-contact-icon {
    width: 1em; height: 1em; flex: 0 0 auto;
    color: var(--card-link-bg, var(--section-link-bg, var(--color-primary, #0f172a)));}
.m-ap-contact-icon svg { width: 100%; height: 100%; display: block; }
.m-ap-card--themed .m-ap-contact-icon {
    color: var(--card-link-bg, var(--card-fg, var(--section-box-fg, inherit)));
}
/* === Modul Box-Blocks · Freie Block-Anordnung === */
/*
 * Modul-Klasse `m-bb`.
 * Block-Typen: headline, text (1/2/3-spaltig), infobox (Icon + Text), separator.
 * Layout: Bild links/rechts/oben oder kein Bild — Inhalt in der Gegenseite.
 */
.m-bb-section { color: var(--section-fg, inherit); padding: 3.333rem 0; }
.m-bb-wrap { width: 100%; }
.m-bb-layout { display: grid; gap: 2.222rem; align-items: start; }
.m-bb-layout--none { grid-template-columns: 1fr; }
.m-bb-layout--left,
.m-bb-layout--right { grid-template-columns: 1fr 1fr; }
.m-bb-layout--top { grid-template-columns: 1fr; }

.m-bb-image { width: 100%; }
.m-bb-image img { width: 100%; height: auto; display: block; border-radius: 0.444rem; }

.m-bb-headline {
    display: block;
    margin: 0 0 1.111rem 0;
    line-height: 1.15;
    color: var(--section-heading, var(--section-fg, inherit));
}
.m-bb-headline .m-bb-h1 {
    display: block;
    font-size: 1.667rem;
    font-weight: 300;
    color: var(--section-muted, var(--section-fg, inherit));
}
.m-bb-headline .m-bb-h2 {
    display: block;
    font-size: 2rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.02em;
}

.m-bb-text { margin: 0 0 1.444rem 0; color: var(--section-fg, inherit); }
.m-bb-text:last-child { margin-bottom: 0; }
.m-bb-text p { margin: 0 0 0.778rem 0; }
.m-bb-text p:last-child { margin-bottom: 0; }
.m-bb-text ul, .m-bb-text ol { margin: 0 0 0.778rem 1.222rem; padding: 0; }
.m-bb-text--cols-2 { columns: 2; column-gap: 1.778rem; }
.m-bb-text--cols-3 { columns: 3; column-gap: 1.444rem; }
.m-bb-text--cols-2 p, .m-bb-text--cols-3 p { break-inside: avoid; }
.m-bb-text--left    { text-align: left; }
.m-bb-text--center  { text-align: center; }
.m-bb-text--justify { text-align: justify; hyphens: auto; }

.m-bb-infobox { margin: 0 0 1.444rem 0; padding: 1rem 1.222rem; border-radius: 0.444rem; background: rgba(255,255,255,0.06); border: 1px solid rgba(255,255,255,0.12); }
.m-tone-light .m-bb-infobox { background: #f1f5f9; border-color: #e2e8f0; }
.m-bb-infobox-title { font-weight: 700; margin-bottom: 0.667rem; font-size: 1.111rem; }
.m-bb-infobox-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.556rem; }
.m-bb-infobox-list li { display: flex; align-items: flex-start; gap: 0.667rem; }
.m-bb-infobox .m-bb-icon { flex: 0 0 24px; display: inline-flex; align-items: center; justify-content: center; color: var(--section-heading, currentColor); }
.m-bb-infobox .m-bb-icon svg { width: 20px; height: 20px; }
.m-bb-infobox .m-bb-text-wrap { display: flex; flex-direction: column; }
.m-bb-infobox .m-bb-text-wrap strong { font-weight: 700; }
.m-bb-infobox .m-bb-text-wrap span { color: var(--section-fg, inherit); }

.m-bb-sep { border: 0; border-top: 1px solid rgba(0,0,0,0.1); margin: 1.444rem 0; }
.m-tone-dark .m-bb-sep { border-top-color: rgba(255,255,255,0.18); }

@media (max-width: 47.99em) {
    .m-bb-layout--left,
    .m-bb-layout--right { grid-template-columns: 1fr; }
    .m-bb-layout--right .m-bb-image { order: -1; }
    .m-bb-text--cols-2,
    .m-bb-text--cols-3 { columns: 1; }
    .m-bb-headline .m-bb-h1 { font-size: 1.333rem; }
    .m-bb-headline .m-bb-h2 { font-size: 1.556rem; }
}

/* === Modul Box-Grid · N-Spalten-Layout === */
/*
 * Modul-Klasse `m-bg`. Stapelbare Inhaltsboxen.
 * Layout: 1/2/3/4 Spalten · Block-Typen: headline, text, image, iconbox.
 */
.m-bg-section { color: var(--section-fg, inherit); }
.m-bg-grid { display: grid; gap: 0; }
.m-bg-grid--c1     { grid-template-columns: 1fr; }
.m-bg-grid--c11,
.m-bg-grid--c11o-l,
.m-bg-grid--c11o-r { grid-template-columns: 1fr 1fr; }
.m-bg-grid--c12    { grid-template-columns: 1fr 2fr; }
.m-bg-grid--c21    { grid-template-columns: 2fr 1fr; }
.m-bg-grid--c13    { grid-template-columns: 1fr 3fr; }
.m-bg-grid--c31    { grid-template-columns: 3fr 1fr; }
.m-bg-grid--c111   { grid-template-columns: 1fr 1fr 1fr; }
.m-bg-grid--c1111  { grid-template-columns: repeat(4, 1fr); }
.m-bg-grid--c11111 { grid-template-columns: repeat(5, 1fr); }

@media (min-width: 64em) {
    .m-bg-grid--c1,
    .m-bg-grid--c11,
    .m-bg-grid--c12, .m-bg-grid--c21,
    .m-bg-grid--c13, .m-bg-grid--c31,
    .m-bg-grid--c111, .m-bg-grid--c1111, .m-bg-grid--c11111 {
        padding-left:  max(var(--gutter, 1.5rem), calc((100% - var(--max-w, 1485px)) / 2));
        padding-right: max(var(--gutter, 1.5rem), calc((100% - var(--max-w, 1485px)) / 2));
        gap: var(--gap, 1.5rem);
    }
}

/* Aussenkante der c11o-Layouts auf den Inhaltsrahmen ausrichten.
 *
 * Die anderen Layouts holen sich den Rahmen über das Grid:
 *   padding = max(gutter, (100% - max-w) / 2)     — 100% = Grid-Breite.
 * Bei c11o darf das Grid kein Padding haben (sonst kann die Bild-Spalte nicht
 * bis zum Fensterrand laufen), also sitzt die Formel an der Spalte. Dort
 * bezieht sich `100%` aber auf die SPALTE — und die ist nur halb so breit.
 * `(956px - 1485px) / 2` ist negativ, deshalb gewann immer der Gutter und der
 * Text lief bis ~27 px an den Fensterrand (sichtbar ab ca. 1500 px Breite;
 * darunter fallen beide Werte zufaellig zusammen, dort fiel es nicht auf).
 *
 * Herleitung der Korrektur: Das Raster ist `1fr 1fr` ohne Gap, also gilt
 * Grid = 2 x Spalte. Gesucht ist (Grid - max-w) / 2 = Spalte - max-w / 2.
 * Auf die Spalte bezogen also `calc(100% - var(--max-w) / 2)`.
 * Kontrolle bei 1920 px: Spalte 956 - 742.5 = 213.5 px — exakt der Wert, den
 * das Grid der Nachbarsektionen ausweist. Bei 1440 px: 716 - 742.5 < 0, der
 * Gutter gewinnt wie bisher, dort aendert sich nichts.
 * ACHTUNG: gilt nur solange c11o gap-frei und 1fr 1fr ist. */
@media (min-width: 64em) {
    .m-bg-grid--c11o-l > .m-bg-col:first-child,
    .m-bg-grid--c11o-r > .m-bg-col:first-child {
        padding-left: max(var(--gutter, 1.5rem), calc(100% - var(--max-w, 1485px) / 2));
        padding-right: 2.222rem;
    }
    .m-bg-grid--c11o-l > .m-bg-col:last-child,
    .m-bg-grid--c11o-r > .m-bg-col:last-child {
        padding-left: 2.222rem;
        padding-right: max(var(--gutter, 1.5rem), calc(100% - var(--max-w, 1485px) / 2));
    }
}

@media (max-width: 63.99em) {
    .m-bg-grid {
        padding-left:  var(--gutter, 1.5rem);
        padding-right: var(--gutter, 1.5rem);
        gap: var(--gap, 1rem);
    }
}

/* ── Vertikaler Abstand einer Spalte: Stufenfaktor ──────────────────
 * `--m-col-scale` kommt als Inline-Style vom Box-Grid-Modul (Feld
 * „Vertikaler Abstand", REX_VALUE 10): kompakt = 0.5, minimal = 0.25,
 * keiner = 0. Ohne Auswahl fehlt die Variable, `var(--m-col-scale, 1)`
 * liefert 1 — alle Werte bleiben exakt die bisherigen (Bestandsschutz).
 *
 * Der Faktor multipliziert JEDEN vertikalen Abstand der Spalte: das
 * Aussenpadding hier, den Abstand zwischen den Bloecken (`gap`) und im
 * Kachel-Fall zusaetzlich Innenpadding + Kachel-`gap` (siehe
 * `.m-bg-col--card` weiter unten). Nur so wirkt die Stufe auch dort,
 * wo der Redakteur sie sieht — zwischen Icon und Text.
 * ───────────────────────────────────────────────────────────────── */
.m-bg-col {
    display: flex; flex-direction: column;
    gap: calc(var(--m-col-scale, 1) * 1.444rem);
    padding-top: calc(var(--m-col-scale, 1) * 2rem);
    padding-bottom: calc(var(--m-col-scale, 1) * 2rem);
}
@media (min-width: 64em) {
    .m-bg-col {
        padding-top: calc(var(--m-col-scale, 1) * 3rem);
        padding-bottom: calc(var(--m-col-scale, 1) * 3rem);
    }
}
@media (min-width: 112.5em) {
    .m-bg-col {
        padding-top: calc(var(--m-col-scale, 1) * 3.5rem);
        padding-bottom: calc(var(--m-col-scale, 1) * 3.5rem);
    }
}
@media (min-width: 112.5em) {
    .box-element > .text,
    .box-element > .infobox,
    .box-element > .bildtextbox,
    .box-element > .bild {
        padding-top: 3.5rem;
        padding-bottom: 3.5rem;
    }
}
@media (max-width: 63.99em) {
    .m-bg-col:not(:first-child) { padding-top: 0; }
    .m-bg-col:not(:last-child)  { padding-bottom: 0; }

    .m-bg-grid--c11 > .m-bg-col,
    .m-bg-grid--c11o-l > .m-bg-col,
    .m-bg-grid--c11o-r > .m-bg-col,
    .m-bg-grid--c12 > .m-bg-col,
    .m-bg-grid--c21 > .m-bg-col,
    .m-bg-grid--c13 > .m-bg-col,
    .m-bg-grid--c31 > .m-bg-col {
        padding-top: calc(var(--m-col-scale, 1) * 2rem);
        padding-bottom: calc(var(--m-col-scale, 1) * 2rem);
    }
}
.m-bg-section--continuation .m-bg-col:not(.m-bg-col--card) { padding-top: 0 !important; }

/* Abstands-Stufe „Aus Seitenkonfiguration übernehmen": Dann trägt die <section>
 * die Padding-Klasse (z. B. `pt-36 pb-18`) und die Spalte gar keinen Abstand.
 * Für Fortsetzungs-Blöcke derselben Sektion gilt dieselbe Logik wie eine Zeile
 * darüber — der obere Abstand gehört an den ersten Block, sonst steht er ein
 * zweites Mal mitten in der Sektion. Per CSS, weil das `pt-*` aus einer
 * Tailwind-Klasse kommt und sich serverseitig nicht herausrechnen lässt
 * (responsive Varianten wie `lg:pt-36`). */
.m-bg-section--continuation.m-bg-section--pad-section { padding-top: 0 !important; }

.m-bg-headline { display: block; line-height: 1.15; }
/* Zeile 1 und Zeile 3 teilen sich den leichten Schnitt — Zeile 3 erlaubt die
   umgekehrte Reihenfolge (fett oben, leicht unten) und dreizeilige Überschriften. */
.m-bg-headline .m-bg-h1,
.m-bg-headline .m-bg-h3 {
    display: block;
    font-size: 1.667rem;
    font-weight: 300;
    color: var(--section-muted, var(--section-fg, inherit));
}
.m-bg-headline .m-bg-h2 {
    display: block;
    font-size: 2rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.02em;
    color: var(--section-heading, var(--section-fg, inherit));
}

.m-bg-text { color: var(--section-fg, inherit); }
.m-bg-text p { margin: 0 0 0.778rem 0; }
.m-bg-text p:last-child { margin-bottom: 0; }
.m-bg-text ul, .m-bg-text ol { margin: 0 0 0.778rem 1.222rem; }
.m-bg-text--cols-2 { columns: 2; column-gap: 1.667rem; }
.m-bg-text--cols-3 { columns: 3; column-gap: 1.444rem; }
.m-bg-text--left    { text-align: left; }
.m-bg-text--center  { text-align: center; }
.m-bg-text--justify { text-align: justify; hyphens: auto; }

.m-bg-image { margin: 0; }
.m-bg-image img { width: 100%; height: auto; display: block; border-radius: 0.444rem; }
.m-bg-image--h-auto img { height: auto; }

/* row-stretch ab ≥ 48em — exakt dort wo c11/c12/c21/c13/c31 als 2-spaltige
 * Layouts side-by-side bleiben. Unter 48em stacken die Cols, dann würde
 * flex-basis:0 die Bild-Col auf 0 kollabieren und das absolut positionierte
 * <img> verschwinden. Dort greift der Default .m-bg-image img
 * { width:100%; height:auto }. */
@media (min-width: 48em) {
    .m-bg-image--h-row-stretch {
        position: relative;
        flex: 1 1 0;
        min-height: 0;
        width: 100%;
        overflow: hidden;
        border-radius: 0.444rem;
    }
    .m-bg-image--h-row-stretch img {
        position: absolute;
        inset: 0;
        width: 100%;
        height: 100%;
        object-fit: cover;
        display: block;
        border-radius: 0;
    }
}

.m-bg-image--h-natural img { width: auto; max-width: 100%; height: auto; }
/* === Utility · Bild-Größen-Klassen === */
/*
 * Bild-Größen-Klassen (image_size_class) — projektweite Stufen aus
 * rex_sws_css_options. Setzen `max-width` auf das `<figure>`-Element,
 * `<img>` darin behält `width:100%`. Damit wird das Bild auf die
 * gewünschte Display-Größe begrenzt, ohne die Spalte zu stretchen.
 *
 * Pflege im Backend: Page Composer → CSS-Klassen → Kategorie
 * "image_size_class". Werte müssen mit den hier definierten
 * Selektoren übereinstimmen.
 *
 * Bild-Groessen + Ausrichtungs-Klassen werden NICHT mehr hier gepflegt!
 * Quelle: rex_sws_css_options (Kategorien image_size_class + image_align_class)
 * Generierte Datei: assets/css/sws-managed.css (vom Backend automatisch geschrieben)
 * Editor: Backend → Verwaltung → Page Composer → CSS-Klassen
 *
 * Generator: sws_managed_css::generate() — läuft automatisch beim Save der
 * CSS-Klassen-Seite. Initial via scripts/seed-image-classes.php.
 */

/* Icon-Block (.m-bg-iconblock) — figure mit SVG, eigenstaendiger Block-Typ
 * im mod_box_grid. Hinweis: NICHT mit .m-bg-icon verwechseln, das ist die
 * (kleine, fixe) Icon-Spalte in `.m-bg-iconbox-list li`. */
.m-bg-iconblock { margin: 0; line-height: 0; width: 100%; color: var(--color-accent, #f59e0b); }.m-bg-iconblock svg { width: 100%; height: auto; display: block; }
.m-bg-iconblock a { display: block; color: inherit; }

.m-bg-col { min-height: 0; }

/* Spalte als Kachel — Box sieht aus wie der Inhaltstyp `.m-bg-kachel`. */
.m-bg-col--card {
    background: var(--card-bg, transparent);
    color: var(--card-fg, var(--section-fg, inherit));
    border-radius: 0.222rem;
    overflow: hidden;
    /* Vertikal skaliert der Stufenfaktor mit (oben: Abstand über dem Icon,
       `gap`: Abstand Icon → Text). Horizontal bleibt 1.111rem fix — die
       Stufe steuert ausdruecklich nur den vertikalen Abstand.
       Das `!important` bleibt noetig, weil `.m-bg-col--card` sonst gegen
       die Breakpoint-Regeln von `.m-bg-col` verliert; der Faktor wirkt
       trotzdem, weil er im Wert steckt und nicht in einer zweiten Regel. */
    padding: calc(var(--m-col-scale, 1) * 1rem) 1.111rem calc(var(--m-col-scale, 1) * 1.222rem) 1.111rem !important;
    gap: calc(var(--m-col-scale, 1) * 0.667rem);
}
.m-bg-col--card > .m-bg-image:first-child {
    margin: -1rem -1.111rem 0 -1.111rem;
    border-radius: 0;
    aspect-ratio: 340 / 185;
    overflow: hidden;
}
.m-bg-col--card > .m-bg-image:first-child img {
    border-radius: 0;
    width: 100%; height: 100%; object-fit: cover; display: block;
}

/* KARTENFARBEN HOCHZIEHEN — für Karten UND Icon-Teaser.
 *
 * Der Teaser fehlte hier bis 0.24.2. Er bekam damit zwar seinen Hintergrund
 * (siehe `.m-bg-icon-teaser` weiter unten), aber Überschrift, Text und Knopf
 * blieben auf ihren Vorgabefarben — auf einem dunklen Kartenschema also
 * unlesbar. Die Sites haben das einzeln nachgebaut; dieselbe Regel gehört
 * einmal hierher.
 *
 * Es geht ausschliesslich um FARBEN. Die Typografie-Angaben der Kachel
 * (Schriftgrösse, Polster, Versalien) stehen weiter unten und gelten bewusst
 * NICHT für den Teaser — er ist ein anderes Format. */
.m-bg-col--card .m-bg-headline .m-bg-h1,
.m-bg-col--card .m-bg-headline .m-bg-h3,
.m-bg-icon-teaser .m-bg-headline .m-bg-h1,
.m-bg-icon-teaser .m-bg-headline .m-bg-h3 { color: var(--card-muted, var(--card-fg, inherit)); }
.m-bg-col--card .m-bg-headline .m-bg-h2,
.m-bg-icon-teaser .m-bg-headline .m-bg-h2 { color: var(--card-heading, var(--card-fg, inherit)); }
.m-bg-col--card .m-bg-text,
.m-bg-icon-teaser .m-bg-text { color: var(--card-fg, inherit); }
.m-bg-col--card .m-bg-linkbox,
.m-bg-icon-teaser .m-bg-linkbox {
    background-color: var(--card-link-bg, var(--section-link-bg, #2563eb));    color: var(--card-link-fg, var(--section-link-fg, #ffffff)) !important;
}

.m-bg-linkbox-wrap {
    margin: 1rem 0 0 0;
    break-inside: avoid;
}
.m-bg-linkbox {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    background-color: var(--section-link-bg, #2563eb);    color: var(--section-link-fg, #ffffff) !important;
    font-weight: 400;
    font-size: 1rem;
    padding: 0.389rem 0.889rem;
    border-radius: 0.222rem;
    text-decoration: none !important;
    text-transform: uppercase;
    letter-spacing: 0.02em;
    transition: filter 0.2s ease;
}
.m-bg-linkbox:hover { filter: brightness(0.95); }
.m-bg-linkbox .m-bg-linkbox-arrow {
    display: inline-flex; align-items: center; justify-content: center;
    width: 1.111rem; height: 1.111rem;
    color: var(--color-accent, #fde68a);
    transition: transform 0.15s ease;
}
.m-bg-linkbox .m-bg-linkbox-arrow svg { width: 1.111rem; height: 1.111rem; }
.m-bg-linkbox:hover .m-bg-linkbox-arrow { transform: translateX(3px); }

/* --- Block · Icon-Teaser (Icon neben Text, ganze Box anklickbar) ---------
 *
 * Angefragt vom Auftritt Frauennotruf Westerburg (2026-08-24).
 *
 * DER GESTRECKTE LINK ist der Kern dieses Blocks. „Ganze Box verlinkt" plus
 * „Button" ergibt naiv ein <a> im <a> — ungültiges HTML, und der Parser
 * schließt das äußere Element selbsttätig, wodurch das Layout zerfällt.
 * Stattdessen ist die Box `position: relative` und der Button trägt ein
 * ::after, das über die ganze Fläche gezogen wird. Ergebnis: ein einziger
 * Link, ein zugänglicher Name, gültiges Markup.
 *
 * Preis dieses Musters: Text in der Box lässt sich nicht mehr mit der Maus
 * markieren. Das ist bei einem Teaser vertretbar — bei Fließtext wäre es das
 * nicht, deshalb steht das Muster hier und nicht in `.m-bg-text`.
 */
/* KARTENSCHEMA: `--card-*`, nicht `--box-*`.
 *
 * Hier standen bis 0.24.2 die Vorgängernamen `--box-bg` / `--box-fg`. Geschrieben
 * werden sie nirgends: `sws_section_config::buildCardVars()` setzt ausschliesslich
 * `--card-*`. Die drei Lesestellen im Icon-Teaser waren damit tot — das gewählte
 * Kartenschema kam hier nie an, und `box-white` blieb wirkungslos.
 *
 * Gefunden beim Auftritt Frauennotruf Westerburg, und zwar erst durch einen
 * `cache:clear`: Bis dahin lief die Seite auf Artikel-HTML von VOR dem Update,
 * das noch die alten Namen schrieb. Ein alter Seiten-Cache kann eine halbe
 * Umbenennung also monatelang verdecken. */
.m-bg-icon-teaser {
    position: relative;
    width: 100%;
    border-radius: 0.222rem;
    padding: 1.333rem;
    background-color: var(--card-bg, transparent);
    color: var(--card-fg, inherit);
    transition: filter 0.2s ease;
}
.m-bg-icon-teaser:hover { filter: brightness(0.97); }

/* Der innere Container trägt die Anordnung. Er ist entweder ein <div> oder —
 * wenn kein Button gesetzt ist — selbst das <a>; beide sollen gleich aussehen,
 * deshalb die Textauszeichnung hier zurücksetzen. */
.m-bg-icon-teaser .m-bg-icon-teaser-inner {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: 1rem;
    color: inherit;
    text-decoration: none;
}
a.m-bg-icon-teaser-inner:hover { text-decoration: none; }

.m-bg-icon-teaser--icon-right .m-bg-icon-teaser-inner { flex-direction: row-reverse; }

.m-bg-icon-teaser .m-bg-icon-teaser-icon {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* 2.667rem = 48px bei 18px Grundschrift — dieselbe Größe wie die
       Vorschau-Kachel im Editor, damit Redaktion und Frontend übereinstimmen. */
    width: 2.667rem;
    height: 2.667rem;
    color: var(--card-fg, currentColor);
}
.m-bg-icon-teaser .m-bg-icon-teaser-icon svg {
    width: 100%;
    height: 100%;
}

/* WANN DER TEXT UNTER DAS ICON RUTSCHT — und warum das keine Media-Query ist.
 *
 * Auslöser ist die Breite der BOX, nicht die des Fensters. Ein Icon-Teaser
 * steht in einer Box-Grid-Spalte: Bei schmalem Fenster stapelt das Raster auf
 * eine Spalte, die Box wird also BREITER, nicht schmäler. Eine
 * `max-width`-Abfrage auf den Viewport würde genau dann stapeln, wenn am
 * meisten Platz da ist.
 *
 * Der erste Entwurf hatte hier `@media (max-width: 30em)` — ein Wert, den es
 * sonst nirgends in dieser Datei gibt (die Leiter des Projekts ist
 * 40/48/64/112.5em) und dessen Herleitung „~24em Text" eine Schätzung war.
 * Beides vom regel-check beanstandet, zu Recht.
 *
 * Stattdessen bricht die Flex-Zeile um, sobald der Textspalte weniger als ihre
 * Grundbreite bleibt. HERLEITUNG DIESER GRUNDBREITE: 18em sind bei einer
 * durchschnittlichen Zeichenbreite von ~0.5em rund 36 Zeichen je Zeile. Die
 * typografische Spanne für lesbaren Fließsatz beginnt bei etwa 45 Zeichen; 36
 * ist bewusst darunter, weil ein Teaser aus wenigen Wörtern besteht und ein zu
 * früher Umbruch mehr stört als eine knappe Zeile.
 *
 * ZWEI BEISPIELE, durchgerechnet mit den Werten dieser Datei
 * (Innenabstand 1.333rem je Seite, Icon 2.667rem, Abstand 1rem):
 *
 *   Box 30em: 30 − 2×1.333 − 2.667 − 1 = 23.67em ≥ 18em → nebeneinander
 *   Box 20em: 20 − 2×1.333 − 2.667 − 1 = 13.67em < 18em → Text unter das Icon
 *
 * Die Umschaltbreite liegt damit rechnerisch bei 18 + 2.666 + 2.667 + 1 =
 * 24.33em Boxbreite — hergeleitet, nicht gesetzt, und ohne einen Wert, der in
 * der Breakpoint-Leiter nichts zu suchen hat. */
.m-bg-icon-teaser .m-bg-icon-teaser-body {
    flex: 1 1 18em;
    min-width: 0;   /* sonst sprengt langer Text ohne Leerzeichen die Flex-Spalte */
}

/* Icon über dem Text — jetzt eine EIGENE Auswahl, keine Kopplung mehr.
 *
 * Bis 2026-08-25 stand hier `.m-bg-icon-teaser.m-bg-text--center …` mit der
 * Begründung, bei zentriertem Text gehöre das Icon in die Mitte. Nachvollziehbar,
 * aber falsch gebaut: `halign` hat im Renderer den Vorgabewert `center`, die
 * Regel griff also im AUSLIEFERUNGSZUSTAND. Wer nichts einstellte, bekam das
 * gestapelte Bild — und beide Optionen des Feldes „Icon-Position" waren ohne
 * jede Wirkung, bis jemand die Textausrichtung auf links oder Blocksatz stellte.
 *
 * Eine Vorgabe darf eine ausdrückliche Auswahl nicht überschreiben. Gemeldet vom
 * Auftritt Frauennotruf Westerburg, dessen Agentur-Vorlage genau die verhinderte
 * Anordnung zeigt: Icon links, Text zentriert daneben. Ihr Vorschlag — dritte
 * Option statt Kopplung — ist umgesetzt. */
.m-bg-icon-teaser--icon-top .m-bg-icon-teaser-inner {
    flex-direction: column;
    align-items: center;
}

.m-bg-icon-teaser .m-bg-linkbox-wrap { margin-top: 1rem; }

/* Der gestreckte Link. `z-index: 1` hält ihn über dem Hintergrund der Box,
   ohne Inhalte zu überdecken, die selbst keinen Stapelkontext aufmachen. */
.m-bg-icon-teaser .m-bg-icon-teaser-link::after {
    content: '';
    position: absolute;
    inset: 0;
    z-index: 1;
    border-radius: inherit;
}

.m-bg-html { width: 100%; }
/* === Utility · TinyMCE-Listen-Marker === */
/*
 * Standard-Listen-Marker für TinyMCE-Body-Container (alle Inhalts-Module):
 * Tailwind-Reset entfernt list-style komplett, daher hier mit ::before-
 * Pseudo-Element ein Akzent-Pfeil als Marker.
 * Geltungsbereich: Box-Element-Slots + Box-Grid-Blöcke + News-Detail.
 */
.m-bg-text ul,
.m-abt-body ul,
.m-bg-kachel-content ul,
.m-bg-infobox-body ul,
.m-bg-col--card ul,
.box-element > .text .box-body ul,
.box-element > .infobox .box-body ul,
.box-element > .bildtextbox .box-text ul,
.m-kachel-text ul,
.m-news-detail-text ul {
    list-style: none;
    padding-left: 1.333rem;
    margin: 0 0 0.778rem 0;
}
.m-bg-text ul > li,
.m-abt-body ul > li,
.m-bg-kachel-content ul > li,
.m-bg-infobox-body ul > li,
.m-bg-col--card ul > li,
.box-element > .text .box-body ul > li,
.box-element > .infobox .box-body ul > li,
.box-element > .bildtextbox .box-text ul > li,
.m-kachel-text ul > li,
.m-news-detail-text ul > li {
    position: relative;
    padding-left: 0;
    margin-bottom: 0.222rem;
}
.m-bg-text ul > li::before,
.m-abt-body ul > li::before,
.m-bg-kachel-content ul > li::before,
.m-bg-infobox-body ul > li::before,
.m-bg-col--card ul > li::before,
.box-element > .text .box-body ul > li::before,
.box-element > .infobox .box-body ul > li::before,
.box-element > .bildtextbox .box-text ul > li::before,
.m-kachel-text ul > li::before,
.m-news-detail-text ul > li::before {
    content: "";
    position: absolute;
    left: -1.333rem;
    top: 0.25em;
    width: 1em; height: 1em;
    background-color: var(--bullet-color, var(--color-accent, #fde68a));
    -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M5 12h14'/><path d='m12 5 7 7-7 7'/></svg>") no-repeat center / contain;
            mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M5 12h14'/><path d='m12 5 7 7-7 7'/></svg>") no-repeat center / contain;
}
/* Auf gelben Section-/Card-Hintergruenden den Akzent-Pfeil auf Primaer-Blau
 * umstellen — sonst geht der gelbe Pfeil im gelben Hintergrund unter. */
.bg-accent,
.box-accent,
.m-bg-kachel.bg-accent,
.m-bg-kachel.box-accent,
.m-kachel.bg-accent,
.m-kachel.box-accent,
.m-bg-col--card.bg-accent,
.m-bg-col--card.box-accent {
    --bullet-color: var(--color-primary, #0f172a);}

/* InfoBox (aufklappbar) */
.m-bg-infobox { width: 100%; }
.m-bg-infobox-summary {
    list-style: none;
    cursor: pointer;
    padding: 0.667rem 0;
    border-bottom: 1px solid currentColor;
    display: flex; flex-direction: column;
}
.m-bg-infobox-summary::-webkit-details-marker { display: none; }
.m-bg-infobox-summary::after {
    content: "▾"; align-self: flex-end;
    font-size: 1.111rem; line-height: 1; transition: transform 0.2s;
    color: var(--color-accent, #fde68a);
}
.m-bg-infobox[open] > .m-bg-infobox-summary::after { transform: rotate(180deg); }
.m-bg-infobox-summary .m-bg-h1,
.m-bg-infobox-summary .m-bg-h3 {
    display: block; font-weight: 300; font-size: 1.667rem;
    color: var(--section-muted, var(--section-fg, inherit));
}
.m-bg-infobox-summary .m-bg-h2 {
    display: block; font-weight: 800; font-size: 2rem;
    text-transform: uppercase; letter-spacing: 0.02em;
    color: var(--section-heading, var(--section-fg, inherit));
}
.m-bg-infobox-body { padding: 1rem 0; color: var(--section-fg, inherit); }

/* Kachel — Card-Layout 1:1 zu .m-kachel (m-be / Box-Element-Modul). */
.m-bg-kachel {
    display: flex; flex-direction: column;
    border-radius: 0.222rem;
    overflow: hidden;
    background: var(--card-bg, #ffffff);
    color: var(--card-fg, var(--section-fg, inherit));
}
.m-bg-kachel-img {
    margin: 0;
    width: 100%;
    aspect-ratio: 340 / 185;
    overflow: hidden;
}
.m-bg-kachel-img img,
.m-bg-kachel-img picture { width: 100%; height: 100%; object-fit: cover; display: block; }
.m-bg-kachel-content {
    /* Vertikal folgt der Stufenfaktor der Spalte (`--m-col-scale`, gesetzt vom
       Box-Grid-Modul und hierher vererbt) — analog `.m-bg-col--card`. Horizontal
       bleibt 1.111rem fix; die Stufe steuert ausdruecklich nur den vertikalen
       Abstand. Ohne Auswahl liefert der Fallback 1 die bisherigen Werte. */
    padding: calc(var(--m-col-scale, 1) * 1rem) 1.111rem calc(var(--m-col-scale, 1) * 1.222rem) 1.111rem;
    display: flex; flex-direction: column;
    flex: 1;
}

.m-bg-kachel .m-bg-headline,
.m-bg-col--card .m-bg-headline { line-height: 1.2; margin: 0; }
.m-bg-kachel .m-bg-headline .m-bg-h1,
.m-bg-col--card .m-bg-headline .m-bg-h1 {
    font-size: 1.167rem;
    font-weight: 300;
    line-height: 1.25;
    margin: 0 0 0.333rem 0;
    color: var(--card-muted, var(--card-fg, inherit));
}
.m-bg-kachel .m-bg-headline .m-bg-h2,
.m-bg-col--card .m-bg-headline .m-bg-h2 {
    font-size: 1.167rem;
    font-weight: 800;
    line-height: 1.2;
    text-transform: uppercase;
    letter-spacing: 0.02em;
    margin: 0 0 0.667rem 0;
    color: var(--card-heading, var(--card-fg, inherit));
}
/* Zeile 3 (leicht) im Card-/Kachel-Kontext: Typografie identisch zu Zeile 1.
   Sie ist immer die letzte Zeile der Überschrift und übernimmt deshalb den
   Abstand zum Folgeinhalt (0.667rem), den sonst Zeile 2 trägt; Zeile 2 fällt
   dann auf den Zeilenabstand innerhalb der Überschrift (0.333rem) zurück.
   Ohne Zeile 3 ist Zeile 2 letztes Kind → alles bleibt unverändert. */
.m-bg-kachel .m-bg-headline .m-bg-h3,
.m-bg-col--card .m-bg-headline .m-bg-h3 {
    font-size: 1.167rem;
    font-weight: 300;
    line-height: 1.25;
    margin: 0 0 0.667rem 0;
    color: var(--card-muted, var(--card-fg, inherit));
}
.m-bg-kachel .m-bg-headline .m-bg-h2:not(:last-child),
.m-bg-col--card .m-bg-headline .m-bg-h2:not(:last-child) {
    margin-bottom: 0.333rem;
}
.m-bg-kachel .m-bg-text,
.m-bg-col--card .m-bg-text {
    font-size: 0.944rem;
    font-weight: 400;
    line-height: 1.4;
    margin: 0 0 1rem 0;
    color: var(--card-fg, inherit);
}
.m-bg-kachel .m-bg-text > :first-child,
.m-bg-col--card .m-bg-text > :first-child { margin-top: 0; }
.m-bg-kachel .m-bg-text > :last-child,
.m-bg-col--card .m-bg-text > :last-child { margin-bottom: 0; }
.m-bg-kachel .m-bg-linkbox,
.m-bg-col--card .m-bg-linkbox {
    background-color: var(--card-link-bg, var(--section-link-bg, #2563eb));    color: var(--card-link-fg, var(--section-link-fg, #ffffff)) !important;
    font-size: 1rem;
    font-weight: 400;
    padding: 0.389rem 0.889rem;
    border-radius: 0.222rem;
    text-transform: uppercase;
    letter-spacing: 0.02em;
}

/* Galerie — Lead-Bild + Thumbnails */
.m-bg-galerie { display: flex; flex-direction: column; gap: 0.667rem; }
.m-bg-galerie-lead img { width: 100%; height: auto; display: block; border-radius: 0.444rem; }
.m-bg-galerie-thumbs { display: grid; grid-template-columns: repeat(auto-fill, minmax(80px, 1fr)); gap: 0.444rem; }
.m-bg-galerie-thumbs a { display: block; aspect-ratio: 1; overflow: hidden; border-radius: 0.222rem; }
.m-bg-galerie-thumbs img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Grid-Items duerfen unter ihre Inhaltsbreite schrumpfen.
 *
 * WARUM DAS HIER STEHEN MUSS: Grid- und Flex-Items haben von Haus aus
 * `min-width: auto` — sie duerfen NICHT schmaler werden als ihr Inhalt. Bei
 * einem Swiper läuft daraus eine Rueckkopplung: Swiper setzt die Slide-Breite
 * inline, diese Breite geht in die Inhaltsbreite der Spalte ein, die Spalte
 * waechst, und weil der Slider mit `observer: true` auf Layout-Aenderungen
 * reagiert, rechnet er erneut — mit der neuen, groesseren Spalte.
 *
 * Gemessen am 09.08.2026 auf demo (Layout c1, vier Slides): Spalte
 * 33.553.886 px bei 2.521 px Grid-Breite, Slide 11.184.618 px, Sektion
 * 7.456.475 px hoch. Mit `min-width: 0` an derselben Stelle: Spalte 1.485 px,
 * Slide 484 px, Sektion 386 px.
 *
 * Die Regel schuetzt auch alles andere, was eine Spalte sprengen kann —
 * lange Wortketten, Tabellen, <pre>-Bloecke. */
.m-bg-col { min-width: 0; }

/* Video-Block */
.m-bg-video { position: relative; margin: 0; width: 100%; min-width: 0; border-radius: 0.444rem; overflow: hidden; }
.m-bg-video-el { display: block; width: 100%; }
/* Nur mit fester Hoehe darf beschnitten werden — ohne sie traegt das Element das
 * Seitenverhaeltnis der Datei, und `cover` haette nichts zu beschneiden. */
.m-bg-video-el[style*="height"] { object-fit: cover; }

/* Der Hero-Anhalteknopf teilt sich diese Regeln über die Selektorliste, statt
 * sie im Hero-Teil zu wiederholen: Es ist derselbe Knopf an derselben Kante,
 * und zwei Kopien liefen mit der Zeit auseinander. Eine Selektorliste ändert
 * die Spezifität nicht (jeder Selektor behält seine eigene), der Vertrag mit
 * den Sites bleibt also unberührt — siehe css-spezifitaet-ist-ein-vertrag.md.
 *
 * Pause-Knopf für automatisch startende Videos ohne native Bedienelemente.
 * Unten rechts, weil dort kein Bildinhalt erwartet wird und die native Leiste
 * an derselben Kante saesse — die Bedienung bleibt am gewohnten Ort.
 * Masse aus dem Projektraster: 2.667rem = 48 px bei 18-px-Root, die uebliche
 * Mindestgroesse einer Schaltflaeche für Finger. */
.m-bg-video-pause,
.m-hero-video-pause {
    position: absolute;
    right: 0.889rem;
    bottom: 0.889rem;
    width: 2.667rem;
    height: 2.667rem;
    border: 0;
    border-radius: 50%;
    background: rgba(0, 0, 0, 0.55);
    color: #fff;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: background 0.15s;
}
.m-bg-video-pause:hover,
.m-bg-video-pause:focus-visible,
.m-hero-video-pause:hover,
.m-hero-video-pause:focus-visible { background: rgba(0, 0, 0, 0.75); }
/* Zwei Balken = Pause. Im angehaltenen Zustand wird daraus ein Dreieck (Play),
 * erzeugt aus denselben zwei Elementen über Rahmen — kein zweites Icon noetig. */
.m-bg-video-pause-icon,
.m-hero-video-pause-icon {
    width: 0.556rem;
    height: 0.889rem;
    border-left: 0.167rem solid currentColor;
    border-right: 0.167rem solid currentColor;
}
.m-bg-video-pause.is-paused .m-bg-video-pause-icon,
.m-hero-video-pause.is-paused .m-hero-video-pause-icon {
    width: 0;
    height: 0;
    border-left: 0.667rem solid currentColor;
    border-right: 0;
    border-top: 0.444rem solid transparent;
    border-bottom: 0.444rem solid transparent;
    margin-left: 0.167rem;
}

/* Slider — Swiper-Carousel.
 *
 * `overflow: hidden` und die Eckenrundung hingen bis hierher an dieser
 * Basisklasse. Für eine BILDreihe ist das richtig: Der angeschnittene letzte
 * Slide braucht die harte Kante, und die Rundung gehoert ans Bild.
 * Für eine KACHELreihe ist es falsch — ein Schatten oder eine Anhebung beim
 * Ueberfahren (`transform: scale(…)`) wird an der Containerkante abgeschnitten.
 * Beides sitzt deshalb an der Bild-Variante; eine andere Reihe erbt nur noch
 * Breite und `min-width`. Gemeldet von HGK-Events.
 *
 * `min-width: 0` bleibt an der Basis: Ohne das sprengt ein Slider jede
 * Grid-Spalte, weil Grid-Items `min-width: auto` haben. */
.m-bg-slider { width: 100%; min-width: 0; }
.m-bg-slider--images { overflow: hidden; border-radius: 0.444rem; }

/* Kachelreihe: Ueberstand zulassen, ohne die Nachbar-Slides zu zeigen.
 *
 * Die Basisklasse allein genuegt dafuer NICHT — `overflow: hidden` kommt
 * zusaetzlich aus `swiper-bundle.min.css` (`.swiper`), also aus der Bibliothek.
 * Am Prueftand gemessen: Nach dem Entfernen an `.m-bg-slider` stand der
 * Kartenslider weiterhin auf `hidden`, und die gewinnende Regel war Swipers.
 *
 * `overflow: clip` clippt wie `hidden`, erlaubt aber über
 * `overflow-clip-margin` einen Rand — Schatten und eine Anhebung beim
 * Ueberfahren bleiben sichtbar, angrenzende Slides nicht.
 * Rand hergeleitet: Eine Kachel von rund 300 px waechst bei `scale(1.1)` um
 * 15 px je Seite; ein ueblicher Schatten (`0 4px 12px`) braucht 12 px. 1.5rem
 * (27 px bei 18-px-Root) deckt beides ab.
 * Kennt ein Browser `clip` nicht (Safari < 16), wird die Deklaration verworfen
 * und Swipers `hidden` bleibt — der alte Zustand, kein kaputter. */
.m-bg-cardslider.swiper {
    overflow: clip;
    overflow-clip-margin: 1.5rem;
}
.m-bg-slider .swiper-slide img { width: 100%; height: auto; display: block; }
.m-bg-slider .swiper-pagination { position: relative; margin-top: 0.5rem; }

/* Bedienelement IM FLUSS (Schiebebalken, Punkte) — der Wrapper darf dann keine
 * Prozenthöhe tragen.
 *
 * Swiper liefert `.swiper-wrapper { height: 100% }` mit. Der `.m-bg-slider`
 * selbst hat keine gesetzte Höhe, sie entsteht aus dem Inhalt — und dieser
 * Inhalt enthält das Bedienelement bereits. Die Prozenthöhe löst sich also
 * gegen eine Höhe auf, die den Balken schon einschliesst: Der Wrapper wird um
 * exakt dessen Blockgröße zu hoch, schiebt ihn um dieselbe Strecke nach unten
 * und `overflow: hidden` (Zeile oben) schneidet ihn ab. Sichtbar ist nichts.
 *
 * An echtem Inhalt gemessen (HGK-Events, 10.08.2026, vier Zustände):
 *   ohne Balken im Fluss   .swiper 540,09  Wrapper 540,09  → Balken sichtbar
 *   mit Balken im Fluss    .swiper 612,08  Wrapper 612,08  → Balken abgeschnitten
 *   612,08 = 540,09 + 64 (margin-top) + 8 (Höhe) — exakt die Blockgröße.
 * `height: auto` wirkt NUR am Wrapper: Der `.swiper` ist ohnehin auto, und der
 * Slide ist Flex-Item und wird auf die Wrapper-Höhe gedehnt.
 *
 * Bewusst nur diese beiden Fälle: Bei Pfeilen sind die Bedienelemente absolut
 * positioniert, und ein Projekt darf dem `.swiper` eine feste Höhe geben
 * (`.m-slider` tut das per `aspect-ratio`) — dort ist die Prozenthöhe richtig. */
.m-bg-slider--scrollbar .swiper-wrapper,
.m-bg-slider--pagination .swiper-wrapper { height: auto; }
/* Pfeile: Foundation-Größe statt Swiper-Default (44 px), damit sie nicht
 * über schmalen Slides thronen. */
.m-bg-slider .swiper-button-prev,
.m-bg-slider .swiper-button-next { color: var(--color-primary, #334155); }
.m-bg-slider .swiper-button-prev::after,
.m-bg-slider .swiper-button-next::after { font-size: 1.5rem; }

/* Schiebebalken (Bedienelement „Scrollbar" am Slider-Block).
 *
 * Er steht UNTER der Reihe, nicht darüber: Swiper legt seine Scrollbar per
 * `position:absolute` über den unteren Bildrand — als Fortschrittsanzeige einer
 * Bildreihe verdeckt sie dort Inhalt.
 *
 * Spezifität mit Absicht dreistellig: Swiper liefert `.swiper-horizontal >
 * .swiper-scrollbar` (zwei Klassen) mit, und sein Stylesheet wird vom
 * Render-Helfer erst im Body eingebunden — also NACH dieser Datei. Bei
 * gleicher Spezifität gewänne deshalb Swiper.
 *
 * Maße aus dem Projektraster hergeleitet (1 rem = Root-Schriftgröße, 18 px im
 * größten Breakpoint):
 *   Höhe  0.444rem = 8 px — dieselbe Stufe wie die Eckenrundung der Slider-Box
 *   Radius = halbe Höhe → Kapselform
 *   Abstand nach oben 1.444rem = der Blockabstand innerhalb einer Spalte
 *     (`.m-bg-col { gap }`), damit der Balken wie ein eigener Block sitzt
 * Farbe folgt der Sektion (`--section-heading`), damit er auf dunklem Grund
 * nicht verschwindet — Muster wie bei `.m-news-title`. */
.m-bg-slider.swiper > .swiper-scrollbar {
    position: relative;
    left: auto;
    bottom: auto;
    width: 100%;
    /* zentriert, sobald ein Projekt den Balken schmaler macht als die Reihe —
       ein Design gibt den Balken regelmäßig kürzer an als die Bildreihe
       (Beispiel aus der Praxis: 1539 von 1924 px). Ohne diese Zeile klebte er
       dann am linken Rand und das Projekt bräuchte eine zweite Regel. */
    margin-inline: auto;
    height: 0.444rem;
    margin-top: 1.444rem;
    border-radius: 0.222rem;
    background: color-mix(in srgb, var(--section-heading, var(--color-primary, #334155)) 18%, transparent);
}
.m-bg-slider .swiper-scrollbar-drag {
    background: var(--section-heading, var(--color-primary, #334155));
    border-radius: 0.222rem;
}

/* Kartenslider — Kacheln statt Bilder in der Swiper-Reihe (Block-Typ
 * `kartenslider`). Der Block trägt `.m-bg-slider` zusätzlich und erbt damit
 * alles oben; hier steht nur, was die Kachel vom Bild-Slide unterscheidet.
 *
 * Bewusst ohne Farben, feste Maße und Farbwechsel der Kacheln: Das sind Werte
 * des jeweiligen Entwurfs, nicht Mechanik. Ein Projekt setzt sie über
 * `.m-bg-cardslider .swiper-slide:nth-child(3n+1)` und Geschwister — tragfähig
 * ist dieser Selektor nur, weil der Block ohne `loop` initialisiert wird
 * (output.php): Mit Endlosschleife klont Swiper Slides an beide Enden der
 * Reihe, und die DOM-Reihenfolge wäre nicht mehr die des Backends.
 *
 * Gleiche Kachelhöhe entsteht über die Flex-Kette, nicht über Prozente: Der
 * Slide ist Flex-Item des `.swiper-wrapper` und wird auf die Höhe der höchsten
 * Kachel gedehnt; als eigener Flex-Container gibt er diese Höhe an die Kachel
 * weiter. `height: 100%` trüge hier nicht, weil der Wrapper bei Bedienelement
 * im Fluss `height: auto` bekommt (Regel oben) und eine Prozenthöhe daran
 * nicht auflöst. */
.m-bg-cardslider .swiper-slide { display: flex; height: auto; }
.m-bg-card {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    /* Aus dem Raster der Foundation übernommen: 0.667rem ist der Blockabstand
       innerhalb einer Kachel-Spalte (`.m-bg-col--card`), 1.222rem das seitliche
       Innenpadding der `.m-bg-iconbox`. */
    gap: 0.667rem;
    padding: 1.222rem;
}
.m-bg-card-icon { display: inline-flex; align-items: center; justify-content: center; }
.m-bg-card-value,
.m-bg-card-label { display: block; }

/* Linkboxen-Block */
.m-bg-linkboxes { gap: 0.778rem; margin: 0; }
@media (max-width: 47.99em) {
    .m-bg-linkboxes { gap: 0.667rem; }
}

.m-bg-linkboxes--w-stretch { display: grid; }
.m-bg-linkboxes--w-stretch.m-bg-linkboxes--cols-1 { grid-template-columns: 1fr; }
.m-bg-linkboxes--w-stretch.m-bg-linkboxes--cols-2 { grid-template-columns: 1fr 1fr; }

.m-bg-linkboxes--w-natural { display: flex; flex-wrap: wrap; }
.m-bg-linkboxes--w-natural .m-bg-linkbox-item { flex: 0 0 auto; }
.m-bg-linkboxes--w-natural.m-bg-linkboxes--cols-1 { flex-direction: column; align-items: flex-start; }
.m-bg-linkbox-item {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.389rem 0.889rem;
    font-size: 1rem;
    font-weight: 400;
    text-transform: uppercase;
    letter-spacing: 0.02em;
    text-decoration: none !important;
    border-radius: 0.222rem;
    transition: filter 0.2s ease, background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}
.m-bg-linkbox-item .m-bg-linkbox-label { flex: 1; }
.m-bg-linkbox-item .m-bg-linkbox-arrow {
    flex: 0 0 auto;
    width: 1.111rem; height: 1.111rem;
    color: var(--color-accent, #fde68a);
    display: inline-flex; align-items: center; justify-content: center;
    transition: transform 0.15s ease;
}
.m-bg-linkbox-item .m-bg-linkbox-arrow svg { width: 1.111rem; height: 1.111rem; }
.m-bg-linkbox-item:hover .m-bg-linkbox-arrow { transform: translateX(3px); }
.m-bg-linkbox-icon-left { flex: 0 0 1.111rem; display: inline-flex; align-items: center; justify-content: center; }
.m-bg-linkbox-icon-left svg { width: 1.111rem; height: 1.111rem; }

.m-bg-linkboxes--primary .m-bg-linkbox-item {
    background-color: var(--section-link-bg, #2563eb);    color: var(--section-link-fg, #ffffff) !important;
}
.m-bg-linkboxes--primary .m-bg-linkbox-item:hover { filter: brightness(0.95); }

.m-bg-linkboxes--outline .m-bg-linkbox-item {
    background-color: transparent;
    color: var(--section-fg, inherit) !important;
    border: 2px solid var(--section-link-bg, #2563eb);    padding: 0.222rem 0.722rem;
}
.m-bg-linkboxes--outline .m-bg-linkbox-item:hover {
    background-color: var(--section-link-bg, #2563eb);    color: var(--section-link-fg, #ffffff) !important;
}

.m-bg-linkboxes--plain .m-bg-linkbox-item {
    background-color: transparent;
    color: var(--section-fg, inherit) !important;
    padding: 0.444rem 0;
    border-radius: 0;
}
.m-bg-linkboxes--plain .m-bg-linkbox-item:hover { color: var(--section-heading, inherit) !important; }

@media (max-width: 47.99em) {
    .m-bg-linkboxes--w-stretch.m-bg-linkboxes--cols-2 { grid-template-columns: 1fr; }
    .m-bg-linkboxes--w-natural { flex-direction: column; align-items: flex-start; }
}

/* Iconbox — Icon 45x45 px, Titel Figtree Regular 18px, Text Figtree Light 18px */
.m-bg-iconbox { padding: 1rem 1.222rem; border-radius: 0.444rem; background: rgba(255,255,255,0.06); border: 1px solid rgba(255,255,255,0.12); }
.m-tone-light .m-bg-iconbox { background: #f1f5f9; border-color: #e2e8f0; }
.m-bg-iconbox-title { font-weight: 700; font-size: 1.111rem; margin-bottom: 0.667rem; }
.m-bg-iconbox-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.778rem; }
.m-bg-iconbox-list--cols-1 { grid-template-columns: 1fr; }
.m-bg-iconbox-list--cols-2 { grid-template-columns: 1fr 1fr; }
.m-bg-iconbox-list--cols-3 { grid-template-columns: 1fr 1fr 1fr; }
.m-bg-iconbox-list li { display: flex; align-items: center; gap: 0.778rem; }
.m-bg-icon {
    flex: 0 0 2.5rem;
    width: 2.5rem; height: 2.5rem;
    display: inline-flex; align-items: center; justify-content: center;
    color: var(--section-heading, currentColor);
}
.m-bg-icon svg { width: 2.5rem; height: 2.5rem; }

/* Grundgröße jedes Box-Grid-Symbols.
 *
 * Bis 0.3.14 baute sws_box_grid_render::iconSvg() das SVG selbst und schrieb
 * width="20" height="20" ins Tag. Seit 0.3.15 delegiert die Methode an
 * sws_icon(), das statt der Attribute eine Klasse setzt — die Größe muss
 * seitdem aus dem CSS kommen.
 *
 * 20px waren der bisherige Wert; die Grundschrift dieses Projekts ist 18px,
 * also 20/18 = 1.111rem — derselbe Wert, den .m-bg-iconlist-icon svg und
 * .m-bg-linkbox-arrow svg bereits tragen.
 *
 * Container-Regeln wie `.m-bg-icon svg` (0,1,1) sind spezifischer als diese
 * Klasse (0,1,0) und behalten ihre eigene Größe. Für .m-bg-card-icon, das
 * keine eigene svg-Regel hat, ist sie die einzige Größenquelle: ohne sie
 * fällt ein viewBox-SVG ohne Attribute auf die CSS-Ersatzgröße zurück.
 * Sie wirkt zugleich auf Voll-SVGs aus „Eigene Icons“, deren eigene
 * width/height-Attribute vom CSS geschlagen werden — genau so gewollt. */
.m-bg-icon-svg { width: 1.111rem; height: 1.111rem; }

.m-bg-itext { display: flex; flex-direction: column; line-height: 1.25; }
.m-bg-itext strong,
.m-bg-itext span {
    font-family: 'Figtree', sans-serif;
    font-weight: 300;
    font-size: 1rem;
    color: var(--section-fg, inherit);
}
.m-bg-itext strong { color: var(--section-heading, var(--section-fg, inherit)); }

/* Icon-Liste */
.m-bg-iconlist-wrap { width: 100%; }
.m-bg-iconlist-title { font-weight: 700; font-size: 1.111rem; margin-bottom: 0.667rem; }
.m-bg-iconlist { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.444rem 1.222rem; }
.m-bg-iconlist--cols-1 { grid-template-columns: 1fr; }
.m-bg-iconlist--cols-2 { grid-template-columns: 1fr 1fr; }
.m-bg-iconlist--cols-3 { grid-template-columns: 1fr 1fr 1fr; }
.m-bg-iconlist li {
    display: flex; align-items: baseline; gap: 0.556rem;
    font-family: 'Figtree', sans-serif;
    font-weight: 300;
    font-size: 1rem;
    line-height: 1.45;
    color: var(--section-fg, inherit);
}
.m-bg-iconlist-icon {
    flex: 0 0 1.111rem;
    width: 1.111rem; height: 1.111rem;
    display: inline-flex; align-items: center; justify-content: center;
    color: var(--color-accent, #FFD200);
    transform: translateY(0.111rem);
}
.m-bg-iconlist-icon svg { width: 1.111rem; height: 1.111rem; }
.m-bg-iconlist-text { flex: 1 1 0; min-width: 0; }

@media (max-width: 63.99em) {
    .m-bg-grid--c111,
    .m-bg-grid--c1111,
    .m-bg-grid--c11111 { grid-template-columns: 1fr 1fr; }
}
/* Tablet/Laptop (48–64em): 3-spaltige Inhalte auf 2 Cols downscalen.
 * Lange Labels / Worte in 3 schmalen Cols blähen die min-content der äußeren
 * Text-Col auf, sodass im 1:3-Layout (c13/c31) die Bild-Col auf ~50px
 * kollabiert. 2 Cols entspannen min-content ausreichend. */
@media (min-width: 48em) and (max-width: 63.99em) {
    .m-bg-iconbox-list--cols-3,
    .m-bg-iconlist--cols-3 { grid-template-columns: 1fr 1fr; }
    .m-bg-text--cols-3 { columns: 2; }
}
@media (max-width: 47.99em) {
    .m-bg-grid--c11,
    .m-bg-grid--c11o-l,
    .m-bg-grid--c11o-r,
    .m-bg-grid--c12,
    .m-bg-grid--c21,
    .m-bg-grid--c13,
    .m-bg-grid--c31,
    .m-bg-grid--c111,
    .m-bg-grid--c1111,
    .m-bg-grid--c11111 { grid-template-columns: 1fr; }
    .m-bg-text--cols-2,
    .m-bg-text--cols-3 { columns: 1; }
    .m-bg-iconbox-list--cols-2,
    .m-bg-iconbox-list--cols-3 { grid-template-columns: 1fr; }
    .m-bg-iconlist--cols-2,
    .m-bg-iconlist--cols-3 { grid-template-columns: 1fr; }
    .m-bg-headline .m-bg-h1,
    .m-bg-headline .m-bg-h3 { font-size: 1.333rem; }
    .m-bg-headline .m-bg-h2 { font-size: 1.556rem; }
}

/* Globale strong/b-Schrift */
strong,
b {
    font-weight: 600;
}

/* Tabellen */
table tr > td, table tr > th {
    padding: 0.5rem 0.5rem;
    vertical-align: top;
    text-align: left;
}


/* === Modul · Split-Sektion (Bild + Text) ==================================
 *
 * BIS ZUM 27.08.2026 HATTE DIESES MODUL KEIN STYLESHEET. Sein Output emittiert
 * zwölf `m-abt-*`-Klassen, von denen genau EINE (`.m-abt-text`) irgendwo eine
 * Regel hatte — im SOT wie im ausgelieferten CSS jeder Site. Wer es im Backend
 * wählte, bekam unformatiertes Markup: kein randloses Bild, keine
 * Spaltenteilung, keine Titelgewichte. Gefunden beim Aufbau der Seite Ronja
 * (Frauennotruf Westerburg), dort als Befund F-8 gemeldet.
 *
 * DIE GEOMETRIE IST HERGELEITET, NICHT GEWÄHLT. Gemessen im gerasterten Entwurf
 * (72 dpi = 1:1 bei 1920 pt) an zwei Sektionen derselben Bauart:
 *
 *     Bild        x 0..968 (D) bzw. 0..953 (G)  → 50,5 % / 49,7 % der Breite
 *     Sektion     642 px (D) bzw. 641 (G)
 *     969 px Bildbreite / Verhältnis 1,5        → 646 px — 0,6 % daneben
 *     Textkante   x 995 (G) = Viewport-Mitte + 35 px
 *
 * Daraus die drei tragenden Entscheidungen:
 *
 *   1. DAS BILD NIMMT DIE LINKE HÄLFTE DES VIEWPORTS, nicht der Inhaltsbox —
 *      es läuft bis an den Seitenrand. Deshalb ist die Sektion selbst das
 *      Raster, nicht ein `.m-max-w`-Kind.
 *
 *   2. DIE SEKTIONSHÖHE KOMMT VOM BILD in seinem natürlichen Verhältnis.
 *      Deshalb bleibt es im Fluss. Ein `position: absolute` wäre bequemer,
 *      trägt aber NICHTS zur Zeilenhöhe bei — die Sektion fällt dann auf die
 *      Höhe des Textes zusammen. Genau dieser Fehler ist in diesem Projekt
 *      zweimal aufgetreten (Box-Grid `row-stretch` bei kurzem Text).
 *      Ist der Text länger als das Bild hoch, streckt `object-fit: cover` das
 *      Bild mit, statt eine Lücke zu lassen.
 *
 *   3. DER TEXT BEGINNT AN DER VIEWPORT-MITTE PLUS DEM RANDPOLSTER DER
 *      FOUNDATION (`m-px-edge`: 1.5rem, ab 1024 px 2rem) und endet an der
 *      rechten Kante der Inhaltsbox. Bei 1920 px und `--max-w: 1485px` ergibt
 *      das links 960 + 36 = 996 gegen gemessene 995, rechts
 *      1920 − (1920 − 1485) / 2 = 1702 gegen gemessene 1699.
 *
 * TITELGEWICHTE NACH HAUSREGEL: Zeile 1 mager, Zeile 2 fett und versal — wie
 * `.m-bg-h1` und `.m-bg-h2` in jedem anderen Modul. Die Feldbeschriftungen des
 * Moduls sagten bis heute das Gegenteil; sie sind mitkorrigiert worden.
 */
.m-abt-section {
    display: grid;
    grid-template-columns: 1fr 1fr;
    align-items: stretch;
}

.m-abt-img {
    display: flex;
    overflow: hidden;
    /* DECKEL GEGEN UNBEGRENZTES WACHSTUM. Die Sektionshoehe kommt vom Bild in
       seinem Verhaeltnis, und das Bild ist die halbe Viewport-Breite — auf einem
       sehr breiten Schirm waechst die Sektion damit ins Unermessliche. Gemeldet
       vom User am 27.08.2026: „Das Bild drueckt die Sektion bei grossen Breiten
       viel zu hoch."
       Der Deckel ist ein rem-Wert, kein Anteil: 35.667rem = 642 px bei 18 px
       Grundschrift — die in der Vorlage gezeichnete Sektionshoehe. Oberhalb
       davon beschneidet `object-fit: cover`, das Bild bleibt randlos.
       Ueberschreibbar je Site über `--abt-img-max-h`. */
    max-block-size: var(--abt-img-max-h, 35.667rem);
}

.m-abt-img img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.m-abt-wrap {
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
    padding-block: 1.5rem;
    padding-inline-start: 1.5rem;
    /* Rechte Kante auf die Inhaltsbox ziehen: der halbe Überhang des Viewports
       über `--max-w`. `max()` hält bei schmalen Schirmen das Randpolster. */
    padding-inline-end: max(1.5rem, calc((100vw - var(--max-w, 1485px)) / 2));
}

.m-abt-title { margin: 0 0 0.778rem 0; }

.m-abt-title-line1 {
    display: block;
    font-size: 1.667rem;
    font-weight: 300;
    color: var(--section-muted, var(--section-fg, inherit));
}

.m-abt-title-line2 {
    display: block;
    font-size: 2rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.02em;
    color: var(--section-heading, var(--section-fg, inherit));
}

/* Ab 1024 px dasselbe Randpolster wie `.m-px-edge` — damit der Text auf
   derselben Linie beginnt wie der Inhalt jeder anderen Sektion. Gemessen:
   Viewport-Mitte 960 + 2rem = 996 gegen 995 in der Vorlage. */
@media (min-width: 1024px) {
    .m-abt-wrap { padding-inline-start: 2rem; }
}

/* DIE VIGNETTE BEANSPRUCHT KEINE TEXTBREITE. Der Output sagt es selbst:
   „Wheel ist seit dem 50:50-Refactor absolut positioniert und beansprucht keinen
   horizontalen Raum mehr in der Text-Spalte". Eine Flex-Spalte dafür wäre gegen
   die Absicht des Moduls — sie würde den Text schmäler machen, sobald jemand
   eine Vignette setzt.

   KEINE VORLAGE HAT DAS BISHER BESTÄTIGT: Weder Ronja noch eine andere Seite
   dieses Projekts setzt eine Vignette. Die Lage unten rechts folgt der Absicht
   des Moduls, nicht einer Messung — wer die erste Vignette baut, misst nach. */
.m-abt-content { position: relative; }
.m-abt-text { min-width: 0; }
.m-abt-body p { margin: 0 0 0.778rem 0; }
.m-abt-body p:last-child { margin-bottom: 0; }
.m-abt-body ul, .m-abt-body ol { margin: 0 0 0.778rem 1.222rem; }

/* Der Output setzt je nach Feld „Text-Spalten" eine der beiden Klassen — ohne
   Regel dazu wäre die Zweispaltigkeit eine leere Zusage. Spaltenabstand wie
   `.m-bg-text--cols-2`, damit Text überall im selben Rhythmus läuft. */
/* Huelle des Knopfes im Textkoerper. `break-inside: avoid`, damit der
   Mehrspaltensatz sie nicht an der Spaltengrenze zerreisst; `margin-block-end: 0`,
   damit unter dem Knopf kein Absatzabstand haengen bleibt. Der Abstand DARUEBER
   wird je Site gesetzt — die Vorlagen zeichnen ihn unterschiedlich. */
.m-abt-btn-wrap {
    margin-block: var(--abt-btn-abstand, 1.556rem) 0;
    break-inside: avoid;
}

.m-abt-body--2col { columns: 2; column-gap: 1.667rem; }
.m-abt-body--2col > *:first-child { margin-top: 0; }

@media (max-width: 47.99em) {
    .m-abt-body--2col { columns: 1; }
}

/* Die Vignette ist optional — ohne Bild und ohne Zeichen rendert der Output sie
   gar nicht erst. Sie bekommt eine feste Spalte, damit der Text nicht springt,
   wenn sie fehlt. */
.m-abt-wheel {
    position: absolute;
    right: 0;
    bottom: 0;
    width: 6.667rem;
    max-width: 30%;
    pointer-events: none;
}
.m-abt-wheel-svg { display: block; width: 100%; height: auto; }

.m-abt-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.556rem;
    margin-top: 1.111rem;
    padding: 0.611rem 1.333rem;
    border-radius: 0.222rem;
    font-weight: 700;
    text-decoration: none;
    background: var(--section-link-bg, var(--color-primary, #0f172a));
    color: var(--section-link-fg, #ffffff);
}

.m-abt-btn:hover,
.m-abt-btn:focus-visible { filter: brightness(1.1); }

/* UNTER DEM SPALTEN-BREAKPOINT STAPELN. 48em ist derselbe Wert, an dem auch das
   Box-Grid seine Spalten auflöst — zwei Hälften nebeneinander sind auf einem
   Telefon weder lesbar noch als Bild erkennbar. Darunter bekommt das Bild ein
   festes Verhältnis, weil es dann keine zweite Spalte mehr gibt, an der es sich
   ausrichten könnte. */
@media (max-width: 47.99em) {
    .m-abt-section { grid-template-columns: 1fr; }
    .m-abt-img { aspect-ratio: 3 / 2; }
    .m-abt-wrap { padding-inline: 1.5rem; }
}
/* === Sticky-Header mit Compact-Modus (analog stahlbauhoch3.de) === */
/*
 * Header startet bei voller Höhe (8.611rem; ≈ 155 px @ 18 px root) und klebt
 * von Anfang an oben fest. Beim Scrollen > 100 px setzt m-header.js die
 * Klasse `.is-compact` → Header schrumpft auf 4.444rem (≈ 80 px), Logo-Halo
 * von 12.333rem auf 4rem, Steuerrad-Logo von 10.333rem auf 3.5rem.
 *
 * `body { padding-top: var(--m-header-h-full) }` kompensiert den entfallenen
 * Layout-Fluss — sonst rutscht der Hero unter den fixed Header.
 * `scroll-padding-top` sorgt, dass Anker (Fahrtenrevier-Orte, FAQ-Items …)
 * nicht hinter dem Header landen.
 */
:root {
    --m-header-h-full: 8.611rem;
    --m-header-h-compact: 4.444rem;
}

html { scroll-padding-top: var(--m-header-h-compact); }
body { padding-top: var(--m-header-h-full); }

#header {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    transition: box-shadow 0.25s ease;
}
#header .m-header-h,
#header .m-logo-circle,
#header .m-logo-steering {
    transition: height 0.25s ease, width 0.25s ease, left 0.25s ease;
}

#header.is-compact { box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08); }
#header.is-compact .m-header-h    { height: var(--m-header-h-compact); }
#header.is-compact .m-logo-circle { width: 4rem;  height: 4rem; left: var(--edge-pad); }
#header.is-compact .m-logo-steering { width: 3.5rem; height: 3.5rem; }

#header.is-compact .m-megamenu-viewport { top: var(--m-header-h-compact); }

@media (max-width: 1023px) {
    #header {
        max-height: 100vh;
        overflow-y: auto;
        -webkit-overflow-scrolling: touch;
    }
}

/* Tablet + Mobile (< 1024 px): Logo verkleinern + bündig auf Inhalts-Edge. */
@media (max-width: 1023px) {
    .m-logo-circle {
        width: 8.5rem;
        height: 8.5rem;
        left: var(--edge-pad);
        top: 50%;
        transform: translateY(-50%);
    }
    .m-logo-steering {
        width: 7.2rem;
        height: 7.2rem;
    }
}

/* Desktop ≥ 1024 px im Vollmodus: Größe aus dem Token-Kanal.
 *
 * Bis zum 17.09.2026 stand hier `13.5rem` bzw. `11.5rem`, mit dem Kommentar „Logo etwas
 * größer als die Token-Defaults“ — also ausdrücklich GEGEN das Token. Die Tokens sagen
 * 12.333rem und 10.333rem; auf beiden Live-Sites gemessen (17.09.2026), identisch.
 * Der Docblock dieser Datei nennt 12.333rem ebenfalls als Vollgröße.
 *
 * Rückfall bleibt der bisherige Literal, damit diese Hälfte für sich nichts ändert.
 * Mit Kanal wird das Logo 21 px kleiner — das ist die sichtbare Änderung, die je Site
 * vorzulegen ist (`update-aendert-die-ausgabe-nicht.md`).
 */
@media (min-width: 1024px) {
    .m-logo-circle {
        width:  var(--tok-m-logo-circle-width,  13.5rem);
        height: var(--tok-m-logo-circle-height, 13.5rem);
        left: var(--edge-pad);
    }
    .m-logo-steering {
        width:  var(--tok-m-logo-steering-width,  11.5rem);
        height: var(--tok-m-logo-steering-height, 11.5rem);
    }
}

/* === Box-/Kachel-Design (pflegbar via Page Composer → CSS-Optionen) === */
/*
 * Border-Radius, Schatten und Rahmen werden pro Box-Klasse im Backend gepflegt
 * (Spalten border_radius, border_width, border_color, box_shadow in
 * rex_sws_css_options/category=box_class). Werte landen als CSS-Variablen
 * am gerenderten Card-Element via Inline-Style:
 *   --card-border-radius, --card-border-width, --card-border-color, --card-shadow
 *
 * Greift NUR, wenn die Variable im Inline-Style gesetzt ist (Attribute-Selector).
 * Ohne gesetzten Wert bleiben die Card-spezifischen Defaults (z. B.
 * .m-bg-col--card { border-radius: 0.222rem }) unangetastet.
 */
[style*="--card-border-radius"] {
    border-radius: var(--card-border-radius);
}
[style*="--card-shadow"] {
    box-shadow: var(--card-shadow);
}
[style*="--card-border-color"],
[style*="--card-border-width"] {
    border: var(--card-border-width, 1px) solid var(--card-border-color, currentColor);
}
/* === sws_starter Lite-Templates · Header + Footer · Vanilla-CSS (kein Tailwind) === */
/*
 * Wird von den Default-Templates `data/templates/header.php` und
 * `data/templates/footer.php` genutzt. Komplett eigenständig.
 *
 * KORREKTUR 2026-08-25: Hier stand, die Vorlagen bauten „nur auf Tokens
 * (`.site-max-w`, `.site-px-edge`, ggf. .site-header-h)" auf. Das trifft nicht
 * zu — sie emittieren `lite-*`-Klassen, und die drei genannten Selektoren kommen
 * in keiner Vorlage und in keinem gerenderten HTML vor. Der Satz hat einen ganzen
 * Token-Satz im Seed am Leben gehalten, den niemand benutzt hat.
 *
 * Projekt
 * kann diese Klassen beliebig overriden in eigener overrides.css oder die
 * Templates komplett ersetzen.
 */

/* === Lite-Header ===
 * Farbschema kommt aus dispatch_header.php (sws_starter_get_header_appearance):
 * --header-bg / --header-text / --header-heading / --header-link-bg / --header-link-fg
 * werden als Inline-Style auf <header> gesetzt. Fallback hier = Foundation-Defaults.
 */
.lite-header {
    background: var(--header-bg, #ffffff);
    color: var(--header-text, #334155);
    border-bottom: 1px solid #e2e8f0;
    position: sticky;
    top: 0;
    z-index: 40;
}
.lite-header-inner {
    max-width: var(--max-w, 1485px);
    margin: 0 auto;
    padding: 0 1.5rem;
    min-height: 4rem;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1.5rem;
}
.lite-logo { display: inline-flex; align-items: center; text-decoration: none; color: var(--header-heading, #0f172a); }
.lite-logo img { max-height: 2.5rem; width: auto; display: block; }
.lite-logo-text { font-weight: 800; font-size: 1.25rem; letter-spacing: -0.01em; color: var(--header-heading, #0f172a); }
.lite-logo-icon { height: 2.5rem; width: auto; display: block; color: var(--header-heading, #0f172a); }

/* === Heading-Vorlagen (responsive via clamp) ===
 * Wirkt global pro Site, gesetzt im Starter-Setup → rex_config sws_starter/heading_h1_class etc.
 * Module rendern die Klasse zusätzlich zu ihren bestehenden Headline-Klassen.
 * Skalierung: Min-Wert (mobil) – 5vw Vorzugswert – Max-Wert (desktop).
 */
.m-h1-s       { font-size: clamp(1.25rem, 3.5vw, 1.5rem);  line-height: 1.2; }
.m-h1-m       { font-size: clamp(1.5rem,  4.5vw, 2rem);    line-height: 1.18; }
.m-h1-l       { font-size: clamp(2rem,    5.5vw, 2.75rem); line-height: 1.12; }
.m-h1-xl      { font-size: clamp(2.5rem,  6.5vw, 3.5rem);  line-height: 1.08; }
.m-h1-display { font-size: clamp(3rem,    8vw,   4.5rem);  line-height: 1.05; }

.m-h2-s  { font-size: clamp(1rem,    2.5vw, 1.125rem); line-height: 1.3; }
.m-h2-m  { font-size: clamp(1.125rem, 3vw,  1.375rem); line-height: 1.25; }
.m-h2-l  { font-size: clamp(1.375rem, 3.5vw, 1.75rem); line-height: 1.2; }
.m-h2-xl { font-size: clamp(1.625rem, 4vw,  2.25rem);  line-height: 1.15; }

/* === Linkbox-Vorlagen (Button-Varianten) ===
 * Wirkt global, gesetzt im Starter-Setup → rex_config sws_starter/linkbox_class.
 * Module fügen die Klasse zu ihrem Button-Selektor zusätzlich an (z.B. `m-tis-btn m-btn-outline`).
 * Color/BG nutzen Section-aware Custom-Properties wo möglich.
 */
.m-btn-solid {
    background: var(--color-accent);
    color: var(--color-accent-foreground);
    padding: 0.85rem 1.75rem;
    border: 0;
    border-radius: 0.25rem;
    transition: filter 0.15s;
}
.m-btn-solid:hover { filter: brightness(0.92); }

.m-btn-outline {
    background: transparent;
    color: var(--color-accent);
    padding: 0.75rem 1.65rem;
    border: 2px solid var(--color-accent);
    border-radius: 0.25rem;
    transition: background 0.15s, color 0.15s;
}
.m-btn-outline:hover {
    background: var(--color-accent);
    color: var(--color-accent-foreground);
}

.m-btn-ghost {
    background: transparent;
    color: var(--color-accent);
    padding: 0.85rem 1rem;
    border: 0;
    border-radius: 0.25rem;
    transition: background 0.15s;
}
.m-btn-ghost:hover { background: color-mix(in srgb, var(--color-accent) 12%, transparent); }

.m-btn-pill {
    background: var(--color-accent);
    color: var(--color-accent-foreground);
    padding: 0.85rem 2rem;
    border: 0;
    border-radius: 999px;
    transition: filter 0.15s;
}
.m-btn-pill:hover { filter: brightness(0.92); }

.m-btn-text {
    background: transparent;
    color: var(--color-accent);
    padding: 0.5rem 0;
    border: 0;
    border-bottom: 1px solid var(--color-accent);
    border-radius: 0;
    transition: opacity 0.15s;
}
.m-btn-text:hover { opacity: 0.7; }

/* Icon im Button (gepflegt im Starter-Setup → linkbox_icon, aus sws_verwaltung Icons) */
.m-btn-icon {
    width: 1.1em;
    height: 1.1em;
    flex-shrink: 0;
    color: currentColor;
}
.m-btn-icon svg { width: 100%; height: 100%; display: block; }

/* --- Variante „Spacious" (Aldorf-Stil): höherer Header + größerer Logo-Slot --- */
.lite-header--spacious .lite-header-inner { min-height: 5.5rem; padding-top: 0.75rem; padding-bottom: 0.75rem; }
.lite-header--spacious .lite-logo img        { max-height: 3.5rem; }
.lite-header--spacious .lite-logo-icon       { height: 3.5rem; }
.lite-header--spacious .lite-logo-text       { font-size: 1.5rem; }
.lite-header--spacious .lite-nav--desktop ul { gap: 2.25rem; }
.lite-header--spacious .lite-nav--desktop a  { font-size: 1rem; text-transform: none; letter-spacing: 0; font-weight: 600; }

/* --- Modifier „Logo-Box": weiße Box mit Schatten, ragt unter den Header.
 * Box ist via position:absolute aus dem Flex-Layout genommen — der Header-Streifen
 * behält seine ursprüngliche Höhe. Box-Breite passt sich dem Logo-Inhalt an
 * (min-width = Box-Höhe, also mindestens quadratisch; bei breiten Wortmarken wächst sie).
 * Der Inner-Container reserviert per padding-left Platz für die Box.
 */
.lite-header--logo-box                              { overflow: visible; }
.lite-header--logo-box .lite-header-inner           { position: relative; padding-left: 8rem; }
.lite-header--logo-box .lite-logo {
    position: absolute;
    left: 1.5rem;
    top: -1rem;     /* Überstand oben */
    bottom: -1rem;  /* Überstand unten — symmetrisch */
    width: auto;
    min-width: 6rem;  /* untere Schranke = ungefähre Box-Höhe → quadratisch wenn Logo schmal */
    max-width: 16rem; /* obere Schranke damit lange Wortmarken nicht das halbe Layout fressen */
    background: #ffffff;
    box-shadow: 0 6px 16px -2px rgba(0,0,0,0.18), 0 2px 6px rgba(0,0,0,0.10);
    border: 1px solid rgba(0,0,0,0.06);
    border-radius: 6px;
    padding: 0.7rem 1rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    z-index: 5;
}
/* Logo-Inhalt füllt die Box vertikal aus; Breite folgt der Aspect-Ratio des Originals,
 * wodurch das Logo dynamisch breit wird und die Box mitwächst. */
.lite-header--logo-box .lite-logo img,
.lite-header--logo-box .lite-logo .lite-logo-icon {
    max-height: 100%;
    max-width: 100%;
    width: auto;
    height: 4.5rem;       /* fest → Breite ergibt sich aus Aspect-Ratio */
    display: block;
}
.lite-header--logo-box .lite-logo-text {
    color: #0f172a;
    font-size: 0.95rem;
    line-height: 1.15;
    text-align: center;
    font-weight: 700;
}
/* Bei Spacious darf die Box größer + Überstand symmetrisch tiefer */
.lite-header--spacious.lite-header--logo-box .lite-header-inner { padding-left: 9.5rem; }
.lite-header--spacious.lite-header--logo-box .lite-logo {
    min-width: 7.5rem;
    top: -1.25rem;
    bottom: -1.25rem; /* symmetrisch */
}
.lite-header--spacious.lite-header--logo-box .lite-logo img,
.lite-header--spacious.lite-header--logo-box .lite-logo .lite-logo-icon {
    height: 5.5rem;
}
/* Bei Hero-Overlay bleibt die Box weiß auch wenn Header transparent */
.lite-header--hero.lite-header--logo-box .lite-logo {
    background: #ffffff;
    color: #0f172a;
}
/* Centered-Variante: Box mittig, symmetrischer Überstand */
.lite-header--centered.lite-header--logo-box .lite-header-inner { padding-left: 0; }
.lite-header--centered.lite-header--logo-box .lite-logo {
    position: relative;
    left: auto;
    top: auto;
    bottom: auto;
    margin: -1rem auto -1rem auto; /* symmetrisch, gleichzeitig Container-Höhe stabil */
}

/* Desktop-Nav (sichtbar ≥ 64em) */
.lite-nav--desktop { display: none; }
.lite-nav--desktop ul { list-style: none; margin: 0; padding: 0; display: flex; gap: 1.75rem; align-items: center; }
.lite-nav--desktop a {
    color: var(--header-text, #334155);
    text-decoration: none;
    font-size: 0.95rem;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    transition: color 0.15s;
}
.lite-nav--desktop a:hover, .lite-nav--desktop a[aria-current="page"] { color: var(--header-link-bg, #2563eb); }

/* MENÜPUNKTE BLEIBEN EINZEILIG.
 *
 * Die Liste ist ein Flex-Container ohne `white-space`-Vorgabe. Reicht der Platz
 * nicht, schrumpft Flex die Punkte, und der Text bricht um -- betroffen sind
 * zuerst die Punkte MIT Aufklapp-Pfeil, weil sie ein Zeichen mehr tragen. Der
 * Pfeil landet dann unter dem Wort statt dahinter, und weil die umgebrochenen
 * Punkte doppelt so hoch werden, sitzt die halbe Leiste höher als der Rest.
 *
 * Gemessen auf demo.msm.de am 07.09.2026: 8 Punkte mit zusammen 860 px, dazu
 * 7 Lücken zu 45 px (Variante `spacious`) = 1175 px bei 1176 px verfügbarer
 * Breite. Es fehlte EIN Pixel. Punkte ohne Pfeil blieben 27 px hoch, die mit
 * Pfeil wurden 54 px hoch.
 *
 * `nowrap` nur auf der obersten Ebene (`> ul > li > a`): Die Inhalte der
 * Mega-Menüs sollen weiterhin umbrechen dürfen. Wo der Platz wirklich fehlt,
 * lüuft die Leiste jetzt sichtbar über, statt still umzubrechen -- ein
 * erkennbarer Fehler ist besser als ein getarnter.
 *
 * WARUM CSS UND NICHT `whitespace-nowrap` IM MARKUP (tailwind-first.md):
 * Die Leiste erzeugt das Header-Modul, nicht ein Redakteur. Eine Utility-Klasse
 * müsste dort im Template stehen und würde auf jeder Site einzeln gepflegt --
 * genau die Foundation-Drift, gegen die ssot-foundation-drift.md geschrieben ist.
 * Als Regel wirkt sie überall, ohne dass eine Site ihr Markup ändern muss. */
.lite-nav--desktop > ul > li > a { white-space: nowrap; }


/* Burger (sichtbar < 64em) */
.lite-burger {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: transparent;
    border: 0;
    color: var(--header-text, #334155);
    padding: 0.5rem;
    cursor: pointer;
}
.lite-burger:hover { color: var(--header-link-bg, #2563eb); }

/* Mobile-Accordion-Nav */
.lite-nav--mobile { background: var(--header-bg, #ffffff); border-top: 1px solid #e2e8f0; }
.lite-nav--mobile[hidden] { display: none; }
.lite-nav--mobile ul {
    list-style: none; margin: 0; padding: 0 1.5rem;
    max-width: var(--max-w, 1485px); margin-left: auto; margin-right: auto;
}
.lite-nav--mobile li { border-bottom: 1px solid rgba(0,0,0,0.05); }
.lite-nav--mobile li:last-child { border-bottom: 0; }
.lite-nav--mobile a {
    display: block;
    padding: 0.875rem 0;
    color: var(--header-heading, #0f172a);
    text-decoration: none;
    font-weight: 500;
}
.lite-nav--mobile a:hover, .lite-nav--mobile a[aria-current="page"] { color: var(--header-link-bg, #2563eb); }

/* Der Umschaltpunkt Desktop-Nav ↔ Burger stand hier bis 2026-08-09 fest auf 64em.
   Er ist jetzt je Header-Variante pflegbar (`nav_breakpoint`, Default 1024 px = 64em,
   weil 1em in Media Queries immer 16 px sind) und wird deshalb von
   `lib/dispatch_header.php` als <style>-Block erzeugt — eine Media Query kann keine
   Custom Property lesen. Bewusst nur dort, nicht zusätzlich hier: Zwei Schwellen
   ergäben im Bereich dazwischen einen Zustand, den niemand gewollt hat.
   Gemeldet aus HGK-Events (F-13). */

/* === Lite-Footer === */
.lite-footer { margin-top: auto; background: #0f172a; color: #e2e8f0; }
.lite-footer-main { padding: 3rem 0; }
.lite-footer-inner {
    max-width: var(--max-w, 1485px);
    margin: 0 auto;
    padding: 0 1.5rem;
    display: grid;
    grid-template-columns: 1fr;
    gap: 2rem;
}
@media (min-width: 48em) {
    .lite-footer-inner { grid-template-columns: 1fr 1fr 1fr; gap: 2.5rem; }
}
.lite-footer-col h3 {
    font-size: 0.875rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    margin: 0 0 1rem 0;
    color: #ffffff;
}
.lite-footer-col ul { list-style: none; margin: 0; padding: 0; }
.lite-footer-col li { margin-bottom: 0.5rem; font-size: 0.95rem; }
.lite-footer-col a { color: #cbd5e1; text-decoration: none; transition: color 0.15s; }
.lite-footer-col a:hover { color: #ffffff; text-decoration: underline; }
.lite-footer-col--address strong { display: block; color: #ffffff; font-size: 1rem; margin-bottom: 0.5rem; }
.lite-footer-col--address div { font-size: 0.9rem; color: #cbd5e1; line-height: 1.5; }

.lite-footer-bar { background: #020617; border-top: 1px solid #1e293b; }
.lite-footer-bar .lite-footer-inner {
    display: flex; flex-direction: column; gap: 0.5rem;
    align-items: center; justify-content: space-between;
    padding-top: 0.75rem; padding-bottom: 0.75rem;
    font-size: 0.8rem; color: #94a3b8;
}
@media (min-width: 48em) {
    .lite-footer-bar .lite-footer-inner { flex-direction: row; }
}
.lite-footer-copyright { margin: 0; }
.lite-footer-legal { display: flex; gap: 1rem; }
.lite-footer-legal a { color: #94a3b8; text-decoration: none; }
.lite-footer-legal a:hover { color: #e2e8f0; text-decoration: underline; }

/* ============================================================================
 * sws_starter Header-Varianten — Phase 5 v2 (2026-05-17)
 * ============================================================================
 * Aufbauend auf den .lite-header / .lite-nav / .lite-logo / .lite-burger Basis-
 * Klassen weiter oben. Jede Variante erbt Layout-Defaults und überschreibt nur
 * die spezifischen Aspekte.
 */

/* --- Variante „Centered" ----------------------------------------------------
 * Logo zentriert oben, Nav darunter zentriert. Burger oben rechts auf mobile.
 */
.lite-header--centered { position: relative; padding-bottom: 0.5rem; }
.lite-header--centered .lite-header-centered-stack {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    padding: 1.25rem 1rem 0;
    gap: 0.75rem;
}
.lite-logo--centered img { max-height: 3.25rem; }
.lite-nav--centered { display: none; }
.lite-nav--centered ul { justify-content: center; }
.lite-burger--top-right {
    position: absolute;
    top: 0.5rem;
    right: 0.75rem;
    z-index: 2;
}
@media (min-width: 64em) {
    .lite-nav--centered { display: block; }
    .lite-header--centered .lite-burger--top-right { display: none; }
}

/* --- Variante „Hero-Overlay" -------------------------------------------------
 * Header liegt transparent über der ersten Section. Default: dunkler Text
 * (funktioniert mit hellen Heros). Für DUNKLE Heros: rex_config
 * `sws_starter/hero_overlay_light_text=1` setzen → fügt `.lite-header--hero-light-text` hinzu.
 * Beim Scroll > 50 px togglet JS `.lite-header--hero-solid` (immer cream-BG + dunkler Text).
 */
.lite-header--hero {
    position: absolute;
    top: 0; left: 0; right: 0;
    background: transparent;
    /* neutral halten — Brandfarbe kommt ueber --color-border von der Site */
    border-bottom: 1px solid var(--color-border, rgba(0, 0, 0, 0.12));
    color: var(--color-foreground);
    transition: background-color 0.25s ease, border-color 0.25s ease, color 0.25s ease;
}
/* Default: dunkler Text auf transparentem Header (für helle Heros) */
.lite-header--hero .lite-logo,
.lite-header--hero .lite-logo-text,
.lite-header--hero .lite-nav--desktop a,
.lite-header--hero .lite-burger { color: var(--color-foreground); }
.lite-header--hero .lite-nav--desktop a:hover,
.lite-header--hero .lite-nav--desktop a[aria-current="page"] { color: var(--color-primary); }

/* Light-Text-Modus für DUNKLE Heros (per rex_config aktivierbar) */
.lite-header--hero.lite-header--hero-light-text {
    border-bottom-color: rgba(255, 255, 255, 0.18);
    color: #ffffff;
}
.lite-header--hero.lite-header--hero-light-text .lite-logo,
.lite-header--hero.lite-header--hero-light-text .lite-logo-text,
.lite-header--hero.lite-header--hero-light-text .lite-nav--desktop a,
.lite-header--hero.lite-header--hero-light-text .lite-burger { color: #ffffff; }
.lite-header--hero.lite-header--hero-light-text .lite-nav--desktop a:hover,
.lite-header--hero.lite-header--hero-light-text .lite-nav--desktop a[aria-current="page"] { color: var(--color-accent); }

/* Scroll-Solid: respektiert das gewählte Header-Schema (--header-*) — sonst Cream-Default */
.lite-header--hero.lite-header--hero-solid {
    position: fixed;
    background: var(--header-bg, var(--color-background));
    border-bottom-color: var(--color-border);
    color: var(--header-text, var(--color-foreground));
    box-shadow: 0 4px 6px -1px var(--header-shadow, rgba(0,0,0,0.10));
}
.lite-header--hero.lite-header--hero-solid .lite-logo,
.lite-header--hero.lite-header--hero-solid .lite-logo-text { color: var(--header-heading, var(--color-foreground)); }
.lite-header--hero.lite-header--hero-solid .lite-nav--desktop a,
.lite-header--hero.lite-header--hero-solid .lite-burger { color: var(--header-text, var(--color-foreground)); }
.lite-header--hero.lite-header--hero-solid .lite-nav--desktop a:hover,
.lite-header--hero.lite-header--hero-solid .lite-nav--desktop a[aria-current="page"] { color: var(--header-link-bg, var(--color-primary)); }

/* --- Variante „Mega-Menu-ready" ---------------------------------------------
 * Erweitert Classic um Mega-Panels (Subcats) per Hover/Focus.
 */
.lite-nav--mega li.lite-nav__has-mega { position: relative; }
.lite-nav__caret { font-size: 0.75em; margin-left: 0.25em; opacity: 0.7; }
.lite-mega-panel {
    position: absolute;
    top: 100%;
    left: 0;
    min-width: 14rem;
    max-width: 18rem;                     /* Defensiv-Limit damit Panel nicht über Viewport rausläuft */
    background: var(--color-background);
    border: 1px solid var(--color-border);
    border-top: 2px solid var(--color-primary);
    /* Neutraler Foundation-Default. Der Wert kam bei der Zusammenfuehrung am
       2026-08-07 als kundenspezifischer Braunton (Thiemann-Palette) mit — in
       die Foundation gehoert er nicht. Sites branden ueber `--panel-shadow`,
       ohne von der Foundation-Datei abzuweichen. */
    box-shadow: 0 10px 20px -6px var(--panel-shadow, rgba(0,0,0,0.12));
    padding: 0.5rem 0;
    z-index: 60;
    opacity: 0;
    visibility: hidden;
    transform: translateY(0.25rem);
    transition: opacity 0.15s ease, transform 0.15s ease, visibility 0s linear 0.15s;
}
.lite-nav--mega li.lite-nav__has-mega:hover > .lite-mega-panel,
.lite-nav--mega li.lite-nav__has-mega:focus-within > .lite-mega-panel {
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
    transition: opacity 0.15s ease, transform 0.15s ease, visibility 0s linear 0s;
}

/* Items VERTIKAL stacken (überschreibt das .lite-nav--desktop ul-flex der Parent-Nav,
 * das via Selector-Vererbung sonst auch das verschachtelte ul im Mega-Panel zur Flex-Row macht).
 */
.lite-mega-panel ul {
    list-style: none;
    margin: 0;
    padding: 0;
    display: block;                       /* kein flex erben */
    gap: 0;
}
.lite-mega-panel li { display: block; padding: 0; border: 0; }
.lite-mega-panel a {
    display: block;
    padding: 0.55rem 1.1rem;
    color: var(--color-foreground);
    text-decoration: none;
    font-size: 0.95rem;
    line-height: 1.35;
    white-space: nowrap;                  /* Cat-Namen nicht umbrechen — Panel-Breite über min/max gesteuert */
    overflow: hidden;
    text-overflow: ellipsis;
}
.lite-mega-panel a:hover {
    background: var(--color-light);
    color: var(--color-primary);
}

/* Rechts-Auto-Align für Cats im rechten Viewport-Bereich.
 * Klasse `.lite-nav__has-mega--right` wird von der Variante per JS (oder PHP-Detection)
 * gesetzt — Fallback: nutzbar via Direct-Attribut, derzeit noch nicht autom. gesetzt.
 */
.lite-nav__has-mega--right > .lite-mega-panel { left: auto; right: 0; }

/* Mobile-Sub-Nav (Mega-Variante zeigt Subcats eingerückt) */
.lite-mobile-sub {
    list-style: none;
    margin: 0;
    padding: 0 0 0.5rem 1.25rem;
    background: #f8fafc;
}
.lite-mobile-sub li { border: 0; }
.lite-mobile-sub a {
    padding: 0.5rem 1rem;
    font-size: 0.9rem;
    color: #64748b;
}

/* --- Footer-Artikel-Wrapper ------------------------------------------------- */
.sws-footer { margin-top: auto; }

/* ============================================================================
 * sws_starter Modul-Defaults (Tischlerei-Demo Quick-Fix)
 * ============================================================================
 * Minimal-CSS für die m-*-Klassen, die Text-Bild-Splitter + Hero-Einzelbild
 * benutzen. Ohne diese rendert alles als nackter HTML-Text. Projekt-spezifische
 * Verfeinerung kommt sonst aus der projekt-eigenen overrides.css.
 */

/* Hero-Einzelbild — Höhe aus dem Token-Kanal, siehe .claude/rules/token-kanal.md
 *
 * Bis zum 17.09.2026 stand hier `height: 70vh; min-height: 420px; max-height: 720px`.
 * Das überfuhr das Backend-Token `.m-hero-image-h { height }` (16.111rem = 290 px @ 18 px),
 * für das prolahns und bcls Banner-Bilder erzeugt sind (1920 x 291). Ergebnis: Bilder
 * 2,47-fach hochgerechnet auf 22 von 36 Seiten, drei Wochen lang unbemerkt.
 *
 * WARUM ALLE DREI DEKLARATIONEN DENSELBEN KANAL LESEN. Jede behält ihren bisherigen
 * Literal als Rückfall — ohne Kanal steht also byte-genau das Frühere da (Pflicht 1 der
 * Regel). Mit Kanal werden height, min-height und max-height GLEICH, und damit gewinnt
 * der Token-Wert exakt: Eine Untergrenze, die dem Wert selbst entspricht, klemmt nicht.
 *
 * Der naheliegende Weg — min-/max-height streichen und einen `clamp()`-Rückfall bauen —
 * wäre zwar gleichwertig (am 17.09. an sieben Fällen im Browser gemessen), aber der
 * Rückfall wäre dann eine Umformung und kein Zitat. Diese Form braucht die Messung gar
 * nicht: Sie lässt jeden Literal stehen, wo er stand.
 *
 * Gegengemessen am 17.09.2026: ohne Kanal 559,297 px bzw. 399,5 px wie zuvor; mit Kanal
 * 290 px, auch wenn der Wert unter 420 oder über 720 px liegt.
 */
.m-hero-image-h {
    height:     var(--tok-m-hero-image-h-height, 70vh);
    min-height: var(--tok-m-hero-image-h-height, 420px);
    max-height: var(--tok-m-hero-image-h-height, 720px);
}
.m-hero-images-wrap { position: relative; width: 100%; height: 100%; }
@media (max-width: 768px) {
    .m-hero-image-h {
        height:     var(--tok-m-hero-image-h-height, 50vh);
        min-height: var(--tok-m-hero-image-h-height, 280px);
    }
}

/* Text-Bild-Splitter */
.m-tis-wrap { max-width: 1280px; margin: 0 auto; padding: 0 1.5rem; }
.m-tis-grid { display: grid; gap: 3rem; align-items: center; grid-template-columns: 1fr; }
@media (min-width: 768px) { .m-tis-grid { grid-template-columns: 1fr 1fr; } }

/* Bild links statt rechts — Slot 7 im Backend („links (gespiegelt)").
 *
 * Erst ab dem Zweispalter, denn darunter liegen Text und Bild ohnehin
 * untereinander; ein `row-reverse` würde dort das Bild ÜBER den Text schieben
 * und die Lesereihenfolge umdrehen. Über `order` statt `direction`, damit die
 * Reihenfolge im DOM (Text zuerst) für Screenreader erhalten bleibt. */
@media (min-width: 768px) {
    .m-tis-grid--bild-links > .m-tis-text { order: 2; }
    .m-tis-grid--bild-links > .m-tis-img  { order: 1; }
}

/* Bild bis zum Viewport-Rand — Slot 8 im Backend.
 *
 * Der Überhang wird aus dem tatsächlichen Abstand zur Content-Zone gerechnet,
 * nicht geschätzt: `100vw` minus Inhaltsbreite, halbiert, ergibt den Rand einer
 * Seite. `max()` mit 0 verhindert einen negativen Wert, sobald der Viewport
 * schmaler ist als die Content-Zone — dort gibt es keinen Überhang. */
.m-tis-img--full-bleed {
    --_tis-ueberhang: max(0px, (100vw - var(--max-w, 1485px)) / 2);
    margin-inline-end: calc(var(--_tis-ueberhang) * -1);
}
@media (min-width: 768px) {
    .m-tis-grid--bild-links > .m-tis-img--full-bleed {
        margin-inline-end: 0;
        margin-inline-start: calc(var(--_tis-ueberhang) * -1);
    }
}

.m-tis-text { padding: 1rem 0; }
.m-tis-title { margin: 0 0 1.5rem 0; line-height: 1.15; }
.m-tis-title-line1 {
    display: block;
    font-size: 0.85rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: var(--color-accent);
    margin-bottom: 0.5rem;
}
.m-tis-title-line2 {
    display: block;
    font-size: clamp(1.5rem, 3vw, 2.5rem);
    font-weight: 800;
    color: var(--section-heading, var(--color-foreground));
}

.m-tis-body-single, .m-tis-body-2col, .m-tis-body { font-size: 1.05rem; line-height: 1.65; color: var(--section-fg, var(--color-foreground)); }
.m-tis-body-single p, .m-tis-body-2col p, .m-tis-body p { margin: 0 0 1rem 0; }
.m-tis-body-single p:last-child, .m-tis-body-2col p:last-child { margin-bottom: 0; }
@media (min-width: 768px) {
    .m-tis-body-2col { column-count: 2; column-gap: 2rem; }
}

/* .m-tis-btn: nur Layout + Typo. Background/Color/Padding/Border-Radius kommen aus der
 * globalen Linkbox-Vorlage (m-btn-solid / m-btn-outline / m-btn-ghost / m-btn-pill / m-btn-text),
 * gesetzt im Starter-Setup → rex_config sws_starter/linkbox_class.
 * Fallback wenn keine Vorlage gesetzt: greift `.m-tis-btn:not([class*="m-btn-"])` mit Solid-Look. */
.m-tis-btn, .m-tis-text a.button, .m-tis-text a.btn {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    margin-top: 1.5rem;
    font-size: 0.95rem;
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    text-decoration: none;
}
/* Symbol im Knopf.
 *
 * Stand bis 0.4.4 als eigener <style>-Block IM MODUL-OUTPUT — und damit einmal
 * pro Instanz im DOM. Fünf Karten in einer Sektion ergaben fünf identische
 * Blöcke, die als Geschwister zwischen den <section>-Elementen lagen. Sie sind
 * `display: none`, kosten also kein `gap`, ZÄHLEN ABER BEI `:nth-child()` MIT:
 * Ein naheliegendes `:nth-child(even)` auf die Karten trifft dann die
 * Style-Blöcke statt der Karten. Gemeldet aus HGK-Events (16.08.2026), die
 * deshalb auf `:nth-child(even of section:has(> .m-tis-wrap))` ausweichen mussten.
 *
 * Die Regel ist generisch — sie gehört hierher, nicht in den Output. */
.m-tis-btn-icon { width: 20px; height: 20px; flex-shrink: 0; display: inline-block; }

/* Solid-Fallback wenn KEIN m-btn-* Modifier gesetzt ist */
.m-tis-btn:not([class*="m-btn-"]) {
    padding: 0.85rem 1.75rem;
    background: var(--color-accent);
    color: var(--color-accent-foreground);
    border-radius: 0.25rem;
}

/* Bild-Seite */
.m-tis-image, .m-tis-image-col { width: 100%; }
.m-tis-image img, .m-tis-image-col img { display: block; width: 100%; height: auto; max-height: 600px; object-fit: cover; }

/* Tone-Klassen (sws_section_config) — sorgen für Schrift-Kontrast je nach BG */
/* === Tone-Foundation: Section-Color via CSS-Inheritance ===
 * Setzt die Default-Schrift-Color der Section. Descendant-Elements ohne eigene
 * `color`-Regel erben sie automatisch (CSS-`color` ist von Natur aus vererbt).
 *
 * Komponenten die ihre eigene Color setzen MÜSSEN sie aus den Section-Custom-Properties
 * lesen (`var(--section-fg, var(--color-foreground))`), damit sie sich an die Section
 * anpassen. Siehe sws_section_config::getSectionStyleAttr() — setzt --section-fg etc. inline.
 *
 * KEIN universal-Selector `.m-tone-dark *` mehr — der überschrieb sonst SVG-currentColor
 * und Button-Inhalte, was zu unlesbaren CTAs führte.
 */
.m-tone-dark { color: var(--color-cta-foreground); }

/* Textlinks in dunklen Sektionen bekommen Akzentfarbe für Sichtbarkeit.
 * Buttons ausnehmen — sie definieren eigene Color.
 *
 * `.m-is-button` ist der vorgesehene Weg: Ein Link, der wie ein Knopf aussieht,
 * trägt diese Marker-Klasse und ist damit ausgenommen, ohne dass hier eine
 * weitere `:not()`-Bedingung dazukommt. Ein Projekt hängt sie an seine eigenen
 * Knopf-Klassen und muss die Foundation dafür nicht anfassen — bis 0.3.18
 * musste jede Site jede betroffene Stelle einzeln nachziehen (HGK-Events M3-16).
 *
 * ## Warum die Kette in `:where()` steht
 *
 * Jedes `:not()` zählt für die Spezifität wie eine Klasse. Als `.m-is-button`
 * dazukam, stieg die Regel von (0,4,1) auf (0,5,1) — und zwei Gegenregeln in
 * HGK-Events, die vorher mit (0,5,1) knapp gewannen, standen plötzlich im
 * Gleichstand. Bei Gleichstand entscheidet die Ladereihenfolge, und das Template
 * lädt `styles.css` VOR `sws-overrides.css`: Die Foundation gewann, die
 * Beschriftung jedes CTA-Knopfs stand in Rot auf Blau, Kontrast 1,05. Am selben
 * Tag traf es dort ein zweites Mal die Kontaktzeilen, Kontrast 1,00.
 *
 * `:where()` hat Spezifität NULL. Die Regel bleibt damit bei (0,1,1), egal wie
 * viele Ausnahmen die Liste noch bekommt — eine Site überschreibt sie mit einer
 * einzigen Klasse, dauerhaft.
 *
 * Geprüft vor der Umstellung: Keine der vier eigenen Sites (demo, demo1, BCL,
 * ProLahn) trägt eine Gegenregel zu diesem Selektor. Die Senkung ändert dort
 * also nichts; sie wirkt nur dort, wo jemand bewusst überschreibt.
 *
 * REGEL für neue Ausnahmen: Sie kommen INNERHALB des `:where()` dazu. Wer eine
 * Bedingung davor schreibt, hebt die Spezifität wieder an und bricht damit still
 * die Overrides aller Sites. */
.m-tone-dark a:where(:not(.m-is-button):not(.m-tis-btn):not(.button):not(.btn)) { color: var(--color-accent); }

/* CTA-Sektion (bg-cta) — Text größer + zentriert */
.bg-cta .m-tis-wrap { text-align: center; }
.bg-cta .m-tis-title-line2 { font-size: clamp(1.75rem, 3.5vw, 3rem); }

/* Sektions-Reset — MUSS in einer Schicht liegen.
 *
 * Ungelayertes CSS gewinnt in der Kaskade gegen JEDE Schicht, unabhängig von
 * Spezifität und Dateireihenfolge. Diese Regel stand ungelayert und schlug
 * damit sämtliche Padding-Utilities, die Tailwind in `@layer utilities`
 * erzeugt — die Padding-Auswahl der Sektionskonfiguration war eine Oberfläche
 * ohne Wirkung. Im Browser gemessen (12.08.2026 auf demo):
 *
 *   <div class="py-32">  144 px   |   <section class="py-32">  0 px
 *   <div class="pt-36">  162 px   |   <section class="pt-36">  0 px
 *
 * Darunter standen drei Nachbauten (`section.py-8`, `section.py-20`,
 * `section.lg\:py-28` mit 2rem / 5rem / 7rem) — die drei gängigsten Werte
 * wurden von Hand ersetzt, statt die Ursache zu suchen. Sie sind entfallen:
 * Die Utilities liefern exakt dieselben Werte (`calc(0.25rem * 20)` = 5rem),
 * nur eben für ALLE Stufen statt für drei. Gemeldet von HGK-Events.
 *
 * Der Reset bleibt — in `@layer base` schlägt er weiterhin den Browser-Default,
 * verliert aber gegen `@layer utilities`. Die Decor-Regeln weiter oben tragen
 * `!important` und sind davon unberührt. */
@layer base {
    section { padding-block: 0; }
}

/* m-max-w + m-px-edge (Universal-Template Inner-Wrapper)
   max-width aus dem Token `site-max-w` (→ `:root { --max-w }` je Breakpoint in
   sws-breakpoints.css). Der Fallback entspricht dem Foundation-Standardwert und
   greift nur, wenn die Token-Zeile auf einer Site fehlt. */
.m-max-w { max-width: var(--max-w, 1485px); margin-inline: auto; }
.m-px-edge { padding-inline: 1.5rem; }
@media (min-width: 1024px) { .m-px-edge { padding-inline: 2rem; } }

/* ============================================================================
 * Footer-Layout-Regeln (kein Color-Override — Farben kommen aus rex_sws_css_options)
 * ============================================================================
 */
section.bg-nav-bar .m-tis-grid { grid-template-columns: 1fr; text-align: center; }
section.bg-nav-bar .m-tis-text { max-width: 70ch; margin: 0 auto; }
section.bg-cta.py-8 .m-tis-grid { grid-template-columns: 1fr; }
section.bg-cta.py-8 .m-tis-wrap { padding: 0 1rem; }

/* ─── Honeypot-Feld (Spam-Schutz für m-kontakt-form + m-anmeldung-form) ───
 * Off-screen positioning statt display:none — manche Bots überspringen
 * display:none-Felder bewusst (sehen das als "nicht-relevant"-Signal),
 * off-screen ist robuster und bleibt für Screen-Reader theoretisch
 * zugänglich. aria-hidden="true" am Wrapper sorgt für korrektes
 * Screen-Reader-Ignorieren. */
.m-form-hp {
    position: absolute !important;
    left: -9999px !important;
    top: -9999px !important;
    width: 1px !important;
    height: 1px !important;
    overflow: hidden !important;
}


/* ============================================================================
 * Foundation-Patches (synced from BCL 2026-05-20)
 * Box-Grid Overflow-Right Layout + Overlay-Layout-Bild-Bleed
 * ============================================================================ */

/* c11o-r/c11o-l Bleed-Override: die Bild-Spalte (last-child bei c11o-r, first-child bei c11o-l)
 * verzichtet auf das Content-Zone-Padding aus dem allgemeinen Block — das Bild
 * soll bis zum jeweiligen Viewport-Rand reichen, NICHT vor der Content-Zone enden. */
@media (min-width: 64em) {
    .m-bg-grid--c11o-r > .m-bg-col:last-child  { padding-right: 0; }
    .m-bg-grid--c11o-l > .m-bg-col:first-child { padding-left:  0; }
}

/* === Overlay-Layout c11o-r / c11o-l Bild-Bleed: keine Border-Radius, kein col-padding-top/bottom ===
   Im Overlay-Layout soll das Bild flächig bis zum Section-Rand gehen — die runden Ecken
   und das vertikale col-Padding sind nur in der Standard-Variante sinnvoll. */
.m-bg-grid--c11o-r > .m-bg-col:last-child .m-bg-image,
.m-bg-grid--c11o-l > .m-bg-col:first-child .m-bg-image {
    border-radius: 0;
}
.m-bg-grid--c11o-r > .m-bg-col:last-child .m-bg-image--h-row-stretch img,
.m-bg-grid--c11o-l > .m-bg-col:first-child .m-bg-image--h-row-stretch img {
    border-radius: 0;
}
@media (min-width: 48em) {
    .m-bg-grid--c11o-r > .m-bg-col:last-child,
    .m-bg-grid--c11o-l > .m-bg-col:first-child {
        padding-top: 0;
        padding-bottom: 0;
    }
}

/* m-bg-linkbox-wrap höhere Specificity — überschreibt die .m-bg-text-p-Regel (margin: 0 0 0.778rem 0)
   sodass die Linkbox visuellen Abstand zum vorherigen Text-Block bekommt. */
.m-bg-text .m-bg-linkbox-wrap, p.m-bg-linkbox-wrap { margin-top: 2rem; margin-bottom: 0; }
/* Softscroll bei Anker-Aufruf (Foundation-Default).
   Wirkt für href="#anker"-Links + Browser-eigene Page-Anchor-Navigation.
   scroll-padding-top wird vom Header-Offset gesetzt (separate Regel,
   meist abhängig von der Header-Variante).
   prefers-reduced-motion deaktiviert die Animation für sensible Nutzer. */
html {
    scroll-behavior: smooth;
}
@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
}

/* Hero-Slider Vorschau-Bild (rex_sws_slides.BILD).
   Wird vom Slide-Modul gerendert wenn ein zusätzliches BILD pro Slide
   gepflegt ist. ART (L/R) steuert die Seite. Bestands-Slides ohne BILD
   bekommen das Layer nicht ausgespielt. Pattern analog picodent.de —
   Floating-Box im Hero rechts/links neben dem Text-Layer. */
.m-hero-vorschau {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    width: 50%;
    max-width: 44rem;
    max-height: 90%;
    pointer-events: none;
}
.m-hero-vorschau--R { right: 0; }
.m-hero-vorschau--L { left: 0; }
.m-hero-vorschau-img {
    display: block;
    width: 100%;
    height: auto;
    max-height: 100%;
    object-fit: contain;
}
/* Tablet: Vorschau-Bild zwischen Desktop und Mobile-Stack */
@media (max-width: 1024px) {
    .m-hero-vorschau {
        width: 55%;
        max-width: 30rem;
        max-height: 85%;
    }
}

/* Mobile: Bild + Text bleiben NEBENEINANDER (kein Stack). Text-Layer wird
   nur schmaler, um dem Bild rechts/links Platz zu machen. Greift nur wenn
   ein Vorschau-Bild im Slide ist. Plus Hero-Box-Schrift kleiner — sonst
   ist sie auf Mobile riesig im Verhaeltnis zum Rest. */
@media (max-width: 768px) {
    .m-hero-box {
        font-size: 1.444rem;        /* ~26px @18 — sonst zu dominant */
        padding: 0.667rem;          /* ~12px statt 18 px */
    }
    .m-hero-vorschau {
        width: 50%;
        max-width: none;
        max-height: 85%;
        opacity: 1;
    }
    .m-hero-slide:has(.m-hero-vorschau--R) .m-hero-text {
        max-width: 48%;
        padding-right: 0.5rem;
    }
    .m-hero-slide:has(.m-hero-vorschau--L) .m-hero-text {
        left: auto;
        right: 1.5rem;
        max-width: 48%;
        text-align: right;
    }
}

/* ─────────────────────────────────────────────────────────────────────
 * Hero-Video (mod_hero_video)
 *
 * Das Video füllt den Hero-Wrapper und wird beschnitten, statt sein
 * Seitenverhältnis durchzusetzen — sonst bestimmte die Datei die Höhe der
 * Sektion, und zwei Seiten mit verschiedenen Videos hätten verschieden hohe
 * Heroes. Die Höhe kommt aus dem Token `m-hero-h`, genau wie beim Slider.
 *
 * Den Anhalteknopf teilt sich das Modul über die Selektorliste mit dem
 * Box-Grid (siehe 10-module.css).
 * ───────────────────────────────────────────────────────────────────── */
.m-hero-video-el {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* ─────────────────────────────────────────────────────────────────────
 * Hero-Textbox (mod_hero_slider)
 *
 * Fläche hinter dem Slide-Text. Gesteuert wird sie in der Slide-Verwaltung
 * (Medienverwaltung -> Slides): Checkbox "Reinragende Textbox", Box-Schema und
 * Textfarbe. Bis 0.42.0 las das Modul diese drei Spalten nicht aus — die
 * Auswahl wirkte nie.
 *
 * Theme-neutral: Die Flächenfarbe kommt über `--card-*` aus der
 * box_class-Registry, nicht aus diesem Stylesheet. Hier stehen nur Struktur
 * und die Rückfallwerte.
 * ───────────────────────────────────────────────────────────────────── */
.m-hero-textbox {
    /* Geometrie bewusst von `.m-hero-box` übernommen (00-foundation-navigation.css).
     * Diese Textbox ersetzt funktional die Box, die Redaktionen sich bis dahin von
     * Hand in den Slide-Text geschrieben haben — sie muss deshalb dort sitzen, wo
     * die Redaktion sie erwartet, und nicht am oberen Rand kleben.
     *
     * Ohne diese drei Zeilen lief die Fläche über die volle Breite des
     * Text-Layers und begann direkt unter der Kopfzeile; gemessen am 01.09.2026
     * auf demo.msm.de, wo sie damit unter dem Logo hervorstand.
     *
     * `max-width` kommt zu `fit-content` hinzu: Ein langer Slide-Text hat in der
     * handgesetzten Variante nie vorkommen können, hier schon. */
    display: block;
    width: fit-content;
    margin-top: 11.111rem;

    /* Obergrenze der Zeilenlänge, hergeleitet statt gegriffen.
     *
     * `fit-content` allein genügt nicht: Ein Slide-Text, der aus einem langen
     * Satz besteht, ergibt eine Box über die halbe Bildbreite — gemessen am
     * 01.09.2026 auf demo.msm.de: 1121 px in einem 1485 px breiten Hero.
     *
     * Die engere der beiden Textsorten bestimmt die Grenze. Der Fliesstext
     * rendert mit 18 px, eine mittlere Zeichenbreite liegt bei rund 0,5 em,
     * also ~9 px. Für die typografische Obergrenze von 75 Zeichen je Zeile
     * folgt 75 × 9 px = 675 px ≈ 42 rem (bei 16-px-Root). Die Überschrift mit
     * 2.222 rem bricht dadurch früher um, was gewollt ist.
     *
     * `100%` bleibt als zweite Grenze: In einem schmalen Layout gewinnt sie. */
    max-width: 42rem;

    /* Schriftgröße von `.m-hero-box` übernommen: Der Slide-Text enthält eine
     * Überschrift, die im Hero-Kontext sonst mit 16 px rendert — kleiner als
     * der Fliesstext darunter (18 px). Die handgesetzte Box vererbte hier
     * 2.222 rem, und genau dieses Bild ist die Redaktion gewohnt. */
    font-size: 2.222rem;
    line-height: 1.1;

    padding: 1rem 1.333rem;
    border-radius: var(--card-border-radius, 0.333rem);
    box-shadow: var(--card-shadow, none);
    /* Rückfall-Grund, wenn kein Box-Schema greift (Altwerte blue/red/green
     * aus der Contenido-Zeit, oder eine Site ohne gepflegte Registry).
     *
     * Die Deckkraft ist hergeleitet, nicht gegriffen: Der ungünstigste Fall
     * ist weißer Text auf einem rein weißen Hintergrundbild. Schwarz mit
     * Deckkraft a über Weiß ergibt den sRGB-Wert c = 1 − a; WCAG AA verlangt
     * für Fließtext 4,5:1, also (1,0 + 0,05) / (L + 0,05) >= 4,5 und damit
     * L <= 0,1833. Über die sRGB-Transferfunktion L = ((c + 0,055)/1,055)^2,4
     * folgt c <= 0,4652, also a >= 0,535.
     *
     * Gegenprobe für den gewählten Wert 0,55: c = 0,45 -> L = 0,1708 ->
     * Kontrast 1,05 / 0,2208 = 4,76:1. Hält AA mit etwas Reserve; 0,53 läge
     * mit 4,52:1 auf der Kante, 0,5 mit 4,26:1 darunter. */
    background: var(--card-bg, rgba(0, 0, 0, 0.55));
}

/* "Transparent" ist eine Box ohne Fläche: Innenabstand und Radius bleiben,
 * der Grund verschwindet. Ab hier trägt der Redakteur den Kontrast selbst —
 * deshalb steht die Textfarbe daneben zur Wahl. */
.m-hero-textbox--transparent {
    background: transparent;
    box-shadow: none;
}

/* Textfarbe. `--card-fg` kommt aus dem gewählten Box-Schema und hat Vorrang:
 * Ohne diesen Vorrang stünde bei Schema "Weiß" (Registry-Vordergrund
 * #334155) plus Wahl "heller Text" weiß auf weiß. Genau deshalb setzt
 * `.m-hero-textbox` selbst KEIN `color` — sonst entschiede die Reihenfolge im
 * Stylesheet, nicht die Absicht. */
.m-hero-text--light { color: var(--card-fg, var(--color-cta-foreground, #ffffff)); }
.m-hero-text--dark  { color: var(--card-fg, var(--color-primary, #0f172a)); }

@media (max-width: 768px) {
    /* Analog zu .m-hero-box: auf Mobile ist der Innenabstand sonst zu
     * dominant im Verhältnis zur verbleibenden Textbreite. */
    .m-hero-textbox {
        /* Analog `.m-hero-box`: Auf Mobile ist die grosse Schrift im Verhältnis
         * zur verbleibenden Textbreite zu dominant, und die 42-rem-Grenze wäre
         * breiter als der Bildschirm. */
        max-width: 100%;
        font-size: 1.444rem;
        padding: 0.667rem 0.889rem;
    }
}

/* ─────────────────────────────────────────────────────────────────────
 * Footer-Bar (mod_footer_bar)
 *
 * Dünne Bar-Variante für Copyright/Impressum-Zeilen am Fuß. Hat im
 * Gegensatz zu Box-Grid KEINE inneren `.m-bg-col`-Spalten — das Padding
 * kommt direkt vom Section-Wrapper (über die im Backend gewählte
 * `section_padding`-Klasse) plus einem schmalen Inner-Wrap-Padding hier.
 * So bleibt die Bar bei `py-3 lg:py-4` ~50 px statt 150 px hoch.
 * ───────────────────────────────────────────────────────────────────── */
/* Footer-Bar-Inner — Inhalt mit Body-Edge ausrichten.
   Pattern: .m-max-w-Klasse macht schon max-width 1485 + margin auto
   zentriert. Hier ergänzen wir Edge-Padding NUR für Viewports < 1485,
   damit der Inhalt nicht am Viewport-Rand klebt. Bei großen Viewports
   (>= 1485) ist der Wrapper bereits zentriert und der Inhalt liegt
   bündig mit den Body-Cols (= Grid-Edge, kein Inner-Padding nötig). */
@media (max-width: 1484px) {
    .m-footer-bar-inner {
        padding-left: 1.5rem;
        padding-right: 1.5rem;
    }
}
.m-footer-bar-inner > * + * {
    margin-top: 0.5rem;
}

/* ─────────────────────────────────────────────────────────────────────
 * Vertikaler-Abstand-Override für .m-bg-col
 *
 * Quelle ist das Feld „Vertikaler Abstand" im Box-Grid-Modul selbst
 * (REX_VALUE 10, Stufen kompakt/minimal/keiner) — NICHT die Padding-
 * Auswahl der Seitenkonfiguration: mod_box_grid ist ein Full-Bleed-
 * Modul, rendert seine `<section>` selbst mit `py-0` und ignoriert das
 * Section-Padding konstruktiv. Der sichtbare vertikale Abstand einer
 * Box-Grid-Sektion entsteht allein aus dem `.m-bg-col`-Padding oben in
 * dieser Datei; nur dort kann er sinnvoll verkleinert werden.
 *
 * Mechanik: Das Modul setzt pro Spalte NUR den Stufenfaktor als
 * Inline-Style (`--m-col-scale`: 0.5 kompakt, 0.25 minimal, 0 keiner).
 * Die Regeln stehen nicht hier, sondern direkt an den Default-Werten
 * oben in dieser Datei (`.m-bg-col`, `.m-bg-col--card`) — jeder
 * vertikale Wert ist dort als `calc(var(--m-col-scale, 1) * <default>)`
 * geschrieben. Ohne Auswahl fehlt die Variable, der Fallback 1 liefert
 * exakt die bisherigen Werte.
 *
 * Warum kein eigener Override-Block (bis 2026-08-07 stand hier einer mit
 * `--m-col-py`): Ein zweiter, spezifischerer Selektor kann
 * `.m-bg-col--card` nicht schlagen, weil dessen Padding `!important`
 * trägt. Die Stufe blieb deshalb bei Kachel-Spalten wirkungslos — genau
 * dort, wo Redakteure sie erwarten. Steckt der Faktor dagegen IM Wert,
 * wirkt er auch unter `!important`: Abstand über dem Icon (Padding) und
 * zwischen Icon und Text (`gap`) skalieren mit.
 * ───────────────────────────────────────────────────────────────────── */

/* === Utility · Kappenhöhen-Trimmung (optischer Textschnitt) ==============
 *
 * Ein Entwurfswerkzeug wie Figma schneidet jede Textebene auf die Kappenhöhe
 * zu — oben endet die Box an der Oberkante der Großbuchstaben, unten an der
 * Grundlinie. Ein Browser tut das nicht: Er reserviert die volle Inhaltsfläche
 * der Schrift plus das halbe Leading darüber und darunter. Jede Textbox rendert
 * dadurch höher als im Entwurf, und der Unterschied summiert sich über eine
 * Sektion. Gemeldet aus HGK-Events (14.08.2026), dort an drei Stellen gefunden.
 *
 * Die Rechnung dahinter, in Geviert-Anteilen (em):
 *
 *   halbes Leading = (Zeilenhöhe − Inhaltsfläche) / 2
 *   oben  = halbes Leading + (Oberlänge − Kappenhöhe)
 *   unten = halbes Leading + Unterlänge
 *
 * Gegenprobe mit Roboto (2048 Einheiten/Geviert: Oberlänge 1900, Unterlänge
 * 500, Kappenhöhe 1456) bei 24 px und 120 % Zeilenhöhe:
 *   halbes Leading = (1,2 − 1,17188)/2 = 0,01406
 *   oben  = 0,01406 + (0,92773 − 0,71094) = 0,23085 em → 5,54 px
 *   unten = 0,01406 + 0,24414            = 0,25820 em → 6,20 px
 *   zusammen 11,74 px — die Größenordnung, die im Bericht steht.
 *
 * ZWEI STUFEN, absichtlich getrennt durch @supports:
 *
 * 1. `text-box-trim` — der Browser nimmt die Metriken der TATSÄCHLICH
 *    gerenderten Schrift. Chrome/Edge ab 133, Safari ab 18.2; Firefox kennt es
 *    bislang nicht und zeigt dort schlicht den bisherigen Stand.
 * 2. Ersatzrechnung über negative Aussenabstände — nur wo Stufe 1 fehlt, sonst
 *    würde zweimal getrimmt.
 *
 * DIE ZAHLEN SIND SCHRIFTGEBUNDEN. Die Werte oben gehören Roboto; Segoe UI,
 * San Francisco und jede andere Schrift haben andere. `--font-sans` ist in
 * dieser Foundation ein System-Stack — welche Schrift rendert, weiß man dann
 * nicht einmal sicher. Deshalb steht der Schalter `--font-trim` auf 0 und die
 * Ersatzrechnung wirkt NICHT, solange eine Site ihre Metriken nicht setzt.
 * Kein Trimmen ist besser als falsches Trimmen; Stufe 1 arbeitet unabhängig
 * davon, weil sie die Metriken selbst kennt.
 *
 * Eine Site mit fest eingebundener Webfont setzt einmal:
 *
 *   :root {
 *     --font-trim: 1;
 *     --font-asc:  0.92773;   Oberlänge  / Einheiten je Geviert
 *     --font-desc: 0.24414;   Unterlänge / Einheiten je Geviert
 *     --font-cap:  0.71094;   Kappenhöhe / Einheiten je Geviert
 *   }
 *
 * `--font-content` (die Inhaltsfläche) ergibt sich daraus und muss nur gesetzt
 * werden, wenn der Browser eine andere Höhe reserviert als Oberlänge plus
 * Unterlänge — das kommt bei Schriften vor, deren hhea- und OS/2-Tabellen
 * auseinanderlaufen. Im Zweifel die gerenderte Zeilenbox messen.
 *
 * `--lh` ist die Zeilenhöhe des Elements ALS ZAHL. CSS kann `line-height`
 * nicht zurückrechnen, deshalb muss sie mitgegeben werden — wer
 * `line-height: 1.2` setzt, setzt `--lh: 1.2` daneben. Ohne Angabe gilt 1.2.
 *
 * ZWEI FALLEN, beide aus dem Bericht und beide nur Stufe 2 betreffend:
 *   - In Flex- und Grid-Containern schlägt `gap` die negativen Abstände; dort
 *     hilft nur, den Abstand selbst zu verkleinern.
 *   - An Tabellenzellen und Inline-Elementen wirken sie gar nicht. Dort führt
 *     allein die Zeilenhöhe zum Ziel, was bei mehrzeiligem Text überlappt.
 * Stufe 1 hat beide Einschränkungen nicht.
 * ───────────────────────────────────────────────────────────────────────── */
:root {
    --font-trim: 0;
    --font-asc: 0;
    --font-desc: 0;
    --font-cap: 0;
}

.m-text-trim {
    text-box-trim: trim-both;
    text-box-edge: cap alphabetic;
}

@supports not (text-box-trim: trim-both) {
    .m-text-trim {
        /* Die Inhaltsfläche wird HIER gebildet, nicht im :root. Eine dort
         * abgeleitete Custom Property wird auch dort aufgelöst — mit den
         * :root-Werten, also mit 0; ein Element, das seine Metriken selbst
         * setzt, ändert daran nichts mehr. Gemessen kamen so -19,60 px statt
         * -5,54 px heraus. `--font-content` bleibt als Überschreibung möglich,
         * darf dafür aber nicht im :root vorbelegt sein. */
        --_inhalt: var(--font-content, calc(var(--font-asc) + var(--font-desc)));
        --_halbes-leading: calc((var(--lh, 1.2) - var(--_inhalt)) / 2);
        margin-block-start: calc(
            var(--font-trim) * -1em *
            (var(--_halbes-leading) + var(--font-asc) - var(--font-cap))
        );
        margin-block-end: calc(
            var(--font-trim) * -1em *
            (var(--_halbes-leading) + var(--font-desc))
        );
    }
}

/* Nur oben oder nur unten schneiden — etwa für eine Überschrift, die bündig
 * am oberen Rand einer Karte sitzen soll, unten aber ihren Abstand behält. */
.m-text-trim--start { text-box-trim: trim-start; text-box-edge: cap alphabetic; }
.m-text-trim--end   { text-box-trim: trim-end;   text-box-edge: cap alphabetic; }

@supports not (text-box-trim: trim-both) {
    .m-text-trim--start {
        /* Die Inhaltsfläche wird HIER gebildet, nicht im :root. Eine dort
         * abgeleitete Custom Property wird auch dort aufgelöst — mit den
         * :root-Werten, also mit 0; ein Element, das seine Metriken selbst
         * setzt, ändert daran nichts mehr. Gemessen kamen so -19,60 px statt
         * -5,54 px heraus. `--font-content` bleibt als Überschreibung möglich,
         * darf dafür aber nicht im :root vorbelegt sein. */
        --_inhalt: var(--font-content, calc(var(--font-asc) + var(--font-desc)));
        --_halbes-leading: calc((var(--lh, 1.2) - var(--_inhalt)) / 2);
        margin-block-start: calc(
            var(--font-trim) * -1em *
            (var(--_halbes-leading) + var(--font-asc) - var(--font-cap))
        );
    }
    .m-text-trim--end {
        /* Die Inhaltsfläche wird HIER gebildet, nicht im :root. Eine dort
         * abgeleitete Custom Property wird auch dort aufgelöst — mit den
         * :root-Werten, also mit 0; ein Element, das seine Metriken selbst
         * setzt, ändert daran nichts mehr. Gemessen kamen so -19,60 px statt
         * -5,54 px heraus. `--font-content` bleibt als Überschreibung möglich,
         * darf dafür aber nicht im :root vorbelegt sein. */
        --_inhalt: var(--font-content, calc(var(--font-asc) + var(--font-desc)));
        --_halbes-leading: calc((var(--lh, 1.2) - var(--_inhalt)) / 2);
        margin-block-end: calc(
            var(--font-trim) * -1em *
            (var(--_halbes-leading) + var(--font-desc))
        );
    }
}
/* ═══════════════════════════════════════════════════════════════════════════
 * SCHUTZEBENE — fängt Schäden auf, die im Editor entstehen
 * ═══════════════════════════════════════════════════════════════════════════
 *
 * Die erste Layoutebene ist das Markup im Slice. Über die hat die Foundation
 * keine Kontrolle: Es entsteht im Editor, und der schreibt es beim Speichern um.
 * Jede Reparatur dort hält bis zum nächsten Speichern.
 *
 * Diese Ebene greift unabhängig vom Markup und überlebt jeden Editorlauf.
 * Sie ist ein Netz, kein Gestaltungsmittel: Jede Regel hier darf NUR den
 * Fehlerfall fassen und muss von einer Site überschreibbar bleiben.
 */

/* ─── Icons, denen die Größenangabe abhanden kam ──────────────────────────
 *
 * Regel:              Ein <img> auf eine Datei unterhalb eines `/icons/`-Ordners,
 *                     das KEIN `width`-Attribut trägt, wird auf 2em begrenzt.
 * Gilt für:           Inhalte aus dem Editor (Slices). Module und Templates
 *                     geben keine solchen Bilder aus — flottenweit gemessen am
 *                     17.09.2026: 0 Treffer.
 * Verstöße führen zu: einer Sektion, die ihre Höhe vervierfacht. Auf
 *                     frauennotruf.msm.de am 16.09.2026 gemessen: Ein Icon
 *                     rendete 729 × 689 px statt 28 × 28, die Kontakt-Sektion
 *                     wuchs von 335 px auf 1515 px.
 * Verifizierung:      `php bin/test_schutzebene.php`.
 *
 * URSACHE, nicht Symptom: Die Icon-SVG tragen nur eine `viewBox`, keine eigene
 * Breite. Ein <img> darauf ohne `width` hat damit KEINE Eigengröße und füllt
 * den Container. Der Editor entfernt beim Umschreiben genau dieses Attribut.
 *
 * WARUM AM ABLAGEORT UND NICHT AM DATEITYP: „SVG ohne Eigengröße" ist kein
 * Fehler — es ist auf bcl und prolahn Absicht. Dort füllen `m-steuerrad.svg`
 * und `logo.svg` ihre Box genau deshalb. Beide liegen unter `assets/img/`,
 * während frauennotrufs 20 größenlose Icons unter `assets/site/icons/` liegen.
 * Der Ordner trennt die beiden Fälle, der Dateityp nicht. Gemessen über drei
 * Auftritte am 17.09.2026.
 *
 * WARUM 2em: Ein Icon in einer Textzeile darf die Zeile nicht sprengen. 2em
 * sind bei den Wurzelschriftgrößen der Leiter (12 px bis 18 px) zwischen
 * 24 px und 36 px und umschließen damit die 28 px, die frauennotruf site-weit
 * an 74 Inhalts-Icons gesetzt hat. Der Wert wächst mit der Leiter, wie jedes
 * andere Maß der Foundation.
 *
 * WARUM :where() — das ist der Vertrag mit den Sites: Die Regel trägt damit die
 * Spezifität (0,0,1), also die eines bloßen Typselektors. JEDE Site-Regel mit
 * einer Klasse schlägt sie. Das ist gewollt: Eine ausdrückliche Angabe der
 * Site ist Absicht, und Absicht gewinnt. Das Netz fängt die ABWESENHEIT von
 * Absicht (siehe .claude/rules/css-spezifitaet-ist-ein-vertrag.md).
 *
 * Bilder MIT `width` fasst die Regel nie an — `:not([width])` schließt jede
 * bewusst gesetzte Größe aus.
 */
img:where([src*="/icons/"]):where(:not([width])) {
    max-width: 2em;
    max-height: 2em;
    width: auto;
    height: auto;
}
