/*
 * NETZLICHT WP - globale Styles (Schicht 2 des Schichtenmodells).
 *
 * Schichten, in Kaskaden-Reihenfolge:
 *   1. theme.json      Vorgaben (Farben, Schriften, Größen, Abstände, Radien,
 *                      Schatten, Breiten) als --wp--preset--* und --wp--custom--*,
 *                      dazu Schrift, Farbe und Abstände von body, h1-h4 und
 *                      Links. WordPress gibt das als globale Styles aus
 *   2. base.css        diese Datei: Reset, Typografie, Layout, gemeinsame
 *                      Komponenten, Seitenrahmen
 *   3. Block-CSS       blockstudio/sections/<block>/style.css, nur Blockeigenes.
 *                      Blockstudio schreibt es NACH allen Theme-Stylesheets in den
 *                      <head>, es gewinnt bei gleicher Spezifität
 *   4. Fork site.css   assets/css/site.css, nur in Forks; steht hinter dem
 *                      Block-CSS (Filter blockstudio/render/head) und gewinnt bei
 *                      gleicher Spezifität, kein !important
 *
 * Regel: jede Regel steht an genau einer Stelle. Was zwei oder mehr Blöcke
 * brauchen, gehört hierher (Abschnitte 3 und 4), was nur einer braucht, ins
 * Block-CSS. Farben, Radien und Abstände nur über die Variablen aus
 * theme.json; feste Farben nur für Weiß auf dunklen Flächen und für
 * gerechnete Schleier (rgba(var(--wp--custom--veil), a)). Diese Datei deklariert
 * keine eigenen Variablen auf :root (check.sh prüft das).
 * Kein !important ausser den drei dokumentierten Overrides in Abschnitt 7
 * (.visually-hidden, .screen-reader-text, reduced-motion).
 *
 * Herkunft: das CSS der NETZLICHT-Framework-Sites (src/global/base.css), zuerst
 * 1:1 für website-maulhardt-gruppe portiert; Kommentare nennen Maulhardt dort,
 * wo eine Regel dort hergeleitet wurde.
 *
 * Inhaltsverzeichnis (Suche nach "N ·" springt zum Abschnitt):
 *    1 · Reset und Elementbasis  Reset, Umbruch, Medien, html/body, p, a,
 *                                Formularfelder, Tabellen
 *    2 · Typografie-Bausteine    .lead, .kicker, .section-head (+ Scroll-Reveal)
 *    3 · Layout                  .container, .stack, .cluster, .section--*,
 *                                Überlappung, .section--bg, .split, Raster,
 *                                Kartenraster, Utilities
 *    4 · Komponenten             .btn, .card, .feature, .usp-num, .steps, .accordion,
 *                                Hero-Steuerung (Video, Bildwechsel, Pause-Knöpfe),
 *                                Stellen-Tag, Lightbox
 *    5 · Seitenrahmen            Topbar, Header, Navigation, Burger, Drawer, Footer
 *    6 · Inhaltsseiten           Rechtstexte, 404
 *    7 · Barrierefreiheit        .visually-hidden, Skip-Link, .screen-reader-text,
 *                                reduced-motion
 *    8 · WordPress               freie Kernblöcke zwischen Sektionen, Admin-Leiste
 */

/* ═══════════════════════════════════════════════════════════════════════
   1 · RESET UND ELEMENTBASIS
   Nackte Elemente, kaum Klassen (nur die Anti-Quetsch-Helfer). Schriftart,
   Links, Formularfelder und Tabellen.
   ═══════════════════════════════════════════════════════════════════════ */

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

/* ── Anti-Quetsch-Defaults ──
   Verhindern ungewollte Overlaps, Clipping und zu enge Nachbarschaft.
   Spezielle Designs koennen mit eigenen Klassen uebersteuern. */

/* Lange Woerter/URLs brechen statt Container zu sprengen.
   Headings: KEINE Silbentrennung (Typo-Regel — sieht nicht clean aus),
   nur Wort-Breaks bei Extrem-Faellen (URLs). text-wrap:balance fuer
   schoenere Umbrueche auf modernen Browsern. */
h1, h2, h3, h4, h5, h6 {
    overflow-wrap: break-word;
    word-wrap: break-word;
    hyphens: manual;
    -webkit-hyphens: manual;
    text-wrap: balance;
}
p, li, dd, dt, figcaption {
    overflow-wrap: break-word;
    word-wrap: break-word;
    hyphens: auto;
    -webkit-hyphens: auto;
}
/* Inline-Highlights (mark) brechen sauber ueber Zeilen:
   box-decoration-break: clone wiederholt padding + border pro Zeile,
   sonst kleben die Zeilen oft aneinander. */
mark {
    box-decoration-break: clone;
    -webkit-box-decoration-break: clone;
}

/* Inline-elements innerhalb von Headlines erben die Line-Height und kriegen
   eigene padding-block - verhindert Quetschen wie beim alten "Seit 1934"-Fall. */
h1 > span, h2 > span, h3 > span,
h1 > mark, h2 > mark, h3 > mark {
    line-height: inherit;
    padding-block: 0.05em;
}

/* Bilder/Media sprengen nie den Container */
img, video, iframe, svg, picture, canvas {
    max-width: 100%;
    height: auto;
    display: block;
}

/* Pre/Code scrollen statt ueberlaufen */
pre { overflow-x: auto; }

/* Tabellen: bei Enge scrollen statt rauszuhengen (Wrapper um <table> vorausgesetzt) */
.table-wrap { overflow-x: auto; }

html { font-size: 16px; scroll-behavior: smooth; }

/* Anker-Sprungziele nicht unter den sticky Header schieben.
   .site-header ist position:sticky und ~4.25rem hoch (gescrollt ~3rem) —
   ohne scroll-margin landet jeder #anchor-Sprung teilweise dahinter, das
   Sprungziel ist dann angeschnitten oder ganz verdeckt. Betrifft jede Seite
   mit Sprunglinks (Startseite "Leistungen ansehen", Lager-Zweiwege-Block,
   AGB-Inhaltsverzeichnis). 5.5rem deckt den ungescrollten Header plus Luft. */
:where(h1, h2, h3, section, li)[id] { scroll-margin-top: 5.5rem; }

/* Font, size, colour, line height and letter spacing of body, h1-h4 and links
   come from theme.json (styles.typography, styles.elements); only what
   theme.json cannot express stays here. */
body {
    -webkit-font-smoothing: antialiased;
    transition: background-color .2s ease, color .2s ease;
}

p  { margin-bottom: 1rem; }
p:last-child { margin-bottom: 0; }

a { text-underline-offset: 3px; text-decoration-thickness: 1px; text-decoration-color: var(--wp--preset--color--primary); }
a:focus-visible { outline: 2px solid var(--wp--preset--color--primary); outline-offset: 2px; }
@media (hover: hover) and (pointer: fine) {
    a:hover { text-decoration-thickness: 2px; }
}

address { font-style: normal; }

label         { font-size: var(--wp--preset--font-size--sm); font-weight: 500; color: var(--wp--preset--color--contrast); }
input, textarea, select {
    padding:       .75rem 1rem;
    /* border_input #6e7180 (4.3:1 auf Weiss) — WCAG 1.4.11 Non-Text
       Contrast fuer UI-Komponenten; die dekorative Rahmenfarbe
       (--wp--custom--color--border) ist fuer Form-Controls nicht zulaessig. */
    border:        1px solid var(--wp--custom--color--field-border);
    border-radius: var(--wp--preset--border-radius--md);
    font-size:     var(--wp--preset--font-size--base);
    font-family:   inherit;
    width:         100%;
    background:    var(--wp--custom--color--surface);
    color:         var(--wp--preset--color--contrast);
}
input:focus-visible,
textarea:focus-visible,
select:focus-visible { outline: 2px solid var(--wp--preset--color--primary); outline-offset: 2px; border-color: transparent; }
textarea { resize: vertical; min-height: 8rem; }

/* ── Tabellen (kantig-technisch: nur horizontale 1px-Linien) ──
   th klein/uppercase/tracking wie die Kicker-Labels, Zeilen-Hover
   bg-soft. Auf Mobile in .table-wrap einschlagen (scrollt statt
   Container zu sprengen, Regel oben bei den Anti-Quetsch-Defaults). */
table {
    width: 100%;
    border-collapse: collapse;
    text-align: left;
    font-size: 1rem;
}
th, td {
    padding: 0.75rem 1rem;
    border-bottom: 1px solid var(--wp--custom--color--border);
    vertical-align: top;
}
thead th {
    font-family: var(--wp--preset--font-family--heading);
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--wp--preset--color--muted);
    /* Kopfkante kraeftiger als die Zeilenlinien (bleibt 1px horizontal) */
    border-bottom-color: var(--wp--custom--color--field-border);
}
@media (hover: hover) and (pointer: fine) {
    tbody tr:hover { background: var(--wp--preset--color--soft); }
}

/* ═══════════════════════════════════════════════════════════════════════
   2 · TYPOGRAFIE-BAUSTEINE
   .lead, .kicker und der Sektions-Kopf aus beidem (nl_section_head() in inc/blocks.php).
   ═══════════════════════════════════════════════════════════════════════ */

.lead {
    text-wrap: pretty;                 /* Lead-Absaetze pretty-gebrochen */
    font-size: clamp(1.05rem, 1.3vw, 1.25rem);
    line-height: 1.55;
    color: var(--wp--preset--color--muted);
}

/* ── Eyebrow-Kicker (Erkennungszeichen der Site) ──
   Klein, uppercase, weites Tracking, Brand-Rot, kurzer 2rem-Strich
   davor — echtes ::before-Element mit currentColor, kein Overlay-Hack.
   Auf dunklen Sektionen kippt er komplett auf Weiss (Rot auf Navy
   waere fuer kleinen Text kontrastschwach). */
.kicker {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    font-family: var(--wp--preset--font-family--heading);
    font-size: 0.875rem;
    font-weight: 700;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--wp--custom--color--primary-text);
    margin-bottom: var(--wp--preset--spacing--xs);
}
.kicker::before {
    content: '';
    width: 2rem;
    height: 3px;
    background: currentColor;
    flex-shrink: 0;
}
.text-center .kicker { justify-content: center; }
.section--dark .kicker,
.section--bg .kicker,
.section--primary .kicker { color: #ffffff; }

/* Sektions-Kopf: kicker + h2 + optional .lead als konsistentes
   Kopf-Pattern fuer Content-Sektionen. */
.section-head {
    max-width: var(--wp--style--global--content-size);
    margin-bottom: var(--wp--preset--spacing--lg);
}
.section-head > :last-child { margin-bottom: 0; }

/* Scroll-Reveal der Sektions-Koepfe (CSS-only, scroll-driven animations).
   Der Default-Zustand ist der ENDzustand (sichtbar) — die Animation blendet
   nur ein. Das ist Pflicht: Firefox unterstuetzt animation-timeline bis
   heute nicht (Chromium 115+, Safari 26+), ein `opacity: 0`-Default wuerde
   die Koepfe dort dauerhaft verstecken. Guard-Muster + Erstanwendung:
   TWZV verband.css (stats-morph), Memory reference_scroll_driven_animations.
   Kicker/H2/Lead laufen leicht versetzt, damit der Kopf als Einheit
   hereinkommt statt als drei Einzelteile. */
@keyframes nl-reveal-up {
    from { opacity: 0; transform: translateY(1.25rem); }
    to   { opacity: 1; transform: translateY(0); }
}
@supports (animation-timeline: view()) {
    @media (prefers-reduced-motion: no-preference) {
        .section-head > .kicker,
        .section-head > h2,
        .section-head > .lead {
            animation: nl-reveal-up linear both;
            animation-timeline: view();
        }
        .section-head > .kicker { animation-range: entry 5%  cover 18%; }
        .section-head > h2      { animation-range: entry 8%  cover 24%; }
        .section-head > .lead   { animation-range: entry 11% cover 30%; }
    }
}

/* ═══════════════════════════════════════════════════════════════════════
   3 · LAYOUT
   Container, Sektionsflaechen (.section--*), Ueberlappung, Bildsektion, Split, Raster,
   Kartenraster und die Utility-Klassen. Block-Layouts, die nur ein Block braucht,
   stehen im Block-CSS.
   ═══════════════════════════════════════════════════════════════════════ */

/* ── Container ── */
.container {
    max-width:     var(--wp--style--global--wide-size);
    margin:        0 auto;
    padding-left:  var(--wp--custom--gutter);
    padding-right: var(--wp--custom--gutter);
}
.container--mid   { max-width: var(--wp--custom--width--mid); }
.container--text  { max-width: var(--wp--style--global--content-size); }
.container--full  { max-width: 100%; padding: 0; }

/* ── Stack und Cluster ──
   .stack: Inhalt untereinander mit gleichmaessigem Abstand (Textspalten,
   Medienspalten). .cluster: nebeneinander mit Umbruch (Buttonreihen). */
.stack   { display: flex; flex-direction: column; gap: var(--wp--preset--spacing--md); }
.cluster { display: flex; flex-wrap: wrap; gap: var(--wp--preset--spacing--sm); align-items: center; }

/* ── Section (responsive Padding via clamp) ── */
.section              { padding: var(--wp--preset--spacing--2-xl) 0; }
.section--tight       { padding: var(--wp--preset--spacing--xl) 0; }
.section--spacious    { padding: var(--wp--preset--spacing--4-xl) 0; }
.section--alt         { background: var(--wp--preset--color--soft); }
/* Dunkle Sektionen wie alte Site: Fläche dunkel (Palette dark) als Standard,
   .section--dark--anthrazit als zweiter Ton. Headlines dort WEISS
   (Original-Pattern; Brand-Rot auf Navy waere kontrastschwach). */
.section--dark        { background: var(--wp--preset--color--dark); color: var(--wp--custom--color--on-dark); }
.section--dark--anthrazit { background: var(--wp--preset--color--dark-alt); }
/* Flaeche warm: helle Flaeche wie .section--alt, Text normal (kein Kontrastwechsel). */
.section--sand        { background: var(--wp--preset--color--warm); color: var(--wp--preset--color--contrast); }
.section--dark .lead  { color: rgba(255,255,255,.8); }
.section--dark h1,
.section--dark h2,
.section--dark h3     { color: var(--wp--custom--color--on-dark); }
/* Links auf Navy: global gilt die Linkfarbe aus theme.json (contrast) = #000000 und
   damit 1.05:1 auf #010032 — praktisch unsichtbar. Gegenstueck zum
   .section--primary-Block unten: auf #ffffff kippen (20.05:1). */
.section--dark a:not(.btn) {
    color: var(--wp--custom--color--on-dark);
    text-decoration-color: rgba(255, 255, 255, 0.6);
}
.section--dark a:not(.btn):focus-visible { outline-color: var(--wp--custom--color--on-dark); }

/* Rote Vollflaechen-Sektion — das kraeftige Marken-Statement (die alte
   Kadence-Site hatte solche Farbfelder). Weiss auf #e61d21 = 4.6:1 (AA).
   WICHTIG: KEINE rgba-Abschwaechung fuer Fliesstext auf Rot — schon
   rgba(255,255,255,.9) faellt unter 4.5:1. Alles voll weiss. */
.section--primary        { background: var(--wp--preset--color--primary); color: #ffffff; }
.section--primary h1,
.section--primary h2,
.section--primary h3     { color: #ffffff; }
.section--primary .lead  { color: #ffffff; }
.section--primary a:not(.btn) {
    color: #ffffff;
    text-decoration-color: rgba(255, 255, 255, 0.6);
}
.section--primary a:not(.btn):focus-visible,
.section--primary .btn:focus-visible { outline-color: #ffffff; }
/* Roter Button verschwindet auf Rot → Invert-Variante: weiss mit rotem
   Text (4.6:1). Hover kippt auf Navy wie der Original-Button-Hover. */
.section--primary .btn-primary {
    background: #ffffff;
    border-color: #ffffff;
    color: var(--wp--preset--color--primary);
}
@media (hover: hover) and (pointer: fine) {
    .section--primary .btn-primary:hover {
        background: var(--wp--preset--color--dark);
        border-color: var(--wp--preset--color--dark);
        color: var(--wp--custom--color--on-dark);
    }
}

/* ── Overlap-Layouts (Layer-Pattern) ──
   Element ragt aus der eigenen Sektion nach OBEN in die vorige dunkle
   Hero-/Farb-Sektion: echtes DOM-Element, position:relative malt es
   ueber den BG der vorigen Sektion (kein ::before-z-index-Deko-Hack).
   Voraussetzungen: die eigene Sektion braucht genug padding-top
   (Standard-.section reicht); die Sektion darueber endet bei Bedarf
   mit .section--flush-bottom. Einsatz als erstes Kind des .container:
   nachfolgende Inhalte ruecken mit nach oben. */
.pull-up        { position: relative; margin-top: calc(-1 * var(--wp--preset--spacing--3-xl)); }
.pull-up--deep  { position: relative; margin-top: calc(-1 * var(--wp--preset--spacing--4-xl)); }
.section--flush-bottom { padding-bottom: 0; }

/* ── Background-Image-Section (Hero mit Parallax + Overlay) ── */
/* Usage: <section class="section section--bg" style="--bg:url(/img/pages/xyz.webp)">
   Desktop: background-attachment fixed fuer Parallax-Effekt.
   Mobile: scroll (iOS-Fix — fixed funktioniert dort nicht).
   prefers-reduced-motion wird respektiert (kein Parallax). */
.section--bg {
    position: relative;
    background-image: var(--bg);
    background-size: cover;
    background-position: center;
    background-repeat: no-repeat;
    color: #ffffff;
    /* Background color under the photo: white text needs a defined background
       (WCAG F24), also while the image loads or when it fails. Checkers
       ignore the ::before overlay and measured 1:1 against white. */
    background-color: var(--wp--preset--color--dark-alt);
    padding: clamp(5rem, 10vw, 9rem) 0;
    overflow: hidden;
    isolation: isolate;
}
.section--bg::before {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, rgba(0,0,0,.55) 0%, rgba(0,0,0,.65) 100%);
    z-index: -1;
}
.section--bg .container { position: relative; z-index: 1; }
.section--bg h1, .section--bg h2, .section--bg h3 { color: #ffffff; }
/* Lead in reinem Weiss: auf hellen Fotos faellt rgba(255,255,255,.9) hinter dem
   Schleier auf 4,56:1, genau an die AA-Kante (gemessen am Unternehmensgruppe-
   Hero); reines Weiss gibt 5,20:1. Gilt fuer jeden Seitenkopf mit Foto, weil
   der Kunde Fotos tauscht, ohne neu zu messen. */
.section--bg .lead { color: #ffffff; }
@media (min-width: 1025px) and (prefers-reduced-motion: no-preference) {
    .section--bg { background-attachment: fixed; }
}

/* ── Split-Image: Text + Bild nebeneinander ── */
.split {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: clamp(2rem, 5vw, 4rem);
    align-items: center;
}
.split--reverse .split__media { order: 2; }
.split__text  { min-width: 0; }
.split__media { min-width: 0; }
.split__media img {
    width: 100%;
    height: auto;
    display: block;
}
@media (max-width: 820px) {
    .split { grid-template-columns: 1fr; }
    .split--reverse .split__media { order: 0; }
}

/* ── Grid-Utilities fuer Produkt-/Feature-Raster ── */
/* Gap auf der Abstandsskala aus theme.json statt fixer 1.5rem: im 1600er-Container werden
   .grid-2-Karten fast 800px breit — 24px Luft dazwischen liessen sie
   aneinanderkleben. clamp gibt auf grossen Viewports 2.5rem, auf kleinen
   bleibt es kompakt. */
.grid-auto-fit {
    display: grid;
    gap: var(--wp--preset--spacing--lg);
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
}
.grid-2 { display: grid; gap: var(--wp--preset--spacing--lg); grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid-3 { display: grid; gap: var(--wp--preset--spacing--lg); grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grid-4 { display: grid; gap: var(--wp--preset--spacing--lg); grid-template-columns: repeat(4, minmax(0, 1fr)); }
.grid-6 { display: grid; gap: var(--wp--preset--spacing--lg); grid-template-columns: repeat(6, minmax(0, 1fr)); }
@media (max-width: 1200px) {
    .grid-6 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
    .grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 720px) {
    .grid-auto-fit, .grid-2, .grid-3, .grid-4, .grid-6 {
        grid-template-columns: 1fr;
    }
}

/* Safety-Gap zwischen benachbarten Bloecken im Container:
   Verhindert, dass handgeschriebene Pages Nachbarn ohne Luft setzen.
   .card, .feature usw. haben ihren Gap ueber Grid/Flex — hier greift es
   nur wenn gar keine Klasse/Kontext Abstand vorgibt. */
main .container > * + :where(h2, h3, section, div, ul, ol, p, figure) {
    margin-top: 1rem;
}
main .container > * + h2 { margin-top: 3rem; }
main .container > h2 + *,
main .container > p.lead + * { margin-top: 2rem; }

/* ── Utility-Klassen (framework-weit, site-uebergreifend) ──
   Minimales Set, um die haeufigsten Inline-Styles zu ersetzen.
   Konvention: .u-* oder kurze semantische Namen. */

/* Text-Ausrichtung */
.text-center    { text-align: center; }
.text-muted     { color: var(--wp--preset--color--muted); }

/* Margin-Top Rhythmus (clamp-respektierend — Mobile enger) */
/* Spacing-Utilities auf der Abstandsskala aus theme.json. Vorher Fixwerte (1 / 2 / 2.5rem):
   die skalierten nicht mit der Viewport-Breite und lagen so dicht
   beieinander, dass mt-2 -> mt-3 nur 0.5rem Unterschied machte — zu wenig,
   um "gequetscht" von "luftig" zu trennen. Jetzt clamp-basiert und mit
   mt-4 als grosszuegiger Stufe (z.B. Logo-Strip -> Button). */
.mt-1           { margin-top: var(--wp--preset--spacing--md); }
.mt-2           { margin-top: var(--wp--preset--spacing--lg); }
.mt-3           { margin-top: var(--wp--preset--spacing--xl); }

/* Breiten-Limits fuer Text im wide Container */
.max-w-text     { max-width: var(--wp--style--global--content-size); }
.max-w-mid      { max-width: var(--wp--custom--width--mid); }

/* Meta-Text (klein, muted) — fuer Ort/Jahr, Unterzeilen, Sublabels */
.meta           { color: var(--wp--preset--color--muted); font-size: var(--wp--preset--font-size--sm); }

/* Prose-Listen (Bulletlisten mit komfortabler Line-Height) */
.prose-list {
    list-style: disc;
    padding-left: 1.5rem;
    line-height: 1.8;
    max-width: var(--wp--style--global--content-size);
}
.prose-list li { margin-bottom: 0.25rem; }

/* ── Card-Grids (verschiedene Kartengroessen) ──
   Spaltenzahl ist nach oben gedeckelt (--card-grid-max, Default 3).
   Grund: auto-fit mit reinem Pixel-Floor rechnet gegen die CONTAINER-Breite,
   und im 1600er-Container (unser Default) passen bei 280px-Floor fuenf Karten
   nebeneinander — die 5 offenen Stellen standen dadurch als gequetschte
   Fuenfer-Reihe. Ab ~4 Karten pro Zeile kippt die Optik.
   Technik: Der Floor ist das MAXIMUM aus Pixel-Floor und "1/n der freien
   Breite". Sobald 1/n groesser wird, koennen rechnerisch nie mehr als n
   Spalten entstehen; darunter greift wieder der Pixel-Floor und auto-fit
   faellt frei auf 2 und 1 Spalte zurueck. Kein Breakpoint noetig.
   Einzelne Grids duerfen bewusst mehr: --card-grid-max am Element setzen. */
.card-grid {
    --card-grid-gap:   2rem;
    --card-grid-floor: 280px;
    --card-grid-max:   3;
    display: grid;
    gap: var(--card-grid-gap);
    grid-template-columns: repeat(auto-fit, minmax(
        max(
            var(--card-grid-floor),
            (100% - (var(--card-grid-max) - 1) * var(--card-grid-gap)) / var(--card-grid-max)
        ), 1fr));
    margin-top: 2.5rem;
}
.card-grid--sm { --card-grid-floor: 220px; --card-grid-gap: 1.75rem; }
.card-grid--lg { --card-grid-floor: 320px; }

/* CTA-Group (Button-Reihe zentriert) — wie hero-cta fuer sekundaere Stellen */
.cta-group {
    display: flex;
    gap: 1rem;
    flex-wrap: wrap;
    justify-content: center;
    margin-top: 2rem;
}

/* Bild-Container (responsive Bild mit Radius) */
.img-fluid      { width: 100%; height: auto; border-radius: var(--wp--preset--border-radius--md); display: block; }

/* ═══════════════════════════════════════════════════════════════════════
   4 · KOMPONENTEN
   Von mehreren Bloecken geteilt: Buttons, Karten, Features, Kennzahl, Schritte,
   Akkordeon, Hero-Steuerung (Video, Bildwechsel, Pause-Knoepfe), Stellen-Tag, Lightbox.
   ═══════════════════════════════════════════════════════════════════════ */

/* ── Buttons ── */
.btn {
    display:         inline-flex;
    align-items:     center;
    gap:             var(--wp--preset--spacing--2-xs);
    padding:         0.875rem 1.75rem;
    border-radius:   var(--wp--preset--border-radius--button);   /* Pill wie alte Site (40px+) */
    font-weight:     600;
    font-size:       var(--wp--preset--font-size--base);
    text-decoration: none;
    cursor:          pointer;
    border:          2px solid transparent;
    transition:      opacity .15s, transform .08s, background-color .15s, border-color .15s;
    font-family:     var(--wp--preset--font-family--body);
}
.btn:focus-visible { outline: 2px solid var(--wp--preset--color--dark); outline-offset: 2px; }
.btn:active        { transform: translateY(1px); }
@media (hover: hover) and (pointer: fine) {
    .btn:hover { opacity: .92; }
}
.btn-primary {
    background: var(--wp--preset--color--primary);
    color:      var(--wp--custom--color--on-primary);
    border-color: var(--wp--preset--color--primary);
}
.btn-outline {
    background:    transparent;
    border-color:  var(--wp--preset--color--contrast);
    color:         var(--wp--preset--color--contrast);
}
/* Outline-Button auf dunklem Grund (section--bg-Hero, section--dark) —
   genutzt von index.md UND karriere.md, deshalb hier statt page-CSS.
   Hover-Regel steht im Block "Button-Hover" direkt darunter, nach
   .btn-outline:hover, damit sie im Cascade gewinnt. */
.btn-outline--ondark {
    border-color: rgba(255, 255, 255, 0.85);
    color: #ffffff;
}

/* ── Button-Hover ──
   Nur auf Pointer-Geraeten. Reihenfolge ist Kaskade: .btn:hover (oben), dann
   .btn-primary:hover, dann .btn-outline:hover, zuletzt .btn-outline--ondark:hover
   (gleiche Spezifitaet, die letzte gewinnt). */
@media (hover: hover) and (pointer: fine) {
    /* Original-Hover der alten Site: Rot kippt auf Navy */
    .btn-primary:hover {
        background: var(--wp--preset--color--dark);
        border-color: var(--wp--preset--color--dark);
        opacity: 1;
        transform: translateY(-1px);
        box-shadow: var(--wp--preset--shadow--md);
    }
    .btn-outline:hover { background: var(--wp--preset--color--contrast); color: var(--wp--preset--color--base); }
    .btn-outline--ondark:hover {
        background: #ffffff;
        color: var(--wp--preset--color--dark);
        opacity: 1;
    }
}

/* ── Cards (generisch, mit Hover/Focus-States) ──
   Basis-Card: Box mit Padding, Border, Radius.
   Modifier:
     .card--link   → als <a> verwendet, Hover-Lift + Border-Color-Change
     .card--sm     → kleineres Padding (1.75rem)
     .card--highlight → FERO-Gelb BG mit schwarzem Text (CTA-Akzent)
   WCAG: Focus-Visible-Outline, prefers-reduced-motion respektiert, Hover
   nur auf echten Pointer-Geraeten (kein iOS-Sticky-Hover).
   PageSpeed: transform + opacity (GPU), kein Layout-Thrashing. */
/* ── Card (Editorial-Umbau 2026-07) ──
   Der 1px-Rahmen ist RAUS. Ein Rahmen um jede Gruppierung war das alte
   Ordnungsprinzip; bei vier Karten nebeneinander liest sich das wie ein
   Wireframe statt wie eine gefuehrte Seite. Kontur entsteht jetzt durch
   Flaeche, Bild und Typografie (Runbook 5.1).
   Textkarten behalten eine helle Traegerflaeche — auf .section--alt kippt
   sie auf Weiss, sonst waere Grau auf Grau unsichtbar. */
.card {
    padding:       var(--card-pad, 2.5rem);
    background:    var(--wp--preset--color--soft);
    border:        none;
    border-radius: var(--wp--preset--border-radius--md);
    transition:    background-color .18s ease;
}
/* Kontext-Background NUR fuer Traeger-Karten, NICHT fuer .card--highlight:
   die highlight-Karte (roter Vollton) hat mit 1 Klasse weniger Spezifitaet
   als diese 2-Klassen-Regel und wuerde sonst auf .section--alt weiss
   uebermalt -> weisser Text auf weiss unsichtbar (AG-Section 100.000-m²-Box). */
:is(.section--alt, .section--sand) .card:not(.card--highlight),
.section--dark .card:not(.card--highlight) { background: var(--wp--custom--color--surface); }
.card--sm       { --card-pad: 2rem; }
.card h3        { margin-bottom: 0.75rem; }
.card p         { margin-bottom: 1rem; }
.card p:last-child { margin-bottom: 0; }
.card--link {
    display:         block;
    color:           var(--wp--preset--color--contrast);
    text-decoration: none;
}
.card--link h3  { transition: color .18s ease; }

/* Bild-Karten: rein editorial. Kein Padding, keine Flaeche — das Bild
   traegt die Karte, der Text steht offen darunter. Deshalb faellt auch
   der frueher noetige Negativ-Margin-Trick weg (er hob nur das Padding
   auf, das es jetzt nicht mehr gibt). */
.card--media,
:is(.section--alt, .section--sand) .card--media,
.section--dark .card--media {
    padding: 0;
    background: transparent;
}
.card--media > img:first-child {
    width: 100%;
    max-width: none;
    margin: 0 0 var(--wp--preset--spacing--md);
}
/* Hover-Akzent der Bild-Karten: roter Strich waechst unter dem Titel —
   dieselbe Sprache wie die Hauptnavigation. inline-block, damit der
   Strich am Text endet und nicht an der Spaltenkante. */
.card--media.card--link h3 {
    display: inline-block;
    position: relative;
}
.card--media.card--link h3::after {
    content: '';
    position: absolute;
    left: 0; right: 0; bottom: -0.12em;
    height: 2px;
    background: var(--wp--preset--color--primary);
    transform: scaleX(0);
    transform-origin: left;
    transition: transform .22s ease;
}
.card--highlight {
    padding:      var(--card-pad, 2.5rem);
    background:   var(--wp--preset--color--primary);
    color:        var(--wp--custom--color--on-primary);
}
.card--highlight h3,
.card--highlight p { color: var(--wp--custom--color--on-primary); }

.card--link:focus-visible {
    outline:        2px solid var(--wp--preset--color--primary);
    outline-offset: 2px;
}

@media (hover: hover) and (pointer: fine) {
    /* Ohne Rahmen gibt es nichts mehr zum Einfaerben und ohne Flaeche
       nichts zum Anheben — der Hover laeuft jetzt ueber Titel + Strich
       (Bild-Karten) bzw. eine minimal dunklere Flaeche (Textkarten). */
    .card--link:hover h3 { color: var(--wp--custom--color--primary-text); }
    .card--media.card--link:hover h3::after { transform: scaleX(1); }
    .card--link:not(.card--media):not(.card--highlight):hover {
        background: color-mix(in oklab, var(--wp--preset--color--soft) 88%, var(--wp--preset--color--contrast));
    }
    .card--highlight.card--link:hover { opacity: .94; }
    .card--highlight.card--link:hover h3 { color: var(--wp--custom--color--on-primary); }
}

@media (prefers-reduced-motion: reduce) {
    .card, .card--link { transition: none; }
    .card--media.card--link h3::after { transition: none; }
}

/* ── Link-Unterstreichung mit animiertem Akzent ──
   Default: dezent unterstrichen mit Primary-Farbe.
   Hover auf Pointer-Geraeten: dicker. */
main a:not(.btn):not(.card--link):not(.theme-toggle):not(.skip-link):not(.nl-download-card):not(.nl-job-card__link) {
    transition: text-decoration-thickness .12s ease;
}
@media (hover: hover) and (pointer: fine) {
    main a:not(.btn):not(.card--link):not(.theme-toggle):not(.skip-link):not(.nl-download-card):not(.nl-job-card__link):hover {
        text-decoration-thickness: 2px;
    }
}

/* ── Feature (Text-Kachel mit Border-Top-Akzent) ──
   Fuer Vorteil-Grids mit H3 + Text, ohne echte Box-Card. Konsistenter Look
   ueber alle Seiten: gelber 3px-Balken oben, padding-top, rest luftig. */
.feature {
    padding-top: 1rem;
    border-top: 3px solid var(--wp--preset--color--primary);
}
.feature h3    { margin-top: 0; margin-bottom: 0.5rem; }
.feature p     { margin-bottom: 0; }

/* Feature-Grids (Gap + Columns)
   Gleiche Deckelung wie .card-grid (siehe dort): der 220px-Floor liess im
   1600er-Container bis zu sieben Kacheln in eine Zeile — Sektionen mit 5 oder
   6 Features standen als gequetschte Reihe statt in zwei ruhigen Zeilen. */
.feature-grid {
    --feature-grid-gap:   1.75rem;
    --feature-grid-floor: 220px;
    --feature-grid-max:   3;
    display: grid;
    gap: 2rem var(--feature-grid-gap);
    grid-template-columns: repeat(auto-fit, minmax(
        max(
            var(--feature-grid-floor),
            (100% - (var(--feature-grid-max) - 1) * var(--feature-grid-gap)) / var(--feature-grid-max)
        ), 1fr));
    margin-top: 2rem;
}

/* ── Kennzahlen / Big-Numbers ──
   .usp-num  = grosse Zahl im USP-Kontext (Startseite) */
.usp-num {
    font-family: var(--wp--preset--font-family--heading);
    font-weight: 900;
    /* Zaehler-Aesthetik: gleichbreite Ziffern, Zahlen stehen exakt untereinander */
    font-variant-numeric: tabular-nums;
    color: var(--wp--preset--color--dark);
    line-height: 1;
    margin-bottom: var(--wp--preset--spacing--2-xs);
    letter-spacing: -0.02em;
    font-size: clamp(2.25rem, 3.5vw, 3rem);
}

/* ── Prozess-Schritte (ol mit grossen Zaehler-Ziffern) ──
   Markup: <ol class="steps"><li><h3>Titel</h3><p>Text</p></li>…</ol>
   Grosse 900er-Ziffer ("01", "02", …) in Brand-Rot mit duenner
   Border-Box drum, Titel + Text darunter. Auto-Grid: traegt 3er- wie
   5er-Strecken. Rot ist hier large text (>=3:1 auf bg + bg-soft ok). */
.steps {
    list-style: none;
    counter-reset: steps;
    display: grid;
    gap: var(--wp--preset--spacing--lg) var(--wp--preset--spacing--md);
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 220px), 1fr));
    padding: 0;
    margin: 0;
}
.steps > li { counter-increment: steps; }
.steps > li::before {
    content: counter(steps, decimal-leading-zero);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 3.25rem;
    height: 3.25rem;
    padding: 0 0.6rem;
    border: 1px solid var(--wp--custom--color--field-border);
    font-family: var(--wp--preset--font-family--heading);
    font-size: 1.6rem;
    font-weight: 900;
    font-variant-numeric: tabular-nums;
    line-height: 1;
    color: var(--wp--preset--color--primary);
    margin-bottom: var(--wp--preset--spacing--sm);
}
.steps > li h3 { font-size: 1.2rem; margin-bottom: 0.5rem; }
.steps > li p  { margin-bottom: 0; }
/* Auf dunklen Sektionen: Box-Kante rgba-weiss, Ziffer bleibt rot (>=3:1 auf Navy) */
.section--dark .steps > li::before { border-color: rgba(255, 255, 255, 0.4); }

/* ── Akkordeon (native details/summary, fuer FAQ-Sektionen) ──
   Markup: <div class="accordion"><details><summary>Frage</summary>
   <div class="accordion__body"><p>Antwort</p></div></details>…</div>
   Kantig: 1px Rahmen, Eintraege nur durch horizontale Linien getrennt.
   Plus/Minus-Indikator rein per CSS: zwei Striche in Brand-Rot, der
   vertikale dreht bei [open] auf horizontal (Minus). Fokus-Ring mit
   NEGATIVEM offset, damit er innerhalb des 1px-Rahmens liegt und
   nirgends abgeschnitten wird. */
.accordion {
    border: 1px solid var(--wp--custom--color--border);
}
.accordion > details + details {
    border-top: 1px solid var(--wp--custom--color--border);
}
.accordion summary {
    position: relative;
    display: block;              /* entfernt das native Dreieck */
    list-style: none;
    padding: var(--wp--preset--spacing--md);
    padding-right: calc(var(--wp--preset--spacing--md) + 2.25rem);
    font-family: var(--wp--preset--font-family--heading);
    font-weight: 700;
    cursor: pointer;
    transition: background-color .15s ease;
}
.accordion summary::-webkit-details-marker { display: none; }
.accordion summary::before,
.accordion summary::after {
    content: '';
    position: absolute;
    top: 50%;
    right: var(--wp--preset--spacing--md);
    width: 1rem;
    height: 3px;
    background: var(--wp--preset--color--primary);
    translate: 0 -50%;
    transition: rotate .2s ease;
}
.accordion summary::after { rotate: 90deg; }
.accordion details[open] summary::after { rotate: 0deg; }
.accordion details[open] summary { border-bottom: 1px solid var(--wp--custom--color--border); }
.accordion summary:focus-visible {
    outline: 2px solid var(--wp--preset--color--primary);
    outline-offset: -2px;
}
@media (hover: hover) and (pointer: fine) {
    .accordion summary:hover { background: var(--wp--preset--color--soft); }
}
.accordion__body {
    padding: var(--wp--preset--spacing--md);
    max-width: var(--wp--style--global--content-size);
}
.accordion__body > :last-child { margin-bottom: 0; }
/* Dunkle Variante fuer section--dark: Kanten rgba-weiss, Indikator
   bleibt rot (UI-Grafik >=3:1 auf Navy ok), Hover hellt minimal auf. */
.accordion--ondark,
.accordion--ondark > details + details { border-color: rgba(255, 255, 255, 0.25); }
.accordion--ondark details[open] summary { border-bottom-color: rgba(255, 255, 255, 0.25); }
.accordion--ondark summary:focus-visible { outline-color: #ffffff; }
@media (hover: hover) and (pointer: fine) {
    .accordion--ondark summary:hover { background: rgba(255, 255, 255, 0.08); }
}

/* ── Hero (Utility) ── */
.hero        { padding: clamp(4rem, 8vw, 7rem) 0 clamp(3rem, 6vw, 5rem); text-align: center; }
.hero h1     { margin-bottom: 1.5rem; }
.hero .lead  { margin-bottom: 2rem; max-width: 54ch; margin-left: auto; margin-right: auto; }

/* ── Hero-Steuerung: Bildwechsel, Hintergrundvideo, Pause-Knoepfe (WCAG 2.2.2) ──
   Stage of the cross-fading slideshow, background video stage and the pause
   toggle of both, shared by nl/hero and nl/hero-bildwechsel (markup:
   nl_slideshow(), nl_hero_video(), inc/blocks.php; logic: init.js sections 2
   and 3; keyframes are generated per image count in nl_slideshow()). The
   toggle sits bottom right of its stage; --hero-toggle-inset overrides the
   distance per block. Icon pair CSS-only (no inline SVG): pause = two bars,
   play = triangle, switched by aria-pressed. */
/* Slideshow stage. Image 1 is static until the rotation starts (LCP candidate);
   scale(1.08) is the start value of the Ken Burns curve, so the switch to
   .is-ready stays jump-free. The rotation runs only with .is-ready (init.js);
   animation-delay -1.2s lets image 1 (--i:0) enter at the opacity:1 keyframe
   instead of 0%, otherwise the visible image blinks away and Chrome drops the
   LCP candidate (FERO 2026-07-09, measured 9-16s instead of ~2s). Even slides
   zoom IN instead of out. The pause toggle freezes both animations; with
   reduced motion image 1 stays static (init.js then sets no .is-ready and
   does not load slides 2+). */
.hero-slides__stage { position: absolute; inset: 0; overflow: hidden; }
.hero-slides__img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    opacity: 0;
    will-change: opacity, transform;
}
.hero-slides__stage:not(.is-ready) .hero-slides__img:first-child { opacity: 1; transform: scale(1.08); }
.hero-slides__stage.is-paused .hero-slides__img { animation-play-state: paused; }
@media (prefers-reduced-motion: reduce) {
    .hero-slides__img { animation: none; }
    .hero-slides__img:first-child { opacity: 1; transform: none; }
}
.hero-video { position: absolute; inset: 0; overflow: hidden; background: var(--wp--preset--color--dark); }
.hero-video__poster,
.hero-video__el { width: 100%; height: 100%; object-fit: cover; display: block; }
.hero-video__poster { position: absolute; inset: 0; }
.hero-video__el { position: relative; }
.hero-slides__toggle,
.hero-video__toggle {
    position: absolute;
    right: var(--hero-toggle-inset, var(--wp--preset--spacing--lg));
    bottom: var(--hero-toggle-inset, var(--wp--preset--spacing--lg));
    width: 2.75rem;
    height: 2.75rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1px solid rgba(255, 255, 255, 0.6);
    border-radius: var(--wp--preset--border-radius--button);
    background: rgba(var(--wp--custom--veil), 0.45);
    color: #ffffff;
    cursor: pointer;
    transition: background-color .15s ease, border-color .15s ease;
}
.hero-slides__toggle[hidden],
.hero-video__toggle[hidden] { display: none; }
.hero-slides__toggle:focus-visible,
.hero-video__toggle:focus-visible { outline: 2px solid #ffffff; outline-offset: 2px; }
@media (hover: hover) and (pointer: fine) {
    .hero-slides__toggle:hover,
    .hero-video__toggle:hover { background: rgba(var(--wp--custom--veil), 0.75); border-color: #ffffff; }
}
.hero-slides__toggle .icon-pause,
.hero-video__toggle .icon-pause { width: 12px; height: 14px; border-left: 4px solid currentColor; border-right: 4px solid currentColor; }
.hero-slides__toggle .icon-play,
.hero-video__toggle .icon-play { display: none; width: 0; height: 0; border-block: 7px solid transparent; border-left: 11px solid currentColor; margin-left: 3px; }
.hero-slides__toggle[aria-pressed="true"] .icon-play,
.hero-video__toggle[aria-pressed="true"] .icon-play { display: block; }
.hero-slides__toggle[aria-pressed="true"] .icon-pause,
.hero-video__toggle[aria-pressed="true"] .icon-pause { display: none; }

/* Employment-Type als solider Tag (Akzent-Paar, kantig, uppercase), geteilt von
   nl/stellenliste (.nl-job-card__type) und nl/stellenanzeige (.nl-job-detail__type).
   Der Rest der Stellen-Optik steht im Block-CSS dieser beiden Bloecke (die Meta-Zeile Ort und Start folgt direkt darunter). */
.nl-job-card__type,
.nl-job-detail__type {
    display: inline-flex;
    align-self: flex-start;
    padding: var(--wp--preset--spacing--3-xs) var(--wp--preset--spacing--xs);
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    background: var(--wp--preset--color--accent);
    color: var(--wp--custom--color--on-accent);
    border-radius: var(--wp--preset--border-radius--sm);
}

/* Meta-Zeile mit Punkt-Trenner zwischen den Spans (Ort · Start). Greift
   fuer Card (__location/__start-Spans) und Detail (blanke Spans). Steht hier,
   weil eine Stellen-Seite nur das CSS von nl/stellenanzeige laedt, nicht das
   von nl/stellenliste; die Detail-Abweichung (zentriert, Textgroesse) steht
   im Block-CSS von nl/stellenanzeige. */
.nl-job-card__meta,
.nl-job-detail__meta {
    display: flex;
    flex-wrap: wrap;
    gap: var(--wp--preset--spacing--3-xs) var(--wp--preset--spacing--sm);
    font-size: var(--wp--preset--font-size--sm);
    color: var(--wp--preset--color--muted);
    margin: 0;
}
.nl-job-card__meta > span + span::before,
.nl-job-detail__meta > span + span::before {
    content: "·";
    margin-right: var(--wp--preset--spacing--sm);
    opacity: 0.6;
}

/* ── Lightbox ──
   nl-lightbox aus web-modules (assets/css/lightbox.css, vendored) mit den
   Vorgaben aus theme.json: Ecken wie die Bilder der Blöcke, Fokusring am
   Bild in der Hauptfarbe; im Dialog die dunkle Fläche als Hintergrund und
   der Fokusring in der Textfarbe darauf (die Hauptfarbe erreicht auf
   dunklem Grund nicht überall 3:1). Gesetzt auf Auslöser und Dialog statt
   auf :root, das Modul liest sie dort. */
.nl-lb {
    --nl-lb-accent: var(--wp--preset--color--primary);
    --nl-lb-radius: var(--wp--preset--border-radius--md);
}
.nl-lb-dialog {
    --nl-lb-backdrop: color-mix(in srgb, var(--wp--preset--color--dark) 94%, transparent);
    --nl-lb-text:     var(--wp--custom--color--on-dark);
    --nl-lb-accent:   var(--wp--custom--color--on-dark);
    --nl-lb-radius:   var(--wp--preset--border-radius--md);
}

/* ═══════════════════════════════════════════════════════════════════════
   5 · SEITENRAHMEN
   Topbar, Header, Hauptnavigation, Burger, Drawer, Footer (Markup: header.php, footer.php,
   inc/navigation.php; Logik: assets/js/init.js). Der Nav-Umbruch steht im Drawer-
   Abschnitt (1200px) und wird pro Site in site.css angepasst.
   ═══════════════════════════════════════════════════════════════════════ */

/* ── Top-Bar (duenn, Navy wie Brand-Sekundaerfarbe): Kundenportal links,
   Telefon + E-Mail rechts. Hover hellt auf (Rot auf Navy waere
   kontrastschwach ~2.5:1). ── */
.site-topbar {
    background: var(--wp--preset--color--dark);
    color: #e8e9f2;
    font-size: 0.8125rem;
    letter-spacing: 0.03em;
    /* Das rote Marken-Signal: duenne Akzentlinie als unterer Abschluss */
    border-bottom: 2px solid var(--wp--preset--color--primary);
}
.site-topbar__inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: var(--wp--preset--spacing--2-xs) 1.5rem;
    min-height: 38px;
}
/* Portal side holds Kundenportal and, once the customer enters the link,
   Sendungsverfolgung: same gap and divider as the contact side. */
.site-topbar__portal,
.site-topbar__contact {
    display: flex;
    align-items: center;
    gap: 1.25rem;
}
.site-topbar__portal { min-height: 22px; }
/* Feiner Trenner zwischen Telefon | E-Mail (rgba-weiss, mittig im Gap) */
.site-topbar__portal a + a,
.site-topbar__contact a + a {
    border-left: 1px solid rgba(255, 255, 255, 0.22);
    padding-left: 1.25rem;
}
.site-topbar__portal a,
.site-topbar__contact a {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    color: #e8e9f2;
    text-decoration: none;
    font-weight: 500;
    transition: color .15s ease;
}
.site-topbar__portal svg,
.site-topbar__contact svg { width: 1rem; height: 1rem; }
.site-topbar__portal a:focus-visible,
.site-topbar__contact a:focus-visible {
    outline: 2px solid #ffffff;
    outline-offset: 2px;
}
@media (hover: hover) and (pointer: fine) {
    .site-topbar__portal a:hover,
    .site-topbar__contact a:hover { color: #ffffff; }
}

/* Live-Status-Badge */
.live-status {
    display: inline-flex;
    align-items: center;
    gap: var(--wp--preset--spacing--2-xs);
    font-weight: 500;
    font-size: 0.875rem;
    color: #e5e5e5;
    text-decoration: none;
}
.site-topbar a { text-decoration: none; transition: color .15s ease; }
@media (hover: hover) and (pointer: fine) {
    .live-status:hover { color: var(--wp--preset--color--primary); }
}
.live-status__dot {
    width: 8px; height: 8px;
    border-radius: 50%;
    flex-shrink: 0;
    position: relative;
}
.live-status--open .live-status__dot { background: #22c55e; }
.live-status--closed .live-status__dot { background: #9ca3af; }
/* Pulsing ring, nur bei 'open' */
.live-status--open .live-status__dot::after {
    content: '';
    position: absolute;
    inset: -4px;
    border-radius: 50%;
    border: 2px solid #22c55e;
    animation: livePulse 2s ease-out infinite;
}
@keyframes livePulse {
    0%   { transform: scale(0.8); opacity: 0.8; }
    100% { transform: scale(1.6); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
    .live-status--open .live-status__dot::after { animation: none; }
}

@media (max-width: 480px) {
    .site-topbar__contact a span { display: none; }
    .site-topbar__contact { gap: 0.75rem; }
    .site-topbar__contact svg { width: 1.1rem; height: 1.1rem; }
}

/* ── Main-Header ── */
.site-header {
    padding:        0.75rem 0;
    border-bottom:  1px solid var(--wp--custom--color--border);
    position:       sticky;
    top:            0;
    background:     color-mix(in oklab, var(--wp--preset--color--base) 88%, transparent);
    z-index:        100;
    backdrop-filter: saturate(180%) blur(10px);
    -webkit-backdrop-filter: saturate(180%) blur(10px);
    transition: padding .18s ease, background .18s ease;
}
.site-header.is-scrolled { padding: 0.4rem 0; }
.site-header__inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1.5rem;
}
.site-header .logo {
    display: inline-flex;
    align-items: center;
    gap: 0.75rem;
    text-decoration: none;
    color: var(--wp--preset--color--contrast);
    flex-shrink: 0;
}
/* Logo: Hoehe fixieren (breite Wortmarken wie Maulhardt 541x131),
   Breite folgt der Ratio (Template-Default 3rem x 3rem war fuers
   quadratische Icon+Text-Muster). */
.site-header .logo img { height: 2.75rem; width: auto; transition: height .18s ease; }
.site-header.is-scrolled .logo img { height: 2.25rem; }
/* Logo fallback without a custom logo: the site name as text */
.logo__text {
    font-family: var(--wp--preset--font-family--heading);
    font-weight: 800;
    font-size: 1.25rem;
    color: var(--wp--preset--color--contrast);
    white-space: nowrap;
}
.site-footer .logo__text,
.site-drawer .logo__text { color: inherit; }
.site-header .logo__text {
    font-family: var(--wp--preset--font-family--heading);
    font-weight: 700;
    /* Brand-Text skaliert mit runter statt auf Mobile versteckt zu werden.
       Auf 320px-Screens faellt der Text auf ~0.78rem, bleibt sichtbar. */
    font-size: clamp(0.78rem, 3.4vw, 1.35rem);
    letter-spacing: -0.015em;
    color: var(--wp--preset--color--contrast);
    white-space: nowrap;
}

.site-nav {
    display: flex;
    gap: 1.75rem;
    align-items: center;
    margin-left: auto;
    margin-right: auto;
}
.site-nav a {
    text-decoration: none;
    color: var(--wp--preset--color--contrast);
    font-size: 0.95rem;
    font-weight: 500;
    padding: var(--wp--preset--spacing--2-xs) 0;
    position: relative;
}
.site-nav a::after {
    content: '';
    position: absolute;
    bottom: 0; left: 0; right: 0;
    height: 2px;
    background: var(--wp--preset--color--primary);
    transform: scaleX(0);
    transform-origin: left;
    transition: transform .2s ease;
}
.site-nav a:focus-visible { outline: 2px solid var(--wp--preset--color--primary); outline-offset: 3px; }
@media (hover: hover) and (pointer: fine) {
    .site-nav a:hover::after { transform: scaleX(1); }
}
@media (prefers-reduced-motion: reduce) {
    .site-nav a::after { transition: none; }
}
/* Aktive Seite (aria-current="page", gesetzt von init.js): rote
   Unterstreichung permanent + staerkeres Gewicht. */
.site-nav a[aria-current="page"] { font-weight: 600; }
.site-nav a[aria-current="page"]::after { transform: scaleX(1); }

/* Werkstatt-Dropdown (Desktop): oeffnet per :hover (Maus) + :focus-within
   (Tastatur). Top-Link fuehrt zur Werkstatt-Seite — Touch-Fallback, nie tot.
   Pattern aus TWZV uebernommen. */
.nav-has-sub { position: relative; display: flex; align-items: center; }

.nav-caret {
    display: inline-block;          /* span braucht inline-block, sonst kollabiert der border-Pfeil zum Strich */
    width: 0.42em; height: 0.42em;
    margin-left: 0.45em;
    border-right: 2px solid currentColor;
    border-bottom: 2px solid currentColor;
    transform: translateY(-0.18em) rotate(45deg);
    transition: transform 0.2s ease;
}

.nav-has-sub:focus-within .nav-caret { transform: translateY(0.06em) rotate(225deg); }

@media (hover: hover) and (pointer: fine) {
    .nav-has-sub:hover .nav-caret { transform: translateY(0.06em) rotate(225deg); }
}

.nav-sub {
    position: absolute;
    top: calc(100% + 0.4rem);
    left: 50%;
    transform: translate(-50%, 6px);
    min-width: 15rem;
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: var(--wp--preset--spacing--2-xs);
    background: var(--wp--preset--color--base);
    border-radius: var(--wp--preset--border-radius--md);
    box-shadow: var(--wp--preset--shadow--md);
    border: 1px solid var(--wp--custom--color--border);
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.18s ease, transform 0.18s ease, visibility 0.18s;
    z-index: 200;
}

.nav-has-sub:focus-within .nav-sub {
    opacity: 1;
    visibility: visible;
    transform: translate(-50%, 0);
}

@media (hover: hover) and (pointer: fine) {
    .nav-has-sub:hover .nav-sub {
        opacity: 1;
        visibility: visible;
        transform: translate(-50%, 0);
    }
}

/* ESC-Dismiss (WCAG 1.4.13): init.js setzt .is-dismissed auf die Gruppe,
   solange Hover/Fokus noch anliegen. Muss NACH den :hover/:focus-within-
   Regeln stehen (gleiche Spezifitaet, letzte Regel gewinnt). visibility
   hidden macht die Sub-Links unfokussierbar — Tab ueberspringt sie sauber.
   mouseleave/focusout entfernen die Klasse wieder (re-armed). Framework-
   Pattern aus website-template (TWZV-Audit 2026-07-17). */
.nav-has-sub.is-dismissed .nav-sub {
    opacity: 0;
    visibility: hidden;
    transform: translate(-50%, 6px);
}

.nav-has-sub.is-dismissed .nav-caret { transform: translateY(-0.18em) rotate(45deg); }

.nav-sub a {
    color: var(--wp--preset--color--contrast);
    font-size: 1rem;
    font-weight: 500;
    padding: var(--wp--preset--spacing--2-xs) var(--wp--preset--spacing--sm);
    border-radius: var(--wp--preset--border-radius--sm);
    white-space: nowrap;
}

.nav-sub a::after { display: none; }

@media (hover: hover) and (pointer: fine) {
    .nav-sub a:hover { background: var(--wp--preset--color--soft); }
}

.site-header__actions {
    display: flex;
    align-items: center;
    gap: var(--wp--preset--spacing--2-xs);
}
.btn-sm { padding: 0.5rem 1rem; font-size: 0.9rem; }
/* Header-CTA: bewusst clean ohne Icon — Gewicht + Padding tragen ihn */
.site-header__cta {
    white-space: nowrap;
    padding: 0.55rem 1.25rem;
    font-weight: 700;
}

/* ── Burger-Button (nur mobile) ── */
.nav-toggle {
    display: none;
    background: transparent;
    border: 1px solid var(--wp--custom--color--border);
    border-radius: var(--wp--preset--border-radius--button);
    padding: var(--wp--preset--spacing--2-xs);
    cursor: pointer;
    color: var(--wp--preset--color--contrast);
    transition: border-color .15s ease;
}
.nav-toggle:focus-visible { outline: 2px solid var(--wp--preset--color--primary); outline-offset: 2px; }
.nav-toggle__box {
    display: inline-flex;
    flex-direction: column;
    justify-content: space-between;
    width: 20px;
    height: 14px;
}
.nav-toggle__box span {
    display: block;
    height: 2px;
    background: currentColor;
    transition: transform .25s ease, opacity .25s ease;
}
.nav-toggle[aria-expanded="true"] .nav-toggle__box span:nth-child(1) { transform: translateY(6px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] .nav-toggle__box span:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] .nav-toggle__box span:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }
@media (prefers-reduced-motion: reduce) {
    .nav-toggle__box span { transition: none; }
}

/* ── Mobile-Drawer (Off-Canvas) ──
   Drawer ist als Sibling des <header> ins HTML geschrieben — nicht mehr als
   Kind. Vorteile:
   - Header behaelt seinen backdrop-filter ohne den Drawer im Containing-
     Block einzusperren (W3C Filter Effects L2).
   - Der body.nav-open-Backdrop ueberdeckt Viewport inkl. Header → Blur
     wirkt durchgehend ueber Logo/Topbar.
   - Drawer (z-index 110) liegt ueber dem Backdrop (105), beide im Root-
     Stacking-Context. */
.site-drawer        { display: none; }
.site-drawer__close { display: none; }

/* Nav-Breakpoint 1200px: Platz fuer etwa 6 Nav-Items + CTA. Pro Site an
   die Menuelaenge anpassen (960px reicht fuer 3-4 kurze Items). */
@media (max-width: 1200px) {
    .site-topbar .sm-hide { display: none; }
    .nav-toggle           { display: inline-flex; }
    .site-nav             { display: none; }     /* Desktop-Nav auf Mobile ausblenden */
    .site-header__cta     { display: none; }

    /* Drawer sichtbar + Off-Canvas von rechts */
    .site-drawer {
        display: flex;
        flex-direction: column;
        position: fixed;
        top: 0; right: 0; bottom: 0;
        width: min(88vw, 360px);
        padding: 4.5rem 0 2rem;                   /* Platz fuer Close-X */
        background: var(--wp--preset--color--base);
        border-left: 1px solid var(--wp--custom--color--border);
        /* Closed = not painted. translateX(100%) alone parks the box right
           next to the viewport: the lg shadow and the border-left painted a 1
           to 2px line at the right edge (Chrome up to 1.7px, WebKit 1px).
           visibility interpolates discretely (visible during the whole
           transition), so the slide-out still shows; reduced motion
           (transition: none below) hides at once. Keyboard and screen reader
           state is unchanged: the closed drawer is already inert +
           aria-hidden (init.js). Per MDN visibility (Interpolation,
           Accessibility), verified 2026-09-24. */
        visibility: hidden;
        transform: translateX(100%);
        transition: transform .28s ease, visibility .28s;
        box-shadow: var(--wp--preset--shadow--lg);
        z-index: 110;
        overflow-y: auto;
        overscroll-behavior: contain;
    }
    .site-drawer[data-open="true"] { transform: translateX(0); visibility: visible; }

    /* Close-Button (X). Enter-Animation rotate(-90deg) scale(0.85) → 0.
       Respektiert prefers-reduced-motion weiter unten. */
    .site-drawer__close {
        display: inline-flex;
        position: absolute;
        top: 0.9rem; right: 1rem;
        width: 2.5rem;
        height: 2.5rem;
        align-items: center;
        justify-content: center;
        border: 1px solid var(--wp--custom--color--border);
        border-radius: 999px;
        background: transparent;
        color: var(--wp--preset--color--contrast);
        cursor: pointer;
        transform: rotate(-90deg) scale(0.85);
        opacity: 0;
        transition: transform .32s cubic-bezier(.2,.7,.2,1.3) .08s,
                    opacity   .24s ease .08s,
                    background-color .15s,
                    border-color .15s;
    }
    .site-drawer[data-open="true"] .site-drawer__close {
        transform: rotate(0) scale(1);
        opacity: 1;
    }
    .site-drawer__close:focus-visible {
        outline: 2px solid var(--wp--preset--color--primary);
        outline-offset: 2px;
    }
    @media (hover: hover) and (pointer: fine) {
        .site-drawer__close:hover {
            background: var(--wp--preset--color--soft);
            border-color: var(--wp--preset--color--primary);
            transform: rotate(90deg) scale(1.05);
        }
    }
    .site-drawer__close:active { transform: rotate(180deg) scale(0.95); }

    /* Kleine Wortmarke oben links — der Drawer wirkt sonst "nackt".
       Absolut im 4.5rem-Kopfbereich, vertikal auf Hoehe des Close-X. */
    .site-drawer__brand {
        position: absolute;
        top: 1.15rem;
        left: 1.75rem;
    }
    .site-drawer__brand img { height: 2rem; width: auto; }

    /* Nav-Items im Drawer */
    .site-drawer__items {
        display: flex;
        flex-direction: column;
        gap: 0;
        padding: 0 1.75rem;
    }
    .site-drawer__items a {
        font-size: 1.1rem;
        padding: 0.9rem 0;
        width: 100%;
        border-bottom: 1px solid var(--wp--custom--color--border);
        color: var(--wp--preset--color--contrast);
        text-decoration: none;
    }
    .site-drawer__items a::after { display: none; }

    /* Aktive Seite im Drawer: roter 3px-Kantenbalken links */
    .site-drawer__items a[aria-current="page"]:not(.btn) {
        border-left: 3px solid var(--wp--preset--color--primary);
        padding-left: 0.75rem;
        font-weight: 600;
    }

    /* Werkstatt-Untergruppe im Drawer: leicht eingerueckt */
    .site-drawer__sub {
        display: flex;
        flex-direction: column;
        padding-left: 1rem;
    }
    .site-drawer__sub a { font-size: 1rem; }

    /* CTA + Meta-Links (Kundenportal, Telefon) unten im Drawer */
    .site-drawer__cta {
        margin-top: 1.25rem;
        justify-content: center;
        border-bottom: none;
    }
    .site-drawer__items a.site-drawer__cta {
        color: var(--wp--custom--color--on-primary);
        border-bottom: none;
        padding: 0.875rem 1.75rem;
    }
    /* Meta-Links (Kundenportal, Telefon) optisch abgesetzt */
    .site-drawer__meta {
        display: flex;
        flex-direction: column;
        margin-top: 1.25rem;
        padding-top: 0.75rem;
        border-top: 1px solid var(--wp--custom--color--border);
    }
    .site-drawer__meta a {
        font-size: 0.95rem;
        color: var(--wp--preset--color--muted);
        padding: var(--wp--preset--spacing--2-xs) 0;
        border-bottom: none;
        text-decoration: none;
    }

    /* Backdrop + Body-Lock. Backdrop liegt im Root-Stacking-Context und
       ueberdeckt dank z-index 105 jetzt auch den Header (z-index 100) —
       Blur wirkt durchgehend. Drawer (110) bleibt klar darueber. */
    body.nav-open::after {
        content: '';
        position: fixed;
        inset: 0;
        background: rgba(0,0,0,.45);
        backdrop-filter: blur(6px) saturate(140%);
        -webkit-backdrop-filter: blur(6px) saturate(140%);
        z-index: 105;
        animation: fadeIn .2s ease;
    }
    body.nav-open { overflow: hidden; }

    @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
    @media (prefers-reduced-motion: reduce) {
        .site-drawer        { transition: none; }
        .site-drawer__close { transition: opacity .15s ease; transform: none; }
        body.nav-open::after { animation: none; }
    }
}

/* ── Footer-System (Redesign 2026-07) ──
   Aufbau: (1) rote Pre-Footer-CTA-Box — komponiert aus .section--primary
   (Farben) + .pull-up (Overlap) + .site-footer__closing (Layout) — ragt aus dem
   Navy-Footer nach oben in dessen margin-top-Luftraum (dort steht nie
   Seiten-Content, das Overlap ist auf jeder Seite kollisionsfrei);
   (2) Navy-Hauptfooter, 4-Zonen-Grid (Brand / Leistungen / Unternehmen /
   Kontakt); (3) Bottom-Bar; (4) riesige halbtransparente MAULHARDT-
   Wortmarke, unten vom Clip-Wrapper angeschnitten.
   Alle Links weiss unterstrichen (die globalen a-Farben waeren auf Navy
   unsichtbar/kontrastschwach), Focus-Outline weiss. */
.site-footer {
    /* flow-root: BFC verhindert den Margin-Collapse footer <-> pull-up-Box
       (sonst wandert die Navy-Kante mit der Box nach oben, kein Overlap).
       Bewusst KEIN overflow:hidden hier — das wuerde die Box kappen. */
    display: flow-root;
    background: var(--wp--preset--color--dark);
    color: var(--wp--custom--color--on-dark);
    margin-top: calc(var(--wp--preset--spacing--3-xl) + var(--wp--preset--spacing--xl));
    font-size: clamp(0.9rem, 0.82rem + 0.3vw, 1rem);
}
/* Variante ohne Pre-Footer-CTA (Rechtstexte: build.py haengt die Klasse an,
   wenn der NL-FOOTER-CTA-Block rausgeschnitten wird). Der grosse margin-top
   oben ist der Luftraum fuer die pull-up-Box — ohne Box wirkt er als totes
   Weiss zwischen Content und Footer. Und weil sonst die CTA-Box den oberen
   Innenabstand traegt, braucht das Grid hier ein eigenes padding-top. */
.site-footer--no-cta { margin-top: var(--wp--preset--spacing--2-xl); }
.site-footer--no-cta .site-footer__grid { padding-top: var(--wp--preset--spacing--3-xl); }
/* :not(.btn) ist PFLICHT (Spezifizitaets-Falle, gleiche Klasse wie die
   Framework-Lesson "main a:not(...) schluckt Card-Transitions"): dieser
   Selektor ist 0-1-1 und schlaegt damit .btn (0-1-0) — die Buttons der
   Pre-Footer-CTA-Box haetten sonst eine Unterstreichung im Normal- UND
   Hover-State. Gleiches Muster wie .section--dark a:not(.btn) oben. */
.site-footer a:not(.btn) {
    color: var(--wp--custom--color--on-dark);
    text-decoration: underline;
    text-underline-offset: 3px;
    text-decoration-thickness: 1px;
    text-decoration-color: rgba(255, 255, 255, 0.35);
    transition: text-decoration-color .15s ease;
}
.site-footer a:focus-visible {
    outline: 2px solid var(--wp--custom--color--on-dark);
    outline-offset: 3px;
}
@media (hover: hover) and (pointer: fine) {
    .site-footer a:not(.btn):hover {
        text-decoration-color: var(--wp--preset--color--primary);
        text-decoration-thickness: 2px;
    }
}

/* (1) Pre-Footer-CTA-Box (Markup: class="site-footer__closing section--primary pull-up") */
.site-footer__closing {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--wp--preset--spacing--md) var(--wp--preset--spacing--lg);
    padding: var(--wp--preset--spacing--xl);
    margin-bottom: var(--wp--preset--spacing--2-xl);
}
/* Text links waechst, Buttons stehen rechts daneben (wrappen erst
   wenn wirklich zu eng) */
.site-footer__closing-text { flex: 1 1 30rem; min-width: min(100%, 24rem); }
.site-footer__closing-title {
    font-size: clamp(1.6rem, 2.6vw, 2.5rem);
    font-weight: 900;
    line-height: 1.15;
    color: #ffffff;
    margin-bottom: var(--wp--preset--spacing--3-xs);
}
.site-footer__closing-sub { margin-bottom: 0; }   /* volles Weiss erbt von .section--primary */
.site-footer__closing-actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--wp--preset--spacing--sm);
}

/* (2) Haupt-Footer: 4-Zonen-Grid */
.site-footer__grid {
    display: grid;
    gap: var(--wp--preset--spacing--xl) var(--wp--preset--spacing--lg);
    grid-template-columns: 1.6fr 1fr 1fr 1.2fr;
}
.site-footer__brand > p {
    color: rgba(255, 255, 255, 0.75);
    max-width: 40ch;
    margin: var(--wp--preset--spacing--md) 0;
    hyphens: manual;               /* keine Auto-Trennung ("Lei-nefelde") im Brand-Text */
    -webkit-hyphens: manual;
}
.site-footer__logo {
    height: 2.25rem;
    width: auto;
    filter: brightness(0) invert(1);   /* Wortmarke als Weiss-Variante */
}
/* Spalten-Labels im Kicker-Stil, mit kurzem rotem Strich */
/* Footer-Spaltentitel sind seit dem BITV-Test 2026-08 echte <h2>
   (Pruefschritt 9.1.3.1a, gemeldet fuer die Schwester-Site TWZV, hier
   dasselbe Muster): sie betiteln je eine Link- bzw. Adress-Gruppe. Die
   h1-h4-Basisregel wird neutralisiert (font-weight/line-height/color),
   damit die Optik exakt bleibt. */

.site-footer__label {
    line-height: 1.6;
    display: flex;
    align-items: center;
    gap: 0.6rem;
    font-family: var(--wp--preset--font-family--heading);
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, 0.65);
    margin-bottom: var(--wp--preset--spacing--sm);
}
.site-footer__label::before {
    content: '';
    width: 1.25rem;
    height: 2px;
    background: var(--wp--preset--color--primary);
    flex-shrink: 0;
}
.site-footer__list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--wp--preset--spacing--2-xs);
}
.site-footer address { line-height: 1.9; }
/* Social-Icons in kantigen 1px-Rahmen, Hover kippt die Kante auf Rot */
.site-footer__profiles {
    display: flex;
    gap: 0.75rem;
    margin-top: var(--wp--preset--spacing--sm);
}
.site-footer__profiles a {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.5rem;
    height: 2.5rem;
    border: 1px solid rgba(255, 255, 255, 0.25);
    text-decoration: none;
    transition: border-color .15s ease, background-color .15s ease;
}
.site-footer__profiles svg { display: block; }
@media (hover: hover) and (pointer: fine) {
    .site-footer__profiles a:hover {
        border-color: var(--wp--preset--color--primary);
        background: rgba(255, 255, 255, 0.06);
    }
}

/* (3) Bottom-Bar */
.site-footer__bottom {
    display: flex;
    flex-wrap: wrap;
    gap: var(--wp--preset--spacing--2-xs) var(--wp--preset--spacing--lg);
    justify-content: space-between;
    align-items: center;
    margin-top: var(--wp--preset--spacing--2-xl);
    padding: var(--wp--preset--spacing--md) 0;
    border-top: 1px solid rgba(255, 255, 255, 0.18);
    font-size: 0.85rem;
    color: rgba(255, 255, 255, 0.75);
}
.site-footer__bottom p { margin-bottom: 0; }
.site-footer__legal {
    display: flex;
    flex-wrap: wrap;
    gap: var(--wp--preset--spacing--2-xs) var(--wp--preset--spacing--md);
}
.site-footer__year { cursor: help; }

/* (4) Riesen-Wortmarke: Deko-Typo in 7% Weiss auf Navy, unten vom
   Clip-Wrapper angeschnitten (negative margin-bottom + overflow hidden
   am Wrapper statt am Footer, siehe oben). */
.site-footer__watermark-clip { overflow: hidden; }
/* Der Text steht als ::before aus data-text, nicht als Textknoten: reine
   Deko mit 1,1:1 ist nach WCAG 1.4.3 ausgenommen, ein Prüfer (axe) meldet
   aber jeden Textknoten. Verifiziert 2026-10-13, axe 4.14. */
.site-footer__watermark::before { content: attr(data-text); }
.site-footer__watermark {
    font-family: var(--wp--preset--font-family--heading);
    font-size: clamp(2.75rem, 12vw, 12rem);
    font-weight: 900;
    line-height: 1;
    letter-spacing: 0.02em;
    white-space: nowrap;
    text-align: center;
    color: color-mix(in srgb, #ffffff 7%, var(--wp--preset--color--dark));
    margin-top: var(--wp--preset--spacing--sm);
    margin-bottom: -0.35em;
    user-select: none;
    -webkit-user-select: none;
    pointer-events: none;
}

@media (max-width: 980px) {
    .site-footer__grid { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 560px) {
    .site-footer__grid { grid-template-columns: 1fr; }
}

/* ═══════════════════════════════════════════════════════════════════════
   6 · INHALTSSEITEN
   Rechtstexte (nl/rechtstext) und 404.
   ═══════════════════════════════════════════════════════════════════════ */

/* ── Legal-Content (Impressum / Datenschutz) ── */
.legal-content h1 {
    font-size: clamp(2rem, 4vw, 3rem);
    margin-bottom: 2rem;
}
.legal-content h2 {
    font-size: clamp(1.35rem, 2vw, 1.75rem);
    margin-top: 2.5rem;
    margin-bottom: 1rem;
    padding-bottom: var(--wp--preset--spacing--2-xs);
    border-bottom: 1px solid var(--wp--custom--color--border);
}
.legal-content h3 {
    font-size: 1.15rem;
    margin-top: 1.5rem;
    margin-bottom: var(--wp--preset--spacing--2-xs);
}
.legal-content p     { margin-bottom: 1rem; line-height: 1.7; }
.legal-content ul    { padding-left: 1.5rem; margin-bottom: 1rem; line-height: 1.7; }
.legal-content li    { margin-bottom: 0.5rem; }
.legal-content a     { color: var(--wp--preset--color--contrast); text-decoration-color: var(--wp--preset--color--primary); }
.legal-content strong{ color: var(--wp--preset--color--contrast); }
.legal-content hr    { border: none; border-top: 1px solid var(--wp--custom--color--border); margin: 2rem 0; }
/* ADR 2026-07-15 (Anti-Slop): kein border-left: 4px solid var(--wp--preset--color--primary).
   Rot bedeutet an einem Adressblock im Impressum nichts (kein Status, keine
   Priorität, keine aktive Seite) — reine Deko. Die bg-soft-Fläche setzt den
   Block bereits vom Fliesstext ab, Weglass-Test: es fehlt nichts. Herkunft des
   Patterns: website-template (CLAUDE.md dokumentiert .legal-content als
   "address mit Soft-BG + Primary-Left-Border") — dort separat zu fixen. */
.legal-content address {
    font-style: normal;
    background: var(--wp--preset--color--soft);
    padding: 1.25rem 1.5rem;
    border-radius: var(--wp--preset--border-radius--md);
    margin: 1rem 0;
}

/* ── 404 ── */
.error-page    { padding: 8rem 0; text-align: center; }
.error-page h1 { font-size: 6rem; color: var(--wp--preset--color--muted); margin-bottom: 1rem; }

/* ═══════════════════════════════════════════════════════════════════════
   7 · BARRIEREFREIHEIT
   .visually-hidden, Skip-Link, .screen-reader-text (WordPress-Konvention) und
   reduced-motion. Die drei einzigen !important der Datei stehen hier (je eins
   pro Regel, jeweils mit Grund).
   ═══════════════════════════════════════════════════════════════════════ */

/* ── Visually hidden (Screen-Reader only) ── */
.visually-hidden {
    position: absolute !important;   /* must win over every component's own position (framework utility) */
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0,0,0,0);
    white-space: nowrap; border: 0;
}

/* ── Skip-Link ── */
.skip-link {
    position:       absolute;
    left:           -9999px;
    top:            0;
    z-index:        1000;
    padding:        var(--wp--preset--spacing--2-xs) 1rem;
    background:     var(--wp--preset--color--primary);
    color:          var(--wp--custom--color--on-primary);
    font-weight:    600;
    text-decoration: none;
    border-radius:  0 0 var(--wp--preset--border-radius--md) 0;
}
.skip-link:focus { left: 0; }

/* ── Reduced Motion ── */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}

/* ── .screen-reader-text ──
   Not part of the framework CSS: WP core and plugins rely on this class. */
.screen-reader-text {
    position: absolute !important; /* framework constraint override: WP core convention class, must win everywhere */
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/* ═══════════════════════════════════════════════════════════════════════
   8 · WORDPRESS
   Freie Kernbloecke zwischen den Sektionen, Admin-Leiste.
   ═══════════════════════════════════════════════════════════════════════ */

/* Free content between the sections: core blocks the customer inserts
   directly on a page (paragraph, heading, list, table, form ...) have no
   container of their own, so they get the reading width of the framework
   (.container--text) and the side gutter. Section blocks (wp-block-nl-*)
   stay full width. */
#main > :not([class*="wp-block-nl-"]) {
    max-width: calc(var(--wp--style--global--content-size) + 2 * var(--wp--custom--gutter));
    margin-inline: auto;
    padding-inline: var(--wp--custom--gutter);
}
#main > :not([class*="wp-block-nl-"]):first-child { margin-top: var(--wp--preset--spacing--xl); }
#main > :not([class*="wp-block-nl-"]) + :not([class*="wp-block-nl-"]) { margin-top: var(--wp--preset--spacing--sm); }
#main > [class*="wp-block-nl-"] + :not([class*="wp-block-nl-"]),
#main > :not([class*="wp-block-nl-"]) + [class*="wp-block-nl-"] { margin-top: var(--wp--preset--spacing--xl); }

/* The admin bar of logged-in users sits on top of the sticky header unless the
   header moves down by its height (32px desktop, 46px at <=782px, per
   wp-includes/css/admin-bar.css). */
.admin-bar .site-header { top: 32px; }
@media screen and (max-width: 782px) {
    .admin-bar .site-header { top: 46px; }
}
