/*
  Design-System "Aktien für Einsteiger" — Sprint 2, Track B (design-system-frontend).
  Grundlage: docs/concept/04-independent-design-ux-concept.md (§5 Farben, §6 Typo,
  §9/§13 Tokens, §10 Boxen/Register, §11 Kopf/Footer, §14/§15 Zustände/A11y) sowie
  docs/concept/04c-startseite-entwurf-editorial-broadsheet.md (Editorial-Broadsheet)
  und D-123 (site-weiter Standard: Haarlinien/Register statt Karten, kompakter
  Serifen-Kopf auf Unterseiten, editorial-flache Lernbausteine mit erhaltener
  Signalwirkung bei Risiko/Warnung/Disclaimer).

  Dark Mode (F-26, D-148, Sprint 12 WP-1): seit Sprint 12 umgesetzt. Grundfall ist die
  automatische Übernahme von "prefers-color-scheme" (D-104-Vorbereitung "Tokens sind
  dark-mode-fähig" eingelöst); zusätzlich übersteuert ein manueller Umschalter
  (assets/js/site.js + kleines Inline-Skript in base.njk <head>, FOUC-Vermeidung) per
  "data-theme" auf <html> in BEIDE Richtungen. Details/Tokenwerte/Kontrastpaare:
  Abschnitt 23 "Dark Mode". `color-scheme` wird je Modus mitgesetzt (verhindert eine
  zusätzliche, ungewollte Browser-Auto-Invertierung, 04 §12).

  Inhaltsverzeichnis:
    1. Design-Tokens (:root)
    2. Basis-Reset & Grundgerüst (html/body, Canvas/Papier-Schale)
    3. Utilities (sr-only, Skip-Link, Fokus, Container)
    4. Typografie (Überschriften, Fließtext, Links, Listen)
    5. Buttons
    6. Tabellen
    7. Lernbausteine (Box-System, D-123 editorial-flach)
    8. Autorenbox
    9. Register-/Haarlinien-Komponente (D-123)
    10. Navigation & Kopfbereich (Desktop + mobil) — inkl. Dark-Mode-Umschalter-Optik
    11. Breadcrumbs
    12. Footer (hell, 04 §11.7)
    13. Artikel-Layout (Meta, Lernpfad-Hinweis, Voraussetzungen-Kasten, TOC, Blockquote)
    14. Artikel-Aktionen (Teilen/Feedback, .js-only) + Lernpfad-Weiter
    15. Anzeigen-Platzhalter (Optik, Sprint-3 Track A)
    16. Illustrationen (Grundset, Sprint 3 Track A4)
    17. Startseite S1 (Hero, Themen-Register, Etappen, Werkzeuge/Vertrauen — 04c)
    18. Pagefind-Theming (Such-Seiten-Shell)
    19. Glossar-Shell (Alphabet-Navigation/-Filter, Definitionsliste — Filter Sprint 13, WP-2)
    20. Bewegung (prefers-reduced-motion)
    21. Design-Vorschau (interne Abnahmeseite, kein Website-Baustein)
    22. Werkzeuge (Rechner, Checkliste, Sortier-Tabelle, Speicher-Opt-in — Sprint 4, Track T; Quiz — Sprint 12, WP-2)
    23. Dark Mode (Token-Overrides, F-26/D-148, Sprint 12 WP-1)
    24. Druck-CSS (bleibt Light, unabhängig vom Dark-Mode-Zustand)
    25. Glossar-Tooltip (Popover für automatisch verlinkte Begriffe — Sprint 13, WP-2)
*/

/* ==========================================================================
   1. Design-Tokens (04 §13 — kanonische Quelle für Gestaltungswerte)
   ========================================================================== */

:root {
  /* Licht-Grundwerte (immer aktiv, keine Media-Bedingung) — zugleich der garantierte
     Druck-Fallback (Sektion 24) und die Basis, die der Dark-Mode-Grundfall
     (@media screen and (prefers-color-scheme: dark), Sektion 23) auf Bildschirmen
     überschreibt. "color-scheme: light" hier verhindert eine ungewollte Browser-
     Auto-Invertierung, solange kein Dark-Mode-Zweig greift (04 §12). */
  color-scheme: light;

  /* --- 13.1 Farben ---------------------------------------------------- */
  --color-primary: #1B4965;
  --color-primary-dark: #123950;
  --color-primary-light: #E8F1F5;
  --color-secondary-surface: #F3EEE7;
  --color-secondary-deco: #BFD7E4;
  --color-accent: #8C4B10;
  /* Hinweis: --color-accent-bright (#E9A24B, 04b/D-120) ist mit D-121/D-123 NICHT
     Teil des gewählten Editorial-Broadsheet-Standards und wird hier bewusst
     nicht definiert (nur in 04b als geprüfte Alternative dokumentiert). */
  --color-info: #175E88;
  --color-info-surface: #E7F1F8;
  --color-success: #1E7A46;
  --color-success-text: #14532D;
  --color-success-surface: #E6F4EA;
  --color-warning: #7A5200;
  --color-warning-surface: #FFF4DC;
  --color-danger: #A62828;
  --color-danger-text: #8F1D1D;
  --color-danger-surface: #FCEBEA;
  --color-text: #1F2933;
  --color-text-muted: #52606D;
  --color-text-subtle: #7B8794;
  --color-border: #D3DCE3;
  --color-surface: #F5F7FA;
  --color-bg: #FBF9F6;
  --color-bg-elevated: #FFFFFF;
  --color-canvas: #E7E3DC; /* D-122: Fläche außerhalb des Inhaltscontainers, site-weit */
  --color-focus: #1B4965; /* auf dunklen Flächen wird --color-bg-elevated (#FFFFFF) verwendet, kein Zusatz-Token nötig */

  /* --- 13.2 Typografie -------------------------------------------------- */
  /* Self-Hosting umgesetzt in Track C (P-20/P-11, @font-face-Regeln siehe Block
     unter Abschnitt 1). Fallback-Stacks bleiben so robust, dass die Seite auch
     bei einem Ladefehler der woff2-Dateien sofort sinnvoll rendert. */
  --font-family-base: "Source Sans 3", system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
  --font-sans: var(--font-family-base); /* Alias, siehe Sprint-2-Auftrag Track B */
  --font-serif: "Source Serif 4", Georgia, "Times New Roman", serif; /* D-121: site-weit für Wortmarke, H1, H2 — nie H3/H4/Fließtext/Labels */

  --font-size-sm: 0.875rem;
  --font-size-base: clamp(1rem, 0.96rem + 0.25vw, 1.125rem);
  --font-size-lead: clamp(1.125rem, 1.07rem + 0.3vw, 1.25rem);
  --font-size-h4: 1.125rem;
  --font-size-h3: clamp(1.25rem, 1.19rem + 0.3vw, 1.375rem);
  --font-size-h2: clamp(1.5rem, 1.39rem + 0.55vw, 1.75rem);
  --font-size-h1: clamp(1.875rem, 1.6rem + 1.35vw, 2.5rem);

  --line-height-body: 1.65;
  --line-height-heading: 1.25;
  --line-height-tight: 1.4;

  --font-weight-regular: 400;
  --font-weight-semibold: 600;
  --font-weight-bold: 700;
  --font-weight-black: 900; /* ausschließlich H1/Wortmarke, siehe Abschnitt 4/10 — im Editorial-Broadsheet-Standard (04c) aktuell nicht angewandt (dort Gewicht 700), aber als Token verfügbar (D-118) */

  --content-max: 46rem; /* Lesespalte, ≈ 70 Zeichen */
  --container-max: 72rem; /* weiter Container: Hubs, Startseite, Kopf/Footer */

  /* --- 13.3 Spacing ------------------------------------------------------ */
  --space-3xs: 0.25rem;
  --space-2xs: 0.5rem;
  --space-xs: 0.75rem;
  --space-s: 1rem;
  --space-m: 1.5rem;
  --space-l: 2rem;
  --space-xl: 3rem;
  --space-2xl: 4rem;
  --space-3xl: 6rem;

  /* --- 13.4 Radius und Schatten ------------------------------------------ */
  --radius-s: 0.25rem; /* Buttons, Eingabefelder — 04c/D-123: Buttons bleiben eckig */
  --radius-m: 0.5rem; /* Karten, Boxen */
  --radius-l: 1rem; /* aus 04a/D-118, bleibt verfügbar (aktuell nicht im gewählten Standard genutzt) */
  --radius-full: 999px; /* Pill-Form/Kreis, z. B. Autorenbox-Avatar */
  --shadow-s: 0 1px 3px rgb(31 41 51 / 0.08);
  --shadow-m: 0 4px 12px rgb(31 41 51 / 0.12);

  /* --- 13.6 Bewegung ------------------------------------------------------ */
  --duration-fast: 120ms;
  --duration-base: 200ms;
  --easing-standard: ease-out;
}

/*
  @font-face: Track C (P-20/P-11) — Source Sans 3 + Source Serif 4, self-hosted
  (SIL OFL 1.1, nie Google-Fonts-CDN, DSGVO/04 §6.1, P-10). Bezug: npm-Pakete
  @fontsource/source-sans-3@5.3.0 / @fontsource/source-serif-4@5.3.0 (identische
  Dateien wie die offiziellen Adobe-Fonts-Releases, siehe docs/redaktion/lizenzregister.md
  §1.1/§1.2). Nur die tatsächlich benötigten statischen Schnitte 400/600/700 (normal,
  kein Italic, kein Variable Font) im "latin"-Subset — dieses Subset deckt den
  Unicode-Bereich U+0000–00FF (deutsche Umlaute/ß) und U+20AC (Euro-Zeichen)
  vollständig ab, daher kein zusätzliches latin-ext nötig. Dateien liegen unter
  src/assets/fonts/ (Lizenztexte: OFL-source-sans-3.txt / OFL-source-serif-4.txt),
  werden von scripts/fingerprint-assets.js gehasht; die url()-Referenzen unten
  verwenden bewusst die unfingerprinteten Namen, das Skript schreibt sie im
  Post-Build-Schritt auf die gehashten Dateinamen um.

  Performance-Budget-Hinweis (D-061): Mit dieser Ergänzung lädt jede Seite site-weit
  ZWEI Font-Familien (bis zu 3 Schnitte je Familie). Gegenmaßnahmen bereits umgesetzt:
  nur genutzte Schnitte (keine 200/300/500/800/900, kein Italic), Latin-Subsetting
  (kein Cyrillic/Greek/Vietnamese/Latin-Ext), `font-display: swap` gegen
  Render-Blocking. Core-Web-Vitals-Nachmessung mit beiden Familien ist für Sprint 10
  vorgesehen (07 CWV-Budget: LCP ≤ 2,5 s auch mit aktiver Werbung).
*/

@font-face {
  font-family: "Source Sans 3";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/assets/fonts/source-sans-3-latin-400-normal.0f73f35e08.woff2") format("woff2");
}

@font-face {
  font-family: "Source Sans 3";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("/assets/fonts/source-sans-3-latin-600-normal.14527d193b.woff2") format("woff2");
}

@font-face {
  font-family: "Source Sans 3";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("/assets/fonts/source-sans-3-latin-700-normal.ae35266f2a.woff2") format("woff2");
}

@font-face {
  font-family: "Source Serif 4";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/assets/fonts/source-serif-4-latin-400-normal.02194deb92.woff2") format("woff2");
}

@font-face {
  font-family: "Source Serif 4";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("/assets/fonts/source-serif-4-latin-600-normal.f2b7e1cf1d.woff2") format("woff2");
}

@font-face {
  font-family: "Source Serif 4";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("/assets/fonts/source-serif-4-latin-700-normal.7691c51bc2.woff2") format("woff2");
}

/*
  13.5 Breakpoints (Referenzwerte — Custom Properties sind in @media nicht nutzbar,
  04 §13.5). In diesem Stylesheet als Kommentarkonvention konsistent verwendet:
    --bp-sm:  30rem (480px)
    --bp-md:  48rem (768px)  — hier als Grenze Mobil-Overlay/Desktop-Nav genutzt
    --bp-lg:  64rem (1024px)
    --bp-xl:  80rem (1280px)
*/

/* ==========================================================================
   2. Basis-Reset & Grundgerüst
   ========================================================================== */

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

html {
  /* Root-Schriftgröße bleibt unangetastet (04 §15.2) — Nutzer-Zoom muss wirken */
  scroll-behavior: smooth;
}

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

body {
  margin: 0;
  font-family: var(--font-family-base);
  font-size: var(--font-size-base);
  line-height: var(--line-height-body);
  color: var(--color-text);
  background: var(--color-canvas); /* D-122: Fläche außerhalb des Inhaltscontainers */
  padding: var(--space-xs);
}

@media (min-width: 48rem) {
  body {
    padding: var(--space-l);
  }
}

@media (min-width: 64rem) {
  body {
    padding: var(--space-2xl) var(--space-l);
  }
}

/* Inhaltscontainer ("Blatt auf dem Tisch", 04 §7.2/D-122): Kopf, Inhalt und
   Footer stehen gemeinsam auf einer minimal helleren Papierfläche innerhalb
   der Canvas-Fläche des <body>. */
.site-shell {
  max-width: var(--container-max);
  margin-inline: auto;
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-m);
  box-shadow: var(--shadow-m);
  overflow: clip;
}

/* ==========================================================================
   3. Utilities
   ========================================================================== */

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* Skip-Link: sichtbar bei Tastaturfokus (04 §15, WCAG 2.4.1) */
/* ":visited" explizit, sonst überschreibt "a:visited" (§4, Spezifität 0,1,1) die helle
   Textfarbe mit Primärblau — unsichtbar auf dem primärblauen Grund (vgl. Kommentar §5 Buttons). */
.skip-link,
.skip-link:visited {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 1000;
  padding: var(--space-2xs) var(--space-s);
  background: var(--color-primary);
  color: var(--color-bg-elevated);
  text-decoration: none;
  font-weight: var(--font-weight-semibold);
  border-radius: 0 0 var(--radius-s) 0;
}

.skip-link:focus {
  left: 0;
}

/* Sichtbarer Fokus für ALLE interaktiven Elemente, ohne Ausnahme (04 §14.2) */
:focus-visible {
  outline: 3px solid var(--color-focus);
  outline-offset: 2px;
}

/* Breite Container-Bausteine (04 §7.2): .container = weiter Container (Hubs,
   Startseite, Kopf/Footer); .container--narrow = Lesespalte (Artikel/Rechtstexte). */
.container {
  max-width: var(--container-max);
  margin-inline: auto;
  padding-inline: var(--space-s);
}

@media (min-width: 48rem) {
  .container {
    padding-inline: var(--space-l);
  }
}

.container--narrow {
  max-width: var(--content-max);
}

.icon {
  width: 1.5rem;
  height: 1.5rem;
  flex-shrink: 0;
}

.icon--sm {
  width: 1.25rem;
  height: 1.25rem;
}

.tabular-nums {
  font-variant-numeric: tabular-nums;
}

/* Gezielte Silbentrennung für sehr lange Komposita auf schmalen Viewports
   (04 §6.2) — bewusst kein globales hyphens:auto, nur als Opt-in-Klasse. */
.hyphenate {
  hyphens: none;
}

@media (max-width: 30rem) {
  .hyphenate {
    hyphens: auto;
  }
}

/* Sprint 11 WP-1/A-4 (SC 1.4.10 Reflow): ".site-shell" clippt mit "overflow: clip"
   (§2) unsichtbar statt zu scrollen – ohne Umbruch-Fallback wird ein sehr langes,
   leerzeichenloses Wort (lange Komposita, Hostnamen in Linktexten) bei 320px
   abgeschnitten statt umgebrochen (Inhaltsverlust, bestätigter Fall: /datenschutz/).
   Bewusst NUR auf Fließtext-Container, NICHT auf Tabellen/".table-scroll" (§6) – deren
   "overflow-x: auto" bleibt für breite Tabellen unverändert wirksam, Zellinhalte sind
   hier kein bestätigter Fall. */
.artikel-prose,
.register__excerpt,
.site-footer,
.breadcrumbs {
  overflow-wrap: break-word;
}

/* Bestätigter Einzelfall: <code>-Inline-Elemente (z. B. Hostnamen in der DSE) sind ein
   einzelnes, leerzeichenloses "Wort" – Umbruch-Fallback unabhängig vom umgebenden
   Container, damit auch künftige Vorkommen außerhalb der obigen Liste abgedeckt sind. */
code {
  overflow-wrap: break-word;
}

/* ==========================================================================
   4. Typografie
   ========================================================================== */

h1,
h2,
h3,
h4 {
  color: var(--color-text);
  font-weight: var(--font-weight-bold);
  line-height: var(--line-height-heading);
  text-wrap: balance;
}

/* D-121: site-weit Serif für H1/H2 auf ALLEN Seiten; H3/H4 bleiben Source Sans 3 */
h1,
h2 {
  font-family: var(--font-serif);
}

h3,
h4 {
  font-family: var(--font-family-base);
  line-height: var(--line-height-tight);
}

h1 {
  font-size: var(--font-size-h1);
  margin: 0 0 var(--space-l);
}

/* Vor jeder H2 deutlich mehr Raum als danach (04 §7.3 Weißraum-Prinzip) */
h2 {
  font-size: var(--font-size-h2);
  margin: var(--space-xl) 0 var(--space-s);
}

h3 {
  font-size: var(--font-size-h3);
  margin: var(--space-l) 0 var(--space-xs);
}

h4 {
  font-size: var(--font-size-h4);
  margin: var(--space-m) 0 var(--space-2xs);
}

p {
  margin: 0 0 var(--space-s);
  text-align: left; /* nie Blocksatz, 04 §6.2 */
}

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

.lead {
  font-family: var(--font-family-base);
  font-size: var(--font-size-lead);
  line-height: 1.6;
  font-weight: var(--font-weight-regular);
  color: var(--color-text);
}

ul,
ol {
  margin: 0 0 var(--space-s);
  padding-inline-start: 1.25em;
}

li {
  margin-bottom: var(--space-2xs);
}

li:last-child {
  margin-bottom: 0;
}

strong {
  font-weight: var(--font-weight-bold);
}

em {
  font-style: italic;
}

small,
.text-sm {
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
}

/* Textlinks im Fließtext: Primärfarbe + Unterstreichung als einziges
   nicht-farbliches Merkmal (04 §10.1, WCAG SC 1.4.1) */
a {
  color: var(--color-primary);
  text-decoration: underline;
  text-decoration-thickness: max(1px, 0.08em);
  text-underline-offset: 0.15em;
}

a:hover {
  color: var(--color-primary-dark);
}

a:visited {
  color: var(--color-primary); /* 04 §14.3: besuchte Links behalten die Linkfarbe */
}

/* ==========================================================================
   5. Buttons
   ========================================================================== */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2xs);
  min-height: 44px;
  padding: var(--space-xs) var(--space-m);
  border-radius: var(--radius-s);
  border: 1.5px solid transparent;
  font-family: var(--font-family-base);
  font-weight: var(--font-weight-bold);
  font-size: var(--font-size-base);
  line-height: 1.2;
  text-decoration: none;
  cursor: pointer;
  transition:
    background-color var(--duration-fast) var(--easing-standard),
    color var(--duration-fast) var(--easing-standard),
    border-color var(--duration-fast) var(--easing-standard);
}

/* Buttons werden teils als <a> gerendert (Hero-CTA, Lernpfad-Navigation). Die globale
   Regel "a:visited" (§4) hat Spezifität (0,1,1) und schlägt damit reine Klassen-Selektoren
   (0,1,0): Auf besuchten Links würde der Text primär-auf-primär und damit unsichtbar
   (Betreiber-Befund 2026-08-08, Hero "Themen entdecken"). Darum führt jede Button-Variante
   ":visited" explizit in der Selektorliste mit — die Hover-Regeln (0,2,0) sind von allein
   spezifischer. Gleiches Muster beim .skip-link (§3). */
.btn--primary,
.btn--primary:visited {
  background: var(--color-primary);
  border-color: var(--color-primary);
  color: var(--color-bg-elevated);
}

.btn--primary:hover {
  background: var(--color-primary-dark);
  border-color: var(--color-primary-dark);
  color: var(--color-bg-elevated);
}

.btn--secondary,
.btn--secondary:visited {
  background: transparent;
  border-color: var(--color-primary);
  color: var(--color-primary);
}

.btn--secondary:hover {
  background: var(--color-primary-light);
  border-color: var(--color-primary-dark);
  color: var(--color-primary-dark);
}

/* ==========================================================================
   6. Tabellen
   ========================================================================== */

.table-scroll {
  overflow-x: auto;
  margin-block: var(--space-l);
}

/* N-19 (Sprint 8/10, WCAG 2.1.1): tabindex="0"/role="region"/aria-label werden zentral als
   Eleventy-Transform ergänzt (eleventy.config.js, "tableScrollA11y") – hier nur der sichtbare
   Fokusring, wenn der Wrapper dadurch fokussierbar/mit der Tastatur scrollbar wird. Die
   site-weite ":focus-visible"-Regel (oben, §3 Utilities) deckt das an sich schon ab ("ALLE
   interaktiven Elemente, ohne Ausnahme"); die explizite Regel hier macht den Fokusindikator für
   dieses Muster zusätzlich unabhängig von künftigen Änderungen an der globalen Regel – gleiches
   Token, keine neue Optik. overflow-x:auto clippt den eigenen Outline nicht (nur den Inhalt). */
.table-scroll:focus-visible {
  outline: 3px solid var(--color-focus);
  outline-offset: 2px;
}

table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--font-size-base);
}

caption {
  caption-side: top;
  text-align: left;
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
  margin-bottom: var(--space-2xs);
}

thead th {
  text-align: left;
  font-weight: var(--font-weight-bold);
  border-bottom: 2px solid var(--color-border);
  padding: var(--space-xs) var(--space-s);
  vertical-align: bottom;
}

tbody th,
tbody td {
  padding: var(--space-xs) var(--space-s);
  border-bottom: 1px solid var(--color-border);
  text-align: left;
}

tbody tr:nth-child(even) {
  background: var(--color-surface);
}

/* Zahlenspalten: rechtsbündig + Tabellenziffern (04 §6.1/§10.1) */
.table-numeric,
td[data-numeric],
th[data-numeric] {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* ==========================================================================
   7. Lernbausteine (Box-System) — D-123 editorial-flach
   Basisregeln: heller Haarlinien-Rahmen (--color-border) statt gefüllter Fläche,
   4px-Akzentkante links in der Semantik-Vollfarbe, Titelzeile aus Icon + Label
   in der dunklen Semantikfarbe, Fließtext immer --color-text (nie Semantikfarbe).
   PFLICHT-AUSNAHME (nicht verhandelbar): Risikohinweis- und Warnhinweisbox
   behalten die helle Semantik-Füllfläche, der Disclaimer-Baustein bleibt neutral
   grau — alle drei NICHT auf Haarlinie reduzieren (04 §10.2, D-123).
   ========================================================================== */

.lernbaustein {
  --lb-accent: var(--color-primary);
  --lb-label-color: var(--color-primary);
  position: relative;
  margin-block: var(--space-l);
  padding: var(--space-m);
  background: transparent; /* editorial-flach: steht auf dem Papiergrund, keine eigene Fläche */
  border: 1px solid var(--color-border);
  border-left: 4px solid var(--lb-accent);
  border-radius: var(--radius-m);
}

.lernbaustein__title {
  display: flex;
  align-items: center;
  gap: var(--space-2xs);
  margin: 0 0 var(--space-2xs);
  font-family: var(--font-family-base); /* Box-Titel bleiben Source Sans, D-121 */
  font-size: var(--font-size-h4);
  font-weight: var(--font-weight-bold);
  line-height: var(--line-height-tight);
  color: var(--lb-label-color);
}

.lernbaustein__icon {
  color: var(--lb-label-color);
}

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

/* Definitionsbox: „Einfach erklärt" */
.lernbaustein--definition {
  --lb-accent: var(--color-primary);
  --lb-label-color: var(--color-primary);
}

/* Beispielbox: „Beispiel (hypothetisch)" */
.lernbaustein--beispiel {
  --lb-accent: var(--color-accent);
  --lb-label-color: var(--color-accent);
}

/* Merksatzbox: „Merksatz" */
.lernbaustein--merksatz {
  --lb-accent: var(--color-accent);
  --lb-label-color: var(--color-accent);
}

/* Infobox: „Gut zu wissen" */
.lernbaustein--info {
  --lb-accent: var(--color-info);
  --lb-label-color: var(--color-info);
}

/* Kurzfassungsbox: „Das Wichtigste in Kürze" — eigene Variante (M-03, Sprint 7;
   vormals Wiederverwendung von .lernbaustein--info mit abweichendem Titeltext).
   Teilt sich bewusst die Info-Akzentfarbe (kein neues Farb-Token/keine neue Kontrast-
   Paarung, D-123) — Unterscheidung von der Infobox ausschließlich über eigenes Icon
   ("list") + eigenes festes Label, exakt wie sich Beispiel- und Merksatzbox oben
   bereits eine Akzentfarbe teilen und nur über Icon/Label unterschieden werden. */
.lernbaustein--kurzfassung {
  --lb-accent: var(--color-info);
  --lb-label-color: var(--color-info);
}

/* Warnhinweisbox: „Achtung" — PFLICHT-AUSNAHME: helle Füllfläche bleibt erhalten */
.lernbaustein--warnung {
  --lb-accent: var(--color-warning);
  --lb-label-color: var(--color-warning);
  background: var(--color-warning-surface);
  border-color: var(--color-warning-surface);
  /* border-color-Shorthand überschreibt auch border-left-color — 4px-Semantikkante
     danach erneut in der Vollfarbe setzen (QS-Fix, siehe Risikobox). */
  border-left-color: var(--lb-accent);
  print-color-adjust: exact;
  -webkit-print-color-adjust: exact;
}

/* Risikohinweisbox: „Risiko" — PFLICHT-AUSNAHME: helle Füllfläche bleibt erhalten,
   damit die Warnung in der ruhigen Haarlinien-Umgebung nicht untergeht. */
.lernbaustein--risiko {
  --lb-accent: var(--color-danger);
  --lb-label-color: var(--color-danger-text);
  background: var(--color-danger-surface);
  border-color: var(--color-danger-surface);
  /* border-color-Shorthand überschreibt auch border-left-color — 4px-Semantikkante
     danach erneut in der Vollfarbe setzen (QS-Fix). */
  border-left-color: var(--lb-accent);
  print-color-adjust: exact;
  -webkit-print-color-adjust: exact;
}

/* Disclaimer-Baustein: „Keine Anlageberatung" — PFLICHT-AUSNAHME: bewusst neutral
   grau (weiße Fläche, grauer Rahmen ringsum, KEINE farbige Akzentkante), damit die
   Risiko-Semantik nicht verwässert wird (04 §10.2). */
.lernbaustein--disclaimer {
  --lb-label-color: var(--color-text-muted);
  background: var(--color-bg-elevated);
  border-color: var(--color-border);
  border-left-width: 1px;
  border-left-color: var(--color-border);
}

/* ==========================================================================
   8. Autorenbox
   Trust-/E-E-A-T-Baustein (04 §10.1, F-41/D-109). Im Zuge von D-123 im gleichen
   editorial-flachen Muster wie die Lernbausteine (Haarlinie + Primärfarb-Akzent-
   kante + Icon/Label „Über die Autorin/den Autor"), Klarname als eigenständige
   Auszeichnung neben dem Portrait/Avatar.
   ========================================================================== */

.lernbaustein--autor {
  --lb-accent: var(--color-primary);
  --lb-label-color: var(--color-primary);
}

.autorenbox__body {
  display: flex;
  align-items: flex-start;
  gap: var(--space-m);
  flex-wrap: wrap;
}

.autorenbox__avatar {
  width: 64px;
  height: 64px;
  border-radius: var(--radius-full);
  object-fit: cover;
  flex-shrink: 0;
}

.autorenbox__name {
  margin: 0;
  font-family: var(--font-family-base);
  font-size: var(--font-size-h4);
  font-weight: var(--font-weight-bold);
  color: var(--color-text);
}

.autorenbox__role {
  margin: 0 0 var(--space-2xs);
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
}

.autorenbox__text {
  margin: 0 0 var(--space-2xs);
}

.autorenbox__text:last-child {
  margin-bottom: 0;
}

/* ==========================================================================
   9. Register-/Haarlinien-Komponente (D-123)
   Für allgemeine Inhalte (Artikel-/Themen-Teaser, Hub-/Übersichtslisten,
   „verwandte Artikel", Listen) statt gefüllter Karten mit Schatten (04 §10.1).
   Kein neues Token — Trenner ausschließlich --color-border.
   ========================================================================== */

.register {
  list-style: none;
  margin: 0;
  padding: 0;
  border-top: 1px solid var(--color-border);
}

.register__item {
  position: relative;
  padding-block: var(--space-m);
  border-bottom: 1px solid var(--color-border);
  transition: background-color var(--duration-fast) var(--easing-standard);
}

.register__item:hover,
.register__item:focus-within {
  background: var(--color-surface);
}

.register__kicker {
  margin: 0 0 var(--space-3xs);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-text-muted);
}

.register__title {
  margin: 0 0 var(--space-2xs);
  font-family: var(--font-family-base); /* Register-Titel bleiben Source Sans; Serif ist Wortmarke/H1/H2 vorbehalten, D-121 */
  font-size: var(--font-size-h4);
  font-weight: var(--font-weight-bold);
  line-height: var(--line-height-tight);
}

.register__title a {
  color: var(--color-primary);
  text-decoration: none;
}

/* Ganze Zeile klickbar, aber genau ein Link im Markup (Screenreader-freundlich) */
.register__title a::after {
  content: "";
  position: absolute;
  inset: 0;
}

.register__title a:hover,
.register__item:hover .register__title a {
  color: var(--color-primary-dark);
}

.register__excerpt {
  margin: 0 0 var(--space-2xs);
  color: var(--color-text);
}

.register__meta {
  margin: 0;
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
}

/* Optionale mehrspaltige Variante für breite Übersichtsseiten (04 §7.2) */
@media (min-width: 48rem) {
  .register--grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    column-gap: var(--space-l);
  }

  .register--grid .register__item {
    border-bottom: 1px solid var(--color-border);
  }
}

/* ==========================================================================
   10. Navigation & Kopfbereich
   Zwei Ausprägungen (D-123, 04 §11.1): großer zentrierter „bookish" Kopf nur auf
   der Startseite, kompakter Serifen-Kopf auf allen Unterseiten. Mobile Navigation
   progressiv verbessert: ohne JS bleibt die Liste inline sichtbar (keine Faltung/
   kein Overlay); mit JS (Klasse „js" auf <html>, siehe base.njk) wird sie ab der
   Mobil-Grenze (48rem) hinter einem Button mit aria-expanded zum Overlay
   (Fokusfalle + Escape: assets/js/site.js).
   ========================================================================== */

/* Sprint 11 WP-1/A-1: eigenen Stapelkontext über dem geöffneten mobilen Nav-Overlay
   halten (".js .primary-nav.is-open", z-index 300, weiter unten in diesem Abschnitt) –
   sonst überdeckt das fixierte Overlay die Kopfzeile samt Schließen-Button, weil ein
   positioniertes Element ohne eigenen z-index sonst hinter jedem positionierten
   Geschwister-/Nachfahren-Element liegt. Einziger weiterer z-index im Stylesheet ist
   der Skip-Link (1000, §3) – bleibt darüber. Der Google-CMP-Dialog wird als
   Drittanbieter-iframe zur Laufzeit injiziert, ist hier nicht referenziert und liegt in
   einem eigenen, deutlich höheren Stapelkontext. */
.site-header {
  position: relative;
  z-index: 400;
  border-bottom: 1px solid var(--color-border);
}

.site-header__inner {
  padding-block: var(--space-s);
}

.site-header__bar {
  display: flex;
  align-items: center;
  /* Sprint 12 WP-1 (Dark Mode, D-148): war "space-between". Seit Sprint 16 (D-5,
     Übergabepunkt aus Sprint 12) steht der Dark-Mode-Umschalter als statisches Markup
     in partials/nav.njk (zwischen Wortmarke und .nav-toggle) – vorher hat
     assets/js/site.js ihn zur Laufzeit als drittes Element in diese Leiste eingefügt.
     "space-between" würde drei Elemente gleichmäßig über die volle Breite verteilen
     (Umschalter mittig, große Lücken) – "flex-start" + "margin-inline-start: auto" auf
     ".theme-toggle" (unten) hält die Wortmarke links und schiebt Umschalter+Menü-Button
     gemeinsam nach rechts, unabhängig davon, ob beide gerade sichtbar sind. Ohne JS
     bleiben .nav-toggle UND .theme-toggle unconditional display:none (§10) – keine
     optische Änderung für No-JS-Besucher, nur die Wortmarke ist sichtbar. */
  justify-content: flex-start;
  gap: var(--space-s);
  /* Sprint 11 WP-1/A-1 (Teil 2): Die Kopfzeilen-Leiste (Wortmarke + Menü-/Schließen-Button)
     liegt als GESCHWISTER der .primary-nav im selben Header-Stapelkontext – der z-index
     der .site-header allein reicht daher nicht (im Live-Nachtest verifiziert): Innerhalb
     des Header-Kontexts überdeckte das Overlay (z-index 300) die Leiste weiterhin.
     Erst dieser Rang macht den Schließen-Button bei geöffnetem Overlay sicht- und klickbar. */
  position: relative;
  z-index: 400;
}

.wortmarke {
  margin: 0;
  font-family: var(--font-serif); /* D-121: Wortmarke site-weit in Serif */
  font-weight: var(--font-weight-bold);
  font-size: var(--font-size-h3);
  color: var(--color-primary);
}

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

/* --- Großer, zentrierter „bookish" Kopf — nur Startseite --- */

.site-header--hero {
  border-bottom: none;
}

.site-header--hero .site-header__inner {
  padding-block: var(--space-l) var(--space-s);
  text-align: center;
}

.site-header__eyebrow {
  margin: 0 0 var(--space-2xs);
  font-family: var(--font-family-base);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-bold);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-accent);
}

.site-header--hero .wortmarke {
  font-size: clamp(1.75rem, 1.4rem + 1.6vw, 2.5rem);
}

.site-header--hero .site-header__bar {
  justify-content: center;
  border-bottom: 1px solid var(--color-primary);
  padding-bottom: var(--space-s);
  margin-bottom: var(--space-s);
}

/* Sprint 12, Betreiber-Feedback D-150: Im Hero-Kopf gehört der Umschalter NICHT in die
   zentrierte Wortmarken-Gruppe, sondern nach oben rechts (übliche Position auf den
   meisten Websites). Auto-Margin-Trick (§10 unten) hier zurücknehmen und stattdessen
   an der rechten Kante der Leiste verankern; Anker ist die .site-header__bar
   (position:relative/z-index 400 seit Sprint 11 WP-1/A-1).
   NUR ab 48rem: Darunter steht zusätzlich der Menü-Button in der zentrierten Gruppe –
   eine absolute Rechts-Position würde ihn bei schmalen Viewports (320px im Nachtest)
   überlappen. Mobil bleibt der Umschalter deshalb Teil der zentrierten Gruppe. */
.site-header--hero .theme-toggle {
  margin-inline-start: 0;
}

@media (min-width: 48rem) {
  .site-header--hero .theme-toggle {
    position: absolute;
    right: 0;
    /* Bewusst OHNE top/transform: Ohne Block-Achsen-Angabe behält ein absolut
       positioniertes Flex-Kind seine statische Position aus "align-items: center" der
       Leiste – also exakt auf der Wortmarken-Mittellinie. "top: 50%" würde stattdessen
       die halbe Leistenhöhe INKLUSIVE deren padding-bottom messen und den Umschalter im
       Nachtest um 8px nach unten versetzen. */
  }
}

.site-header--hero .primary-nav {
  justify-content: center;
}

/* --- Mobile Toggle (progressive enhancement) --- */

.nav-toggle {
  display: none; /* bleibt verborgen, solange keine JS-Verbesserung aktiv ist */
  align-items: center;
  gap: var(--space-3xs);
  min-height: 44px;
  min-width: 44px;
  /* Als Flex-Kind der .site-header__bar darf der Button nicht unter seine
     Inhaltsbreite gestaucht werden (Standard flex-shrink: 1) – sonst ragt das
     Label "Menü" auf schmalen Viewports über den Rahmen hinaus; den Platzdruck
     fängt stattdessen die umbruchfähige Wortmarke ab. */
  flex-shrink: 0;
  white-space: nowrap;
  padding: var(--space-2xs) var(--space-s);
  background: transparent;
  /* Sprint 11 WP-1/B-7: an A-3 angeglichen (kein eigener Verstoß, Identifikation ist
     über das sichtbare Textlabel "Menü"/"Schließen" gesichert – reine Konsistenz). */
  border: 1.5px solid var(--color-text-subtle);
  border-radius: var(--radius-s);
  color: var(--color-primary);
  font-family: var(--font-family-base);
  font-weight: var(--font-weight-semibold);
  font-size: var(--font-size-sm);
  cursor: pointer;
}

.nav-toggle__icon--close,
.nav-toggle[aria-expanded="true"] .nav-toggle__icon--open,
.nav-toggle__label-close,
.nav-toggle[aria-expanded="true"] .nav-toggle__label-open {
  display: none;
}

.nav-toggle[aria-expanded="true"] .nav-toggle__icon--close,
.nav-toggle[aria-expanded="true"] .nav-toggle__label-close {
  display: inline-flex;
}

/* --- Dark-Mode-Umschalter (F-26, D-148, Sprint 12 WP-1) ---------------------
   Seit Sprint 16 (D-5, Übergabepunkt aus Sprint 12 "Offene Übergaben" Nr. 3)
   statisches Markup in partials/nav.njk (zwischen Wortmarke und .nav-toggle) statt
   Laufzeit-Injektion durch assets/js/site.js – Sichtbarkeits-Gating übernimmt EXAKT
   das .nav-toggle-Muster oben: "display: none" als Grundzustand, erst
   ".js .theme-toggle" (unten) schaltet sichtbar UND fokussierbar. Ohne JS bleibt der
   Button unsichtbar (kein funktionsloser Button ohne JS, ohne Speicherzugriff könnte
   er seine Funktion ohnehin nicht erfüllen) – Dark Mode selbst bleibt über den reinen
   "prefers-color-scheme"-Grundfall (D-148) trotzdem vollständig funktionsfähig, nur
   ohne manuelle Übersteuerung. Anders als .nav-toggle gilt das Gating hier NICHT nur
   unterhalb der Mobil-Grenze, sondern auf allen Breiten (kein @media-Innenblock, kein
   erneutes display:none auf Desktop) – der Umschalter ist unabhängig von der
   Viewport-Breite verfügbar. Icon-only (Lucide "moon"/"sun", ISC-Lizenz,
   partials/icons.njk), Accessible Name "Dunkelmodus" + Zustand über aria-pressed
   (Standardmuster für Umschalter).
   ZWEI Zustände seit D-151 (Betreiber: "brauchen wir nicht eigentlich nur Sonne und
   Mond?") – der dritte Zustand "Systemeinstellung" aus D-149/L-4 ist entfallen, weil sein
   kombiniertes Sonne-Mond-Symbol bei 20px nicht erkennbar war. data-theme-zustand
   ("light"/"dark") steuert nur noch, welches der beiden Symbole sichtbar ist; gezeigt wird
   die AKTUELL wirksame Darstellung. Kontraststand siehe Abschnitt 23 "Dark Mode". */
.theme-toggle {
  display: none; /* bleibt verborgen, solange keine JS-Verbesserung aktiv ist (wie .nav-toggle oben) */
  align-items: center;
  justify-content: center;
  min-height: 44px;
  min-width: 44px;
  flex-shrink: 0; /* wie .nav-toggle: nie unter Inhaltsbreite stauchen (s. Kommentar dort) */
  margin-inline-start: auto; /* schiebt sich + .nav-toggle gemeinsam nach rechts, s. §10-Kommentar oben */
  padding: var(--space-2xs);
  background: transparent;
  border: 1.5px solid var(--color-text-subtle);
  border-radius: var(--radius-s);
  color: var(--color-primary);
  cursor: pointer;
}

/* Sichtbar/fokussierbar erst mit aktivem JS (assets/js/site.js verdrahtet Klick +
   Zustand) – progressive enhancement, identisches Prinzip wie ".js .nav-toggle"
   weiter unten, hier aber bewusst OHNE @media-Einschränkung (der Umschalter gehört
   auf jede Breite, nicht nur mobil).
   qa-Gate Sprint 16, Auflage QA-8: zusätzlich an [data-theme-zustand] gebunden –
   das Attribut setzt erst site.js beim Initialisieren. Nur ".js" reichte nicht:
   Die .js-Klasse wird von einem frühen Inline-Snippet gesetzt, das deferred site.js
   läuft aber später – im Ladefenster dazwischen war der Button sichtbar und
   fokussierbar, zeigte aber KEIN Icon (Icons hängen an [data-theme-zustand],
   siehe Regeln unten). Mit dem Attribut-Gate erscheint der Button erst fertig
   initialisiert samt Symbol; ohne JS bleibt er wie bisher komplett verborgen. */
.js .theme-toggle[data-theme-zustand] {
  display: inline-flex;
}

.theme-toggle:hover {
  border-color: var(--color-primary);
}

.theme-toggle .theme-toggle__icon {
  display: none;
}

.theme-toggle[data-theme-zustand="light"] .theme-toggle__icon--sun,
.theme-toggle[data-theme-zustand="dark"] .theme-toggle__icon--moon {
  display: inline-flex;
}

/* --- Hauptnavigation: gemeinsames Markup, responsive Darstellung --- */

.primary-nav__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
}

.primary-nav__list a {
  display: flex;
  align-items: center;
  min-height: 44px;
  color: var(--color-text);
  font-weight: var(--font-weight-semibold);
  text-decoration: none;
}

.primary-nav__list a:hover {
  color: var(--color-primary);
}

/* Aktueller Bereich: Unterstreichungsbalken in --color-primary + aria-current (04 §11.1) */
.primary-nav__list a[aria-current="page"] {
  color: var(--color-primary);
  box-shadow: inset 0 -3px 0 0 var(--color-primary);
}

.primary-nav__search {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3xs);
  min-height: 44px;
  color: var(--color-accent);
  font-weight: var(--font-weight-semibold);
  text-decoration: none;
}

.primary-nav__search:hover {
  color: var(--color-primary-dark);
}

@media (max-width: 47.9375rem) {
  /* Ohne JS: Liste bleibt einfach, gestapelt, immer sichtbar (kein Overlay). */
  .primary-nav {
    padding-block: var(--space-s);
    border-top: 1px solid var(--color-border);
  }

  /* Mit JS (Klasse "js" auf <html>): Button sichtbar, Liste wird zum
     Vollbild-Overlay, das erst bei Aktivierung erscheint. */
  .js .nav-toggle {
    display: inline-flex;
  }

  .js .primary-nav {
    display: none;
    border-top: none;
  }

  .js .primary-nav.is-open {
    display: flex;
    flex-direction: column;
    position: fixed;
    inset: 0;
    z-index: 300;
    background: var(--color-bg);
    padding: var(--space-2xl) var(--space-l) var(--space-l);
    overflow-y: auto;
  }

  .js .primary-nav.is-open .primary-nav__list {
    gap: var(--space-s);
  }

  .js .primary-nav.is-open .primary-nav__list a,
  .js .primary-nav.is-open .primary-nav__search {
    font-size: var(--font-size-lead);
  }
}

/* Sprint 16 (D-5, Dark-Mode-Kleinkram-Merker aus Sprint 12/13/14/15): Auf sehr schmalen
   Viewports (WCAG-Reflow-Referenzbreite 320px, 04 §14.1) reichte der Platz in der
   Kopfzeilen-Leiste zwischen Wortmarke, Theme-Toggle und Menü-Button knapp nicht aus
   (Sprint-12-Nachtest: ~7px Überlauf, alle Elemente blieben sichtbar/klickbar — rein
   kosmetisch, kein WCAG-Verstoß). Fix nur unterhalb 360px: Lücke zwischen den drei
   Bar-Elementen sowie der seitliche Innenabstand des Menü-Buttons verringern sich auf
   --space-2xs. Die 44-px-Zielgröße bleibt unangetastet (min-height/min-width beider
   Buttons sind unabhängig von der Innenpolsterung gesetzt, §10 oben); der verbleibende
   Abstand zwischen Theme-Toggle und Menü-Button entspricht weiterhin genau dem in 04 §14.5
   geforderten Mindestabstand zwischen benachbarten Touch-Zielen (kein Unterschreiten von
   --space-2xs). Gilt für beide Kopf-Ausprägungen (kompakt und Hero), da .site-header__bar
   in beiden Fällen dieselbe Klasse trägt. */
@media (max-width: 22.5rem) {
  .site-header__bar {
    gap: var(--space-2xs);
  }

  .nav-toggle {
    padding-inline: var(--space-2xs);
  }
}

@media (min-width: 48rem) {
  .nav-toggle {
    display: none !important;
  }

  .primary-nav {
    display: flex !important;
    align-items: center;
    justify-content: flex-end;
    position: static;
    inset: auto;
    background: none;
    padding: 0;
    border: none;
    gap: var(--space-l);
  }

  .primary-nav__list {
    flex-direction: row;
    align-items: center;
    gap: var(--space-m);
  }

  .primary-nav__list a[aria-current="page"] {
    box-shadow: inset 0 -3px 0 0 var(--color-primary);
    padding-bottom: 2px;
  }
}

/* ==========================================================================
   11. Breadcrumbs
   ========================================================================== */

.breadcrumbs {
  padding-block: var(--space-s);
  font-size: var(--font-size-sm);
}

.breadcrumbs ol {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25em;
  list-style: none;
  padding: 0;
  margin: 0;
  color: var(--color-text-muted);
}

.breadcrumbs a {
  color: var(--color-text-muted);
  text-decoration: underline;
}

.breadcrumbs a:hover {
  color: var(--color-primary);
}

.breadcrumbs [aria-current="page"] {
  color: var(--color-text);
  font-weight: var(--font-weight-semibold);
}

.breadcrumbs li:not(:last-child)::after {
  content: "›";
  margin-inline: 0.25em;
  color: var(--color-text-subtle);
}

/* ==========================================================================
   12. Footer (hell, 04 §11.7 — keine dunkle Ausnahme)
   ========================================================================== */

.site-footer {
  margin-top: var(--space-2xl);
  border-top: 1px solid var(--color-border);
  background: var(--color-surface);
}

.site-footer .container {
  padding-block: var(--space-l) var(--space-m);
}

.site-footer__wortmarke {
  font-size: var(--font-size-h4);
  margin-bottom: var(--space-m);
}

.site-footer__orientation {
  display: grid;
  gap: var(--space-l);
  margin-bottom: var(--space-l);
  list-style: none;
  padding: 0;
}

@media (min-width: 48rem) {
  .site-footer__orientation {
    grid-template-columns: repeat(3, 1fr);
  }
}

.site-footer__group-title {
  margin: 0 0 var(--space-2xs);
  font-family: var(--font-family-base);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-bold);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-text-muted);
}

.footer-linklist {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
}

.footer-linklist a,
.footer-linklist button {
  color: var(--color-text);
  text-decoration: none;
}

.footer-linklist a:hover,
.footer-linklist button:hover {
  color: var(--color-primary);
  text-decoration: underline;
}

/* Sprint 10 (Aufgabe 2, Footer-Widerrufs-Button "Cookie-Einstellungen", J-7c): Browser-
   Standardoptik eines <button> zurückgesetzt, damit er sich optisch nicht von den <a>-Einträgen
   in derselben Liste unterscheidet ("als Text-Button im Stil der Footer-Links", editorial-flach,
   kein neues Token — Farbe/Hover kommen bereits aus der Regel oben). */
.footer-linklist button {
  font: inherit;
  background: none;
  border: none;
  /* Sprint 12 WP-3/R-11 (WCAG 2.5.8 Zielgröße ≥ 24px): der Widerrufs-Button
     ("Cookie-Einstellungen", J-7c) hatte padding:0 – die Trefferfläche war exakt auf die
     Textzeile beschränkt. Vertikales Padding vergrößert die klickbare/tippbare Fläche;
     die kompensierende negative Margin hält die sichtbare Zeilenposition/den Listenabstand
     unverändert (kein Layoutbruch, reine Trefferflächen-Vergrößerung). */
  padding: var(--space-3xs) 0;
  margin-block: calc(var(--space-3xs) * -1);
  cursor: pointer;
}

.footer-linklist--inline {
  flex-direction: row;
  flex-wrap: wrap;
  gap: var(--space-s) var(--space-m);
}

.site-footer__risikohinweis {
  max-width: var(--content-max);
  margin: 0 0 var(--space-m);
  padding-top: var(--space-m);
  border-top: 1px solid var(--color-border);
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
}

.site-footer__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-s);
  padding-top: var(--space-m);
  border-top: 1px solid var(--color-border);
}

.site-footer__copyright {
  margin: 0;
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
}

/* ==========================================================================
   13. Artikel-Layout (Meta-Zeile, Lernpfad-Hinweis, Voraussetzungen-Kasten, TOC)
   Sprint 3, Track A1 — Slots/Hülsen für Track B (Lesezeit/TOC-Generierung, B1)
   und Track C (Lernpfad-Datenauflösung, C4). Ohne echte Daten (aktueller Stand
   aller Platzhalter-Artikel) rendert keiner dieser Blöcke sichtbar etwas.
   ========================================================================== */

.artikel-layout {
  max-width: var(--content-max);
  margin-inline: auto;
  padding-inline: var(--space-s);
}

@media (min-width: 48rem) {
  .artikel-layout {
    padding-inline: var(--space-l);
  }
}

@media (min-width: 64rem) {
  .artikel-layout--with-toc {
    max-width: var(--container-max);
    display: grid;
    grid-template-columns: minmax(0, var(--content-max)) minmax(12rem, 1fr);
    gap: var(--space-2xl);
    align-items: start;
  }
}

.artikel-meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-m);
  margin: 0 0 var(--space-m);
}

.artikel-meta__item {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3xs);
  color: var(--color-text-muted);
}

/* Dezenter Lernpfad-Hinweis (D-119 harte Regel: KEIN Fortschrittsbalken/"Schritt X
   von Y" — deshalb bewusst nur Icon + Fließtext, keine Karte/Box/Füllfläche). */
.lernpfad-hinweis {
  display: flex;
  align-items: center;
  gap: var(--space-2xs);
  margin: 0 0 var(--space-m);
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
}

.lernpfad-hinweis__icon {
  color: var(--color-accent);
  width: 1.25rem;
  height: 1.25rem;
  flex-shrink: 0;
}

/* "Das solltest du vorher kennen"-Kasten (03 §1.2 Prinzip 2) — organisatorisch,
   kein Semantik-Baustein, daher neutraler Akzent statt Farbcodierung. */
.voraussetzungen-kasten {
  margin-block: var(--space-l);
  padding: var(--space-m);
  border: 1px solid var(--color-border);
  border-left: 4px solid var(--color-text-muted);
  border-radius: var(--radius-m);
}

.voraussetzungen-kasten__title {
  margin: 0 0 var(--space-2xs);
  font-weight: var(--font-weight-bold);
  font-size: var(--font-size-sm);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-text-muted);
}

.voraussetzungen-kasten ul {
  margin: 0;
}

/* Mobiles Inhaltsverzeichnis: natives <details>/<summary>, ohne JS, standardmäßig
   eingeklappt (04 §11.5). Ab 64rem übernimmt die sticky Desktop-Spalte. */
.artikel-toc--mobile {
  margin-block: var(--space-l);
  padding: var(--space-s) var(--space-m);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-m);
}

.artikel-toc--mobile summary {
  display: flex;
  align-items: center;
  gap: var(--space-2xs);
  cursor: pointer;
  font-weight: var(--font-weight-semibold);
  color: var(--color-primary);
}

.artikel-toc--mobile nav {
  margin-top: var(--space-s);
}

.artikel-toc--mobile ol {
  margin: 0;
}

@media (min-width: 64rem) {
  .artikel-toc--mobile {
    display: none;
  }
}

.artikel-layout__toc {
  display: none;
}

@media (min-width: 64rem) {
  .artikel-layout--with-toc .artikel-layout__toc {
    display: block;
    position: sticky;
    top: var(--space-l);
    align-self: start;
    font-size: var(--font-size-sm);
  }
}

.artikel-layout__toc-title {
  margin: 0 0 var(--space-2xs);
  font-weight: var(--font-weight-bold);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
}

.artikel-layout__toc ol {
  margin: 0;
  padding-inline-start: 0;
  list-style: none;
  border-left: 2px solid var(--color-border);
}

.artikel-layout__toc li {
  margin-bottom: 0;
}

.artikel-layout__toc a {
  display: block;
  padding: var(--space-3xs) 0 var(--space-3xs) var(--space-s);
  color: var(--color-text-muted);
  text-decoration: none;
}

.artikel-layout__toc a:hover {
  color: var(--color-primary);
}

/* Generische Blockquote-Optik — u. a. für die ENTWURF-Banner der Rechtsseiten
   (Inhalt bleibt unverändert, Scope-Grenze Track A: nur Gestaltung). */
blockquote {
  margin: var(--space-l) 0;
  padding: var(--space-xs) var(--space-m);
  border-left: 3px solid var(--color-border);
  color: var(--color-text-muted);
}

blockquote p:last-child {
  margin-bottom: 0;
}

/* Quellenliste (07 §10) — optionale, gedämpfte Darstellung für die
   Quellen-Sektion am Artikelende (content-authored, kein Pflichtbaustein). */
.quellenliste {
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
}

/* ==========================================================================
   14. Artikel-Aktionen (Teilen/Feedback, .js-only) + Lernpfad-Weiter
   Progressive Enhancement (DoD): Ohne JS bleibt je Aktion mindestens ein voll
   funktionsfähiges Element sichtbar (mailto-Links); .js-only blendet Elemente
   erst ein, wenn die Klasse "js" auf <html> aktiv ist (siehe base.njk).
   ========================================================================== */

.js-only {
  display: none;
}

.js .js-only {
  display: inline-flex;
}

/* Block-level Geschwisterklasse zu .js-only (Sprint 4, Track T, EP-05): für ganze
   Interaktionsbereiche, die ohne JavaScript grundsätzlich sinnlos/unbedienbar wären (Rechner-
   Formular, Speicher-Opt-in-Schalter — style.css §22) — im Unterschied zu .js-only (einzelne
   inline Buttons wie Teilen/Link-kopieren) hier als Block-Container. Ohne JS bleibt an dieser
   Stelle ausschließlich der <noscript>-Ersatzinhalt sichtbar (progressive enhancement, 05 §4.7). */
.js-only-block {
  display: none;
}

.js .js-only-block {
  display: block;
}

/* Sprint 3, Track C2 (05 §4.13): Teilen-/Link-kopieren-Buttons zusätzlich an die
   konkrete Browser-API gekoppelt (nicht nur an "JS ist aktiv"), damit nie ein
   funktionsloser Button erscheint. "can-share"/"can-clipboard" werden synchron
   VOR dem ersten Paint in base.njk gesetzt (kein Nachträglich-Verbergen, also
   kein Layout-Sprung). Höhere Spezifität als ".js .js-only", damit diese Regeln
   unabhängig von der Deklarationsreihenfolge gewinnen. */
.js [data-share-button].js-only {
  display: none;
}

.js.can-share [data-share-button].js-only {
  display: inline-flex;
}

.js [data-copy-link-button].js-only {
  display: none;
}

.js.can-clipboard [data-copy-link-button].js-only {
  display: inline-flex;
}

/* Sprint 4, Track T1 (05 §4.7 URL-Parameter-Skizze): "Diese Berechnung als Link kopieren"
   im Rechner-Ergebnisbereich folgt derselben can-clipboard-Kopplung wie oben — nie ein
   Knopf ohne funktionierende Zwischenablage-Aktion dahinter. */
.js [data-rechner-teilen-button].js-only {
  display: none;
}

.js.can-clipboard [data-rechner-teilen-button].js-only {
  display: inline-flex;
}

/* Sichtbare UND aria-live-angekündigte Erfolgs-/Fehlerrückmeldung fürs
   Link-kopieren (05 §4.13: "textuelle Bestätigung, aria-live") – eine einzige
   Quelle für beide Zielgruppen statt doppelter Texte. Im leeren Ausgangszustand
   wie ".sr-only" geklippt statt "display:none" – bewusst KEIN display/visibility-
   Wechsel, weil eine aria-live-Region zuverlässiger angekündigt wird, wenn sie schon
   VOR der Textänderung im Accessibility-Tree sichtbar ist (display:none/visibility:
   hidden entfernen ein Element daraus, reine Clip-/Positions-Verkleinerung nicht).
   Zugleich nimmt der geklippte Zustand keinen sichtbaren Platz ein (kein Layout-Sprung
   beim Laden); der kleine Sprung BEIM Klick selbst zählt ohnehin nicht gegen CLS
   (Layout-Verschiebungen innerhalb von 500 ms nach einer Nutzerinteraktion sind laut
   Web-Vitals-Definition von der CLS-Messung ausgenommen). */
.artikel-teilen__status {
  margin: var(--space-2xs) 0 0;
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
}

.artikel-teilen__status:empty {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

.artikel-aktion {
  margin-block: var(--space-l);
  padding-top: var(--space-m);
  border-top: 1px solid var(--color-border);
}

.artikel-aktion__label {
  margin: 0 0 var(--space-s);
  font-weight: var(--font-weight-semibold);
}

.artikel-aktion__buttons {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-s);
}

/* Lernpfad-Navigation als Button-Block (D-145, Betreiber-Entscheid 2026-08-08 — revidiert
   den "ruhigen Verweis" aus 04 §11.4: der alte .lernpfad-weiter-Block am Seitenende war zu
   schwer auffindbar). Identischer Block an zwei Stellen in artikel.njk (nach dem Artikel-Meta
   und direkt nach dem Artikeltext). Nutzt die bestehenden .btn-Styles (§5) — Weiter =
   .btn--primary, Zurück = .btn--secondary. D-119 bleibt HART eingehalten: kein
   Fortschrittsbalken, kein "Schritt X von Y". */
.lernpfad-nav {
  margin-block: var(--space-l);
  padding-block: var(--space-m);
  border-top: 1px solid var(--color-border);
  border-bottom: 1px solid var(--color-border);
}

.lernpfad-nav--oben {
  margin-top: var(--space-s);
}

.lernpfad-nav__kicker {
  margin: 0 0 var(--space-xs);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-bold);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-accent);
}

.lernpfad-nav__pfadname {
  display: flex;
  align-items: center;
  gap: var(--space-2xs);
  margin: 0 0 var(--space-xs);
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
}

.lernpfad-nav__icon {
  color: var(--color-accent);
  width: 1.25rem;
  height: 1.25rem;
  flex-shrink: 0;
}

.lernpfad-nav__reihe {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-s);
  margin: 0 0 var(--space-xs);
}

.lernpfad-nav__alle {
  margin: 0;
  font-size: var(--font-size-sm);
}

.lernpfad-nav__alle a {
  color: var(--color-text-muted);
}

/* Schmale Viewports: Buttons stapeln in voller Breite, "Weiter" (Primäraktion) zuerst. */
@media (max-width: 34rem) {
  .lernpfad-nav__reihe {
    flex-direction: column;
    align-items: stretch;
  }

  .lernpfad-nav__reihe .btn {
    width: 100%;
  }

  .lernpfad-nav__reihe .lernpfad-nav__zurueck {
    order: 2;
  }
}

/* Kontextueller Hub-Link am Artikelende (Gate-Befund G-14, 07 §2.1) — Haarlinien-Behandlung
   (D-123: keine Karte/Schatten, gleichrangiger Querverweis, kein neues Token); eigene Klasse,
   weil semantisch eine andere Sache (Cluster-Hub statt Lernpfad-Schritt). */
.mehr-zum-thema {
  margin-block: var(--space-l);
  padding-top: var(--space-m);
  border-top: 1px solid var(--color-border);
}

.mehr-zum-thema p {
  margin: 0 0 var(--space-2xs);
}

.mehr-zum-thema__label {
  font-weight: var(--font-weight-semibold);
}

/* "Auch Teil des Pfads"-Zweit-Hinweise (Sprint 13, WP-1; 05 §4.17 Punkt 2, 04 §11.4 Bullet 2;
   historischer Anlass WP-3-Befund B-4) – für Seiten mit Mehrfach-Pfadzugehörigkeit, direkt nach
   dem unteren .lernpfad-nav-Block in artikel.njk. Bewusst KEIN zweiter Button-/Icon-Block (das
   bleibt dem Primärpfad vorbehalten, D-145) und KEINE Karte/Schatten (D-123) – Haarlinien-
   Behandlung wie .mehr-zum-thema oben, ein gleichrangiger Querverweis unter mehreren. */
.lernpfad-sekundaer {
  margin-block: var(--space-l);
  padding-top: var(--space-m);
  border-top: 1px solid var(--color-border);
}

.lernpfad-sekundaer__eintrag {
  margin: 0 0 var(--space-2xs);
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
}

.lernpfad-sekundaer__eintrag:last-child {
  margin-bottom: 0;
}

/* ==========================================================================
   15. Anzeigen-Platzhalter (Optik) — Aktivierungs-/Consent-Logik und
   Shortcode/Feature-Flag sind Track B/EP-11 (ads-privacy-integrator). CLS-fest:
   feste min-height je Breakpoint; "Anzeige"-Label nur zusammen mit echtem
   Inventar sichtbar (06 §7 Nr. 5) — hier nur die gestaltete Hülse/Demo.
   Sprint 10 (Aufgabe 1): reales <ins class="adsbygoogle"> + V-06-Sichtbarkeitsregel ergänzt.
   ========================================================================== */

.anzeigen-slot {
  margin-block: var(--space-l);
  padding-top: var(--space-s);
  border-top: 1px solid var(--color-border);
  min-height: 15.625rem; /* 250px mobil — Platzhalter-Annahme dieses Tracks, siehe Abschlussbericht */
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
  gap: var(--space-2xs);
}

@media (min-width: 48rem) {
  .anzeigen-slot {
    min-height: 17.5rem; /* 280px ab Tablet */
  }
}

.anzeigen-slot__label {
  align-self: flex-start;
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
}

/* Sprint 11 WP-1/B-9: ".anzeigen-slot__platzhalter-hinweis" entfernt – der "anzeige"-
   Shortcode (eleventy.config.js) erzeugt diese Klasse nie (0 Vorkommen im Produktions-
   Build); sie stand nur mit --color-text-subtle (3,48:1, SC 1.4.3-Verstoß) als toter
   Code im Stylesheet. Eine spätere Reaktivierung hätte den Verstoß sonst still
   zurückgebracht (B-9, a11y-endabnahme-sprint11.md). */

/* Das <ins>-Element selbst füllt die reservierte Breite; die Höhe steuert AdSense abhängig vom
   ausgelieferten Creative innerhalb der ohnehin reservierten min-height oben (kein zusätzliches
   CLS-Risiko, solange kein max-height/overflow:hidden gesetzt wird — P-08 Vorgabe V-07). */
.anzeigen-slot ins.adsbygoogle {
  width: 100%;
}

/* V-06 (P-08, 06 §7.5, Sprint 10): "Anzeige"-Label UND die Haarlinien-Abgrenzung (border-top
   oben) nur sichtbar, wenn AdSense den Slot tatsächlich gefüllt hat — erkennbar am von
   adsbygoogle.js selbst gesetzten Attribut `data-ad-status="filled"` am <ins>-Element
   (dokumentiertes AdSense-Verhalten; vor Live-Betrieb mit echten Anzeigen spotchecken,
   // VERIFIKATION WP-7). Vor dem Füllen (kein <ins> vorhanden ODER data-ad-status ist
   "unfilled"/fehlt, z. B. weil noch keine Einwilligung vorliegt oder AdSense kein Inventar hat)
   bleibt ausschließlich die reservierte CLS-Höhe übrig — keine sichtbare Leerfläche mit Rahmen
   und kein unzutreffendes Label (Leitfaden der Medienanstalten: "unzutreffende, nur
   sicherheitshalber gesetzte Kennzeichnungen vermeiden"). Nur die Rahmenfarbe wird transparent
   (nicht die border-width), damit sich an der reservierten Boxgröße nichts ändert — keine
   zusätzliche CLS-Quelle beim Umschalten. `:has()` ist in allen evergreen Browsern verfügbar
   (Chrome/Edge 105+, Firefox 121+, Safari 15.4+); ohne :has()-Unterstützung bleiben Label/Rahmen
   sichtbar — der unkritischere Fallback (Kosmetik, keine Rechts-/Consent-Frage) statt eines
   fälschlich verborgenen echten Labels. */
.anzeigen-slot:not(:has(ins[data-ad-status="filled"])) {
  border-top-color: transparent;
}

.anzeigen-slot:not(:has(ins[data-ad-status="filled"])) .anzeigen-slot__label {
  display: none;
}

/* Sprint 11 (D-146, Betreiber-Befund "~280px Leerfläche vor den Quellen"): Die CLS-Reservierung
   oben (min-height 250/280px) zahlt sich nur aus, solange noch eine Anzeige KOMMEN KANN. Steht
   fest, dass keine kommt, kollabiert der Slot vollständig — sonst bliebe die Reservierung als
   permanente Leerfläche auf jedem Artikel stehen. Zwei per CSS erkennbare "kommt sicher
   nicht"-Fälle: (1) Hülle ohne <ins> (Position ohne konfigurierte Slot-ID) — statisch ab dem
   ersten Paint, null CLS; (2) AdSense hat den Slot ausdrücklich NICHT befüllt
   (data-ad-status="unfilled" — dieselbe Attribut-Quelle wie V-06 oben) — einmaliger Shift nach
   oben, der dokumentierte Standard-Kompromiss (Googles eigenes Muster zum Ausblenden
   unbefüllter responsiver Slots) statt dauerhafter Leerfläche; die Vorgabe V-07 (kein
   max-height/overflow auf einen KOMMENDEN Ad-Render) bleibt unberührt, denn kollabiert wird
   erst NACH Googles finaler Nicht-Befüllen-Entscheidung. Der dritte Fall — Consent-Entscheidung
   ohne Purpose 1, dann wird push() nie aufgerufen und es gibt nie einen data-ad-status — ist
   nur per JS erkennbar: einwilligung.js setzt dafür .anzeigen-slot--kollabiert (eigene Regel
   unten). Bewusst ZWEI getrennte Regeln statt einer Selektorliste: ein Browser ohne :has()
   verwirft die komplette Liste — die Klassen-Regel (JS-Pfad) muss unabhängig davon greifen.
   Fallback ohne :has() wie bei V-06: Leerfläche bleibt in Fall (1)/(2) stehen (Kosmetik, keine
   Rechts-/Consent-Frage). */
.anzeigen-slot:not(:has(ins.adsbygoogle)),
.anzeigen-slot:has(ins.adsbygoogle[data-ad-status="unfilled"]) {
  min-height: 0;
  margin-block: 0;
  padding-top: 0;
}

.anzeigen-slot--kollabiert {
  min-height: 0;
  margin-block: 0;
  padding-top: 0;
}

/* Googles eigenes Einbindungsmuster für nicht befüllte Slots: das <ins> selbst ausblenden,
   damit der kollabierte Slot wirklich auf 0px zusammenfällt (ein unbefülltes responsives <ins>
   kann sonst eine Resthöhe behalten). Wirkt NUR bei ausdrücklichem "unfilled" — nie vor oder
   während einer noch laufenden Ad-Auslieferung (kein Konflikt mit V-07). */
.anzeigen-slot ins.adsbygoogle[data-ad-status="unfilled"] {
  display: none;
}

/* ==========================================================================
   16. Illustrationen (Grundset, Sprint 3 Track A4) — Eigenwerk, siehe
   partials/illustrations.njk und docs/redaktion/lizenzregister.md §3. Farben
   ausschließlich Token-Palette (04 §8.1) — kein Grün/Rot (nicht semantisch
   gemeint), daher hier bewusst nicht die Erfolg-/Risiko-Token verwendet.
   ========================================================================== */

.illustration {
  width: 6rem;
  height: 6rem;
  flex-shrink: 0;
}

.illustration--lg {
  width: 9rem;
  height: 9rem;
}

.illustration :is(path, rect, circle, ellipse) {
  fill: none;
}

.illustration :is(path, rect, circle, ellipse, line, polygon, polyline) {
  stroke: var(--color-primary);
  stroke-width: 3;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.illustration__fill-primary { fill: var(--color-primary); }
.illustration__fill-accent { fill: var(--color-accent); }
.illustration__fill-deco { fill: var(--color-secondary-deco); }
.illustration__fill-surface { fill: var(--color-secondary-surface); }
.illustration__fill-none { fill: none; }
.illustration__stroke-accent { stroke: var(--color-accent); }

/* ==========================================================================
   17. Startseite S1 (04c "Editorial-Broadsheet", D-121) — Hero, Themen-Register
   (führende Sektion, D-119), optionaler Etappen-Block (KEIN Fortschrittsbalken),
   Werkzeuge/Vertrauen. Kopf (großer "bookish" Kopf) und Footer (hell) sind
   bereits sitewide über nav.njk/footer.njk gelöst (Sprint 2) — hier nur die
   S1-exklusiven Abschnitte dazwischen.
   ========================================================================== */

.section-label {
  margin: 0 0 var(--space-2xs);
  font-family: var(--font-family-base);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-bold);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-accent);
}

/* --- Hero --- */

.hero {
  padding-block: var(--space-2xl) var(--space-xl);
  border-bottom: 1px solid var(--color-border);
}

.hero__eyebrow {
  margin: 0 0 var(--space-s);
  font-family: var(--font-family-base);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-bold);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-accent);
}

.hero__title {
  max-width: 15em;
  margin: 0 0 var(--space-l);
  font-size: clamp(2.25rem, 1.7rem + 2.9vw, 4.75rem);
  line-height: 1.05;
  letter-spacing: -0.02em;
}

.hero__row {
  display: grid;
  gap: var(--space-l);
}

@media (min-width: 64rem) {
  .hero__row {
    grid-template-columns: 1.4fr 1fr;
    align-items: start;
    gap: var(--space-2xl);
  }
}

.hero__lead {
  margin: 0;
  font-size: var(--font-size-lead);
}

@media (min-width: 64rem) {
  .hero__lead {
    column-count: 2;
    column-gap: var(--space-l);
  }
}

.hero__cta {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-s);
}

@media (min-width: 64rem) {
  .hero__cta {
    align-items: flex-end;
    text-align: right;
  }
}

.hero__pfad-link {
  font-weight: var(--font-weight-semibold);
}

.hero__sublabel {
  margin: 0;
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
}

/* --- Themen im Register (führende Sektion, D-119) --- */

.themen-sektion {
  padding-block: var(--space-2xl);
  border-bottom: 1px solid var(--color-border);
  display: grid;
  gap: var(--space-m);
}

@media (min-width: 64rem) {
  .themen-sektion {
    grid-template-columns: 0.8fr 2.2fr;
    gap: var(--space-2xl);
  }
}

.themen-sektion__intro-title {
  margin: 0 0 var(--space-2xs);
}

.themen-sektion__such-hinweis {
  margin-top: var(--space-m);
}

/* --- Der Weg: Etappen (optionaler Lernpfad-Block, unterhalb der Themen) --- */

.etappen-sektion {
  padding-block: var(--space-2xl);
  border-bottom: 1px solid var(--color-border);
}

.etappen-sektion__intro-title {
  margin: 0 0 var(--space-l);
}

.etappen-grid {
  display: grid;
  gap: var(--space-l);
  margin-bottom: var(--space-l);
}

@media (min-width: 64rem) {
  .etappen-grid {
    grid-template-columns: repeat(5, 1fr);
    gap: 0;
  }

  .etappen-grid__item {
    padding-inline: var(--space-m);
    border-left: 1px solid var(--color-border);
  }

  .etappen-grid__item:first-child {
    border-left: none;
    padding-inline-start: 0;
  }
}

.etappen-grid__ziffer {
  display: block;
  font-family: var(--font-serif);
  font-weight: var(--font-weight-bold);
  font-size: 3.5rem;
  line-height: 1;
  color: var(--color-primary);
  margin-bottom: var(--space-2xs);
}

.etappen-grid__item--accent .etappen-grid__ziffer {
  color: var(--color-accent);
}

.etappen-grid__titel {
  margin: 0 0 var(--space-3xs);
  font-weight: var(--font-weight-bold);
}

.etappen-grid__stichwort {
  margin: 0;
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
}

/* --- Werkzeuge & Vertrauen --- */

.werkzeuge-sektion {
  padding-block: var(--space-2xl);
  display: grid;
  gap: var(--space-l);
}

@media (min-width: 48rem) {
  .werkzeuge-sektion {
    grid-template-columns: 1fr 1fr;
    gap: var(--space-2xl);
  }
}

.werkzeuge-liste {
  list-style: none;
  margin: 0;
  padding: 0;
  border-top: 1px solid var(--color-border);
}

.werkzeuge-liste li {
  padding-block: var(--space-s);
  border-bottom: 1px solid var(--color-border);
  margin-bottom: 0;
}

.werkzeuge-liste a {
  color: var(--color-primary);
  font-weight: var(--font-weight-semibold);
  text-decoration: none;
}

.werkzeuge-liste a:hover {
  color: var(--color-primary-dark);
}

.werkzeuge-liste__hinweis {
  color: var(--color-text-muted);
  font-weight: var(--font-weight-regular);
}

/* Sprint 16 (H-12, D-153-Merker): dezenter "Alle …ansehen"-Verweis unterhalb der Liste —
   gleicher Abstand wie .themen-sektion__such-hinweis oben (identischer Zweck: kleiner,
   nachgeordneter Zusatzweg unter einem Register). */
.werkzeuge-liste__alle {
  margin-top: var(--space-m);
}

.vertrauens-karte {
  padding: var(--space-l);
  background: var(--color-primary-light);
  border-radius: var(--radius-m);
}

.vertrauens-karte h3 {
  margin-top: 0;
}

/* --- Autor-/E-E-A-T-Hinweis (Sprint 20, Strang A-2) --- additiver Vertrauensbaustein
   nach der Werkzeuge/Vertrauen-Sektion, vor dem Footer. D-123 (Editorial-Broadsheet):
   Haarlinie statt Karten-Füllfläche — kein .lernbaustein, keine .vertrauens-karte-
   Fläche; die obere Haarlinie schließt zugleich die fehlende untere Kante der
   Werkzeuge-Sektion. H2-Serif kommt bereits aus der globalen "h1, h2"-Regel (D-121). */
.autor-sektion {
  padding-block: var(--space-2xl);
  border-top: 1px solid var(--color-border);
}

.autor-sektion__titel {
  margin-top: 0;
}

.autor-sektion__text {
  max-width: var(--content-max);
}

/* ==========================================================================
   18. Pagefind-Theming (Such-Seiten-Shell, /suche/)
   Reine CSS-Anpassung der offiziellen Pagefind-UI-Custom-Properties an die
   Design-Tokens (https://pagefind.app/docs/ui/#css-custom-properties) — KEINE
   JS-Verhaltensänderung (bleibt Track C, C1). Ohne Build (Pagefind-Assets
   entstehen erst durch "npm run build") bleiben diese Regeln wirkungslos, aber
   harmlos.
   ========================================================================== */

.pagefind-ui {
  --pagefind-ui-scale: 1;
  --pagefind-ui-primary: var(--color-primary);
  --pagefind-ui-text: var(--color-text);
  --pagefind-ui-background: var(--color-bg);
  --pagefind-ui-border: var(--color-border);
  --pagefind-ui-tag: var(--color-surface);
  --pagefind-ui-border-width: 1px;
  --pagefind-ui-border-radius: 0.5rem;
  --pagefind-ui-image-border-radius: 0.5rem;
  --pagefind-ui-image-box-ratio: 3 / 2;
  --pagefind-ui-font: var(--font-family-base);
}

/* Sprint 11 WP-1/A-2 (SC 1.4.3): Pagefind setzt den Platzhaltertext des Suchfelds per
   Vorgabe auf opacity:.2 ("pagefind-ui.css", nicht Teil dieses Stylesheets) – zusammen
   mit --pagefind-ui-text ergibt das effektiv nur 1,48:1. Der Platzhalter ist zugleich
   der einzige Text im Feld (kein sichtbares <label>), daher volle Deckkraft + eigener,
   kontraststarker Text-Token statt der reinen Deckkraft-Reduktion. */
.pagefind-ui .pagefind-ui__search-input::placeholder {
  opacity: 1;
  color: var(--color-text-muted);
}

.suche-seite__intro {
  max-width: var(--content-max);
}

/* ==========================================================================
   19. Glossar-Shell (/glossar/) — Alphabet-Sprungnavigation/-Filter + Definitionsliste.
   Struktur/Optik von Track A (Sprint 3, A1); seit Sprint 3 Track B3 (EP-04)
   datengetrieben aus _data/glossar.json gerendert (glossar/index.md + Filter
   glossarNachBuchstabe in eleventy.config.js) statt hartkodierter Dummy-Einträge.
   Die 59 echten Begriffe/Definitionen sind weiterhin redaktioneller Inhalt
   (Sprint 4, EP-06) – aktuell nur eine kleine, klar gekennzeichnete Beispielmenge.
   Sprint 13, WP-2 (interaction-developer): assets/js/glossar-filter.js wertet dieselbe Leiste
   zu Filter-Umschaltern auf (<button> statt <a>, siehe Kommentare unten) – Selektoren decken
   deshalb bewusst BEIDE Elementtypen ab (ohne JS bleiben es <a>, mit JS <button>).
   ========================================================================== */

.glossar-alphabet {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs);
  margin: 0 0 var(--space-l);
  padding: var(--space-s) 0;
  border-block: 1px solid var(--color-border);
}

.glossar-alphabet a,
.glossar-alphabet button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 2.75rem; /* 44px Touch-Ziel, 04 §14.5 — eigenständiges Bedienelement, keine Fließtext-Ausnahme */
  min-height: 2.75rem;
  padding-inline: var(--space-3xs);
  background: none;
  border: none;
  color: var(--color-primary);
  font: inherit; /* setzt v. a. bei <button> die UA-Formularschrift auf die Fließtextschrift zurück */
  font-weight: var(--font-weight-semibold);
  text-decoration: none;
  border-radius: var(--radius-s);
  cursor: pointer;
}

.glossar-alphabet a:hover,
.glossar-alphabet button:hover {
  background: var(--color-surface);
}

/* Aktiver Filter (assets/js/glossar-filter.js setzt "aria-pressed", Sprint 13, WP-2) – dieselbe
   gefüllte Primärfläche wie .btn--primary (style.css §5), ein etabliertes, nicht rein
   farbbasiertes Muster (Kontrast-/Flächenwechsel statt Farbton allein). Ohne JS existiert kein
   <button> und damit auch kein "aria-pressed" – diese Regel bleibt dann wirkungslos. */
.glossar-alphabet button[aria-pressed="true"] {
  background: var(--color-primary);
  color: var(--color-bg-elevated);
}

.glossar-alphabet button[aria-pressed="true"]:hover {
  background: var(--color-primary-dark);
}

/* Sprint 3, Track B3: Buchstaben ohne Glossareintrag (datengetrieben, kein toter Anker) –
   gleiche Boxmaße wie die aktiven <a>/<button>, aber unauffällig/aria-hidden. Sprint 11 WP-1/B-5:
   --color-text-subtle lag bei 3,48:1 gegen Papier; auch wenn die 1.4.3-Ausnahme für
   inaktive Bedienelemente formal greift, hebt --color-text-muted (6,14:1) das ohne
   Optikbruch über die Diskussion hinaus. Bleiben unverändert <span> (weder <a> noch <button>) –
   Sprint 13, WP-2 fasst sie bewusst nicht an (bereits "nicht klickbar-wirkend", nicht
   fokussierbar, für Screenreader unsichtbar statt als "disabled"-Button hörbar/überflüssig). */
.glossar-alphabet span {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 2.75rem;
  min-height: 2.75rem;
  color: var(--color-text-muted);
}

/* Trefferzahl-/Status-Ankündigung des A–Z-Filters (Sprint 13, WP-2) – ausschließlich mit JS
   befüllt (assets/js/glossar-filter.js). Im leeren Ausgangszustand wie ".artikel-teilen__status"
   (style.css §14) geklippt statt per "hidden"/"display:none" entfernt: damit bleibt die
   aria-live-Region durchgehend im Accessibility-Tree (zuverlässige Ankündigung) und nimmt ohne
   Inhalt zugleich keinen sichtbaren Platz ein (kein Layout-Sprung beim Laden). Der Sprung BEIM
   ersten Filterklick selbst zählt nicht gegen CLS (Verschiebungen innerhalb von 500 ms nach einer
   Nutzerinteraktion sind von der Web-Vitals-Messung ausgenommen). */
.glossar-filter-status {
  margin: 0 0 var(--space-m);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-muted);
}

.glossar-filter-status:empty {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

.glossar-liste {
  margin: 0;
}

.glossar-eintrag {
  padding-block: var(--space-m);
  border-bottom: 1px solid var(--color-border);
  scroll-margin-top: var(--space-l);
}

/* Sprung-Anker der Lernpfad-Schritte (Zweit-Hinweis-Tiefenlinks, Sprint 17):
   ohne scroll-margin landet das Ziel bündig an der Viewport-Oberkante und die
   zugehörige Pfad-Überschrift läge außerhalb des Sichtfelds (QA-4 Sprint 17). */
[id^="pfad-"] {
  scroll-margin-top: var(--space-2xl);
}

.glossar-eintrag__begriff {
  margin: 0 0 var(--space-3xs);
  font-family: var(--font-family-base);
  font-size: var(--font-size-h4);
  font-weight: var(--font-weight-bold);
  color: var(--color-primary);
}

.glossar-eintrag__definition {
  margin: 0;
}

.glossar-eintrag__vertiefung {
  margin: var(--space-3xs) 0 0;
  font-size: var(--font-size-sm);
}

/* ==========================================================================
   20. Bewegung
   ========================================================================== */

@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;
  }
}

/* ==========================================================================
   21. Design-Vorschau (interne Abnahmeseite /design-vorschau/, kein
   Website-Baustein — dient nur der visuellen Abnahme am Track-B-Gate,
   noindex/nofollow, nicht in der Navigation verlinkt).
   ========================================================================== */

.gallery-section {
  margin-block: var(--space-2xl) 0;
  padding-top: var(--space-l);
  border-top: 1px solid var(--color-border);
}

.gallery-section:first-of-type {
  border-top: none;
  padding-top: 0;
}

.swatch-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
  gap: var(--space-m);
  list-style: none;
  margin: 0 0 var(--space-l);
  padding: 0;
}

.swatch {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-m);
  overflow: hidden;
}

.swatch__fill {
  height: 4rem;
}

/* Eine Modifier-Klasse je gezeigtem Farbtoken (statt inline style="background:...",
   damit die Seite ohne no-inline-style-Ausnahme durch html-validate läuft). */
.swatch__fill--primary { background: var(--color-primary); }
.swatch__fill--primary-dark { background: var(--color-primary-dark); }
.swatch__fill--primary-light { background: var(--color-primary-light); }
.swatch__fill--accent { background: var(--color-accent); }
.swatch__fill--secondary-surface { background: var(--color-secondary-surface); }
.swatch__fill--secondary-deco { background: var(--color-secondary-deco); }
.swatch__fill--info { background: var(--color-info); }
.swatch__fill--info-surface { background: var(--color-info-surface); }
.swatch__fill--success { background: var(--color-success); }
.swatch__fill--success-text { background: var(--color-success-text); }
.swatch__fill--success-surface { background: var(--color-success-surface); }
.swatch__fill--warning { background: var(--color-warning); }
.swatch__fill--warning-surface { background: var(--color-warning-surface); }
.swatch__fill--danger { background: var(--color-danger); }
.swatch__fill--danger-text { background: var(--color-danger-text); }
.swatch__fill--danger-surface { background: var(--color-danger-surface); }
.swatch__fill--text { background: var(--color-text); }
.swatch__fill--text-muted { background: var(--color-text-muted); }
.swatch__fill--text-subtle { background: var(--color-text-subtle); }
.swatch__fill--border { background: var(--color-border); }
.swatch__fill--surface { background: var(--color-surface); }
.swatch__fill--bg { background: var(--color-bg); }
.swatch__fill--bg-elevated { background: var(--color-bg-elevated); }
.swatch__fill--canvas { background: var(--color-canvas); }
.swatch__fill--focus { background: var(--color-focus); }

.swatch__meta {
  margin: 0;
  padding: var(--space-xs) var(--space-s);
  background: var(--color-bg-elevated);
}

.swatch__name {
  display: block;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
}

.swatch__hex {
  display: block;
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
  font-variant-numeric: tabular-nums;
}

.gallery-tag {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3xs);
  padding: var(--space-3xs) var(--space-xs);
  margin: 0 0 var(--space-2xs);
  border-radius: var(--radius-s);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  border: 1px solid var(--color-border);
}

.gallery-tag--haarlinie {
  background: var(--color-surface);
  color: var(--color-text-muted);
}

.gallery-tag--fuellflaeche {
  background: var(--color-warning-surface);
  color: var(--color-warning);
  border-color: var(--color-warning);
}

.gallery-swatch-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-m);
  align-items: center;
  margin-bottom: var(--space-l);
}

/* Nur zur Demonstration der Typo-Skala auf nicht-überschriftlichen Elementen
   (die Seite hat genau eine echte H1 — 04 §15, Prinzip 5). */
.demo-h1,
.demo-h2 {
  font-family: var(--font-serif);
}

.demo-h3,
.demo-h4 {
  font-family: var(--font-family-base);
}

.demo-h1,
.demo-h2,
.demo-h3,
.demo-h4 {
  font-weight: var(--font-weight-bold);
  color: var(--color-text);
  margin: 0 0 var(--space-m);
  text-wrap: balance;
}

.demo-h1 {
  font-size: var(--font-size-h1);
  line-height: var(--line-height-heading);
}

.demo-h2 {
  font-size: var(--font-size-h2);
  line-height: var(--line-height-heading);
}

.demo-h3 {
  font-size: var(--font-size-h3);
  line-height: var(--line-height-tight);
}

.demo-h4 {
  font-size: var(--font-size-h4);
  line-height: var(--line-height-tight);
}

/* ==========================================================================
   22. Werkzeuge (Rechner, Checkliste, Sortier-Tabelle, Speicher-Opt-in)
   Sprint 4, Track T, EP-05 (interaction-developer). Editorial-flach wie das übrige
   Box-System (D-123): Haarlinien statt Karten/Schatten, keine neuen Farb-Tokens.
   ========================================================================== */

/* --- Rechner-Grundmodul (05 §4.7) ---------------------------------------- */

.rechner {
  margin-block: var(--space-l);
}

.rechner fieldset {
  margin: 0 0 var(--space-m);
  padding: 0;
  border: none;
}

.rechner legend {
  padding: 0;
  margin: 0 0 var(--space-m);
  font-family: var(--font-family-base);
  font-size: var(--font-size-h4);
  font-weight: var(--font-weight-bold);
  color: var(--color-text);
}

.rechner__feld {
  margin-bottom: var(--space-m);
  max-width: 22rem;
}

.rechner__feld label {
  display: block;
  margin-bottom: var(--space-3xs);
  font-weight: var(--font-weight-semibold);
}

.rechner__feld-hinweis {
  margin: 0 0 var(--space-2xs);
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
}

.rechner__feld input[type="number"] {
  width: 100%;
  min-height: 44px;
  padding: var(--space-2xs) var(--space-xs);
  font-family: var(--font-family-base);
  font-size: var(--font-size-base);
  font-variant-numeric: tabular-nums;
  color: var(--color-text);
  background: var(--color-bg-elevated);
  /* Sprint 11 WP-1/A-3 (SC 1.4.11): Feldfüllung ist fast weiß auf Papier (1,03:1) – die
     Randfarbe ist damit die einzige Identifikation des Feldes und brauchte ≥ 3:1;
     --color-border lag bei 1,32–1,39:1. --color-text-subtle erfüllt mit 3,66:1 (gegen
     Weiß) das Minimum, ohne die Optik zu verschieben. */
  border: 1.5px solid var(--color-text-subtle);
  border-radius: var(--radius-s);
}

.rechner__feld input[type="number"][aria-invalid="true"] {
  border-color: var(--color-danger);
}

.rechner__feld-fehler {
  margin: var(--space-3xs) 0 0;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-danger-text);
}

/* Sprint 19, Strang A/A-2: Moduswahl des Entnahmerechners (bare <label><input type="radio">
   innerhalb .rechner__feld, kein rechnerFeld()-Zahlenfeld) — ohne diese Regel bliebe der
   native Browser-Radiobutton auf ~13px stehen (04 §14.5/DoD: Touch-Ziele ≥ 44px). Gleiches
   Muster/gleiche Tokens wie .quiz__option/.selbsttest__option label + input[type="radio"]
   (§22 unten), hier direkt auf .rechner__feld gemappt statt eine dritte Options-Klasse
   einzuführen. :has() bereits an anderer Stelle im Projekt genutzt (§ Anzeigen-Platzhalter). */
.rechner__feld label:has(input[type="radio"]) {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  min-height: 2.75rem;
  padding-block: var(--space-3xs);
  cursor: pointer;
}

.rechner__feld input[type="radio"] {
  flex-shrink: 0;
  width: 1.25rem;
  height: 1.25rem;
  accent-color: var(--color-primary);
}

.rechner__ergebnis {
  margin-top: var(--space-l);
  padding-top: var(--space-l);
  border-top: 1px solid var(--color-border);
}

.rechner__status {
  padding: var(--space-s) var(--space-m);
  margin: 0 0 var(--space-m);
  background: var(--color-surface);
  border-radius: var(--radius-m);
  font-weight: var(--font-weight-semibold);
}

.rechner__kennzahlen {
  display: grid;
  /* Sprint 11 WP-1/B-3: unter 30rem einspaltig – bei zweispaltiger Darstellung können
     Extremwerte (Maximalwerte der Felder) die Spalten über 320px hinaus dehnen. */
  grid-template-columns: 1fr;
  gap: var(--space-m) var(--space-l);
  margin: 0 0 var(--space-m);
}

@media (min-width: 30rem) {
  .rechner__kennzahlen {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (min-width: 40rem) {
  .rechner__kennzahlen {
    grid-template-columns: repeat(4, 1fr);
  }
}

.rechner__kennzahl dt {
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
}

.rechner__kennzahl dd {
  margin: 0;
  font-family: var(--font-serif);
  font-size: var(--font-size-h3);
  font-weight: var(--font-weight-bold);
  color: var(--color-primary);
  font-variant-numeric: tabular-nums;
}

.rechner__teilen {
  display: flex;
  align-items: center;
  gap: var(--space-s);
  flex-wrap: wrap;
}

/* Sprint 19, Strang A/A-2: Szenarienvergleich stellt mehrere Fieldsets (Szenario A/B/C) in
   EINEM Formular hintereinander. Ohne Trennung wäre der Übergang zwischen Szenario-Blöcken
   (Legende + 5 Felder) optisch kaum von der Feldabstufung INNERHALB eines Blocks zu
   unterscheiden ([data-szenario]-Fieldsets teilen sonst denselben margin-bottom wie
   .rechner__feld). Haarlinie statt Karte/Schatten (D-123), analog .quiz__frage/
   .selbsttest__frage – nur bestehende Tokens, per Attribut auf den Szenarienvergleich
   beschränkt (keine Auswirkung auf Zinseszins-/Sparplan-/Kaufkraft-/Entnahmerechner). */
.rechner fieldset[data-szenario]:not(:last-of-type) {
  padding-bottom: var(--space-m);
  border-bottom: 1px solid var(--color-border);
}

/* --- Checklisten-Modul (05 §4.6) ------------------------------------------ */

.checkliste {
  margin-block: var(--space-l);
}

.checkliste__fortschritt {
  margin: 0 0 var(--space-s);
  font-weight: var(--font-weight-semibold);
  color: var(--color-primary);
}

.checkliste__gruppe {
  margin: 0 0 var(--space-m);
  padding: 0;
  border: none;
}

.checkliste__gruppe legend {
  padding: 0;
  margin: 0 0 var(--space-s);
  font-family: var(--font-family-base);
  font-size: var(--font-size-h4);
  font-weight: var(--font-weight-bold);
  color: var(--color-text);
}

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

.checkliste__punkt {
  display: flex;
  align-items: flex-start;
  gap: var(--space-xs);
  padding-block: var(--space-2xs);
  margin: 0;
  border-bottom: 1px solid var(--color-border);
}

.checkliste__punkt:last-child {
  border-bottom: none;
}

.checkliste__punkt input[type="checkbox"] {
  flex-shrink: 0;
  width: 1.5rem;
  height: 1.5rem;
  margin-top: 0.1rem;
  accent-color: var(--color-primary);
}

/* Touch-Ziel (04 §14.5, Ziel 44 px für eigenständige Bedienelemente): Die sichtbare Checkbox
   selbst bleibt bei üblichen 24 px (bereits doppelt so groß wie der Browser-Default und
   deckungsgleich mit dem WCAG-2.2-AA-Minimum SC 2.5.8) — klickt/tippt man aber auf das
   zugehörige <label> (per for/id verknüpft), aktiviert der Browser die Checkbox unabhängig
   davon, WO innerhalb der Label-Box der Klick erfolgte. min-height 44px + Flex-Zentrierung
   macht diese gesamte Label-Fläche (nicht nur den Text) zum tatsächlichen, großzügigen
   Bedienziel – analog zur in Sprint 3 (Glossar-Alphabet-Nav) korrigierten Regel. */
.checkliste__punkt label {
  display: flex;
  align-items: center;
  min-height: 2.75rem;
  padding-block: var(--space-3xs);
}

/* --- Speicher-Opt-in-Schalter ("Fortschritt speichern?", F-43/D-107) ------ */

.speicher-opt-in {
  margin-block: var(--space-l);
  padding: var(--space-m);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-m);
}

.speicher-opt-in__zeile {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-s);
  margin-bottom: var(--space-2xs);
}

.speicher-opt-in__schalter {
  display: flex;
  align-items: center;
  gap: var(--space-2xs);
}

.speicher-opt-in__schalter input[type="checkbox"] {
  width: 2.5rem;
  height: 1.5rem;
  accent-color: var(--color-primary);
  flex-shrink: 0;
}

/* Touch-Ziel: wie .checkliste__punkt label oben — die Label-Fläche (nicht nur die 24px hohe
   Checkbox) ist über min-height 44px das eigentliche, großzügige Bedienziel. */
.speicher-opt-in__schalter label {
  display: flex;
  align-items: center;
  min-height: 2.75rem;
  font-weight: var(--font-weight-semibold);
}

.speicher-opt-in__status {
  margin: var(--space-2xs) 0 0;
  color: var(--color-text-muted);
}

.speicher-opt-in__status:empty {
  /* wie .artikel-teilen__status: geklippt statt display:none, damit aria-live zuverlässig
     ankündigt (Element bleibt im Accessibility-Tree), aber ohne Layout-Sprung im Ruhezustand. */
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* --- Sortier-Modul für Vergleichstabellen (05 §4.8) ----------------------- */

.sortierbare-tabelle__knopf {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2xs);
  width: 100%;
  padding: 0;
  background: none;
  border: none;
  font: inherit;
  font-weight: inherit;
  color: inherit;
  text-align: inherit;
  cursor: pointer;
}

.sortierbare-tabelle__knopf:hover {
  color: var(--color-primary-dark);
  text-decoration: underline;
}

.sortierbare-tabelle__pfeil {
  color: var(--color-text-subtle);
  font-size: var(--font-size-sm);
}

.table-sortier-status {
  margin: var(--space-2xs) 0 0;
  color: var(--color-text-muted);
}

/* --- Etappen-Selbstcheck / Quiz-Modul (09 §3.2, 03 §7, 05 §5.2 — Sprint 12, WP-2) ---
   Generisches Werkzeug-Modul wie Rechner/Checkliste/Sortier-Tabelle, editorial-flach
   (D-123), nur bestehende Tokens. Markup auch ungestylt nutzbar (partials/quiz.njk).
   Feedback-Zustände (is-richtig/is-falsch-gewaehlt) nutzen dieselbe Surface-Systematik
   wie die Warnbox-Füllflächen — Text-Label steht IMMER zusätzlich zur Farbe (SC 1.4.1). */

.quiz {
  margin-block: var(--space-l);
}

.quiz__intro {
  margin: 0 0 var(--space-m);
  color: var(--color-text-muted);
}

.quiz__frage {
  margin-bottom: var(--space-l);
  padding-bottom: var(--space-m);
  border-bottom: 1px solid var(--color-border);
}

.quiz__frage:last-of-type {
  border-bottom: none;
}

.quiz fieldset {
  margin: 0;
  padding: 0;
  border: none;
}

.quiz legend {
  padding: 0;
  margin: 0 0 var(--space-s);
  font-family: var(--font-family-base);
  font-size: var(--font-size-h4);
  font-weight: var(--font-weight-bold);
  color: var(--color-text);
}

.quiz__frage-nummer {
  display: block;
  margin-bottom: var(--space-3xs);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-muted);
}

.quiz__optionen {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
}

.quiz__option {
  padding: var(--space-2xs) var(--space-xs);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-m);
}

/* Touch-Ziel/Klickfläche (04 §14.5, WCAG 2.5.8): wie .checkliste__punkt label — das ganze
   Label (nicht nur das 20px-Radio) ist über min-height 44px das eigentliche Bedienziel. */
.quiz__option label {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  min-height: 2.75rem;
  padding-block: var(--space-3xs);
  cursor: pointer;
}

.quiz__option input[type="radio"] {
  flex-shrink: 0;
  width: 1.25rem;
  height: 1.25rem;
  accent-color: var(--color-primary);
}

.quiz__erklaerung {
  margin: var(--space-2xs) 0 0;
  padding: var(--space-2xs) var(--space-xs);
  font-size: var(--font-size-sm);
  border-radius: var(--radius-s);
}

.quiz__erklaerung strong {
  margin-right: var(--space-3xs);
}

/* Zustände nach dem Auswerten (quiz.js setzt diese Klassen; Text-Label in
   .quiz__erklaerung > strong steht IMMER zusätzlich zur Farbe — SC 1.4.1). */
.quiz__option.is-richtig {
  border-color: var(--color-success);
}

.quiz__option.is-richtig .quiz__erklaerung {
  background: var(--color-success-surface);
  color: var(--color-success-text);
}

.quiz__option.is-falsch-gewaehlt {
  border-color: var(--color-danger);
}

.quiz__option.is-falsch-gewaehlt .quiz__erklaerung {
  background: var(--color-danger-surface);
  color: var(--color-danger-text);
}

.quiz__frage-fehler {
  margin: var(--space-2xs) 0 0;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-danger-text);
}

.quiz__ergebnis {
  margin-top: var(--space-l);
  padding-top: var(--space-l);
  border-top: 1px solid var(--color-border);
}

.quiz__status {
  padding: var(--space-s) var(--space-m);
  margin: 0 0 var(--space-m);
  background: var(--color-surface);
  border-radius: var(--radius-m);
  font-weight: var(--font-weight-semibold);
}

/* --- Quiz: No-JS-Fallback (<noscript>, vollständig aufgelöst) -------------- */

.quiz--noscript {
  margin-block: var(--space-l);
}

.quiz__noscript-frage {
  margin-bottom: var(--space-s);
  padding: var(--space-xs);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-m);
}

.quiz__noscript-frage summary {
  cursor: pointer;
  font-weight: var(--font-weight-semibold);
}

.quiz__noscript-frage ul {
  margin: var(--space-xs) 0 0;
  padding-left: var(--space-m);
}

.quiz__noscript-frage li {
  margin-bottom: var(--space-xs);
}

/* ==========================================================================
   23. Dark Mode — Token-Overrides (F-26, D-148, Sprint 12 WP-1)
   Grundfall = "prefers-color-scheme" (D-104-Vorbereitung eingelöst); manueller
   Umschalter (assets/js/site.js) übersteuert per "data-theme" auf <html> IN BEIDE
   RICHTUNGEN. Da die gesamte übrige Datei ausschließlich Tokens verwendet
   (keine Hex-Werte in Komponenten, 04 §12 „Vorbereitung in V1"), reicht die
   Neubelegung der Custom Properties hier aus — kein Komponenten-Selektor dieser
   Datei muss sonst verändert werden.

   Spezifitäts-/Reihenfolge-Logik (Artifact-Theming-Muster, wie im Auftrag
   verlangt):
     - ":root" (Sektion 1) = Licht-Grundwerte, IMMER aktiv (kein Media-Bedingung) —
       automatischer Print-Fallback, s. u.
     - "@media screen and (prefers-color-scheme: dark) { :root { … } }" = Dunkel-
       Grundfall, NUR auf Bildschirmen, Spezifität (0,1,0) wie die Lichtwerte oben,
       gewinnt aber durch spätere Position im Cascade.
     - "html[data-theme="dark"]" (Spezifität 0,1,1) schlägt jede reine ":root"-Regel
       unabhängig von der Position im Stylesheet — erzwingt Dunkel auch bei
       hellem System. Ebenfalls auf "@media screen" beschränkt.
     - "html[data-theme="light"]" (Spezifität 0,1,1) schlägt aus demselben Grund
       den Dunkel-Grundfall — erzwingt Hell auch bei dunklem System. BEWUSST OHNE
       Screen-Beschränkung: das ist zugleich die Absicherung, dass ein Druckvorgang
       mit gesetztem data-theme="dark" nicht dunkel gedruckt wird (Duck-CSS, Sektion
       24, verlangt zusätzlich denselben Werte-Satz explizit für den Druckfall –
       siehe Kommentar dort).
   Ergebnis: Ohne JavaScript / ohne gespeicherte Wahl bleibt es beim reinen
   Systemfarbschema (progressive enhancement, D-148 „Grundfall"); der Toggle-Button
   selbst existiert nur mit aktivem JS (§10-Kommentar).

   Geprüfte Kontrastpaare (WCAG 2.1 AA, rechnerisch ermittelt, Formel 04 §5/§15):
     Text/Fläche:
       --color-text (#EDEFF2) auf --color-bg (#1E262D)              ≈ 13,3:1
       --color-text (#EDEFF2) auf --color-canvas (#14181C)          ≈ 15,5:1
       --color-text-muted (#B8C0C8) auf --color-bg                  ≈ 8,3:1
       --color-text-subtle (#8A94A0) auf --color-bg-elevated        ≈ 4,4:1 (Eingabefeld-Rand, wie §22)
       --color-primary (#7FB3D5, Linktext) auf --color-bg           ≈ 6,8:1
       --color-accent (#E0A868) auf --color-bg                      ≈ 7,3:1
       --color-warning (#F5C451) auf --color-warning-surface        ≈ 7,5:1 (Warnbox-Titel/Icon; qa-Gate-Nachrechnung Sprint 12)
       --color-danger-text (#F3A9AC) auf --color-danger-surface     ≈ 8,5:1 (Risikobox-Titel/Icon)
       --color-danger (#E5484D, 4px-Akzentkante) auf --color-bg     ≈ 3,9:1 (nicht-Text-UI, ≥ 3:1)
     Button (.btn--primary: bg = --color-primary, Text = --color-bg-elevated):
       --color-bg-elevated (#262F37) auf --color-primary (#7FB3D5)  ≈ 6,0:1 (Text dunkel auf
         hellem Button; qa-Gate-Nachrechnung Sprint 12 — Rollentausch ändert das Verhältnis
         gegenüber der Linktext-Zeile oben leicht, AA klar erfüllt)
   Nicht rechnerisch neu verifiziert (identische Beziehung wie im Lichtmodus, nur
   mit den neuen Tokenwerten, siehe jeweilige Komponenten-Kommentare):
   .rechner__feld-fehler/.checkliste__fortschritt (Primär-/Dangertext), Fokusring
   gegen alle vorkommenden Hintergründe. → Offener Punkt für die seo-a11y-Abnahme
   (Auftrag verlangt Browser-/Tool-Nachtest, s. u. "offene Punkte").
   ========================================================================== */

@media screen and (prefers-color-scheme: dark) {
  :root {
    color-scheme: dark;

    --color-primary: #7FB3D5;
    --color-primary-dark: #A9CFE6;
    --color-primary-light: #24333D;
    --color-secondary-surface: #2B241C;
    --color-secondary-deco: #3D5A6C;
    --color-accent: #E0A868;
    --color-info: #6FBBDE;
    --color-info-surface: #16323F;
    --color-success: #4ADE80;
    --color-success-text: #86EFAC;
    --color-success-surface: #12301C;
    --color-warning: #F5C451;
    --color-warning-surface: #423313;
    --color-danger: #E5484D;
    --color-danger-text: #F3A9AC;
    --color-danger-surface: #3A1518;
    --color-text: #EDEFF2;
    --color-text-muted: #B8C0C8;
    --color-text-subtle: #8A94A0;
    --color-border: #3A454E;
    --color-surface: #232B32;
    --color-bg: #1E262D;
    --color-bg-elevated: #262F37;
    --color-canvas: #14181C;
    --color-focus: #9FC9E3;
    /* Schlagschatten wirken auf dunklen Flächen kaum – höhere Deckkraft statt einer
       (unwirksamen) helleren Farbe, damit .site-shell (§2) sich weiterhin sichtbar
       von --color-canvas abhebt. */
    --shadow-s: 0 1px 3px rgb(0 0 0 / 0.5);
    --shadow-m: 0 4px 14px rgb(0 0 0 / 0.55);
  }
}

@media screen {
  html[data-theme="dark"] {
    color-scheme: dark;

    --color-primary: #7FB3D5;
    --color-primary-dark: #A9CFE6;
    --color-primary-light: #24333D;
    --color-secondary-surface: #2B241C;
    --color-secondary-deco: #3D5A6C;
    --color-accent: #E0A868;
    --color-info: #6FBBDE;
    --color-info-surface: #16323F;
    --color-success: #4ADE80;
    --color-success-text: #86EFAC;
    --color-success-surface: #12301C;
    --color-warning: #F5C451;
    --color-warning-surface: #423313;
    --color-danger: #E5484D;
    --color-danger-text: #F3A9AC;
    --color-danger-surface: #3A1518;
    --color-text: #EDEFF2;
    --color-text-muted: #B8C0C8;
    --color-text-subtle: #8A94A0;
    --color-border: #3A454E;
    --color-surface: #232B32;
    --color-bg: #1E262D;
    --color-bg-elevated: #262F37;
    --color-canvas: #14181C;
    --color-focus: #9FC9E3;
    --shadow-s: 0 1px 3px rgb(0 0 0 / 0.5);
    --shadow-m: 0 4px 14px rgb(0 0 0 / 0.55);
  }
}

/* Explizite Rückkehr zu Hell, auch bei dunklem System — siehe Spezifitäts-Kommentar
   oben. Bewusst OHNE "@media screen"-Klammer: dieselbe Regel greift dadurch auch im
   Druckfall, falls dort je ein data-theme="light" vorkäme (harmlos/deckungsgleich mit
   Sektion 24). */
html[data-theme="light"] {
  color-scheme: light;

  --color-primary: #1B4965;
  --color-primary-dark: #123950;
  --color-primary-light: #E8F1F5;
  --color-secondary-surface: #F3EEE7;
  --color-secondary-deco: #BFD7E4;
  --color-accent: #8C4B10;
  --color-info: #175E88;
  --color-info-surface: #E7F1F8;
  --color-success: #1E7A46;
  --color-success-text: #14532D;
  --color-success-surface: #E6F4EA;
  --color-warning: #7A5200;
  --color-warning-surface: #FFF4DC;
  --color-danger: #A62828;
  --color-danger-text: #8F1D1D;
  --color-danger-surface: #FCEBEA;
  --color-text: #1F2933;
  --color-text-muted: #52606D;
  --color-text-subtle: #7B8794;
  --color-border: #D3DCE3;
  --color-surface: #F5F7FA;
  --color-bg: #FBF9F6;
  --color-bg-elevated: #FFFFFF;
  --color-canvas: #E7E3DC;
  --color-focus: #1B4965;
  --shadow-s: 0 1px 3px rgb(31 41 51 / 0.08);
  --shadow-m: 0 4px 12px rgb(31 41 51 / 0.12);
}

/* Bilder (echte Fotos, z. B. eine künftige Autorenbox-Aufnahme): dezente Abdunklung
   statt unveränderter, ggf. zu heller Bildfläche neben den nun dunklen Textflächen.
   Betrifft NICHT die Eigenwerk-Illustrationen (§16) — die sind inline-SVG mit
   currentColor/Token-Fills und passen sich über die Token-Overrides oben bereits
   automatisch an; kein <img>, daher kein Filter-Konflikt. Aktuell gibt es in den
   Templates keine <img>-Bindung (Grep bestätigt) — Regel ist bewusste Vorsorge für
   die nächste echte Bildeinbindung (Autorenfoto, künftige Artikelbilder). */
@media screen and (prefers-color-scheme: dark) {
  html:not([data-theme="light"]) .autorenbox__avatar,
  html:not([data-theme="light"]) .artikel-prose img {
    filter: brightness(0.92) contrast(1.02);
  }
}

@media screen {
  html[data-theme="dark"] .autorenbox__avatar,
  html[data-theme="dark"] .artikel-prose img {
    filter: brightness(0.92) contrast(1.02);
  }
}

/* ==========================================================================
   24. Druck-CSS (bleibt IMMER hell — unabhängig vom Dark-Mode-Zustand)
   Architektur-Hinweis: Beide dunkel-erzwingenden Regeln der Sektion 23 stehen
   bewusst in "@media screen and (…)"/"@media screen { … }" — der Medientyp
   "print" erfüllt "screen" per Definition nie, unabhängig von Systemeinstellung
   oder gesetztem "data-theme"-Attribut. Ein Druckvorgang landet dadurch IMMER bei
   den unconditional-Lichtwerten aus Sektion 1 (":root", keine Media-Bedingung) —
   ohne dass diese Sektion die Tokens selbst erneut überschreiben müsste. Die
   folgende Regel ist reine Absicherung/Dokumentation (verhindert stille Regression,
   falls eine künftige Änderung die Screen-Klammer aus Sektion 23 entfernt).
   ========================================================================== */

@media print {
  :root {
    color-scheme: light;
  }

  body {
    background: none;
    padding: 0;
  }

  .site-shell {
    border: none;
    box-shadow: none;
    border-radius: 0;
    background: none;
  }

  /* Glossar-Tooltip (§25, Sprint 13 WP-2) in der folgenden Liste ergänzt: transientes Hover-/
     Fokus-Popover ohne Aussagewert auf Papier – die vollständige Definition steht bereits
     verlinkt auf der Glossarseite. Normalerweise ohnehin per [hidden] unsichtbar; diese Regel
     ist reine Absicherung für den Randfall, dass ein Druckvorgang ausgelöst wird, während
     gerade eines geöffnet ist. */
  .site-header,
  .site-footer,
  .breadcrumbs,
  .nav-toggle,
  .skip-link,
  .artikel-aktion,
  .anzeigen-slot,
  .artikel-toc--mobile,
  .artikel-layout__toc,
  .glossar-tooltip {
    display: none;
  }

  /* Werkzeuge (Sprint 4, Track T, §22): Speicher-Opt-in ist eine geräte-/sitzungslokale
     Einstellung ohne Aussagewert auf Papier; Bedienelemente ohne Papier-Nutzen (Berechnen-/
     Teilen-/Zurücksetzen-Knopf) entfallen. Checkboxen selbst bleiben bewusst sichtbar
     (05 §4.14 "Checklisten mit leeren Kästchen ausdruckbar" — Browser drucken native
     Checkboxen inkl. Ankreuzzustand). */
  .speicher-opt-in,
  .rechner button[type="submit"],
  [data-rechner-teilen-button],
  [data-rechner-teilen-status],
  [data-checkliste-reset] {
    display: none;
  }

  .checkliste__fortschritt {
    color: var(--color-text);
  }

  /* Zwei-Spalten-Layout (Lesespalte + TOC) im Druck aufheben – die TOC-Spalte
     ist ohnehin ausgeblendet (s. o.), die Lesespalte bleibt einspaltig. */
  .artikel-layout--with-toc {
    display: block;
    max-width: none;
  }

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

  .lernbaustein {
    break-inside: avoid;
  }
}

/* ==========================================================================
   25. Glossar-Tooltip (Popover für automatisch verlinkte Begriffe — Sprint 13, WP-2)
   Reines Progressive-Enhancement-Overlay über automatisch verlinkte Glossarbegriffe in
   Artikeltexten (eleventy.config.js linkGlossarBegriffe() + assets/js/glossar-tooltip.js) —
   ohne JS bleibt der Link unverändert der heutige, vollständig funktionierende Link (siehe
   dortige Kopfkommentare); diese Sektion hat daher keinen eigenen No-JS-Zweig.
   "position: fixed" mit von glossar-tooltip.js berechneten Koordinaten (einfache
   Kollisionsbehandlung: oben/unten umklappen, horizontal an den Viewport geklemmt) — das
   Popover nimmt NICHT am Textfluss teil (kein CLS im Fließtext). Keine Transition angesetzt
   (reines Sofort-Ein-/Ausblenden über das "hidden"-Attribut) – "prefers-reduced-motion" ist
   damit gegenstandslos, es gibt nichts zu reduzieren. Ausschließlich bestehende Tokens: Dark
   Mode (§23) wirkt automatisch korrekt mit, ohne dass diese Sektion eigene Overrides bräuchte
   (vgl. Architektur-Hinweis zu Beginn von §23 – gilt hier unverändert, da keine Hex-Werte
   verwendet werden). */

.glossar-tooltip {
  position: fixed;
  z-index: 500; /* über Header-Leiste/-Umschalter (§10, z-index 400) und Mobil-Nav-Overlay (300) */
  max-width: min(20rem, calc(100vw - (var(--space-s) * 2)));
  /* Sprint 18 (qa-Gate QA-3): Die vier Bewertungsmodell-Definitionen sind die längsten des
     Bestands (bis ~95 Wörter); positioniere() in glossar-tooltip.js klemmt nur horizontal.
     Deckel + Scrollbarkeit verhindern, dass das Popover auf kleinen Viewports (320 px) über
     den sichtbaren Bereich hinausläuft. */
  max-height: min(60vh, 24rem);
  overflow-y: auto;
  padding: var(--space-2xs) var(--space-s);
  background: var(--color-bg-elevated);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-m);
  box-shadow: var(--shadow-m);
  color: var(--color-text);
  font-size: var(--font-size-sm);
  line-height: var(--line-height-body);
}

/* ==========================================================================
   Sprint 16: Merkliste + Lernfortschritt
   Neue V1.x-Komfortfunktionen (05 §4.3/§4.4, interaction-developer): "Merken"-Umschalter im
   Artikelkopf (jede Artikelseite), "Als gelesen markieren"-Umschalter im unteren
   Lernpfad-Navigationsblock (nur Seiten mit Pfadzugehörigkeit), dezente "X von Y
   gelesen"-Statuszeilen + ✓-Markierung auf der Lernpfad-Übersicht (/lernpfade/) sowie die
   Listenseite /merkliste/. Ausschließlich bestehende Tokens (Farben/Abstände/Radien) — Dark
   Mode (§23) wirkt automatisch korrekt mit, ohne dass dieser Block eigene Overrides bräuchte
   (vgl. Architektur-Hinweis zu Beginn von §23 bzw. §25 Glossar-Tooltip).

   Wichtiger Struktur-Hinweis (Spezifitäts-/Reihenfolge-Falle vermieden): Die äußeren
   ".js-only-block"-Wrapper (.merken, .lernpfad-nav__gelesen, [data-merkliste-liste]) erhalten
   von diesem Block bewusst KEINE eigene "display"-Deklaration — sie verlassen sich unverändert
   auf die bestehende Regel ".js .js-only-block { display: block }" (§14). Ein späterer,
   gleich- oder niedriger-spezifischer "display"-Wert an dieser Stelle würde die
   No-JS-Ausblendung (".js-only-block { display: none }", §14) aushebeln, weil dieser Block
   textuell NACH §14 steht (analog .rechner/.speicher-opt-in, §22 — dieselbe Konvention). Nur
   NICHT-"display"-Eigenschaften (margin, Farbe, Schrift) und rein innenliegende Elemente
   (Buttons, Listen, Statuszeilen) erhalten eigene Layout-Deklarationen. */

/* --- "Merken"-Umschalter (Artikelkopf, 05 §4.4) --------------------------- */

.merken {
  margin: 0 0 var(--space-m);
}

[data-merken-knopf][aria-pressed="true"] {
  background: var(--color-primary);
  border-color: var(--color-primary);
  color: var(--color-bg-elevated);
}

[data-merken-knopf][aria-pressed="true"]:hover {
  background: var(--color-primary-dark);
  border-color: var(--color-primary-dark);
}

.merken__status {
  margin: var(--space-2xs) 0 0;
  color: var(--color-text-muted);
}

.merken__status:empty {
  /* wie .artikel-teilen__status (§14): geklippt statt display:none, damit aria-live
     zuverlässig ankündigt (Element bleibt im Accessibility-Tree), ohne Layout-Sprung. */
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* --- "Als gelesen markieren"-Umschalter (Lernpfad-Navigation, 05 §4.3) ---- */

.lernpfad-nav__gelesen {
  margin-top: var(--space-s);
}

[data-lernfortschritt-knopf][aria-pressed="true"] {
  background: var(--color-primary);
  border-color: var(--color-primary);
  color: var(--color-bg-elevated);
}

[data-lernfortschritt-knopf][aria-pressed="true"]:hover {
  background: var(--color-primary-dark);
  border-color: var(--color-primary-dark);
}

.lernpfad-nav__gelesen-status {
  margin: var(--space-2xs) 0 0;
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
}

.lernpfad-nav__gelesen-status:empty {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* --- Lernpfad-Übersicht: "X von Y gelesen" + ✓-Markierung (/lernpfade/) --- */

.lernfortschritt-status {
  margin: 0 0 var(--space-s);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-primary);
}

.lernfortschritt-marke {
  margin-inline-start: var(--space-3xs);
  color: var(--color-success);
  font-weight: var(--font-weight-bold);
}

/* --- Merkliste-Seite (/merkliste/) ----------------------------------------- */

.merkliste-anzahl {
  margin: 0 0 var(--space-s);
  font-weight: var(--font-weight-semibold);
}

.merkliste-leer {
  color: var(--color-text-muted);
}

.merkliste-liste {
  list-style: none;
  margin: 0 0 var(--space-m);
  padding: 0;
}

.merkliste-eintrag {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-s);
  padding-block: var(--space-xs);
  border-bottom: 1px solid var(--color-border);
}

.merkliste-eintrag:last-child {
  border-bottom: none;
}

.merkliste-eintrag__datum {
  display: block;
  color: var(--color-text-muted);
}

.merkliste-status {
  margin: var(--space-2xs) 0 0;
  color: var(--color-text-muted);
}

.merkliste-status:empty {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* --- Druck: interaktive Elemente ohne Papier-Nutzen ausblenden (analog §24) --- */

@media print {
  .merken,
  .lernpfad-nav__gelesen,
  .merkliste-eintrag__entfernen,
  .merkliste-leeren {
    display: none;
  }
}

/* Sprint 16: Kosteneffekt-Beispiel */

/* ==========================================================================
   Kosteneffekt-"Leuchtturm"-Beispiel (05 §4.9, B-2 — erstes interaktives
   Beispiel der Site; src/_includes/partials/kosteneffekt-beispiel.njk,
   eingebettet auf /broker-und-depot/kosten-beim-handel/). Wiederverwendet die
   bestehende Rechner-Optik fast vollständig (.rechner/.rechner__ergebnis/
   .rechner__kennzahlen/.rechner__feld-hinweis, §22 oben) — hier nur die
   schieberegler-spezifischen Ergänzungen, die es dort noch nicht gab (§22
   kennt bislang ausschließlich <input type="number">-Felder). Editorial-flach
   wie das übrige Box-System (D-123), kein neues Farb-Token.
   ========================================================================== */

.kosteneffekt__kicker {
  margin: 0 0 var(--space-m);
  font-family: var(--font-family-base);
  font-size: var(--font-size-h4);
  font-weight: var(--font-weight-bold);
  color: var(--color-text);
}

.kosteneffekt__feld {
  margin-bottom: var(--space-m);
  max-width: 28rem;
}

.kosteneffekt__feld > label {
  display: block;
  margin-bottom: var(--space-2xs);
  font-weight: var(--font-weight-semibold);
}

.kosteneffekt__regler {
  display: flex;
  align-items: center;
  gap: var(--space-s);
  flex-wrap: wrap;
}

.kosteneffekt__regler input[type="range"] {
  flex: 1 1 14rem;
  min-width: 10rem;
  /* Touch-Ziel (04 §14.5, analog ".rechner__feld input[type=\"number\"]" oben): die sichtbare
     Spur bleibt schlank, aber die Element-Box selbst bekommt 44px Höhe – Chrome/Firefox werten
     bei <input type="range"> die GESAMTE Element-Box (nicht nur die dünne Spurlinie) als
     Klick-/Tippziel, eine vergrößerte Box vergrößert also tatsächlich das Bedienziel. */
  min-height: 44px;
  accent-color: var(--color-primary);
}

.kosteneffekt__ausgabe {
  min-width: 4.5rem;
  font-family: var(--font-family-base);
  font-weight: var(--font-weight-bold);
  font-variant-numeric: tabular-nums;
  color: var(--color-primary);
  text-align: right;
}

/* Sprint 16: B2-Selbsttest */

/* ==========================================================================
   B2-Risikoprofil-Selbsttest (08 §7 Prüfpunkt 38, 03 §4.2/§7, 05 §4.5 — Sprint 16, D-154;
   src/_includes/partials/selbsttest.njk, assets/js/selbsttest.js). EIGENER Klassen-Namensraum
   ".selbsttest*" (bewusst NICHT ".quiz*" wiederverwendet, siehe Architekturhinweis im
   Partial-Kopfkommentar) — Struktur größtenteils analog zum Quiz-Modul (§ oben, "Etappen-
   Selbstcheck / Quiz-Modul"), aber ohne die dortigen "is-richtig"/"is-falsch-gewaehlt"-
   Zustände: Dieser Selbsttest kennt kein Richtig/Falsch, nur drei gleichrangige, neutrale
   Beschreibungstypen. Editorial-flach (D-123), ausschließlich bestehende Tokens. Dark Mode (§23)
   wirkt automatisch korrekt mit (reine Token-Nutzung, keine eigenen Overrides nötig, analog dem
   Architektur-Hinweis zu Beginn von §23). Markup auch ungestylt nutzbar. */

.selbsttest {
  margin-block: var(--space-l);
}

.selbsttest__intro {
  margin: 0 0 var(--space-m);
  color: var(--color-text-muted);
}

.selbsttest__frage {
  margin-bottom: var(--space-l);
  padding-bottom: var(--space-m);
  border-bottom: 1px solid var(--color-border);
}

.selbsttest__frage:last-of-type {
  border-bottom: none;
}

.selbsttest fieldset {
  margin: 0;
  padding: 0;
  border: none;
}

.selbsttest legend {
  padding: 0;
  margin: 0 0 var(--space-s);
  font-family: var(--font-family-base);
  font-size: var(--font-size-h4);
  font-weight: var(--font-weight-bold);
  color: var(--color-text);
}

.selbsttest__frage-nummer {
  display: block;
  margin-bottom: var(--space-3xs);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-muted);
}

.selbsttest__optionen {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
}

.selbsttest__option {
  padding: var(--space-2xs) var(--space-xs);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-m);
}

/* Touch-Ziel/Klickfläche (04 §14.5, WCAG 2.5.8): wie .quiz__option/.checkliste__punkt label —
   das ganze Label (nicht nur das 20px-Radio) ist über min-height 44px das eigentliche
   Bedienziel. */
.selbsttest__option label {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  min-height: 2.75rem;
  padding-block: var(--space-3xs);
  cursor: pointer;
}

.selbsttest__option input[type="radio"] {
  flex-shrink: 0;
  width: 1.25rem;
  height: 1.25rem;
  accent-color: var(--color-primary);
}

.selbsttest__frage-fehler {
  margin: var(--space-2xs) 0 0;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-danger-text);
}

.selbsttest__ergebnis {
  margin-top: var(--space-l);
  padding-top: var(--space-l);
  border-top: 1px solid var(--color-border);
}

.selbsttest__status {
  padding: var(--space-s) var(--space-m);
  margin: 0 0 var(--space-m);
  background: var(--color-surface);
  border-radius: var(--radius-m);
  font-weight: var(--font-weight-semibold);
}

.selbsttest__typ {
  margin-bottom: var(--space-m);
}

.selbsttest__typ-titel {
  margin: 0 0 var(--space-2xs);
  font-family: var(--font-family-base);
  font-size: var(--font-size-h4);
  font-weight: var(--font-weight-bold);
  color: var(--color-text);
}

.selbsttest__lernhinweise {
  margin: var(--space-2xs) 0 var(--space-m);
  padding-left: var(--space-m);
}

.selbsttest__transparenz {
  margin-top: var(--space-m);
  padding-top: var(--space-m);
  border-top: 1px solid var(--color-border);
  color: var(--color-text-muted);
}

/* --- Selbsttest: No-JS-Fallback (<noscript>, vollständig aufgelöst) -------- */

.selbsttest--noscript {
  margin-block: var(--space-l);
}

.selbsttest__noscript-frage {
  margin-bottom: var(--space-m);
}

.selbsttest__noscript-frage ul {
  margin: var(--space-2xs) 0 0;
  padding-left: var(--space-m);
}
