/* ============================================================
   MP-Verwaltung – Design-System
   Phase 0 des Modernisierungskonzepts (siehe Modernisierungskonzept_MP-Verwaltung.docx)
   Angelehnt an das Erscheinungsbild von www.loewe-med.de
   Schriftart: Open Sans (in Produktion self-hosted, siehe Hinweis in styleguide.html)
   ============================================================ */

:root {
  /* ---------- Farben ---------- */
  --color-primary: #1B2A4A;        /* Marken-Navy (Headlines, Hauptnavigation) */
  --color-primary-light: #3E6B99;  /* Sekundärblau (Links, aktive Zustände) */
  --color-accent: #D5E0EB;         /* Theme-Farbe loewe-med.de (Flächen, Hover-Hintergründe) */
  --color-accent-dark: #A9C0D6;    /* dunklere Accent-Variante (Rahmen, Hover) */

  --color-bg: #F6F8FB;             /* Seitenhintergrund */
  --color-surface: #FFFFFF;        /* Karten/Formulare/Tabellen */
  --color-surface-alt: #F0F3F8;    /* Zebra-Streifen, dezente Flächen */
  --color-border: #DCE3EC;

  --color-text: #1F2733;
  --color-text-muted: #616B7A;
  --color-text-inverse: #FFFFFF;

  --color-success: #2E9E6B;
  --color-success-bg: #E4F5EE;
  --color-warning: #E08A2C;
  --color-warning-bg: #FCEEDC;
  --color-danger: #D14343;
  --color-danger-bg: #FBE7E7;
  --color-info: var(--color-primary-light);
  --color-info-bg: #E7EFF6;
  /* Eigenständige Farbe fuer "Extern geprueft" (Eigentümer-Fund 23.09.2026:
     kollidierte mit dem neuen blauen "Angefangen"-Badge, siehe .badge-extern). */
  --color-extern: #7C4DBB;
  --color-extern-bg: #F1E9F9;

  /* ---------- Typografie ---------- */
  --font-family: "Open Sans", "Segoe UI", Arial, sans-serif;
  --fs-xs: 0.75rem;    /* 12px */
  --fs-sm: 0.875rem;   /* 14px */
  --fs-base: 1rem;     /* 16px */
  --fs-md: 1.125rem;   /* 18px */
  --fs-lg: 1.375rem;   /* 22px */
  --fs-xl: 1.75rem;    /* 28px */
  --fs-xxl: 2.25rem;   /* 36px */
  --lh-base: 1.5;

  /* ---------- Abstände (4px-Raster) ---------- */
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.5rem;
  --space-6: 2rem;
  --space-7: 3rem;
  --space-8: 4rem;

  /* ---------- Radien / Schatten ---------- */
  --radius-sm: 6px;
  --radius-md: 10px;
  --radius-lg: 16px;
  --radius-pill: 999px;
  --shadow-sm: 0 1px 2px rgba(27, 42, 74, 0.08);
  --shadow-md: 0 4px 12px rgba(27, 42, 74, 0.10);
  --shadow-lg: 0 12px 32px rgba(27, 42, 74, 0.16);

  /* ---------- Touch/Bedienung ---------- */
  --touch-target: 44px;   /* Mindestgröße für Buttons/Eingaben – iPad-Fingerbedienung */
  --focus-ring: 0 0 0 3px rgba(62, 107, 153, 0.35);

  /* Skalierungsfaktor für Tabellen-Zeilenhöhe/Schriftgröße (Eigentümer-
     Vorgabe 25.09.2026: "Zeilenhöhe verkleinern ... Schriftgröße
     anpassbar"), von design-system/anzeige-einstellungen.js aus dem
     gespeicherten Wert gesetzt (design-system/anzeige-einstellungen.js
     Klassendoc). 1 = Standard. */
  --tabellen-zoom: 1;

  /* ---------- Breakpoints (als Referenz, in @media direkt verwendet) ----------
     Mobile: < 768px | Tablet/iPad: 768–1279px | Laptop/Desktop: ≥ 1280px */
}

/* ============================================================
   Basis / Reset
   ============================================================ */
*, *::before, *::after { box-sizing: border-box; }

body {
  margin: 0;
  font-family: var(--font-family);
  font-size: var(--fs-base);
  line-height: var(--lh-base);
  color: var(--color-text);
  background: var(--color-bg);
  -webkit-text-size-adjust: 100%;
}

h1, h2, h3, h4 {
  font-family: var(--font-family);
  color: var(--color-primary);
  font-weight: 700;
  margin: 0 0 var(--space-3);
  line-height: 1.25;
  overflow-wrap: break-word;
}
h1 { font-size: var(--fs-xxl); }
h2 { font-size: var(--fs-xl); }
h3 { font-size: var(--fs-lg); }
h4 { font-size: var(--fs-md); }

p { margin: 0 0 var(--space-4); color: var(--color-text); }
.text-muted { color: var(--color-text-muted); }
a { color: var(--color-primary-light); }

/* ============================================================
   Layout-Hilfen
   ============================================================ */
.container {
  max-width: 1280px;
  margin: 0 auto;
  padding: 0 var(--space-5);
}

.stack > * + * { margin-top: var(--space-4); }
.cluster { display: flex; flex-wrap: wrap; gap: var(--space-3); align-items: center; }

.grid {
  display: grid;
  gap: var(--space-5);
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
}

.card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm);
  padding: var(--space-5);
}

/* ============================================================
   Navigation (Kopfbereich)
   ============================================================ */
.app-header {
  background: var(--color-primary);
  color: var(--color-text-inverse);
  padding: var(--space-3) var(--space-5);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  flex-wrap: wrap;
  /* Eigentümer-Feedback 23.09.2026: Kopfzeile blieb beim Scrollen einer
     langen Liste nicht sichtbar - sticky statt normalem Fluss, Höhe wird
     von design-system/sticky-kopfbereich.js laufend in --sticky-header-hoehe
     geschrieben (Nav kann bei schmalen Fenstern mehrzeilig umbrechen, daher
     keine feste Höhe). */
  position: sticky;
  top: 0;
  z-index: 50;
}

.app-header__brand {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  font-weight: 700;
  font-size: var(--fs-md);
  color: var(--color-text-inverse);
}

.app-header__logo {
  display: inline-flex;
  align-items: center;
  background: var(--color-surface);
  border-radius: var(--radius-sm);
  padding: var(--space-1) var(--space-3);
  line-height: 0;
}

.app-header__logo img {
  display: block;
  height: 28px;
  width: auto;
}

.app-header__sandbox-badge {
  display: inline-block;
  background: var(--color-danger);
  color: #fff;
  font-weight: 700;
  font-size: var(--fs-sm);
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-sm);
  letter-spacing: 0.02em;
  text-transform: uppercase;
  white-space: nowrap;
}

.app-nav {
  display: flex;
  gap: var(--space-2);
  flex-wrap: wrap;
}

.app-nav a {
  color: var(--color-text-inverse);
  text-decoration: none;
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-sm);
  min-height: var(--touch-target);
  display: inline-flex;
  align-items: center;
  font-size: var(--fs-sm);
  font-weight: 600;
}

.app-nav a:hover,
.app-nav a:focus-visible {
  background: rgba(255, 255, 255, 0.14);
}

.app-nav a.app-nav__zurueck {
  border: 1px solid currentColor;
  border-radius: var(--radius-sm);
  padding-left: var(--space-3);
  padding-right: var(--space-3);
  font-weight: 700;
}

.app-nav a.is-active {
  background: var(--color-accent);
  color: var(--color-primary);
}

/* Aufklappmenü in der Hauptleiste (<details>), z. B. "Hilfe & Infos". */
.app-nav__menue { position: relative; }
.app-nav__menue > summary {
  list-style: none;
  cursor: pointer;
  color: var(--color-text-inverse);
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-sm);
  min-height: var(--touch-target);
  display: inline-flex;
  align-items: center;
  font-size: var(--fs-sm);
  font-weight: 600;
}
.app-nav__menue > summary::-webkit-details-marker { display: none; }
.app-nav__menue > summary:hover,
.app-nav__menue > summary:focus-visible,
.app-nav__menue[open] > summary { background: rgba(255, 255, 255, 0.14); }
.app-nav__menue-panel {
  position: absolute;
  top: calc(100% + var(--space-1));
  left: 0;
  z-index: 60;
  display: flex;
  flex-direction: column;
  min-width: 16em;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-md);
  padding: var(--space-2);
}
.app-nav .app-nav__menue-panel a {
  color: var(--color-text);
  padding: var(--space-2) var(--space-3);
}
.app-nav .app-nav__menue-panel a:hover,
.app-nav .app-nav__menue-panel a:focus-visible { background: var(--color-surface-alt); }

/* Anzeige-Einstellungen (Desktop/Pad-Umschalter + Tabellenschrift), siehe
   design-system/anzeige-einstellungen.js - gleiche Optik wie die übrigen
   .app-nav-Einträge, plus ein kleines aufklappbares Panel. */
.app-nav__ansicht-button {
  color: var(--color-text-inverse);
  background: transparent;
  border: none;
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-sm);
  min-height: var(--touch-target);
  font-size: var(--fs-sm);
  font-weight: 600;
  font-family: var(--font-family);
  cursor: pointer;
}
.app-nav__ansicht-button:hover,
.app-nav__ansicht-button:focus-visible {
  background: rgba(255, 255, 255, 0.14);
}
.app-nav__ansicht-panel {
  position: absolute;
  top: calc(100% + var(--space-1));
  right: 0;
  z-index: 60;
  background: var(--color-surface);
  color: var(--color-text);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-md);
  padding: var(--space-4);
  min-width: 15em;
}
.app-nav__ansicht-panel label { font-size: var(--fs-sm); font-weight: 400; }
.app-nav__ansicht-titel {
  margin: 0 0 var(--space-2);
  font-size: var(--fs-xs);
  font-weight: 700;
  text-transform: uppercase;
  color: var(--color-text-muted);
}

/* ============================================================
   Kunden-Kontext-Leiste (auf jeder Seite innerhalb eines Kunden,
   z. B. Geräteliste/Prüfberichte) - macht auf einen Blick sichtbar, in
   welchem Kunden man sich gerade befindet, damit man nicht versehentlich
   Daten eines falschen Kunden bearbeitet.
   ============================================================ */
.kunde-context-bar {
  background: var(--color-success-bg);
  color: var(--color-primary);
  padding: var(--space-2) var(--space-5);
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--fs-sm);
  border-bottom: 1px solid var(--color-success);
  /* Bleibt direkt unter der sticky Kopfzeile stehen (siehe .app-header). */
  position: sticky;
  top: var(--sticky-header-hoehe, 0px);
  z-index: 45;
}

.kunde-context-bar a {
  color: var(--color-success);
  text-decoration: none;
  font-weight: 700;
}

.kunde-context-bar a:hover,
.kunde-context-bar a:focus-visible {
  text-decoration: underline;
}

.kunde-context-bar__label {
  text-transform: uppercase;
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--color-text-muted);
}

.kunde-context-bar__betrag {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  font-size: var(--fs-xs);
  color: var(--color-text-muted);
  cursor: pointer;
}

.kunde-context-bar__achtung,
.kunde-context-bar a.kunde-context-bar__achtung {
  background: var(--color-danger);
  color: var(--color-text-inverse) !important;
  font-weight: 700 !important;
  text-decoration: none;
  white-space: nowrap;
  border-radius: var(--radius-sm);
  padding: 2px var(--space-3);
}
.kunde-context-bar a.kunde-context-bar__achtung:hover { filter: brightness(0.92); }

/* Warnmarker im Dispositionskalender / in Listen */
.achtung-marker {
  display: inline-block;
  background: var(--color-danger);
  color: var(--color-text-inverse);
  font-weight: 700;
  font-size: var(--fs-xs);
  border-radius: var(--radius-sm);
  padding: 0 var(--space-2);
  white-space: nowrap;
}
.warn-banner {
  background: var(--color-danger-bg);
  color: var(--color-danger);
  border: 1px solid var(--color-danger);
  border-radius: var(--radius-sm);
  padding: var(--space-2) var(--space-3);
  font-weight: 600;
}

.kunde-context-bar__edit {
  margin-left: auto;
  font-weight: 600 !important;
  background: var(--color-surface);
  border: 1px solid var(--color-success);
  border-radius: var(--radius-sm);
  padding: 2px var(--space-3);
}

/* ============================================================
   Footer (Phase K: Copyright/Version + Impressum-Link auf jeder Seite)
   ============================================================ */
.app-footer {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-4) var(--space-5);
  color: var(--color-text-muted);
  font-size: var(--fs-xs);
  border-top: 1px solid var(--color-border);
}

.app-footer a {
  color: var(--color-text-muted);
}

/* ============================================================
   Buttons
   ============================================================ */
.btn {
  font-family: var(--font-family);
  font-size: var(--fs-sm);
  font-weight: 600;
  border-radius: var(--radius-sm);
  border: 1px solid transparent;
  padding: 0 var(--space-5);
  min-height: var(--touch-target);
  min-width: var(--touch-target);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  cursor: pointer;
  transition: background-color .15s ease, border-color .15s ease, transform .05s ease;
  text-decoration: none;
}
.btn:active { transform: translateY(1px); }
.btn:focus-visible { outline: none; box-shadow: var(--focus-ring); }

.btn-primary { background: var(--color-primary); color: var(--color-text-inverse); }
.btn-primary:hover { background: #142038; }
/* Grüner Knopf, z. B. der Zähler "+1" in der Angebotserfassung (Wunsch 07.10.2026) */
.btn-success { background: var(--color-success); color: #fff; border-color: var(--color-success); }
.btn-success:hover { background: #25865A; border-color: #25865A; }
.btn-success:active { transform: scale(.96); }

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

.btn-danger { background: var(--color-danger); color: var(--color-text-inverse); }
.btn-danger:hover { background: #b23434; }

.btn-ghost { background: transparent; color: var(--color-primary-light); }
.btn-ghost:hover { background: var(--color-accent); }

.btn[disabled] { opacity: .5; cursor: not-allowed; }

/* Kompakte Variante fuer wiederholte Aktionen in Tabellenzeilen (z. B.
   Geraeteliste/Kundenliste) - der volle .btn-Abstand (space-5 + 44px
   Touch-Ziel) macht die Aktionsspalte bei 2-3 Buttons je Zeile sehr breit
   und die Liste dadurch unuebersichtlich. Bewusst weiterhin gut lesbar/
   klickbar (kein Icon-only), nur kompakter. */
.btn-sm {
  padding: 0 var(--space-3);
  min-height: 32px;
  min-width: auto;
  font-size: var(--fs-xs);
}

/* Grosse Kachel-Buttons, z.B. Vertrieb-Hub ("Willkommen bei den
   Vertriebsthemen" - Eigentuemer-Vorgabe 16.09.2026: "grosse Buttons zu
   den entsprechenden Unterseiten"). */
.btn-lg {
  padding: var(--space-3) var(--space-5);
  min-height: 56px;
  font-size: var(--fs-md);
}

/* Aktionsleiste in Formularen: Speichern/Abbrechen bewusst weit auseinander (CMS-5463) */
.form-actions {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-5);
  margin-top: var(--space-6);
  flex-wrap: wrap;
}

/* ============================================================
   Formulare
   ============================================================ */
.field { margin-bottom: var(--space-5); }
.field label {
  display: block;
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--color-text);
  margin-bottom: var(--space-2);
}
.field .hint { font-size: var(--fs-xs); color: var(--color-text-muted); margin-top: var(--space-1); }

.input, .select, .textarea {
  width: 100%;
  font-family: var(--font-family);
  font-size: var(--fs-base);
  color: var(--color-text);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  padding: var(--space-3) var(--space-4);
  min-height: var(--touch-target);
  appearance: none;
}
.textarea { min-height: 120px; resize: vertical; }

.input:focus, .select:focus, .textarea:focus {
  outline: none;
  border-color: var(--color-primary-light);
  box-shadow: var(--focus-ring);
}

.input.is-invalid { border-color: var(--color-danger); background: var(--color-danger-bg); }
.field .error-text { color: var(--color-danger); font-size: var(--fs-xs); margin-top: var(--space-1); }

/* Briefkopf-Wahl vor PDF-Export (Phase T) - bewusst farblich hervorgehoben
   (Rückmeldung des Eigentümers: "soll etwas heraussticht"), da eine falsch
   stehengelassene Auswahl sonst leicht übersehen wird, bevor auf "Als PDF"
   geklickt wird. */
.pdf-marke-select {
  width: auto;
  font-weight: 600;
  background: var(--color-warning-bg);
  border-color: var(--color-warning);
  color: var(--color-text);
}
.pdf-marke-select:focus { border-color: var(--color-warning); }

/* Kompakte Variante von .input - Pendant zu .btn-sm, fuer die von
   table-search.js injizierte Spalten-Suchzeile in Tabellen (siehe unten). */
.input-sm {
  width: 100%;
  font-family: var(--font-family);
  font-size: var(--fs-xs);
  color: var(--color-text);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  padding: 0 var(--space-2);
  min-height: 32px;
  appearance: none;
}
.input-sm:focus {
  outline: none;
  border-color: var(--color-primary-light);
  box-shadow: var(--focus-ring);
}

.form-grid {
  display: grid;
  gap: var(--space-5);
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
}

/* ============================================================
   Tabellen
   ============================================================ */
.table-wrap {
  overflow-x: auto;
  /* "overflow-x: auto" allein zwingt Browser dazu, "overflow-y" ebenfalls
     als "auto" zu berechnen (CSS-Overflow-Contagion-Regel) - .table-wrap
     wird damit IMMER zum sticky-Bezugscontainer fuer .table thead th,
     unabhaengig davon, ob hier ueberhaupt eine eigene Bildlaufleiste
     entsteht. Ohne eigene Hoehenbegrenzung hat .table-wrap aber nie einen
     eigenen Scroll-Offset, "position: sticky" der Kopfzeile griff dadurch
     nie sichtbar (Eigentümer-Fund 23.09.2026: Kopfzeile/Suchzeile
     verschwanden beim Scrollen einer langen Liste vollstaendig). Fix: statt
     dagegen anzukaempfen wird .table-wrap bewusst zu einem eigenen,
     hoehenbegrenzten Scroll-Bereich - kurze Tabellen bleiben optisch
     unveraendert (kein Rollbalken, da Inhalt < max-height), lange Listen
     scrollen jetzt INNERHALB der Karte, mit stets sichtbarer Kopf-/
     Suchzeile.
  */
  overflow-y: auto;
  max-height: 70vh;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
}

.table {
  width: 100%;
  border-collapse: collapse;
  font-size: calc(var(--fs-sm) * var(--tabellen-zoom));
  min-width: 480px;
}

.table thead th {
  position: sticky;
  /* Bezugscontainer ist .table-wrap selbst (siehe dortiger Kommentar zur
     Overflow-Contagion), daher genuegt top:0 - keine Kopfbereich-Hoehe der
     Seite noetig. */
  top: 0;
  z-index: 10;
  background: var(--color-primary);
  color: var(--color-text-inverse);
  text-align: left;
  padding: calc(var(--space-3) * var(--tabellen-zoom)) calc(var(--space-4) * var(--tabellen-zoom));
  font-weight: 600;
  white-space: nowrap;
}

.table thead th.is-sortable { cursor: pointer; }
.table thead th.is-sortable:hover { background: #142038; }

.table tbody td {
  padding: calc(var(--space-3) * var(--tabellen-zoom)) calc(var(--space-4) * var(--tabellen-zoom));
  border-top: 1px solid var(--color-border);
  min-height: calc(var(--touch-target) * var(--tabellen-zoom));
}

/* Eingabefelder INNERHALB von Tabellen (z. B. DGUV-Jahresprüfliste) skalieren
   mit derselben Zoom-Variable, damit "kleinere Schrift = mehr in einer
   Zeile" auch für Formularfelder gilt, nicht nur für reinen Text. Bewusst
   auf .table-wrap begrenzt statt global auf .input/.select/.textarea, damit
   normale Formulare außerhalb von Tabellen unverändert bleiben. */
.table-wrap .input,
.table-wrap .select,
.table-wrap .textarea {
  font-size: calc(var(--fs-base) * var(--tabellen-zoom));
  padding: calc(var(--space-3) * var(--tabellen-zoom)) calc(var(--space-4) * var(--tabellen-zoom));
  min-height: calc(var(--touch-target) * var(--tabellen-zoom));
}

/* "Pad-Modus" (Eigentümer-Vorgabe 25.09.2026: auf Tablet/Handy war die
   ALTE Variante besser - nur der obere App-Header bleibt fixiert, Tabellen-
   Kopfzeile/Suchzeile scrollen wieder normal mit) - umschaltbar über
   design-system/anzeige-einstellungen.js, wirkt NICHT auf .app-header/
   .kunde-context-bar (die bleiben in jedem Modus sticky).
   Bewusst NUR max-height entfernen, "position: sticky" an thead th/
   .table-search-row td UNVERÄNDERT lassen: ohne Höhenbegrenzung hat
   .table-wrap nichts zum Scrollen, "sticky" greift dadurch praktisch nie
   (exakt die Situation vor dem 23.09.2026-Fix, siehe .table-wrap-Kommentar
   oben) - Tabelle scrollt wieder normal mit der Seite. Ein "position:
   static" hier würde stattdessen den Ziehgriff von design-system/
   tabellen-spalten.js kaputt machen (der braucht th als positionierten
   Bezugsrahmen, siehe .spalten-resize-griff-Kommentar). */
html.pad-modus .table-wrap {
  max-height: none;
}

.table tbody tr:nth-child(even) { background: var(--color-surface-alt); }
.table tbody tr:hover { background: var(--color-accent); }

/* Phase D.12: Zeilen mit data-href (siehe design-system/tabellen-zeile-klickbar.js) */
.table tbody tr[data-href] { cursor: pointer; }

/* Spalten-Suchzeile, automatisch von design-system/table-search.js unter
   den Tabellenkopf von table.table-searchable eingefuegt - siehe dortiger
   Kommentar. Jetzt ebenfalls sticky (Eigentümer-Feedback 23.09.2026: die
   Suchleiste verschwand beim Scrollen, was das Arbeiten in langen Listen
   verlangsamte) - "top" wird pro Tabelle von table-search.js gesetzt (eigene
   Hoehe der Tabellenkopfzeile, Bezugscontainer ist .table-wrap). */
.table-search-row td {
  position: sticky;
  z-index: 9;
  padding: var(--space-2) var(--space-3);
  background: var(--color-surface-alt);
  border-top: 1px solid var(--color-border);
}

/* Verstellbare/ein-ausblendbare Spalten, siehe design-system/tabellen-spalten.js.
   .table thead th ist bereits "position: sticky" (siehe oben) - das reicht
   als Positionierungskontext fuer den absolut positionierten Ziehgriff. */
.table tbody td { overflow: hidden; text-overflow: ellipsis; }

.spalten-resize-griff {
  position: absolute;
  top: 0;
  right: 0;
  width: 8px;
  height: 100%;
  cursor: col-resize;
  touch-action: none;
}
.spalten-resize-griff:hover,
.spalten-resize-griff.spalten-resize-aktiv {
  background: rgba(255, 255, 255, 0.35);
}

.spalten-toolbar {
  display: flex;
  justify-content: flex-end;
  position: relative;
  margin-bottom: var(--space-2);
}
.spalten-menu {
  position: absolute;
  top: 100%;
  right: 0;
  z-index: 30;
  margin-top: var(--space-1);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-md);
  padding: var(--space-3);
  min-width: 220px;
  max-height: 60vh;
  overflow-y: auto;
}
.spalten-menu label {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-1) 0;
  font-weight: 400;
  white-space: nowrap;
}
.table-search-empty td { text-align: center; color: var(--color-text-muted); }

/* ============================================================
   Status-Badges (ersetzen die alten Ampel-Icons lichtgelb/lichtaus etc.)
   ============================================================ */
.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: .02em;
  text-transform: uppercase;
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-pill);
}
.badge::before { content: ""; width: 8px; height: 8px; border-radius: 50%; background: currentColor; }

.badge-success { background: var(--color-success-bg); color: var(--color-success); }
.badge-warning { background: var(--color-warning-bg); color: var(--color-warning); }
.badge-danger  { background: var(--color-danger-bg);  color: var(--color-danger); }
.badge-info    { background: var(--color-info-bg);    color: var(--color-info); }
.badge-neutral { background: var(--color-surface-alt); color: var(--color-text-muted); }
.badge-extern  { background: var(--color-extern-bg);   color: var(--color-extern); }

/* Risiko-Einstufung Begehungsbericht (Gefährdungsbeurteilung, Phase G) -
   bewusst deutlich kräftiger als die normalen Status-Badges oben ("muss
   direkt auffallen"): "Hoch"/"Sicherheitskritisch" bekommen eine satte,
   volltonige Füllung statt der sonst üblichen zurückhaltenden Pastellfarbe. */
.badge-risiko-gering      { background: var(--color-success-bg); color: var(--color-success); }
.badge-risiko-mittel      { background: var(--color-warning-bg); color: var(--color-warning); }
.badge-risiko-hoch        { background: var(--color-warning);    color: var(--color-text-inverse); font-size: var(--fs-sm); padding: var(--space-2) var(--space-4); }
.badge-risiko-kritisch    { background: var(--color-danger);     color: var(--color-text-inverse); font-size: var(--fs-sm); padding: var(--space-2) var(--space-4); box-shadow: 0 0 0 2px var(--color-danger-bg); }

/* ============================================================
   Modal (löst modal.css / window.confirm-Dialoge ab)
   ============================================================ */
.modal-overlay {
  position: fixed;
  /* Ausgeschriebene Kurzform statt "inset: 0" - siehe Klassendoc bei
     .barcode-scanner-overlay (Safari < 14.1 kennt "inset" nicht, Modal
     bliebe auf aelteren iPhones unsichtbar/falsch positioniert). */
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  background: rgba(27, 42, 74, 0.45);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-5);
  z-index: 100;
}

.modal-dialog {
  background: var(--color-surface);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  width: 100%;
  max-width: 480px;
  max-height: 90vh;
  overflow-y: auto;
}

.modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-5) var(--space-5) var(--space-3);
}

.modal-header h3 { margin: 0; }

.modal-close {
  background: none;
  border: none;
  font-size: var(--fs-lg);
  color: var(--color-text-muted);
  cursor: pointer;
  min-width: var(--touch-target);
  min-height: var(--touch-target);
  border-radius: var(--radius-sm);
}
.modal-close:hover { background: var(--color-surface-alt); }

.modal-body { padding: 0 var(--space-5) var(--space-5); color: var(--color-text); }

.modal-footer {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-5);
  border-top: 1px solid var(--color-border);
  flex-wrap: wrap;
}

/* ============================================================
   Kamera-Barcode-Scanner (design-system/barcode-scanner.js)
   ============================================================ */
.barcode-scanner-overlay {
  position: fixed;
  /* Ausgeschriebene Kurzform statt "inset: 0" - "inset" wird erst ab
     Safari 14.1 (iOS 14.5, April 2021) verstanden. Auf aelteren iPhones
     (Eigentuemer-Feldtest 10.09.2026) fiel dadurch NUR die Positionierung
     weg, waehrend Hintergrundfarbe/z-index trotzdem griffen - Ergebnis:
     ein abgedunkelter Bildschirm ohne sichtbares Kamerabild/Bedienelemente. */
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  background: rgba(0, 0, 0, 0.85);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-5);
  z-index: 200;
}

.barcode-scanner-modal {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 100%;
  max-width: 480px;
}

/* Abstand ueber Margin statt Flexbox-"gap" - aus demselben Grund wie bei
   .barcode-scanner-overlay (Safari < 14.1 kennt "gap" bei Flexbox nicht). */
.barcode-scanner-modal > * + * {
  margin-top: var(--space-4);
}

.barcode-scanner-video-wrapper {
  position: relative;
  width: 100%;
}

.barcode-scanner-video {
  display: block;
  width: 100%;
  max-height: 60vh;
  border-radius: var(--radius-lg);
  background: #000;
}

/* Rein optischer Zielrahmen - hat auf die tatsaechlich ausgewertete
   Bildflaeche keinen Einfluss, hilft beim Ausrichten des Barcodes. */
.barcode-scanner-rahmen {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 80%;
  height: 35%;
  border: 3px solid var(--color-success);
  border-radius: var(--radius-md);
  box-shadow: 0 0 0 999px rgba(0, 0, 0, 0.35);
  pointer-events: none;
}

/* ============================================================
   Kamera-Fotoaufnahme (design-system/kamera-erfassung.js) - fuer
   Geraete mit Kamera, aber ohne mobiles "capture"-Attribut-Verhalten
   (z.B. Laptop-Webcam bei der Messedokumentation, Eigentuemer-Vorgabe
   16.09.2026). Bewusst eigene Klassen statt Wiederverwendung von
   .barcode-scanner-* - anderer Anwendungsfall (Einzelfoto statt
   Dauer-Decoding, kein Zielrahmen), aber identisches CSS-Grundgeruest
   (siehe .barcode-scanner-overlay-Klassendoc fuer die inset/gap-
   Safari-Vorsicht, hier aus demselben Grund uebernommen).
   ============================================================ */
.kamera-overlay {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  background: rgba(0, 0, 0, 0.85);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-5);
  z-index: 200;
}

.kamera-modal {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 100%;
  max-width: 480px;
}

.kamera-modal > * + * {
  margin-top: var(--space-4);
}

.kamera-video-wrapper {
  width: 100%;
}

.kamera-video {
  display: block;
  width: 100%;
  max-height: 60vh;
  border-radius: var(--radius-lg);
  background: #000;
}

.kamera-hint {
  color: var(--color-text-inverse);
  text-align: center;
  margin: 0;
}

.kamera-buttons {
  display: flex;
  gap: var(--space-3);
  width: 100%;
}
.kamera-buttons > * {
  flex: 1;
}

/* Nicht anwendbare Messfelder bei "Batteriebetrieben" (Muster:
   elektropruefung-jahresansicht.js) - readonly statt disabled fuer
   Text-Eingaben, damit ein bereits gespeicherter Messwert beim
   versehentlichen Hin-und-Zurückschalten nicht durch einen leeren
   Formular-Wert überschrieben wird (disabled-Felder werden beim Absenden
   gar nicht mitgeschickt). */
.input[readonly] {
  background: var(--color-surface-alt);
  color: var(--color-text-muted);
  cursor: not-allowed;
}

.barcode-scanner-hint {
  color: var(--color-text-inverse);
  text-align: center;
  margin: 0;
}

/* Unterschriften-Pad (design-system/signature-pad.js) - Klick/Tap oeffnet
   immer das Vergroesserungs-Modal, cursor:pointer signalisiert das. */
canvas.sig-pad { cursor: pointer; }

/* Modal-Vergroesserungs-Canvas: Klick-Umschalter statt Ziehen-mit-gehaltener-
   Taste (design-system/signature-pad.js) - farbiger Rahmen zeigt an, dass der
   "Stift" aktiv ist und jede Mausbewegung ohne gedrueckte Taste zeichnet. */
canvas.sig-modal-canvas.sig-pad--stift-aktiv {
  border-color: var(--color-primary-light) !important;
  box-shadow: 0 0 0 2px var(--color-accent);
}

/* ============================================================
   Responsive-Anpassungen: Tablet (iPad) und Laptop
   ============================================================ */
@media (max-width: 767px) {
  .app-nav { width: 100%; justify-content: flex-start; }
  .form-actions { flex-direction: column-reverse; align-items: stretch; }
  .form-actions .btn { width: 100%; }
  /* Bugfix 30.09.2026 (Eigentümer-Meldung, Handy-Screenshot): das
     "Ansicht"-Panel ist per `right: 0` relativ zu seinem eigenen Button
     positioniert (passt auf Desktop, wo rechts vom Button genug Platz ist).
     Auf schmalen Bildschirmen landet der Button aber oft am linken Rand
     seiner (umgebrochenen) Nav-Zeile - `right: 0` schiebt das 15em breite
     Panel dann größtenteils über den linken Viewport-Rand hinaus, nichts
     ist mehr anklickbar. Ab hier öffnet sich das Panel stattdessen nach
     rechts vom Button aus (linksbündig) und bleibt zusätzlich innerhalb
     der Bildschirmbreite. */
  .app-nav__ansicht-panel {
    left: 0;
    right: auto;
    max-width: calc(100vw - var(--space-4) * 2);
  }
}

@media (min-width: 768px) and (max-width: 1279px) {
  /* iPad: großzügigere Touch-Ziele, etwas mehr Zeilenabstand für Finger-Bedienung */
  .btn, .input, .select, .textarea { min-height: 48px; }
  .btn-sm { min-height: 36px; }
  .table tbody td, .table thead th { padding: var(--space-4); }
}

@media (min-width: 1280px) {
  .container { padding: 0 var(--space-6); }
}

/* Große/sehr große Bildschirme (Vollbild auf großen Monitoren): der feste
   1280px-Deckel oben ließ auf breiten Displays viel ungenutzten Leerraum
   an den Seiten stehen, während Tabellen (.table-wrap) im schmalen
   Container seitlich gescrollt werden mussten - Rückmeldung des
   Eigentümers ("Es ist einfach viel Leerraum an den Seiten"). Formulare/
   Karten sind davon nicht betroffen, da sie durchgehend ihre eigene
   max-width (inline style) tragen - nur Listen ohne eigene Breitenvorgabe
   profitieren vom zusätzlichen Platz. Ab hier fließend statt fest, damit
   auch Ultrawide-/4K-Displays proportional mehr Raum bekommen, aber nie
   randlos wirken (10% Luft bleibt immer). */
@media (min-width: 1600px) {
  .container { max-width: 90%; }
}

/* ============================================================
   Einfaches horizontales Balkendiagramm (ohne JS-Bibliothek, z. B.
   Auswertung "Zeit je Mitarbeiter/Bereich/Kunde") - Balkenbreite wird
   serverseitig als Inline-style="width:N%" gesetzt.
   ============================================================ */
.bar-chart { display: flex; flex-direction: column; gap: var(--space-2); }
.bar-chart__row { display: grid; grid-template-columns: 11rem 1fr 5rem; align-items: center; gap: var(--space-3); }
.bar-chart__label { font-size: 0.875rem; color: var(--color-text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bar-chart__track { display: block; background: var(--color-surface-alt, var(--color-border)); border-radius: 4px; height: 0.9rem; overflow: hidden; }
.bar-chart__fill { display: block; background: var(--color-primary-light); height: 100%; border-radius: 4px 0 0 4px; min-width: 2px; }
.bar-chart__value { font-size: 0.875rem; color: var(--color-text-muted); text-align: right; white-space: nowrap; }
@media (max-width: 767px) {
  .bar-chart__row { grid-template-columns: 7rem 1fr 4rem; }
}

/* Elektroprüfung-Jahresansicht: Zeilenfarbe je "Prüfung i.O."-Status
   (design-system/elektropruefung-jahresansicht.js setzt data-pruefung-io).
   ".table tbody"-Präfix nötig, damit die Regel spezifischer ist als die
   Zebra-Streifen-Regel .table tbody tr:nth-child(even) oben - sonst
   gewinnt bei geraden Zeilen weiterhin der graue Streifen. */
.table tbody tr[data-zeile-row][data-pruefung-io="1"] { background: var(--color-success-bg); }
.table tbody tr[data-zeile-row][data-pruefung-io="0"] { background: var(--color-danger-bg); }

/* ============================================================
   Vertrieb: Gebietskarten (Phase V) - Regionen als SVG-<path>,
   Pinsel-Auswahl + Statistik in der Seitenleiste. Layout/Optik an das
   Prototyp-CSS (Vertriebsgebiete/*.html) angelehnt, hier in die
   bestehenden Design-Tokens überführt statt dupliziert.
   ============================================================ */
.vertrieb-layout { display: flex; gap: var(--space-4); align-items: flex-start; flex-wrap: wrap; }
.vertrieb-mapcol { flex: 1 1 560px; min-width: 320px; position: relative; }
.vertrieb-side { flex: 0 0 320px; display: flex; flex-direction: column; gap: var(--space-4); min-width: 280px; }
.vertrieb-verwalten-panel {
  /* "inset: 0" durch Langform ersetzt (Safari < 14.1 kennt es nicht,
     siehe .barcode-scanner-overlay-Klassendoc). */
  position: absolute; top: 0; right: 0; bottom: 0; left: 0;
  /* Muss über Leaflets eigenen Kartenebenen liegen (verkaufte-geraete.php
     nutzt Leaflet statt eines reinen SVGs wie die Gebietskarte - Leaflets
     Panes liegen standardmäßig zwischen z-index 200 und 700, ein z-index
     von 5 verschwand deshalb hinter der Karte, nur die Überschrift blieb
     sichtbar, weil sie oberhalb des Kartenbereichs lag). */
  z-index: 1000;
  overflow-y: auto; max-height: 100%;
  box-shadow: 0 4px 24px rgba(0,0,0,0.18);
}
.vertrieb-tooltip {
  position: absolute; z-index: 30; pointer-events: none;
  background: var(--color-text); color: var(--color-surface);
  padding: var(--space-2) var(--space-3); border-radius: var(--radius-sm);
  font-size: 0.8em; line-height: 1.5; max-width: 260px;
}
.vertrieb-tooltip table { border-collapse: collapse; margin-top: 2px; }
.vertrieb-tooltip td { padding: 0 var(--space-2) 0 0; }
.vertrieb-tooltip__zahl { font-variant-numeric: tabular-nums; text-align: right; }
#vertriebKarteSvg { width: 100%; height: auto; display: block; }
.vertrieb-region { stroke: var(--color-border); stroke-width: 0.6; transition: fill 0.12s, stroke 0.12s; }
svg[data-darf-bearbeiten="1"] .vertrieb-region { cursor: pointer; }
svg[data-darf-bearbeiten="1"] .vertrieb-region:hover { stroke: var(--color-text); stroke-width: 1.6; }
.vertrieb-pinsel { display: flex; flex-direction: column; gap: var(--space-2); }
.vertrieb-brush {
  display: flex; align-items: center; gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--color-border); border-radius: var(--radius-sm);
  background: var(--color-surface); cursor: pointer; text-align: left; font-size: 0.875rem;
}
.vertrieb-brush--active { border-color: var(--color-primary); box-shadow: 0 0 0 1px var(--color-primary); }
.vertrieb-swatch { display: inline-block; width: 12px; height: 12px; border-radius: 3px; border: 1px solid var(--color-border); flex: none; margin-right: var(--space-2); }
.vertrieb-label { font-size: 11px; font-weight: 600; fill: #223; paint-order: stroke; stroke: #fff; stroke-width: 2.4px; stroke-linejoin: round; pointer-events: none; user-select: none; }
.vertrieb-zollgrenze { fill: none; stroke: var(--color-danger); stroke-width: 2.4; stroke-dasharray: 5 3; pointer-events: none; stroke-linejoin: round; }
#vertriebBeschriftung label { font-size: 0.8em; color: var(--color-text-muted); display: inline-flex; gap: 4px; align-items: center; }

/* Geräteliste: Prüfstatus des letzten (heutigen) Prüfberichts und
   "Extern geprüft" wurden zunächst als Zeilenfarbe umgesetzt - nach
   echtem Praxis-Feedback (mit Zebra-Streifen zu ähnlich/unübersichtlich)
   auf ein kompaktes Status-Badge neben dem Gerätetyp umgestellt (Muster:
   das bereits vorhandene "Extern"-Badge), keine Zeilenfarbe mehr. Siehe
   templates/geraeteliste/index.php.
*/

/* Disposition-Karte (Phase I.9-Nachtrag): Eigentümer-Feedback "Markierungen
   kaum zu erkennen" - die Basiskarte (OSM-Kacheln, siehe dispo-karte.js
   für die Begründung gegen einen zahlungspflichtigen Anbieter) wird leicht
   entsättigt/aufgehellt, damit der eigene, kräftige Punkt-Marker klar
   davor hervorsticht statt mit Gelände-/Beschriftungsfarben zu
   konkurrieren. */
#dispoKarte .leaflet-tile-pane { filter: grayscale(55%) brightness(1.08) contrast(0.92); }
.dispo-karte-marker span {
  display: block; width: 20px; height: 20px; border-radius: 50%;
  background: var(--color-danger); border: 3px solid #fff;
  box-shadow: 0 1px 5px rgba(0,0,0,0.6);
}
/* Sammel-Marker: mehrere Praxen an derselben Adresse, Anzahl im Kreis. */
.dispo-karte-marker-mehrere span {
  display: flex; align-items: center; justify-content: center;
  width: 24px; height: 24px; color: #fff; font-weight: 700; font-size: 13px; line-height: 1;
}
/* Hotel der Übernachtung: andersfarbiger (oranger) Marker mit "H", Rand in der Tourfarbe. */
.dispo-karte-marker-hotel span {
  display: flex; align-items: center; justify-content: center;
  width: 24px; height: 24px; border-radius: 6px; background: #E07B00; color: #fff;
  font-weight: 700; font-size: 14px; line-height: 1;
}
.dispo-karte-popup-liste { margin-top: 6px; }
.dispo-karte-popup-eintrag { padding: 5px 0; border-top: 1px solid #ddd; }

/* Vertrieb "Verkaufte Systeme"-Karte (Phase V.10) - gleiches Prinzip wie
   die Disposition-Karte oben (entsättigte Basiskarte, kräftiger eigener
   Marker), Farbe kommt hier aber je Gerätetyp dynamisch per Inline-Style
   aus design-system/vertrieb-verkaufte-geraete.js, daher keine feste
   background-Farbe in dieser Klasse. */
#verkaufKarte .leaflet-tile-pane { filter: grayscale(55%) brightness(1.08) contrast(0.92); }
.vertrieb-verkauf-marker span {
  display: block; width: 16px; height: 16px; border-radius: 50%;
  border: 2px solid #fff;
  box-shadow: 0 1px 4px rgba(0,0,0,0.6);
}
/* Fachhandel-Verkäufe (vs. eigener Vertrieb): zusätzlicher dunkler Ring um
   denselben Gerätetyp-Punkt, damit beide Vertriebswege gleichzeitig auf der
   Karte sichtbar UND unterscheidbar bleiben (Eigentümer-Vorgabe 05.09.2026). */
.vertrieb-verkauf-marker.ist-fachhandel span {
  border: 2px solid #1F2933;
  box-shadow: 0 0 0 2px #fff, 0 1px 4px rgba(0,0,0,0.6);
}
/* Apotheken-Verkäufe (Eigentümer-Vorgabe 20.09.2026): quadratisches Symbol
   statt rundem Punkt - bleibt in der Gerätetyp-Farbe, ist aber auch neben
   Fachhandel-Ringen auf einen Blick unterscheidbar. Bei Fachhandel UND
   Apotheke greift zusätzlich der dunkle Ring der Fachhandel-Regel. */
.vertrieb-verkauf-marker.ist-apotheke span {
  border-radius: 3px;
}

/* ============================================================
   Formular-Werkzeuge (design-system/formular-werkzeuge.js) - schwebender
   "Nach oben"-Button + Ein-/Ausklappen einzelner Karten bei langen,
   kartenbasierten Formularen (GBU, Begehungsbericht, ASA, Pruefbericht).
   ============================================================ */
.formular-nach-oben-btn {
  position: fixed;
  right: var(--space-5);
  bottom: var(--space-5);
  z-index: 90;
  border-radius: 999px;
  width: 48px;
  height: 48px;
  padding: 0;
  display: none;
  align-items: center;
  justify-content: center;
  font-size: var(--fs-lg);
  box-shadow: var(--shadow-lg);
}
.formular-nach-oben-btn.ist-sichtbar { display: flex; }

.karte-toggle-btn {
  background: none;
  border: none;
  cursor: pointer;
  font-size: var(--fs-md);
  color: var(--color-text-muted);
  padding: 0 var(--space-2);
  min-width: var(--touch-target);
  min-height: var(--touch-target);
}
.karte-vorschau {
  color: var(--color-text-muted);
  font-size: var(--fs-sm);
  font-weight: 400;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 40ch;
}

/* Changelog-Akkordeon (design-system/changelog-akkordeon.js) */
[data-changelog-toggle] [data-changelog-pfeil] {
  display: inline-block;
  transition: transform 0.15s ease;
}
[data-changelog-toggle][aria-expanded="true"] [data-changelog-pfeil] {
  transform: rotate(180deg);
}
[data-changelog-toggle]:hover {
  background: var(--color-surface-alt) !important;
}

/* Gruppenüberschriften auf der Einstellungen-Übersicht */
.einstellungen-gruppe {
  font-size: var(--fs-md, 1.1rem);
  margin: var(--space-5) 0 var(--space-2);
}

/* Entwurf-Hinweis (formular-entwurf.js): nicht gespeicherte Eingaben im Browser gefunden */
.entwurf-hinweis {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) var(--space-3);
  background: var(--color-info-bg);
  color: var(--color-primary);
  border: 1px solid var(--color-info);
  border-radius: var(--radius-sm);
  padding: var(--space-2) var(--space-3);
  font-weight: 600;
}

/* Startseite "Heute" */
.heute-raster {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 22rem), 1fr));
  gap: var(--space-4);
  align-items: start;
}
.heute-breit { grid-column: 1 / -1; }
.heute-termin {
  display: grid;
  grid-template-columns: 5.5rem 1fr;
  gap: var(--space-3);
  padding-top: var(--space-3);
  border-top: 1px solid var(--color-border);
}
.heute-termin:first-child { border-top: 0; padding-top: 0; }
.heute-termin__zeit { font-weight: 700; font-variant-numeric: tabular-nums; color: var(--color-primary); }
.heute-liste { margin: 0; padding-left: 1.2em; display: grid; gap: var(--space-2); }

/* Kennzahlen-/Faktenblock (z. B. Kunden-Detailseite): bei breiten Bildschirmen nebeneinander statt untereinander */
.faktenraster {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(13rem, 1fr));
  gap: var(--space-4) var(--space-5);
  align-items: start;
}
.faktenraster > h2,
.faktenraster > h3 { grid-column: 1 / -1; margin: 0; }
.faktenraster > .field { margin: 0; }
