/*
 * FORUM BEFA – Anmeldeverwaltung
 * Design-System: konsolidierte Tokens und Kern-Komponenten für das Admin-Backend.
 * Reihenfolge bewusst: erst :root-Tokens, dann Komponenten – so bleibt der
 * Farb- und Maß-Wildwuchs an genau einer Stelle gepflegt.
 *
 * Maßgeblich ist das produktive Anmeldeformular (../forum-befa-anmeldung/css/form.css):
 * Farben, Radien, Schatten und Typografie sind von dort übernommen. Navy ist
 * Akzent – Überschriften, Primäraktion, aktive Navigation, Fokus –, keine Fläche.
 *
 * Design & Entwicklung: SION Design · siondesign.de
 */

/* =========================================================================
   1. Tokens
   Einzige Quelle der Wahrheit. Komponenten greifen ausschließlich hierauf zu,
   damit ein Farb- oder Maßwechsel nie an mehreren Stellen nachgezogen werden muss.
   ========================================================================= */

:root {
  /* Marken- und Flächenfarben. Die Werte stammen aus dem Live-Formular
     (../forum-befa-anmeldung/css/form.css): Formular und Backend sollen
     erkennbar aus derselben Hand kommen. */
  --navy: #00335d;
  --navy-hover: #0b436f;
  --teal: #1d7fa3;
  --teal-link: #13627e;

  /* Getönte Akzentfläche samt Kante – das ruhige Kasten-Rezept des Formulars
     (Hinweise, Fokus-Halo, Hover auf Teal-Flächen). */
  --accent-soft: #eaf3f7;
  --accent-line: #cfe4ec;

  --bg: #f6f7f8;
  --card: #fff;
  --hover-neutral: #f2f5f7;

  /* Teal-Hover ist dieselbe Fläche wie der Akzent. Zwei fast gleiche Blautöne
     nebeneinander wären nur Wildwuchs – hier zeigt einer auf den anderen. */
  --hover-teal: var(--accent-soft);

  /* Linien – abgestuft von sichtbar bis kaum wahrnehmbar */
  --line: #e4e8ec;
  --line-interactive: #d5dbe1;
  --line-subtle: #f0f2f4;

  /* Textfarben – text-muted ist die unterste erlaubte Stufe für echte Schrift */
  --text: #1d2733;
  --text-2: #5d6b78;
  --text-muted: #677480;

  /* Ein einziger Fokusring im ganzen Backend. Der frühere hellere Ring war nur
     nötig, solange die Kopfleiste ein Navy-Block war – sie ist jetzt weiß. */
  --focus: #1d7fa3;

  /* Grün und Rot in einer Wahrheit, ebenfalls aus dem Formular. Sie versorgen
     Meldungen, Pillen, Feld-Diff und Signaturprüfung gemeinsam – dieselbe
     Bedeutung trägt im ganzen Portal denselben Farbwert. */
  --ok: #256c2a;
  --ok-soft: #e7f3e8;
  --danger: #b3261e;
  --danger-soft: #fcebe9;

  /* Kanten der getönten Kästen: eine Spur kräftiger als die Fläche, aber
     deutlich leiser als die Schriftfarbe – ein ganzflächiger Kasten verträgt
     keinen Rahmen in voller Statusfarbe. */
  --danger-line: #f0cdc8;

  /* Gelbstufe der Notiz-Box. Eigene Werte, weil die Status-Pille (--st-inb-*)
     als kleines Etikett kräftiger sein darf als eine ganze Kastenfläche. */
  --warn: #7a5a12;
  --warn-soft: #fdf6e6;
  --warn-line: #ecdcae;

  /* Status: je ein Vordergrund- und ein Flächenwert.
     Reihenfolge neu → in_bearbeitung → bestätigt → abgelehnt → archiviert → storniert. */
  --st-neu-fg: #1e5fae;        --st-neu-bg: #e8f0fb;
  --st-inb-fg: #8a5a06;        --st-inb-bg: #fbf1dd;
  --st-best-fg: var(--ok);     --st-best-bg: var(--ok-soft);
  --st-abg-fg: var(--danger);  --st-abg-bg: var(--danger-soft);
  --st-arch-fg: #5d6b78;       --st-arch-bg: #eef1f3;
  /* Storniert steht zwischen Abgelehnt und Archiviert: Der Aussteller sagt ab –
     das ist kein Fehlerzustand (Rot wäre eine Wertung des Hauses), aber auch kein
     stiller Ablagezustand (Grau). Deshalb ein warmes, entsättigtes Braun aus der
     Warn-Familie. Gegen „In Bearbeitung" grenzt es die fehlende Sättigung ab:
     dort leuchtet das Amber, hier ist es zurückgenommen. Eigene Werte statt
     var(--warn): Das ist die Gelbstufe der Notiz-Box und stünde als Pille direkt
     neben --st-inb-* – zwei Etiketten, ein Ton. */
  --st-storn-fg: #6b5847;      --st-storn-bg: #f2ece3;

  /* Typografie – Systemschrift wie im Live-Formular, keine externen Fonts */
  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;

  /* Nichtproportional für Werte, die zeichengenau abgetippt werden (2FA-Geheimnis,
     Recovery-Codes). Ebenfalls nur Systemschriften – keine externen Fonts. */
  --font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;

  /* Feste Skala 11–27 px; keine Zwischengrößen, um Wildwuchs zu vermeiden.
     15 px ist die Grundschrift: das Formular setzt 16, das Backend darf eine
     Spur kompakter sein – 14 war für Fließtext zu klein. */
  --fs-11: 11px;
  --fs-12: 12px;
  --fs-13: 13px;
  --fs-14: 14px;
  --fs-15: 15px;
  --fs-16: 16px;
  --fs-20: 20px;
  --fs-25: 25px;   /* Seitentitel – die 1,6 rem aus der Markenvorgabe */
  --fs-27: 27px;   /* nur für KPI-Kennzahlen */

  /* Gewichte streng auf 400/500/600/700/800 begrenzt (kein 550/650).
     800 ist allein den Seitentiteln vorbehalten – wie die h1 im Formular. */
  --fw-normal: 400;
  --fw-medium: 500;
  --fw-semibold: 600;
  --fw-bold: 700;
  --fw-extrabold: 800;

  /* Radien wie im Formular: Feld/Button 10 px, Karte 14 px, Pille 100 px */
  --radius: 10px;
  --radius-card: 14px;
  --radius-pill: 100px;

  /* Zwei Schatten aus dem Formular. Der flache liegt unter jeder Karte; der
     hohe nur unter Elementen, die tatsächlich über dem Inhalt schweben
     (Sprunglink, Massenleiste, Login-Karte) – sonst wirkt das Backend unruhig. */
  --shadow-card: 0 1px 2px rgba(16, 40, 64, .05);
  --shadow-hoch: 0 1px 3px rgba(16, 40, 64, .06), 0 8px 24px rgba(16, 40, 64, .05);

  /* Spacing-Stufen 4–32 */
  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 12px;
  --sp-4: 16px;
  --sp-5: 20px;
  --sp-6: 24px;
  --sp-7: 32px;

  /* Höhen der Bedienelemente – M für Standard, S für kompakte Aktionen */
  --control-h: 36px;
  --control-h-s: 32px;

  /* Schrift auf dunklem Grund (gefüllte Buttons, aktive Chips, aktive Seitenzahl).
     Bewusst ein eigener Token statt --card: Weiß ist hier eine Textrolle und
     keine Kartenfläche – die beiden dürfen sich unabhängig ändern lassen.
     Die Abstufungen für den Navy-Header entfallen: Navy ist jetzt Akzent, nicht
     Fläche – die Kopfleiste ist weiß. */
  --on-dark: #fff;

  /* Gedrückter Zustand der destruktiven Aktion (dunkler als --danger) */
  --destruktiv-hover: #8f1e18;

  /* Schattenkante am Rand waagerecht scrollender Tabellen. Die Null-Varianten
     sind nötig, weil `transparent` in Verläufen über Schwarz interpoliert und
     dabei einen grauen Schleier erzeugt. */
  --card-0: rgba(255, 255, 255, 0);
  --scroll-shadow: rgba(16, 34, 51, .12);
  --scroll-shadow-0: rgba(16, 34, 51, 0);
}

/* =========================================================================
   2. Grundlagen
   ========================================================================= */

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

html {
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  font-family: var(--font);
  font-size: var(--fs-15);
  line-height: 1.5;
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* Überschriften wie im Formular: Navy, kräftig, leicht zusammengezogen. Sie
   sind der Ort, an dem die Marke im Backend spricht – nicht ganze Flächen.
   Die Größen kommen aus der Skala, die Abstände bleiben bei den Komponenten. */
h1,
.page-title {
  font-size: var(--fs-25);
  font-weight: var(--fw-extrabold);
  line-height: 1.15;
  letter-spacing: -.01em;
  color: var(--navy);
}

h2,
.section-title,
.section-card__title {
  font-weight: var(--fw-bold);
  letter-spacing: -.005em;
  color: var(--navy);
}

/* Zahlen sollen in Tabellen und Kennzahlen sauber untereinander stehen */
.table td,
.table th,
.kpi__value,
.pagination {
  font-variant-numeric: tabular-nums;
}

a {
  color: var(--teal-link);
  text-decoration: none;
}

a:hover {
  text-decoration: underline;
}

/* Ein einziger, überall sichtbarer Fokusring. Tastaturnutzung darf nie raten,
   wo der Fokus steht. :focus-visible hält den Ring bei Maus-Klicks zurück. */
:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
  border-radius: var(--radius);
}

/* =========================================================================
   3. Layout: Topbar, Shell, Card, Seitentitel
   ========================================================================= */

/* Weiße Kopfleiste wie im Formular. Das Logo ist anthrazit und trägt auf
   dunklem Grund nicht – deshalb steht es auf Weiß, und die Marke wirkt über
   das Logo statt über einen Navy-Balken. */
.topbar {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  height: 72px;
  padding: 0 var(--sp-6);
  background: var(--card);
  color: var(--text);
  border-bottom: 1px solid var(--line);
}

/* Text-Wortmarke. Sie ist nur noch die Rückfallebene der gebrandeten
   Fehlerseiten (Kernel::fehlerseite), die ohne View-Schicht auskommen; die
   reguläre Kopfleiste trägt das Logo. */
.brand {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  font-size: var(--fs-16);
  font-weight: var(--fw-bold);
  letter-spacing: .01em;
  color: var(--navy);
}

.brand:hover {
  text-decoration: none;
}

/* Zusatz zur Wortmarke: leiser gesetzt, damit „FORUM BEFA" führt */
.brand__sub {
  font-weight: var(--fw-normal);
  color: var(--text-2);
}

/* Enthält die Topbar einen zentrierten Inhalts-Container, übernimmt dieser den
   Seitenabstand – die Bar läuft randlos bis zur Fensterkante, ihr Inhalt fluchtet
   dabei exakt mit dem Hauptbereich darunter. */
.topbar:has(.topbar__inner) {
  padding: 0;
}

.topbar__inner {
  flex: 1;
  display: flex;
  align-items: center;
  gap: var(--sp-4);
}

/* ACHTUNG, ALTE FALLE – der Kindselektor ist Absicht:
   .topbar__inner trägt zugleich die Klasse .shell, und .shell steht weiter
   unten im Stylesheet mit `padding: var(--sp-6) var(--sp-6) var(--sp-7)`.
   Eine flache Regel `.topbar__inner { padding-top: 0 }` hat dieselbe
   Spezifität (eine Klasse) und verliert deshalb gegen die spätere .shell-Regel.
   Ergebnis am Server gemessen: 24 px oben, 32 px unten – der Inhalt saß mit
   11 px über und 20 px unter dem Logo sichtbar zu hoch. Zwei Klassen gewinnen
   unabhängig von der Reihenfolge; der seitliche Abstand bleibt bei .shell,
   damit Kopfzeile, Navigation und Inhalt in derselben Flucht stehen.
   Höhe und Zentrierung kommen allein von .topbar (height + align-items). */
.topbar > .topbar__inner {
  padding-top: 0;
  padding-bottom: 0;
}

/* Logo-Link: nur Bildfläche, keine Textdekoration, kein Zeilenversatz */
.topbar__heim {
  display: inline-flex;
  align-items: center;
  flex: none;
}

.topbar__heim:hover {
  text-decoration: none;
}

/* Höhe fest, Breite aus dem Seitenverhältnis (600×150 = 4:1). Die width/height-
   Attribute im Markup (160×40) halten den Platz frei, bevor das Bild geladen
   ist – sonst springt die ganze Zeile beim Nachladen. Wer die Höhe hier ändert,
   muss die Attribute im Markup mitziehen. */
.topbar__logo {
  display: block;
  height: 40px;
  width: auto;
}

/* Zarter senkrechter Strich zwischen Marke und Bereichsbezeichnung – dieselbe
   Trennung wie zwischen Logo und Untertitel im Formular. Er wächst mit dem
   Logo mit, bleibt aber deutlich kürzer: er trennt, er rahmt nicht. */
.topbar__trenner {
  flex: none;
  width: 1px;
  height: 28px;
  background: var(--line);
}

.topbar__bereich {
  font-size: var(--fs-14);
  color: var(--text-2);
  white-space: nowrap;
}

.topbar__logout {
  display: inline-flex;
  align-items: center;
  margin: 0;
}

/* Abmelden ist die einzige Aktion in der Kopfleiste: Navy, aber ohne Fläche */
.topbar__logout .btn--ghost {
  color: var(--navy);
}

/* Zentrierter Inhaltsbereich mit ruhigem Seitenabstand */
.shell {
  max-width: 1160px;
  margin: 0 auto;
  padding: var(--sp-6) var(--sp-6) var(--sp-7);
}

.card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-card);
  padding: var(--sp-5);
}

/* Schmale, zentrierte Karte – z. B. für Hinweis- und Fehlerseiten (403/404/500) */
.card--narrow {
  max-width: 480px;
  margin-left: auto;
  margin-right: auto;
}

/* Größe, Gewicht und Farbe stehen bei den Überschriften (Abschnitt 2) –
   hier nur der Abstand nach unten. */
.page-title {
  margin: 0 0 var(--sp-5);
}

/* =========================================================================
   4. Buttons
   Einheitliche Höhe (M=36/S=32), gemeinsame Basis, Varianten nur über Farbe.
   ========================================================================= */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  height: var(--control-h);
  padding: 0 var(--sp-4);
  border: 1px solid transparent;
  border-radius: var(--radius);
  font-family: inherit;
  font-size: var(--fs-14);
  font-weight: var(--fw-medium);
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  background: transparent;
  color: var(--text);
  transition: background-color .12s ease, border-color .12s ease, color .12s ease;
}

.btn:disabled,
.btn[aria-disabled="true"] {
  opacity: .55;
  cursor: not-allowed;
}

.btn--s {
  height: var(--control-h-s);
  padding: 0 var(--sp-3);
  font-size: var(--fs-13);
}

.btn--primary {
  background: var(--navy);
  color: var(--on-dark);
}

.btn--primary:hover:not(:disabled) {
  background: var(--navy-hover);
}

.btn--secondary {
  background: var(--card);
  border-color: var(--line-interactive);
  color: var(--text);
}

.btn--secondary:hover:not(:disabled) {
  background: var(--hover-neutral);
  border-color: var(--line-interactive);
}

.btn--destructive {
  background: var(--st-abg-fg);
  color: var(--on-dark);
}

.btn--destructive:hover:not(:disabled) {
  background: var(--destruktiv-hover);
}

.btn--ghost {
  background: transparent;
  color: var(--teal-link);
}

.btn--ghost:hover:not(:disabled) {
  background: var(--hover-teal);
  text-decoration: none;
}

/* =========================================================================
   5. Formular
   .field kapselt Label + Control + Fehlermeldung als eine Einheit.
   ========================================================================= */

.field {
  display: flex;
  flex-direction: column;
  gap: var(--sp-1);
  margin-bottom: var(--sp-4);
}

.field__label {
  font-size: var(--fs-13);
  font-weight: var(--fw-medium);
  color: var(--text-2);
}

.input,
.select {
  width: 100%;
  height: var(--control-h);
  padding: 0 var(--sp-3);
  border: 1px solid var(--line-interactive);
  border-radius: var(--radius);
  background: var(--card);
  color: var(--text);
  font-family: inherit;
  font-size: var(--fs-14);
  line-height: 1.4;
  transition: border-color .12s ease, box-shadow .12s ease;
}

/* Eigener Pfeil als Data-URI – kein externes Asset, CSP-konform.
   EINZIGE dokumentierte Ausnahme von der Token-Regel: in einer Data-URI lässt
   sich var() nicht auflösen, der Farbwert muss url-kodiert dort stehen.
   %235d6b78 ist --text-2 – wird der Token geändert, ist diese Zeile mitzuziehen. */
.select {
  appearance: none;
  -webkit-appearance: none;
  padding-right: var(--sp-7);
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'><path fill='%235d6b78' d='M1 1.5 6 6.5 11 1.5'/></svg>");
  background-repeat: no-repeat;
  background-position: right var(--sp-3) center;
}

.input::placeholder {
  color: var(--text-muted);
}

/* Dateifeld: Der native Knopf sitzt ohne Zutun am oberen Rand, weil .input eine
   feste Höhe vorgibt und der Browser den Inhalt darin nicht ausrichtet. Ein
   reiner Flex-Trick genügt hier nicht – wie ein Dateifeld seinen Innenraum
   verteilt, entscheidet jeder Browser für sich (Safari anders als Chrome).
   Deshalb wird die feste Höhe aufgegeben: Das Feld umschließt den Knopf mit
   gleichem Abstand oben und unten, die Mitte ergibt sich von selbst. min-height
   hält es auf Feldhöhe der Nachbarn, align-items zentriert dort, wo der
   Knopf kleiner ausfällt. */
.input[type="file"] {
  display: flex;
  align-items: center;
  height: auto;
  min-height: var(--control-h);
  padding-top: var(--sp-2);
  padding-bottom: var(--sp-2);
}

/* Aktiver Zustand: Rahmen in Teal, dezenter Halo statt harter Umrandung */
.input:focus,
.select:focus {
  outline: none;
  border-color: var(--teal);
  box-shadow: 0 0 0 3px var(--hover-teal);
}

/* Tastaturfokus behält zusätzlich den globalen Ring für Screenreader-Parität */
.input:focus-visible,
.select:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 1px;
}

/* Fehlerzustand: Feld und Meldung sind farblich eindeutig verbunden */
.field--invalid .input,
.field--invalid .select {
  border-color: var(--st-abg-fg);
}

.field--invalid .input:focus,
.field--invalid .select:focus {
  box-shadow: 0 0 0 3px var(--st-abg-bg);
}

.field__error {
  font-size: var(--fs-12);
  color: var(--st-abg-fg);
}

/* =========================================================================
   6. Status-Pills und Chips
   ========================================================================= */

/* Pillen und Chips sind im Formular halbfett und vollrund (100 px) – kleine
   Etiketten müssen auf einen Blick lesbar sein, nicht flüstern. */
.pill {
  display: inline-flex;
  align-items: center;
  padding: 2px var(--sp-2);
  border-radius: var(--radius-pill);
  font-size: var(--fs-12);
  font-weight: var(--fw-semibold);
  line-height: 1.4;
  white-space: nowrap;
}

.pill--neu            { color: var(--st-neu-fg);  background: var(--st-neu-bg); }
.pill--in_bearbeitung { color: var(--st-inb-fg);  background: var(--st-inb-bg); }
.pill--bestaetigt     { color: var(--st-best-fg); background: var(--st-best-bg); }
.pill--abgelehnt      { color: var(--st-abg-fg);  background: var(--st-abg-bg); }
.pill--archiviert     { color: var(--st-arch-fg); background: var(--st-arch-bg); }
.pill--storniert      { color: var(--st-storn-fg); background: var(--st-storn-bg); }

/* Neutrales Meta-Etikett, z. B. für Zähler oder Filter */
.chip {
  display: inline-flex;
  align-items: center;
  /* Ein Chip ist ein Etikett und bricht nie um – in schmalen Tabellenspalten wurde „auf Anfrage" sonst zweizeilig (24.08.). */
  white-space: nowrap;
  gap: var(--sp-1);
  padding: 3px var(--sp-3);
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  font-size: var(--fs-12);
  font-weight: var(--fw-semibold);
  color: var(--text-2);
  background: var(--card);
}

/* =========================================================================
   7. Feedback: Toast und Flash
   Toasts sind kurzlebige, schließbare Meldungen; Flash ist die serverseitige
   Meldung im Seitenfluss. Den Status tragen beide über einen umlaufenden
   1px-Rahmen und eine getönte Fläche – kein farbiger Balken an der linken
   Kante. Der Balken war Baukasten-Optik und sagt nichts, was Rahmen und
   Fläche nicht ruhiger sagen.
   ========================================================================= */

.toast {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--card);
  font-size: var(--fs-13);
  color: var(--text);
}

.toast__body {
  flex: 1;
}

/* Schließen-Fläche ohne eigenes Button-Chrom; Interaktion via app.js */
.toast__close {
  border: 0;
  background: transparent;
  padding: 0 var(--sp-1);
  font-size: var(--fs-16);
  line-height: 1;
  color: var(--text-muted);
  cursor: pointer;
}

.toast__close:hover {
  color: var(--text-2);
}

.toast--success { border-color: var(--ok);         background: var(--ok-soft); }
.toast--warn    { border-color: var(--st-inb-fg);  background: var(--st-inb-bg); }
.toast--error   { border-color: var(--danger);     background: var(--danger-soft); }

.flash {
  padding: var(--sp-3) var(--sp-4);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--card);
  font-size: var(--fs-13);
  color: var(--text);
  margin-bottom: var(--sp-4);
}

/* Optionale Statusfärbung, falls .flash allein steht */
.flash--success { border-color: var(--ok);        background: var(--ok-soft); }
.flash--warn    { border-color: var(--st-inb-fg); background: var(--st-inb-bg); }
.flash--error   { border-color: var(--danger);    background: var(--danger-soft); }

/* Die Flash-Komponente legt einen fertigen Toast in den Fluss (components/flash.php).
   Dann ist .flash nur noch Abstandhalter – zwei ineinander gezeichnete Kästen
   wären genau die Baukasten-Optik, die hier verschwinden soll. */
.flash:has(> .toast) {
  padding: 0;
  border: 0;
  background: none;
}

/* =========================================================================
   8. Tabelle
   Echtes <table>, Zebra-Streifen und ein Sortier-Header mit dezentem Indikator.
   ========================================================================= */

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

.table th,
.table td {
  padding: var(--sp-3) var(--sp-3);
  text-align: left;
  vertical-align: middle;
}

.table thead th {
  border-bottom: 1px solid var(--line);
  font-size: var(--fs-12);
  font-weight: var(--fw-semibold);
  color: var(--text-2);
  white-space: nowrap;
}

.table tbody td {
  border-bottom: 1px solid var(--line-subtle);
  color: var(--text);
}

/* Zebra: nur die geraden Zeilen leicht abheben, damit das Raster ruhig bleibt */
.table tbody tr:nth-child(even) {
  background: var(--hover-neutral);
}

.table tbody tr:hover {
  background: var(--hover-teal);
}

/* Sortierbare Spalte: klickbarer Header mit Pfeil-Indikator per Pseudo-Element.
   Die border-left/right hier sind kein Farbbalken, sondern die beiden
   durchsichtigen Flanken des CSS-Dreiecks – sie bleiben. */
.table th.is-sortable {
  cursor: pointer;
  user-select: none;
}

.table th.is-sortable::after {
  content: "";
  display: inline-block;
  width: 0;
  height: 0;
  margin-left: var(--sp-2);
  vertical-align: middle;
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  opacity: .35;
  border-top: 5px solid currentColor;
}

.table th.is-sortable:hover {
  color: var(--text);
}

/* aria-sort trägt den tatsächlichen Zustand für Screenreader und Optik */
.table th[aria-sort="ascending"]::after {
  opacity: .9;
  border-top: 0;
  border-bottom: 5px solid currentColor;
}

.table th[aria-sort="descending"]::after {
  opacity: .9;
  border-bottom: 0;
  border-top: 5px solid currentColor;
}

/* Der Kopf ist ein echter Link (Tastatur, neuer Tab, Verlauf), soll aber wie
   eine Spaltenüberschrift aussehen: Farbe und Größe vom th, kein Teal, keine
   Unterstreichung im Ruhezustand. Der Pfeil hängt weiter am th – so sitzt er
   auch dann am Spaltenrand, wenn die Beschriftung kurz ist. */
.table th.is-sortable > .sortier-kopf {
  color: inherit;
  font: inherit;
  text-decoration: none;
}

.table th.is-sortable > .sortier-kopf:hover {
  color: var(--text);
  text-decoration: underline;
}

/* Die ganze Kopfzelle klickbar machen: der Pfeil hängt am th und liegt damit
   ausserhalb des Links – ohne diese Fläche zeigte die Zelle zwar den Zeiger
   (cursor: pointer oben), ein Klick auf Pfeil oder Innenabstand liefe aber ins
   Leere. Der Fokusring bleibt am Text, wo er hingehört. */
.table th.is-sortable {
  position: relative;
}

.table th.is-sortable > .sortier-kopf::before {
  content: "";
  position: absolute;
  inset: 0;
}

/* Die aktive Spalte trägt ihren Zustand auch im Text, nicht nur im Pfeil: die
   Kopfzeile ist klein und grau, ein Indikator allein ist schnell übersehen.
   Dieselbe Stufe wie der Zeileninhalt – mehr braucht es nicht, das Gewicht
   tragen alle Köpfe ohnehin. */
.table th.is-sortable[aria-sort] {
  color: var(--text);
}

/* =========================================================================
   9. Leerzustand
   ========================================================================= */

.empty-state {
  padding: var(--sp-7) var(--sp-5);
  text-align: center;
  color: var(--text-muted);
  font-size: var(--fs-13);
}

.empty-state__title {
  margin: 0 0 var(--sp-2);
  font-size: var(--fs-16);
  font-weight: var(--fw-medium);
  color: var(--text-2);
}

.empty-state__text {
  margin: 0;
  font-size: var(--fs-13);
  color: var(--text-muted);
}

/* =========================================================================
   10. Pagination
   ========================================================================= */

.pagination {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
}

.pagination a,
.pagination span {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: var(--control-h-s);
  height: var(--control-h-s);
  padding: 0 var(--sp-2);
  border: 1px solid var(--line-interactive);
  border-radius: var(--radius);
  font-size: var(--fs-13);
  color: var(--text-2);
  background: var(--card);
}

.pagination a:hover {
  background: var(--hover-neutral);
  text-decoration: none;
}

.pagination .is-current {
  border-color: var(--navy);
  background: var(--navy);
  color: var(--on-dark);
  font-weight: var(--fw-medium);
}

.pagination .is-disabled {
  opacity: .5;
  pointer-events: none;
}

/* =========================================================================
   11. KPI-Kachel
   ========================================================================= */

.kpi {
  padding: var(--sp-4);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  background: var(--card);
  box-shadow: var(--shadow-card);
}

.kpi__label {
  font-size: var(--fs-12);
  font-weight: var(--fw-medium);
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: .04em;
}

/* Beträge dürfen nie zwischen Zahl und Währung umbrechen („276.007,10" / „€").
   Damit lange Summen die Kachel trotzdem nicht sprengen, schrumpft die Zahl
   mit der Fensterbreite statt überzulaufen. */
.kpi__value {
  margin-top: var(--sp-2);
  font-size: clamp(var(--fs-20), 2.2vw, var(--fs-27));
  font-weight: var(--fw-bold);
  line-height: 1.1;
  color: var(--text);
  white-space: nowrap;
}

.kpi__hint {
  margin-top: var(--sp-1);
  font-size: var(--fs-12);
  color: var(--text-2);
}

/* =========================================================================
   12. Login
   Zentrierte Karte auf ruhigem Hintergrund – der einzige Screen ohne Topbar.
   Statt einer Kopfleiste steht das Logo über der Karte: die Seite soll auf den
   ersten Blick als FORUM BEFA erkennbar sein.
   ========================================================================= */

.auth {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--sp-5);
  min-height: 100vh;
  padding: var(--sp-5);
  background: var(--bg);
}

.auth__logo {
  display: block;
  width: 200px;
  height: auto;
}

/* Der frühere Zwischenrahmen .login (eigene 100vh-Zentrierung) ist ersatzlos
   entfallen: .auth zentriert Logo und Karte gemeinsam, ein zweiter Rahmen
   drückte das Logo aus der Mitte. Karte und Hinweistext leben unverändert
   weiter – sie tragen auch die 2FA- und Bestätigungsseiten. */

.login__card {
  width: 100%;
  max-width: 380px;
  padding: var(--sp-6);
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  /* Einzige Karte auf leerer Fläche – sie darf sichtbar aufliegen */
  box-shadow: var(--shadow-hoch);
}

/* Hinweistext unter dem Titel der Login- und Fehlerkarten */
.login__hint {
  margin: 0 0 var(--sp-5);
  font-size: var(--fs-13);
  color: var(--text-2);
}

/* Schwebende Rückmeldung auf den kopflosen Auth-Seiten – hält die zentrierte
   Karte darunter mittig, statt sie durch eine Meldung nach unten zu schieben. */
.auth-flash {
  position: fixed;
  top: var(--sp-4);
  left: 50%;
  transform: translateX(-50%);
  width: min(380px, calc(100% - var(--sp-6)));
  z-index: 10;
}

.auth-flash .flash {
  margin-bottom: 0;
}

/* =========================================================================
   13. Kopfleiste: Konto (Nutzername + Abmelden)
   Rechte Seite der Topbar für angemeldete Nutzer.
   ========================================================================= */

/* Das Konto steht am rechten Ende der Kopfleiste; alles davor (Logo, Trenner,
   Bereich) reiht sich links auf. */
.topbar__account {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-3);
  margin-left: auto;
}

/* Nutzername leiser als die Marke – er ist Auskunft, keine Aufforderung */
.topbar__user {
  font-size: var(--fs-13);
  font-weight: var(--fw-medium);
  color: var(--text-2);
  white-space: nowrap;
}

/* =========================================================================
   14. Sekundärnavigation
   Heller Tab-Streifen unter der Topbar; der Inhalt fluchtet über .shell mit
   Topbar und Hauptbereich. Sichtbarkeit ist nur die Spiegelung der Rechte –
   der eigentliche Schutz sitzt serverseitig im Guard der Controller.
   ========================================================================= */

.nav {
  background: var(--card);
  border-bottom: 1px solid var(--line);
}

/* Reuse von .shell für die horizontale Flucht; vertikal bewusst kompakt.
   Der Kindselektor hat denselben Grund wie bei .topbar__inner (siehe Abschnitt 3):
   .shell setzt sein Polster mit gleicher Spezifität, und wer diese Regel einmal
   vor .shell verschiebt, hätte sonst ohne Vorwarnung 24/32 px im Tab-Streifen. */
.nav > .nav__inner {
  padding-top: 0;
  padding-bottom: 0;
}

/* Die Punkte liegen in einer eigenen Liste – sie ist es, die der Burger auf
   schmalen Fenstern auf- und zuklappt (aria-controls zeigt auf ihre id).
   Seit den Untermenüs ist sie eine echte <ul>: Ein Punkt mit Untermenü ist eine
   Liste in der Liste, und das soll auch die Vorlesesoftware so hören. Marker
   und Vorgabe-Polster des Browsers gehören dabei nicht in einen Tab-Streifen. */
.nav__liste {
  /* Bezugsrahmen des breiten Messe-Rasters (siehe .nav__punkt--breit weiter
     unten): Es ist breiter als sein Punkt und richtet sich deshalb an der
     Textspalte aus statt am Punkt. */
  position: relative;
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-1);
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Der Listenpunkt umschließt Link UND Panel. Das ist die tragende Entscheidung
   des Aufklappens: Solange die Maus irgendwo in diesem Element steht – auf dem
   Link oder im Panel darunter –, gilt :hover und das Menü bleibt offen. Läge das
   Panel daneben statt darin, entstünde genau an der Kante ein Spalt, in dem das
   Menü flackernd zufiele. */
.nav__punkt {
  position: relative;
  display: flex;
}

.nav__link {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
  height: 48px;
  padding: 0 var(--sp-3);
  border-bottom: 2px solid transparent;
  font-size: var(--fs-14);
  font-weight: var(--fw-medium);
  color: var(--text-2);
}

.nav__link:hover {
  color: var(--text);
  background: var(--hover-neutral);
  text-decoration: none;
}

/* Aktiver Punkt: Markenfarbe plus tragende Unterkante (aria-current spiegelt es) */
.nav__link--active {
  color: var(--navy);
  font-weight: var(--fw-semibold);
  border-bottom-color: var(--navy);
}

/* Tastaturfokus muss auch im Tab-Streifen klar sichtbar bleiben */
.nav__link:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: -2px;
}

/* -------------------------------------------------------------------------
   Untermenüs (SPEC-Navigation)

   Aufgeklappt wird REIN MIT CSS: :hover und :focus-within am Listenpunkt. Ohne
   JavaScript ist das Menü damit vollständig bedienbar – app.js ergänzt nur die
   aria-Auskunft, Escape und das Tipp-Verhalten auf Geräten ohne Maus.

   Der Hauptpunkt bleibt dabei ein ganz normaler Link: Ein Klick führt auf die
   Bereichsseite, und die trägt alle Ziele des Menüs auch selbst. Das Untermenü
   ist die Abkürzung, nicht die einzige Tür.
   ------------------------------------------------------------------------- */

/* Chevron: 12 px im 16er Raster, currentColor. Er dreht sich im offenen Zustand –
   das ist die einzige Bewegung im Menü und sie sagt etwas („hier klappt etwas
   auf"), statt bloß zu schmücken. */
.nav__chevron {
  flex: none;
  transition: transform .12s ease;
}

.nav__punkt:hover > .nav__link > .nav__chevron,
.nav__punkt:focus-within > .nav__link > .nav__chevron {
  transform: rotate(180deg);
}

@media (prefers-reduced-motion: reduce) {
  .nav__chevron {
    transition: none;
  }
}

/* Der Hauptpunkt trägt im offenen Zustand die Hover-Optik – auch dann, wenn die
   Maus schon unten im Panel steht. Ohne diese Regel verlöre der Punkt beim
   Hinuntergleiten seine Fläche, und das Panel hinge scheinbar an nichts. */
.nav__punkt:hover > .nav__link,
.nav__punkt:focus-within > .nav__link {
  color: var(--text);
  background: var(--hover-neutral);
}

.nav__punkt:hover > .nav__link--active,
.nav__punkt:focus-within > .nav__link--active {
  color: var(--navy);
}

/* Das Panel: eine Karte, absolut unter dem Streifen. top: 100% setzt sie
   unmittelbar an die Unterkante des Punktes – kein Spalt, über den die Maus
   fiele.

   z-index 5 ist bewusst niedrig gewählt und liegt genau zwischen den beiden
   Werten, die es in dieser Datei sonst gibt: über allem Inhalt und über den
   klebenden Leisten (.bulkbar, .vorschau-karte – beide ohne eigenen z-index)
   sowie über den Schattenkanten scrollender Tabellen (reine Hintergründe,
   Abschnitt 29), aber unter der schwebenden Rückmeldung (.auth-flash, 10) und
   dem Sprunglink (.skip-link, 20). Damit bleibt die Skala dreistufig. */
.nav__menu {
  /* Wie das Panel im GEÖFFNETEN Zustand anzeigt: das flache Menü als Block, das
     Messe-Raster der Zusatzbestellungen als Grid. Die Fallunterscheidung steht
     damit an einer Stelle statt in jeder der Öffner-Regeln noch einmal. */
  --nav-menu-anzeige: block;

  display: none;
  position: absolute;
  top: 100%;
  left: 0;
  z-index: 5;
  min-width: 240px;
  max-width: 720px;
  padding: var(--sp-2);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--card);
  box-shadow: var(--shadow-hoch);
}

/* Der letzte Punkt öffnet nach links, sonst liefe sein Panel aus dem Fenster. */
.nav__punkt:last-child > .nav__menu {
  left: auto;
  right: 0;
}

/* Maus (:hover) und Tastatur (:focus-within) öffnen – ohne eine Zeile Skript. */
.nav__punkt:hover > .nav__menu,
.nav__punkt:focus-within > .nav__menu {
  display: var(--nav-menu-anzeige);
}

/* Von app.js geöffnet: der erste Tipp auf einem Gerät ohne Maus. */
.nav__punkt--offen > .nav__menu {
  display: var(--nav-menu-anzeige);
}

/* Von app.js geschlossen: Escape. Die Klasse muss gegen :hover gewinnen – sonst
   ginge das Panel unter der stehenden Maus sofort wieder auf, und Escape hätte
   sichtbar nichts getan. Höhere Spezifität statt !important. */
.nav__punkt--zu > .nav__menu,
.nav__punkt--zu:hover > .nav__menu,
.nav__punkt--zu:focus-within > .nav__menu {
  display: none;
}

@media (hover: none) {
  /* Geräte ohne Maus kennen kein Überfahren: Dort entsteht :hover erst durch den
     Tipp und bliebe danach kleben. Solange app.js läuft ([data-js]), übernimmt
     es das Öffnen (erster Tipp öffnet, zweiter folgt dem Link). Ohne Skript
     bleibt es beim Hover-Verhalten des Browsers – navigieren kann man dann
     trotzdem, und die Bereichsseite trägt alle Ziele. */
  [data-js] .nav__punkt:hover > .nav__menu {
    display: none;
  }

  [data-js] .nav__punkt--offen > .nav__menu {
    display: var(--nav-menu-anzeige);
  }
}

/* Messe-Raster der Zusatzbestellungen: „Übersicht" über die volle Breite, davon
   je Messe eine Spalte. Die Spaltenzahl kommt als Klasse aus dem Markup – ein
   Inline-Stil wäre unter der CSP nicht erlaubt und hier auch nicht nötig. */
.nav__menu--raster {
  --nav-menu-anzeige: grid;

  grid-template-columns: minmax(200px, 1fr);
  gap: var(--sp-2);
}

.nav__menu--spalten-2 {
  grid-template-columns: repeat(2, minmax(200px, 1fr));
}

/* Ab drei Messen bricht das Raster um, statt immer breiter zu werden: 720 px
   fassen genau drei Spalten, alles Weitere rutscht in die nächste Zeile. */
.nav__menu--spalten-3 {
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
}

/* Genau dieses breite Raster passt unter seinem Punkt nicht mehr ins Fenster:
   „Zusatzbestellungen" steht in der Mitte des Streifens, und ein 720-px-Kasten
   von dort aus ragte bei 1161 px Fensterbreite – der schmalsten, in der es
   Panels überhaupt gibt – rechts heraus, samt waagerechtem Seiten-Scroll.

   Deshalb hängt dieses eine Panel NICHT an seinem Punkt, sondern an der LISTE,
   und dort an deren rechter Kante: dieselbe Kante wie die des Inhalts darunter.
   Der Punkt liegt dabei in jeder Fensterbreite, in der es Panels gibt,
   INNERHALB der Panelbreite – die Zuordnung bleibt also sichtbar, obwohl das
   Panel breiter ist als er. Seine Rolle als Bezugsrahmen gibt er dafür ab
   (position: static); der Modifikator kommt aus dem Markup, weil dort ohnehin
   gezählt wird, wie viele Messe-Spalten es gibt. */
.nav__punkt--breit {
  position: static;
}

.nav__punkt--breit > .nav__menu--spalten-3 {
  left: auto;
  right: 0;
  width: 720px;
  /* Nie breiter als die Textspalte – 100 % sind hier die Breite der Liste. */
  max-width: 100%;
}

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

/* Flache Einträge (Übersicht, Aktionen) laufen über alle Spalten. */
.nav__menu-liste--voll {
  grid-column: 1 / -1;
}

.nav__gruppe {
  min-width: 0;
}

/* Gruppentitel = Messename. Er beschriftet, er ist kein Ziel – deshalb leiser
   als die Einträge darunter und ohne eigene Fläche. */
.nav__gruppentitel {
  margin: 0;
  padding: var(--sp-2) var(--sp-3) var(--sp-1);
  font-size: var(--fs-12);
  font-weight: var(--fw-semibold);
  color: var(--text-muted);
}

/* Die erste Gruppe steht schon am oberen Rand des Panels – dort wäre der Abstand
   doppelt. */
.nav__gruppe:first-child .nav__gruppentitel {
  padding-top: 0;
}

/* Trenner vor den Aktionen („Neue …"): eine Linie, kein zweiter Kasten. */
.nav__menu-punkt--trenner {
  margin: var(--sp-1) 0;
  border-top: 1px solid var(--line);
}

/* Eintrag: 36 px Mindesthöhe (Touchziel), kleine Rundung. Ein Token --radius-sm
   gibt es nicht; calc() leitet die 8 px aus der Feld-Rundung ab, statt eine
   vierte Radien-Zahl in die Datei zu tragen. */
.nav__eintrag {
  display: flex;
  align-items: center;
  min-height: 36px;
  padding: var(--sp-2) var(--sp-3);
  border-radius: calc(var(--radius) - 2px);
  font-size: var(--fs-14);
  font-weight: var(--fw-medium);
  color: var(--text);
}

.nav__eintrag:hover {
  background: var(--hover-neutral);
  text-decoration: none;
}

/* Aktiver Eintrag wie die Auswahl im Formular: Markenfarbe auf zart getönter
   Fläche, kein Farbbalken an der Kante (aria-current spiegelt es). */
.nav__eintrag--active {
  color: var(--navy);
  font-weight: var(--fw-semibold);
  background: var(--accent-soft);
}

/* -------------------------------------------------------------------------
   Burger-Knopf (nur schmale Fenster)
   Er steht im Markup in der Kopfleiste – dort ist Platz, dort sucht man ihn,
   und dort bleibt er neben „Abmelden" erreichbar. Bedient wird damit aber die
   Navigation, deshalb trägt er deren Namensraum.

   Grundzustand: unsichtbar. Eingeblendet wird er erst, wenn [data-js] am <html>
   steht (app.js setzt es) UND das Fenster schmal ist – siehe Abschnitt 30.
   Ohne Skript bleibt die Navigation als sichtbarer Streifen stehen und der
   Knopf verborgen: ein Knopf, der nichts tut, wäre schlimmer als keiner.
   ------------------------------------------------------------------------- */

.nav__burger {
  display: none;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 1px solid transparent;
  border-radius: var(--radius);
  background: transparent;
  color: var(--navy);
  cursor: pointer;
  transition: background-color .12s ease, border-color .12s ease;
}

.nav__burger:hover {
  background: var(--hover-neutral);
}

/* Offen: getönte Fläche mit Kante. Bewusst kein Symbolwechsel zum Kreuz – der
   Zustand steht in aria-expanded und ist an der Liste darunter zu sehen; ein
   sich drehendes Icon wäre nur Spielerei. */
.nav__burger[aria-expanded="true"] {
  background: var(--hover-neutral);
  border-color: var(--line-interactive);
}

/* Die Überblendung entfällt bei reduzierter Bewegung – der Zustand wechselt dann
   hart. Der Block steht bewusst HIER und nicht beim Skelett-Platzhalter in
   Abschnitt 9: eine Media-Query erhöht die Spezifität nicht, eine frühere Regel
   verlöre gegen die Grundregel oben. Das Menü selbst klappt ohnehin ohne
   Bewegung auf – es gibt nichts weiter abzuschalten. */
@media (prefers-reduced-motion: reduce) {
  .nav__burger {
    transition: none;
  }
}

/* Symbol: drei Balken aus reinem CSS – keine Icon-Schrift, kein Emoji.
   currentColor, damit die Balken jede Zustandsfarbe des Knopfes mitnehmen. */
.nav__burger-icon {
  position: relative;
  display: block;
  width: 20px;
  height: 2px;
  border-radius: 2px;
  background: currentColor;
}

.nav__burger-icon::before,
.nav__burger-icon::after {
  content: "";
  position: absolute;
  left: 0;
  display: block;
  width: 20px;
  height: 2px;
  border-radius: 2px;
  background: currentColor;
}

.nav__burger-icon::before {
  top: -6px;
}

.nav__burger-icon::after {
  top: 6px;
}

/* =========================================================================
   15. Sekundäre Überschrift und KPI-Raster
   ========================================================================= */

/* Gewicht und Farbe stehen bei den Überschriften (Abschnitt 2) */
.section-title {
  margin: var(--sp-6) 0 var(--sp-4);
  font-size: var(--fs-16);
}

/* Explizite Spaltenzahl statt auto-fill: vier Zähl-Kacheln plus die doppelt
   breite Finanz-Kachel ergeben sechs Einheiten – nur mit fester Spaltenzahl
   landen alle in EINER Reihe (und strecken sich auf gleiche Höhe), statt dass
   die breite allein in die zweite Reihe fällt. */
.kpi-grid {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: var(--sp-4);
  margin-bottom: var(--sp-6);
}

@media (max-width: 1023px) {
  .kpi-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

@media (max-width: 639px) {
  .kpi-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/* Breite Finanz-Kachel: Der Umsatz trägt mehr Angaben als die Zähl-Kacheln
   (Brutto, AUMA-Anteil). Gestapelt als Textzeilen zog das die ganze Reihe in
   die Höhe, während die Nachbarn leer wirkten. Stattdessen: doppelte Breite,
   links die Leitkennzahl, rechts ein ruhiger Nebenblock mit zwei Wertzeilen. */
.kpi--breit {
  grid-column: span 2;
}

/* Nebenblock unter der Leitkennzahl: zwei ruhige Beschriftung/Wert-Zeilen.
   Neben der großen Zahl wäre nur auf sehr breiten Schirmen Platz – der
   Umbruchfall sähe dann wieder gestapelt aus, also gleich untereinander. */
.kpi__neben {
  margin: var(--sp-3) 0 0;
  display: grid;
  gap: var(--sp-1);
}

.kpi__nebenzeile {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--sp-4);
}

.kpi__nebenzeile dt {
  font-size: var(--fs-12);
  color: var(--text-muted);
}

.kpi__nebenzeile dd {
  margin: 0;
  font-size: var(--fs-13);
  font-weight: var(--fw-semibold);
  color: var(--text-2);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* Klickbare KPI-Kachel: erbt Textfarbe, hebt sich nur beim Hover leicht ab */
a.kpi--link {
  color: inherit;
  transition: border-color .12s ease, background-color .12s ease, box-shadow .12s ease;
}

a.kpi--link:hover {
  text-decoration: none;
  border-color: var(--line-interactive);
  background: var(--hover-neutral);
}

/* =========================================================================
   16. Filterleiste (GET-Formular über den Listen)
   ========================================================================= */

.filterbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-2);
  margin-bottom: var(--sp-4);
}

.filterbar__group {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-2);
}

/* Schiebt Suche/Zurücksetzen ans rechte Ende, ohne feste Breiten */
.filterbar__spacer {
  flex: 1 1 var(--sp-4);
}

/* In der Filterleiste sollen Eingaben nicht die volle Breite einnehmen */
.filterbar .input,
.filterbar .select {
  width: auto;
  min-width: 180px;
}

/* Zwei-Zeilen-Variante: Filterfragen oben, Suche und Werkzeuge unten – der
   Umbruch ist Absicht und nicht Folge der Fensterbreite. Nur die Anmeldungsliste
   nutzt sie; alle anderen Leisten bleiben eine umbrechende Reihe. Der Abstand
   zwischen den Zeilen ist eine Spur größer als der zwischen den Bausteinen einer
   Zeile: sonst läse sich die zweite Zeile wie eine Fortsetzung der ersten. */
.filterbar--zeilen {
  flex-direction: column;
  align-items: stretch;
  gap: var(--sp-3);
}

.filterbar__zeile {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-2);
}

/* Beschriftung eines Filterfeldes – sichtbar, nicht nur für Screenreader: Ein
   Auswahlfeld ohne Wort davor beantwortet die Frage „wonach?" nicht. */
.filterbar__label {
  font-size: var(--fs-12);
  font-weight: var(--fw-semibold);
  color: var(--text-muted);
  white-space: nowrap;
}

/* Der Anwenden-Knopf eines selbst abschickenden Auswahlfeldes. OHNE JavaScript
   ist er der einzige Weg, die Auswahl anzuwenden – deshalb steht er im Markup
   und wird erst hier ausgeblendet, unter der Markierung, die app.js am <html>
   setzt. Die Tastaturbedienung holt ihn über .is-sichtbar zurück (Begründung in
   app.js): Pfeiltasten wechseln den Wert und lösen sofort `change` aus; würde
   das jedes Mal abschicken, verlöre der Nutzer bei jedem Tastendruck den Fokus. */
[data-js] [data-auto-submit-knopf] {
  display: none;
}

[data-js] [data-auto-submit-knopf].is-sichtbar {
  display: inline-flex;
}

/* Filter-Chips sind klickbare Links; aktiver Filter in Markenfarbe. */
a.chip {
  cursor: pointer;
  transition: background-color .12s ease, border-color .12s ease, color .12s ease;
}

a.chip:hover {
  text-decoration: none;
  color: var(--text);
  background: var(--hover-neutral);
  border-color: var(--line-interactive);
}

.chip--active,
a.chip.chip--active:hover {
  color: var(--on-dark);
  background: var(--navy);
  border-color: var(--navy);
}

/* Dezent akzentuierter Chip, z. B. Auslandskennzeichnung */
.chip--accent {
  color: var(--st-inb-fg);
  border-color: var(--st-inb-fg);
}

/* =========================================================================
   17. Tabellen-Ergänzungen: horizontaler Scroll, Zahlenspalten, Summenzeile
   ========================================================================= */

/* Breite Tabellen scrollen in ihrem Container statt die Seite zu sprengen */
.table-wrap {
  width: 100%;
  overflow-x: auto;
}

/* Zahlen (Fläche, Brutto) rechtsbündig für ruhige Spaltenkanten */
.table .is-num {
  text-align: right;
  /* Ein Betrag ist eine Einheit: „5.000,00" und „€" dürfen nie auf zwei Zeilen
     stehen. Ohne diese Zeile quetscht der Browser die Spalte, sobald die Tabelle
     eng wird, und der Preis wird unlesbar. Platz ist da – er wird nur nicht
     angefordert. */
  white-space: nowrap;
}

.table tfoot td {
  border-top: 1px solid var(--line);
  border-bottom: 0;
  font-weight: var(--fw-semibold);
  color: var(--text);
}

/* Verweiszelle: der klickbare Anker trägt die Zeile (Detailansicht folgt) */
.table a.zeile-link {
  font-weight: var(--fw-medium);
  color: var(--teal-link);
}

/* Fußzeile unter einer Liste: Trefferzahl links, Seitenblättern rechts */
.list-footer {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  margin-top: var(--sp-4);
}

/* =========================================================================
   18. Status-Pills für Messen (events-Status)
   Ergänzt die vorhandenen Anmeldungs-Pills um die vier events-Zustände.
   ========================================================================= */

.pill--entwurf     { color: var(--text-2);    background: var(--line-subtle); }
.pill--offen       { color: var(--st-best-fg); background: var(--st-best-bg); }
.pill--geschlossen { color: var(--st-inb-fg);  background: var(--st-inb-bg); }
/* .pill--archiviert ist bereits im Anmeldungs-Block definiert und passt hier mit. */

/* =========================================================================
   19. Detailseite: Kopf, zweispaltiges Raster, Abschnitts-Karten
   Hauptspalte links (Stammdaten, Positionen, Belege …), schmale Seitenspalte
   rechts (Status/Zuweisung, Historie). Unter 960 px fällt das Raster auf eine
   Spalte zurück – die Seitenspalte rutscht dann unter den Hauptinhalt.
   ========================================================================= */

.detail-kopf {
  margin-bottom: var(--sp-5);
}

.detail-kopf__zeile {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-3);
}

/* Der Seitentitel bringt eigenen Außenabstand mit – in der Kopfzeile stört er */
.detail-kopf__zeile .page-title {
  margin: 0;
}

.detail-kopf__meta {
  margin: var(--sp-1) 0 0;
  font-size: var(--fs-13);
  color: var(--text-2);
}

.detail-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 340px;
  gap: var(--sp-5);
  align-items: start;
  /* Der Übergang zum Inhalt NACH dem Raster gehört dem Raster selbst: Die
     Karten darin holen ihren Abstand aus dem gap und bringen keine eigene
     Marge mit – ohne diese Zeile klebte die erste freie Karte darunter
     (Ansprechpartner, Löschen) an der letzten Rasterkarte. */
  margin-bottom: var(--sp-6);
}

/* Jede Spalte stapelt ihre Karten mit gleichem Abstand; min-width 0 verhindert,
   dass breite Inhalte (Tabellen, lange User-Agents) das Raster aufdrücken. */
.detail-grid__spalte {
  display: grid;
  gap: var(--sp-5);
  min-width: 0;
}

@media (max-width: 960px) {
  .detail-grid {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* Abschnitts-Karte: wie .card, aber mit Kopfzeile (Titel + Bearbeiten-Aktion) */
.section-card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-card);
  padding: var(--sp-5);
}

/* Im Detail-Raster liefert die Spalte den Abstand (gap). Steht eine Karte frei
   auf einer Listenseite – Statusverteilung der Übersicht, „Je Paket" über der
   Partnerliste –, muss sie ihn selbst mitbringen, sonst klebt sie an dem, was
   darunter kommt. */
.section-card--frei {
  margin-bottom: var(--sp-6);
}

.section-card__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  margin-bottom: var(--sp-4);
}

/* Gewicht und Farbe stehen bei den Überschriften (Abschnitt 2) */
.section-card__title {
  margin: 0;
  font-size: var(--fs-16);
}

/* Leiser Zusatz im Titel, z. B. das Messe-Kürzel hinter dem Messenamen */
.section-card__zusatz {
  font-weight: var(--fw-normal);
  color: var(--text-muted);
}

/* Unterüberschrift innerhalb einer Karte (Preisaufstellung, Hallenplanung …) */
.section-card__untertitel {
  margin: var(--sp-5) 0 var(--sp-3);
  font-size: var(--fs-14);
  font-weight: var(--fw-semibold);
  color: var(--text);
}

/* -------------------------------------------------------------------------
   Notiz-Box: EIN Hinweiskasten für das ganze Backend
   Vorher gab es drei Klassen, die dasselbe taten und sich nur in der Farbe eines
   linken Balkens unterschieden. Jetzt: umlaufender Rahmen, getönte Fläche, kein
   Balken. Drei Stufen reichen – neutral (erklärt), --warnung (nennt eine Folge),
   --fehler (etwas stimmt nicht).
   ------------------------------------------------------------------------- */

/* SENKRECHTER RHYTHMUS – eine Regel für jeden Hinweiskasten im Backend.
   Vorher kannte der Kasten nur einen Abstand nach UNTEN. Wo er auf etwas mit
   eigenem Unterabstand folgte (Filterleiste, Kartenkopf, Seitentitel), fiel das
   nicht auf; folgte er dagegen auf eine kv-liste, eine Tabelle oder eine
   Knopfzeile – alle mit margin 0 –, klebte er daran (Signaturkarte, 08.09.2026).
   Zugleich stand er als LETZTES Kind einer Karte 16 px vor dem Kartenpolster,
   also 36 px vom Rand statt der 20 px oben.
   Deshalb: gleicher Abstand oben wie unten, und an den Kartenkanten keiner –
   dort macht das Polster der Karte den Abstand allein.
   Doppelt wird davon nichts: Im normalen Blockfluss kollabieren benachbarte
   senkrechte Außenabstände zum größeren der beiden (16 unten + 16 oben = 16;
   unter einer Überschrift gewinnt deren eigenes, größeres Maß).
   ACHTUNG für später: In Flex- und Grid-Containern kollabieren Außenabstände
   NICHT – dort addierte sich der obere Abstand auf den gap. Heute steht kein
   Hinweiskasten in so einem Container (über alle Views geprüft: Elternknoten
   sind stets main.shell, .section-card, .card, ein form oder eine Tabellenzelle
   – alles Blockfluss). Landet je einer in einem gap-Container, bekommt genau
   dieser Container eine Ausnahme – Kindselektor auf den Elternknoten, darin
   margin-block auf 0; den Abstand macht dann der gap allein. */
.notiz-box {
  margin: var(--sp-4) 0;
  padding: var(--sp-4);
  border: 1px solid var(--accent-line);
  border-radius: var(--radius);
  background: var(--accent-soft);
  font-size: var(--fs-13);
  color: var(--text);
}

/* An der Kante einer Karte oder eines Abschnitts zählt allein deren Polster.
   In einer Tabellenzelle ist das die einzige Bremse: Aus einer Zelle heraus
   kollabiert kein Außenabstand, dort würde er sich sonst aufs Zellpolster
   addieren. */
.notiz-box:first-child {
  margin-top: 0;
}

.notiz-box:last-child {
  margin-bottom: 0;
}

.notiz-box__titel {
  margin: 0 0 var(--sp-1);
  font-size: var(--fs-13);
  font-weight: var(--fw-bold);
  color: var(--navy);
}

/* Letzter Absatz im Kasten braucht keinen Außenabstand. */
.notiz-box > p:last-child {
  margin-bottom: 0;
}

/* Warnung: gedämpftes Gelb. Sie meldet keinen Fehler, sondern eine Folge
   (Preisänderung, Einmal-Passwort) – deshalb ruhiger als Rot. */
.notiz-box--warnung {
  border-color: var(--warn-line);
  background: var(--warn-soft);
}

.notiz-box--warnung .notiz-box__titel {
  color: var(--warn);
}

/* Fehler: etwas stimmt nicht (Signaturprüfung, ungültige Zeile) */
.notiz-box--fehler {
  border-color: var(--danger-line);
  background: var(--danger-soft);
}

.notiz-box--fehler .notiz-box__titel {
  color: var(--danger);
}

/* =========================================================================
   20. Formulare der Detailseite
   Zweispaltiges Label/Feld-Raster für die Abschnitts-Formulare; unter 700 px
   einspaltig. Volle Breite (Textareas) über den Zeilen-Modifikator.
   ========================================================================= */

.form-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  column-gap: var(--sp-4);
}

.form-grid__voll {
  grid-column: 1 / -1;
}

@media (max-width: 700px) {
  .form-grid {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* Mehrzeilige Eingaben teilen sich das .input-Rezept, brauchen aber Höhe */
textarea.input {
  height: auto;
  min-height: 84px;
  padding: var(--sp-2) var(--sp-3);
  line-height: 1.5;
  resize: vertical;
}

/* Aktionszeile unter einem Formular: Primäraktion vorn, Abbrechen dahinter */
.form-aktionen {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  margin-top: var(--sp-1);
}

/* Formulare, die Abschnitts-Karten stapeln (Neue Anmeldung, Neue Firma):
   Die Karten bringen selbst keinen Abstand mit – im Raster macht das der gap,
   hier muss es der Stapel tun. Auch Knopfzeile und Fußzeile brauchen Luft
   zur letzten Karte, sonst kleben sie an ihr. */
form > .section-card + .section-card {
  margin-top: var(--sp-5);
}

form > .section-card + .form-aktionen {
  margin-top: var(--sp-5);
}

.form-aktionen + .field__hilfe {
  margin-top: var(--sp-3);
}

/* Folgt einem Formular noch eine Karte (Artikel-Ansicht: Kopplungen und
   Löschen stehen bewusst AUSSERHALB des Speichern-Formulars), klebt sie an
   dessen Knopfzeile: Die Regeln oben greifen nur INNERHALB des Formulars, und
   .form-aktionen bringt keinen Abstand nach unten mit. */
form + .section-card {
  margin-top: var(--sp-6);
}

/* Gruppen-Hinweis der Sortiment-Übersicht: Der gewandelte Text kommt als
   Absatz-HTML (Auszeichnung::hinweisHtml). Ein einzelner Absatz soll hinter
   dem Präfix „Formular:" weiterlaufen statt darunter zu rutschen; sobald der
   Text mehrere Absätze hat, ist der Umbruch richtig und bleibt. */
.gruppen-hinweis > p:only-child {
  display: inline;
}

/* =========================================================================
   21. Lesemodus: Schlüssel/Wert-Liste und Preisaufstellung
   ========================================================================= */

/* Derselbe senkrechte Rhythmus wie beim Hinweiskasten – aus demselben Grund:
   Die Liste hatte `margin: 0` und klebte deshalb an allem, was ebenfalls ohne
   Außenabstand kommt (Einrichtung der Zwei-Faktor-Anmeldung: Liste direkt auf
   dem Bestätigungsformular; Mail-Vorschau: Liste direkt auf dem Hilfetext).
   16 px oben wie unten, an den Kartenkanten keiner – das Kollabieren im
   Blockfluss verhindert auch hier jeden Doppelabstand (Kartenkopf 16 + Liste 16
   bleibt 16). Die Liste steht in allen Views direkt in einer .section-card,
   also im Blockfluss; für einen gap-Container gilt der Hinweis oben bei
   .notiz-box sinngemäß. */
.kv-liste {
  display: grid;
  grid-template-columns: 180px minmax(0, 1fr);
  gap: var(--sp-1) var(--sp-4);
  margin: var(--sp-4) 0;
  font-size: var(--fs-13);
}

.kv-liste:first-child {
  margin-top: 0;
}

.kv-liste:last-child {
  margin-bottom: 0;
}

.kv-liste dt {
  font-weight: var(--fw-medium);
  color: var(--text-2);
}

.kv-liste dd {
  margin: 0;
  color: var(--text);
  /* Lange Werte (E-Mail-Adressen, User-Agents) umbrechen statt überlaufen */
  overflow-wrap: anywhere;
}

/* Stiller Wert: eine Angabe, die es (noch) nicht gibt, ohne dass die Zeile
   fehlt – „Tatsächlich: wie angemeldet". Keine eigene Farbe, nur die schon
   vorhandene unterste Stufe. */
.kv-liste__still {
  color: var(--text-muted);
}

@media (max-width: 560px) {
  .kv-liste {
    grid-template-columns: minmax(0, 1fr);
  }

  .kv-liste dt {
    margin-top: var(--sp-2);
  }
}

/* Rabattzeilen der Preisaufstellung in Grün – wie auf dem Beleg */
.table tr.preis-rabatt td {
  color: var(--st-best-fg);
}

/* Leiser Nebentext in einer Tabellenzelle (Ausweise-Hinweis, Partner-Zusatz) */
.table__nebentext {
  font-size: var(--fs-12);
  color: var(--text-muted);
}

/* =========================================================================
   22. Notizen und Status-Historie
   ========================================================================= */

.notiz {
  padding: var(--sp-3) 0;
  border-bottom: 1px solid var(--line-subtle);
}

.notiz__meta {
  margin: 0 0 var(--sp-1);
  font-size: var(--fs-12);
  color: var(--text-muted);
}

.notiz__text {
  margin: 0;
  font-size: var(--fs-13);
  color: var(--text);
  overflow-wrap: anywhere;
}

/* Die letzte Notiz braucht Abstand zum Formular, aber keine Trennlinie */
.notiz:last-of-type {
  border-bottom: 0;
  margin-bottom: var(--sp-3);
}

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

.historie__eintrag {
  padding: var(--sp-2) 0;
  border-bottom: 1px solid var(--line-subtle);
}

.historie__eintrag:last-child {
  border-bottom: 0;
  padding-bottom: 0;
}

.historie__meta {
  margin: 0 0 var(--sp-1);
  font-size: var(--fs-12);
  color: var(--text-muted);
}

.historie__text {
  margin: 0;
  font-size: var(--fs-13);
  color: var(--text);
}

/* =========================================================================
   23. Signaturprüfung und Beleg-Downloads
   ========================================================================= */

/* Prüfergebnis als deutliche Pille: Grün = gültig, Rot = ungültig */
.sig-status {
  display: inline-flex;
  align-items: center;
  padding: 2px var(--sp-2);
  border-radius: var(--radius-pill);
  font-size: var(--fs-12);
  font-weight: var(--fw-semibold);
  white-space: nowrap;
}

.sig-status--ok {
  color: var(--st-best-fg);
  background: var(--st-best-bg);
}

.sig-status--fail {
  color: var(--st-abg-fg);
  background: var(--st-abg-bg);
}

.beleg-buttons {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
}

/* =========================================================================
   24. Massenaktionen: Checkboxen und Leiste
   Die Leiste klebt am unteren Kartenrand, damit die Aktionen auch bei langen
   Listen erreichbar bleiben, sobald Zeilen ausgewählt sind.
   ========================================================================= */

.check {
  width: 16px;
  height: 16px;
  margin: 0;
  accent-color: var(--navy);
  cursor: pointer;
}

/* Schmale Auswahlspalte – die Checkbox bestimmt die Breite, nicht der Text */
.table .is-check {
  width: 1%;
  text-align: center;
}

.bulkbar {
  position: sticky;
  bottom: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-3) var(--sp-4);
  margin-top: var(--sp-4);
  padding: var(--sp-3) var(--sp-4);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--card);
  /* Klebt über der Liste – dafür braucht sie den höheren Schatten, sonst
     verschwimmt sie mit den Tabellenzeilen darunter. */
  box-shadow: var(--shadow-hoch);
}

.bulkbar__titel {
  font-size: var(--fs-13);
  font-weight: var(--fw-medium);
  color: var(--text-2);
}

.bulkbar__gruppe {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
}

.bulkbar__label {
  font-size: var(--fs-13);
  color: var(--text-2);
  white-space: nowrap;
}

/* Kompakte Selects in der Leiste – Höhe wie die S-Buttons daneben */
.bulkbar .select {
  width: auto;
  min-width: 170px;
  height: var(--control-h-s);
  font-size: var(--fs-13);
}

/* =========================================================================
   25. Nutzerverwaltung und eigenes Konto (Phase B)
   Warnkarten für Werte, die nur einmal sichtbar sind (Einmal-Passwörter,
   Recovery-Codes, 2FA-Geheimnis), sowie die Aktionsspalte der Nutzerliste.
   ========================================================================= */

/* Der Nutzername in der Kopfleiste führt zum eigenen Konto. Als Link träfe ihn
   sonst die Teal-Linkfarbe – er soll aber Auskunft bleiben und erst beim
   Überfahren als anklickbar erkennbar werden. */
.topbar a.topbar__user {
  color: var(--text-2);
}

.topbar a.topbar__user:hover {
  color: var(--text);
}

/* Recovery-Codes als Raster: kurze Werte nebeneinander, nichtproportional und
   mit etwas Laufweite – sie werden abgeschrieben, nicht gelesen. */
.codes-liste {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: var(--sp-2);
  margin: var(--sp-3) 0 0;
  padding: 0;
  list-style: none;
}

.codes-liste li {
  padding: var(--sp-2) var(--sp-3);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--card);
  font-family: var(--font-mono);
  font-size: var(--fs-14);
  letter-spacing: .08em;
  text-align: center;
}

/* Einzelwert zum Abtippen oder Kopieren (2FA-Geheimnis, otpauth-Adresse) */
.geheim-wert {
  display: inline-block;
  padding: 2px var(--sp-2);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--hover-neutral);
  font-family: var(--font-mono);
  font-size: var(--fs-13);
  overflow-wrap: anywhere;
}

/* Aktionsspalte der Nutzerliste: mehrere kleine Formulare nebeneinander, die bei
   schmalem Fenster umbrechen statt die Tabelle zu sprengen. */
.zeilen-aktionen {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-2);
}

.zeilen-aktionen form {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  margin: 0;
}

/* Sortimentstabelle: „Bearbeiten" und der Aktiv-Umschalter gehören nebeneinander.
   Die Zellen der Nutzerliste dürfen weiter umbrechen – dort steht ein Auswahlfeld
   in der Zeile, das auf dem Telefon sonst aus der Karte ragt. Hier sind es zwei
   schmale Knöpfe; reicht der Platz nicht, scrollt die Tabelle in ihrem Rahmen,
   wie überall im Backend. */
.zeilen-aktionen--fest {
  flex-wrap: nowrap;
}

.zeilen-aktionen .select {
  width: auto;
  min-width: 150px;
  height: var(--control-h-s);
  font-size: var(--fs-13);
}

/* =========================================================================
   26. Audit, Einstellungen und Export (Phase B, zweiter Teil)
   Nur Tokens, keine neuen Farbwerte: der Diff nutzt die Status-Flächen
   (abgelehnt = vorher, bestätigt = nachher), weil dieselbe Bedeutung überall
   im Backend dieselbe Farbe hat.
   ========================================================================= */

/* Aufgeklappter Feld-Diff innerhalb einer Tabellenzeile. Eigene, ruhigere
   Tabelle statt verschachtelter .table – sie soll als Einschub lesen, nicht
   als zweite Liste konkurrieren. */
.diff-zeile > td {
  background: var(--hover-neutral);
}

.diff-tabelle {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--fs-13);
}

.diff-tabelle th,
.diff-tabelle td {
  padding: var(--sp-2) var(--sp-3);
  border-bottom: 1px solid var(--line);
  text-align: left;
  vertical-align: top;
  overflow-wrap: anywhere;
}

.diff-tabelle thead th {
  font-size: var(--fs-12);
  font-weight: var(--fw-semibold);
  color: var(--text-2);
}

.diff-tabelle tbody th {
  width: 200px;
  font-weight: var(--fw-medium);
  color: var(--text);
}

.diff-tabelle tr:last-child th,
.diff-tabelle tr:last-child td {
  border-bottom: 0;
}

/* Vorher/Nachher farblich eindeutig – ohne Rot/Grün als einzige Unterscheidung:
   die Spaltenüberschrift trägt die Aussage, die Farbe unterstützt sie nur. */
.diff-alt {
  color: var(--st-abg-fg);
  background: var(--st-abg-bg);
}

.diff-neu {
  color: var(--st-best-fg);
  background: var(--st-best-bg);
}

/* Einstellungs-Karten: gleiche Optik wie die Abschnitts-Karten der Detailseiten,
   nur mit Abstand nach unten, weil sie in EINEM Formular untereinander stehen. */
.settings-gruppe {
  margin-bottom: var(--sp-5);
}

/* Hilfetext unter einem Feld – leiser als die Beschriftung, aber lesbar. */
.settings-gruppe__hilfe {
  margin: 0;
  font-size: var(--fs-12);
  color: var(--text-muted);
}

/* Schalter mit Beschriftung daneben; die Box behält ihre Größe, das Label
   nimmt den Rest und bleibt klickbar. */
.settings-gruppe__schalter {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
}

.settings-gruppe__schalter .field__label {
  margin: 0;
  color: var(--text);
}

/* Export-Karten stehen untereinander: jede trägt Erklärung, Messe-Filter und
   Knopf – nebeneinander gedrängt wäre der Erklärungstext nicht mehr lesbar. */
.export-karte {
  margin-bottom: var(--sp-5);
}

.export-karte__text {
  margin: 0 0 var(--sp-4);
  font-size: var(--fs-13);
  color: var(--text-2);
  max-width: 70ch;
}

/* Filter und Knopf in einer Zeile, solange Platz ist; darunter, sobald es eng wird. */
.export-karte__form {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--sp-4);
}

.export-karte__form .field {
  margin-bottom: 0;
  min-width: 240px;
}

.export-karte__form .form-aktionen {
  margin-top: 0;
}

/* =========================================================================
   27. Messen-Selfservice (Phase C)
   Der Editor ist ein einziges Formular über mehrere Abschnitts-Karten; dazu
   kommen die beiden Zeilen-Editoren, die Vorschau-Karte und die Statuszeile.
   Nur Tokens, keine neuen Farbwerte.
   ========================================================================= */

/* Das Editor-Formular ist EIN Element in der Rasterspalte und muss die
   Kartenabstände deshalb selbst herstellen (.detail-grid__spalte kann nur seine
   direkten Kinder verteilen). */
.editor-form {
  display: grid;
  gap: var(--sp-5);
  min-width: 0;
}

/* Statuszeile über dem Editor: Zustand links, erlaubte Aktionen daneben, der
   erklärende Nachsatz rechts. Bricht bei schmalem Fenster mehrzeilig um. */
.status-aktionen {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-2) var(--sp-3);
  margin-bottom: var(--sp-4);
  padding: var(--sp-3) var(--sp-4);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  background: var(--card);
  box-shadow: var(--shadow-card);
}

.status-aktionen form {
  margin: 0;
}

.status-aktionen__titel {
  font-size: var(--fs-13);
  font-weight: var(--fw-medium);
  color: var(--text-2);
}

/* Schiebt den erklärenden Nachsatz ans rechte Ende, ohne feste Breiten */
.status-aktionen__hinweis {
  margin-left: auto;
  font-size: var(--fs-12);
  color: var(--text-muted);
}

/* -------------------------------------------------------------------------
   Zeilen-Editor (Standtypen, Mengenrabatt)
   Jede Zeile ist ein eigenes Raster aus Feldern. Die Beschriftungen stehen an
   jedem Feld statt einmal als Tabellenkopf: nur so bleiben die Zeilen bei
   schmalem Fenster (einspaltig) verständlich und für Screenreader korrekt.
   ------------------------------------------------------------------------- */

.zeilen-editor {
  display: grid;
  gap: var(--sp-2);
}

.zeilen-editor__zeile {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: var(--sp-2) var(--sp-3);
  padding: var(--sp-3);
  border: 1px solid var(--line-subtle);
  border-radius: var(--radius);
  background: var(--hover-neutral);
}

/* Innerhalb einer Zeile sitzen die Felder eng – der Außenabstand kommt von der
   Zeile selbst, sonst klaffen die Spalten auseinander. */
.zeilen-editor__zeile .field {
  margin: 0;
  min-width: 0;
}

/* Zeile mit Fehler: gleiche Sprache wie ein fehlerhaftes Einzelfeld */
.zeilen-editor__zeile--invalid {
  border-color: var(--st-abg-fg);
  background: var(--st-abg-bg);
}

/* Die Fehlermeldung gehört zur ganzen Zeile, nicht zu einem Feld */
.zeilen-editor__fehler {
  grid-column: 1 / -1;
  margin: 0;
}

/* Aktionszeile des Editors („Zeile hinzufügen"). Ohne JavaScript bleibt sie
   sichtbar, aber wirkungslos – deshalb blendet app.js sie erst ein. */
.zeilen-editor__aktion {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
}

.zeilen-editor__aktion[hidden] {
  display: none;
}

/* -------------------------------------------------------------------------
   Vorschau-Karte
   Steht in der schmalen Seitenspalte und bleibt beim Scrollen des langen
   Editors sichtbar – genau dann braucht man sie.
   ------------------------------------------------------------------------- */

.vorschau-karte {
  position: sticky;
  top: var(--sp-4);
}

/* Kompakter als die Listen-Tabellen: hier zählt der Überblick, nicht die Ruhe */
.vorschau-karte .table th,
.vorschau-karte .table td {
  padding: var(--sp-1) 0;
  font-size: var(--fs-12);
}

.vorschau-karte .table tbody tr:nth-child(even),
.vorschau-karte .table tbody tr:hover {
  background: transparent;
}

.vorschau-karte .table tfoot td {
  border-top: 1px solid var(--line);
}

/* Die erste Beispielrechnung braucht keinen zusätzlichen Abstand nach oben */
.vorschau-karte .section-card__untertitel:first-of-type {
  margin-top: var(--sp-4);
}

/* Auf schmalen Fenstern fällt das Raster auf eine Spalte – dort darf die
   Vorschau nicht mehr kleben, sonst überdeckt sie den Editor. */
@media (max-width: 960px) {
  .vorschau-karte {
    position: static;
  }
}

/* =========================================================================
   28. Hilfsklassen der Abschluss-Politur (Phase D)
   Drei kleine Bausteine, die überall gebraucht werden: eine Beschriftung, die
   nur Screenreader hören, der Sprunglink zum Inhalt und der Hilfetext unter
   einem Feld.
   ========================================================================= */

/* Nur für Screenreader. Wichtig: NICHT display:none und NICHT das hidden-
   Attribut – beides nimmt das Element auch aus dem Barrierefreiheitsbaum, ein
   damit versteckter <label>-Text ginge als Feldname verloren. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* Sprunglink: unsichtbar, bis er den Fokus bekommt – dann liegt er sichtbar
   über der Kopfleiste. Erste Tabulator-Station jeder Seite. */
.skip-link {
  position: absolute;
  left: var(--sp-2);
  top: -100px;
  z-index: 20;
  padding: var(--sp-2) var(--sp-4);
  border-radius: var(--radius);
  background: var(--card);
  color: var(--teal-link);
  font-size: var(--fs-13);
  font-weight: var(--fw-medium);
  /* Liegt sichtbar über der Kopfleiste – wie im Formular der höhere Schatten */
  box-shadow: var(--shadow-hoch);
  transition: top .12s ease;
}

.skip-link:focus {
  top: var(--sp-2);
  text-decoration: none;
}

/* Der Sprungziel-Container bekommt tabindex="-1" und darf dafür keinen
   Fokusring zeigen – der Nutzer hat gerade selbst dorthin gesprungen. */
main:focus {
  outline: none;
}

/* Kanonischer Hilfetext unter einem Feld. Gleiche Optik wie
   .settings-gruppe__hilfe (Abschnitt 26), die in den Einstellungs- und
   Messen-Views weiterläuft. */
.field__hilfe {
  margin: 0;
  font-size: var(--fs-12);
  color: var(--text-muted);
}

/* =========================================================================
   29. Waagerecht scrollende Tabellen: Hinweis-Schatten
   Der Verlauf hängt an background-attachment: local – er erscheint NUR, wenn
   wirklich etwas außerhalb des Sichtbereichs liegt, und verschwindet am Rand.
   Ohne diesen Hinweis übersieht man auf schmalen Fenstern ganze Spalten.
   ========================================================================= */

.table-wrap {
  overscroll-behavior-x: contain;
  -webkit-overflow-scrolling: touch;
  background-image:
    linear-gradient(to right, var(--card), var(--card-0)),
    linear-gradient(to left,  var(--card), var(--card-0)),
    linear-gradient(to right, var(--scroll-shadow), var(--scroll-shadow-0)),
    linear-gradient(to left,  var(--scroll-shadow), var(--scroll-shadow-0));
  background-position: left center, right center, left center, right center;
  background-repeat: no-repeat;
  background-size: 28px 100%, 28px 100%, 12px 100%, 12px 100%;
  background-attachment: local, local, scroll, scroll;
}

/* =========================================================================
   30. Responsive (Phase D)
   Additiv: die Regeln oben bleiben die Desktop-Wahrheit, hier steht nur, was
   sich bei schmalen Fenstern ändert. Vier Stufen – ≤ 1100 px (enger Tab-Streifen),
   < 1024 px (Tablet quer und kleine Laptops), < 768 px (Burger-Menü, Telefon quer),
   < 560 px (Telefon).
   ========================================================================= */

/* Ab hier wird es für zehn Punkte in einer Zeile eng: statt umzubrechen oder
   abgeschnitten zu werden, rücken sie enger zusammen. Umbruch wäre der falsche
   Ausweg – eine zweite Reihe verdoppelt die Kopfzone, und der Blick verliert
   die Reihenfolge der Bereiche. Der waagerechte Scroll bleibt als Netz, falls
   eine Rolle einmal mehr Punkte sieht als heute; ausgelegt ist die Stufe aber
   so, dass er bei den zehn Punkten gar nicht erst anspringt.

   Die Grenze lag bis zum 08.09.2026 bei 1100 px und ist auf 1160 px gewandert –
   die Maximalbreite von .shell. Die sechs Chevrons der Untermenüs kosten je
   16 px, zusammen fast 100: Bei voller Polsterung braucht der Streifen nun rund
   1070 px, und die stehen erst zur Verfügung, wenn die Textspalte ihre volle
   Breite erreicht hat. Zwischen 1101 und 1160 px wäre er sonst in eine zweite
   Zeile gerutscht – genau das, was diese Stufe verhindern soll. */
@media (max-width: 1160px) {
  .nav__liste {
    flex-wrap: nowrap;
    gap: 0;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: thin;
  }

  /* Im nicht umbrechenden Streifen darf kein Punkt schrumpfen – sonst würde
     „Zusatzbestellungen" als Erstes zusammengequetscht. */
  .nav__punkt {
    flex: 0 0 auto;
  }

  .nav__link {
    flex: 0 0 auto;
    padding: 0 var(--sp-2);
  }

  /* Ab hier bleiben die Untermenüs zu – und der Chevron verschwindet mit ihnen,
     weil er sonst etwas ankündigte, was nicht kommt.

     Grund ist der waagerechte Scroll eine Regel weiter oben: Ein Kasten mit
     `overflow-x: auto` schneidet auch nach UNTEN ab (overflow-y rechnet dann als
     auto), und das Panel liegt genau dort. Es wäre nur zur Hälfte zu sehen und
     ließe sich mit CSS nicht aus dem Streifen heraushebeln.

     Verloren geht dadurch nichts: Der Hauptpunkt bleibt ein Link, und die
     Bereichsseite trägt alle Ziele des Menüs auch selbst (SPEC-Navigation §0).
     Unterhalb von 768 px übernimmt ohnehin der Burger – dort stehen die
     Untereinträge eingerückt in der Liste. */
  .nav__chevron {
    display: none;
  }

  .nav__menu,
  .nav__punkt:hover > .nav__menu,
  .nav__punkt:focus-within > .nav__menu,
  .nav__punkt--offen > .nav__menu {
    display: none;
  }
}

@media (max-width: 1023px) {
  /* Weniger Rand, mehr Inhalt. Gilt zugleich für Topbar und Nav, weil beide
     ihren Seitenabstand aus .shell beziehen. */
  .shell {
    padding: var(--sp-5) var(--sp-4) var(--sp-6);
  }

  /* Hauptspalte plus 340 px Seitenspalte wird hier zu eng zum Lesen – die
     Seitenspalte rutscht unter den Inhalt. */
  .detail-grid {
    grid-template-columns: minmax(0, 1fr);
  }

  /* Einspaltig darf die Vorschau nicht mehr kleben, sonst verdeckt sie den Editor. */
  .vorschau-karte {
    position: static;
  }
}

@media (max-width: 767px) {
  .shell {
    padding: var(--sp-4) var(--sp-3) var(--sp-6);
  }

  /* Kopfleiste kompakt: Nutzername und Bereichsbezeichnung weichen (der Name
     steht auch unter „Mein Konto", der Bereich in der Navigation darunter),
     Logo, Abmelden und Burger bleiben. Abmelden ist die wichtigste Aktion auf
     einem fremden Gerät – sie gehört nicht hinter eine Klappe.
     Platzrechnung bei 390 px: 24 px Rand + 136 px Logo + 8 px + ~86 px
     „Abmelden" + 8 px + 44 px Burger ≈ 306 px. Es bleibt Luft. */
  .topbar {
    height: 64px;
    gap: var(--sp-2);
  }

  .topbar__inner {
    gap: var(--sp-2);
  }

  /* 28 px waren zu klein, um die Marke zu tragen; 34 px sind dieselbe Höhe,
     die der Desktop vor der Vergrößerung hatte. */
  .topbar__logo {
    height: 34px;
  }

  .topbar__user,
  .topbar__trenner,
  .topbar__bereich,
  .brand__sub {
    display: none;
  }

  /* --- Burger-Menü ------------------------------------------------------
     Alles unter [data-js] hängt an der Markierung, die app.js am <html> setzt.
     Ohne Skript greift keine dieser Regeln: Der Knopf bleibt unsichtbar und
     die Navigation steht als waagerecht scrollbarer Streifen da – alle neun
     Punkte bleiben so auch ohne JavaScript erreichbar. */

  [data-js] .nav__burger {
    display: inline-flex;
  }

  /* Ohne Skript bleibt der waagerecht scrollbare Streifen. Damit nicht verborgen
     bleibt, dass rechts noch Punkte stehen, blendet ein schmaler Verlauf die
     letzte sichtbare Beschriftung aus – der übliche Hinweis „hier geht es
     weiter". Unter [data-js] ist er unnötig, dort klappt das Menü auf. */
  .nav {
    position: relative;
  }

  .nav::after {
    content: "";
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    width: var(--sp-6);
    background: linear-gradient(to right, rgba(255, 255, 255, 0), var(--card));
    pointer-events: none;
  }

  [data-js] .nav::after {
    content: none;
  }

  /* Zugeklappt trägt der Streifen nichts mehr – seine Unterkante stünde sonst
     als zweiter Strich direkt unter dem der Kopfleiste. */
  [data-js] .nav {
    border-bottom: 0;
  }

  [data-js] .nav__liste {
    display: none;
  }

  [data-js] .nav--offen {
    border-bottom: 1px solid var(--line);
  }

  /* Aufgeklappt: ruhige Liste unter der Kopfleiste, kein Overlay über dem
     Inhalt. Der Inhalt rutscht nach unten, statt verdeckt zu werden – das ist
     ehrlicher und braucht keine Fokusfalle. */
  [data-js] .nav--offen .nav__liste {
    display: flex;
    flex-direction: column;
    flex-wrap: nowrap;
    gap: 0;
    overflow: visible;
  }

  /* Jeder Punkt eine Zeile; ein Punkt mit Untermenü wird zu einem Block aus
     Hauptzeile und eingerückten Unterzeilen. */
  [data-js] .nav--offen .nav__punkt {
    display: block;
  }

  /* Volle Breite, 48 px Berührfläche, Trennlinien in --line. Die Tab-Unterkante
     wird zur Trennlinie. Der aktive Punkt trägt KEINEN Farbbalken an der Kante –
     solche Streifen sind aus dem ganzen Backend verschwunden. Er wirkt über die
     Markenfarbe und eine zart getönte Fläche, wie die Auswahl im Formular. */
  [data-js] .nav--offen .nav__link {
    width: 100%;
    height: auto;
    min-height: 48px;
    padding: var(--sp-2) var(--sp-3);
    border-bottom: 1px solid var(--line);
  }

  [data-js] .nav--offen .nav__punkt:last-child > .nav__link:last-child {
    border-bottom-color: transparent;
  }

  [data-js] .nav--offen .nav__link--active {
    background: var(--accent-soft);
    color: var(--navy);
    font-weight: var(--fw-semibold);
  }

  /* --- Untermenüs im Burger --------------------------------------------
     Kein Panel, kein zweites Klappen: Die Untereinträge stehen eingerückt
     unter ihrem Hauptpunkt und sind immer sichtbar. Wer das Menü einmal
     geöffnet hat, will sehen, was es gibt – und nicht ein zweites Mal suchen.
     Die Liste darf dabei lang werden; sie scrollt mit der Seite.

     Die drei Zustandsklassen von app.js (--offen, --zu) haben hier nichts zu
     regeln und werden bewusst mit ausgehebelt: Ein Escape auf dem Telefon darf
     keine Untereinträge verschwinden lassen, die niemand zurückholen kann. */
  [data-js] .nav--offen .nav__menu,
  [data-js] .nav--offen .nav__punkt:hover > .nav__menu,
  [data-js] .nav--offen .nav__punkt--zu > .nav__menu,
  [data-js] .nav--offen .nav__punkt--zu:hover > .nav__menu {
    display: block;
    position: static;
    z-index: auto;
    width: auto;
    min-width: 0;
    max-width: none;
    padding: 0;
    border: 0;
    border-radius: 0;
    box-shadow: none;
  }

  /* Der Chevron kündigt hier nichts mehr an – es ist bereits alles zu sehen. */
  [data-js] .nav--offen .nav__chevron {
    display: none;
  }

  [data-js] .nav--offen .nav__eintrag {
    width: 100%;
    min-height: 48px;
    padding: var(--sp-2) var(--sp-3) var(--sp-2) var(--sp-6);
    border-bottom: 1px solid var(--line);
    border-radius: 0;
  }

  [data-js] .nav--offen .nav__gruppentitel {
    padding: var(--sp-3) var(--sp-3) var(--sp-1) var(--sp-6);
  }

  /* Die Zeilen tragen hier schon Trennlinien – eine zweite darüber wäre nur ein
     doppelter Strich. */
  [data-js] .nav--offen .nav__menu-punkt--trenner {
    margin: 0;
    border-top: 0;
  }

  /* Zweispaltige Formulare sind auf dem Telefon nicht lesbar */
  .form-grid,
  .kv-liste {
    grid-template-columns: minmax(0, 1fr);
  }

  /* Zwei Kacheln je Zeile; die Spaltenzahl regelt der Kachel-Abschnitt selbst
     (6/3/2) – hier bleibt nur der engere Zwischenraum. */
  .kpi-grid {
    gap: var(--sp-3);
  }

  /* Filterleiste: jede Gruppe bekommt die volle Breite und bricht in sich um,
     der Abstandshalter entfällt – rechtsbündig gibt es hier nichts mehr. */
  .filterbar {
    gap: var(--sp-3);
  }

  .filterbar__group {
    width: 100%;
  }

  .filterbar__spacer {
    display: none;
  }

  .filterbar .input,
  .filterbar .select {
    flex: 1 1 160px;
    width: auto;
    min-width: 0;
  }

  /* Massenleiste: nicht mehr klebend (sie fräse sonst den halben Bildschirm weg)
     und mit voller Breite je Gruppe. */
  .bulkbar {
    position: static;
  }

  .bulkbar__gruppe {
    width: 100%;
  }

  .bulkbar .select,
  .zeilen-aktionen .select {
    flex: 1 1 auto;
    width: auto;
    min-width: 0;
  }

  .zeilen-aktionen form {
    flex: 1 1 100%;
  }

  /* Statuszeile des Editors: der Nachsatz steht darunter statt rechts */
  .status-aktionen__hinweis {
    margin-left: 0;
    flex: 1 1 100%;
  }

  /* Export-Karten: Feld und Knopf untereinander */
  .export-karte__form .field {
    min-width: 0;
    width: 100%;
  }

  /* Feld-Diff: die Spaltenbreite von 200 px sprengt schmale Fenster */
  .diff-tabelle tbody th {
    width: auto;
  }

  /* Fußzeile einer Liste: Trefferzahl über den Seitenblättern */
  .list-footer {
    justify-content: flex-start;
  }
}

@media (max-width: 559px) {
  /* Kopf einer Detailseite: Titel, Pille und Kennung untereinander statt
     nebeneinander gequetscht. */
  .detail-kopf__zeile {
    align-items: flex-start;
    gap: var(--sp-2);
  }

  /* Aktionszeilen brechen um, statt den Knopf abzuschneiden */
  .form-aktionen,
  .beleg-buttons {
    flex-wrap: wrap;
  }

  .form-aktionen .btn {
    flex: 1 1 auto;
  }
}

/* -------------------------------------------------------------------------
   Touch: Fingerflächen
   Zwei Auslöser, weil keiner für sich zuverlässig ist – ein Tablet mit Maus
   meldet fein, ein Touch-Laptop bleibt breit. Wer eine Maus hat, verliert
   dadurch nichts: die Höhe wächst nur nach unten.
   ------------------------------------------------------------------------- */

@media (pointer: coarse), (max-width: 767px) {
  .btn {
    min-height: 40px;
  }

  /* Gleiche Höhe wie im Tab-Streifen (48 px) – der Finger soll auf dem Tablet
     nicht kleiner treffen als die Maus auf dem Desktop. */
  .nav__link {
    min-height: 48px;
  }

  /* Untermenü-Einträge sind mit 36 px für die Maus richtig bemessen, für den
     Finger aber knapp – auf Touch-Geräten wachsen sie auf die Knopfhöhe. */
  .nav__eintrag {
    min-height: 44px;
  }

  /* „Abmelden" steht neben dem 44 px hohen Burger in derselben Zeile. Die
     allgemeinen 40 px des Knopfes fielen daneben sichtbar ab und blieben unter
     der Fingerbreite, die für die Kopfzeile gilt. */
  .topbar__logout .btn {
    min-height: 44px;
  }

  .pagination a,
  .pagination span {
    min-width: 40px;
    height: 40px;
  }

  /* Kästchen der Massenauswahl: 16 px trifft man mit dem Finger nicht */
  .check {
    width: 20px;
    height: 20px;
  }

  .table .is-check {
    padding-left: var(--sp-2);
    padding-right: var(--sp-2);
  }

  .toast__close {
    min-width: 40px;
    min-height: 40px;
  }
}

/* =========================================================================
   31. Umbruch-Schutz in Tabellen
   Kennungen (Ref, Messename) und kurze Etikettenspalten (Paketnamen) brachen
   bisher mitten im Wert um. Beides sind Werte, die man am Stück liest –
   bricht der Rahmen, scrollt stattdessen .table-wrap waagerecht (Abschnitt 29).
   ========================================================================= */

.table a.zeile-link {
  white-space: nowrap;
}

/* Für kurze Etikettenspalten ohne Link – bewusst auf .table beschränkt, damit
   die Klasse nicht als allgemeines nowrap durch die Views wandert. */
.table .is-nowrap {
  white-space: nowrap;
}

/* =========================================================================
   32. Status-Verteilung der Übersicht
   Ein schmaler Balken statt fünf gleichförmiger Zahlenkacheln: die Anteile
   sind auf einen Blick zu sehen, die Zahlen stehen darunter in klickbaren
   Pillen. Der Balken ist reine Dekoration (aria-hidden) – die Pillen tragen
   Beschriftung, Anzahl und den Weg in die gefilterte Liste.
   ========================================================================= */

.status-verteilung {
  height: 12px;
  margin-bottom: var(--sp-4);
  border-radius: var(--radius-pill);
  /* Ohne overflow ragten die eckigen Segmente aus den runden Enden heraus. */
  overflow: hidden;
}

/* Die Anteile kommen als SVG-Geometrie (x/width) aus der View, NICHT als
   style-Attribut: Die eigene Content-Security-Policy (style-src 'self')
   blockiert Inline-Styles – ein flex-grow im style-Attribut kam im Browser
   nie an, und der Balken kollabierte auf Krümelbreite. SVG-Attribute sind
   keine Styles und laufen unter der CSP durch. */
.status-verteilung__svg {
  display: block;
  width: 100%;
  height: 100%;
}

.status-verteilung__segment--neu            { fill: var(--st-neu-fg); }
.status-verteilung__segment--in_bearbeitung { fill: var(--st-inb-fg); }
.status-verteilung__segment--bestaetigt     { fill: var(--st-best-fg); }
.status-verteilung__segment--abgelehnt      { fill: var(--st-abg-fg); }
.status-verteilung__segment--archiviert     { fill: var(--st-arch-fg); }
.status-verteilung__segment--storniert      { fill: var(--st-storn-fg); }

.status-pills {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
}

/* Die Pille ist hier ein echter Link. Farbe und Form bleiben die der Pille –
   nur der Unterstrich des Links muss weg, sonst zerschnitte er das Etikett. */
a.pill {
  transition: opacity .12s ease;
}

a.pill:hover {
  text-decoration: none;
  opacity: .82;
}

/* =========================================================================
   33. Sprungleiste des Sortiment-Editors
   Zwölf Warengruppen und 82 Artikel auf einer Seite: Ohne Sprungziele hieß
   „Erdung suchen" zwanzig Bildschirme scrollen. Die Leiste ist bewusst nur
   ein Umbruch-Container für vorhandene .chip-Links – keine eigene Optik, kein
   Zustand, keine Skriptbindung. Anker funktionieren auch im Ausdruck.
   ========================================================================= */

.sprungleiste {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
  margin-bottom: var(--sp-5);
}

/* Kopf der Sortiment-Ansichten: Titel, Kennzahlen-Chips und Aktionszeile
   klebten aufeinander (Rückmeldung vom 24.08.). Bewusst über :has() auf Köpfe
   MIT Aktionszeile beschränkt – die übrigen Detailseiten behalten ihr Maß,
   und in Formularen bleibt .form-aktionen kompakt. Ohne :has()-Unterstützung
   fehlt nur der Chip-Abstand, nichts bricht. */
.detail-kopf:has(> .form-aktionen) .detail-kopf__meta {
  margin-top: var(--sp-3);
}

.detail-kopf > .form-aktionen {
  margin-top: var(--sp-3);
}
