/* ============================================================
   Orbit · Am Zehnhoff-Söns – App Styles
   Custom Design System, kein Build-Tool erforderlich.
   ============================================================ */

/* CSS Reset */
*, *::before, *::after { box-sizing: border-box; }
html { font-size: 16px; -webkit-text-size-adjust: 100%; }
body, h1, h2, h3, h4, h5, h6, p, ul, ol, li, figure, blockquote {
  margin: 0; padding: 0;
}
ul, ol { list-style: none; }
img, svg { display: block; max-width: 100%; }
button, input, select, textarea { font: inherit; }
a { color: inherit; }

/* ---- Textfarb-Utilities auf <a> wiederherstellen --------------------------
   `a { color: inherit }` steht unlayered im Reset und schlägt damit ALLE
   Farb-Utilities aus Tailwinds `@layer utilities` — unlayered CSS gewinnt
   gegen jeden Layer, unabhängig von der Spezifität (gleiche Falle wie bei
   `mb-*` auf <p>, siehe CLAUDE-UI §2.2). Folge: `<a class="bg-primary
   text-white">` bekam geerbtes Dunkelbraun statt Weiß (Leerzustand-Buttons
   „Erstes Formular anlegen", „Ersten Test anlegen"), `<a class="text-primary">`
   blieb grau („5 weitere im Kalender" auf dem Dashboard).
   Element + Klasse (0,1,1) schlägt `a` (0,0,1) — ohne !important, und die
   Utilities bleiben für alle anderen Elemente unangetastet. */
a.text-white            { color: #fff; }
/* Gleiche Falle für die Knopf-Bausteine: .extr-btn--primary/--danger liegen
   in @layer components und verlieren deshalb gegen das ungeschichtete
   `a { color: inherit }`. Betraf u. a. „Erste Lernstrecke anlegen". */
a.extr-btn--primary     { color: hsl(var(--primary-foreground)); } /* UI-Audit DARK-02 */
a.extr-btn--danger,
a.extr-btn--success     { color: #fff; }
a.extr-btn--outline     { color: hsl(var(--foreground)); }
a.extr-btn--ghost       { color: hsl(var(--muted-foreground)); }
a.extr-icon-btn         { color: hsl(var(--muted-foreground)); }
a.extr-icon-btn:hover   { color: hsl(var(--foreground)); }
a.extr-icon-btn--danger,
a.extr-icon-btn--danger:hover,
a.extr-icon-btn--danger-hover:hover { color: hsl(var(--destructive)); }
a.text-primary          { color: hsl(var(--primary)); }
a.text-foreground       { color: hsl(var(--foreground)); }
a.text-muted-foreground { color: hsl(var(--muted-foreground)); }
a.hover\:text-foreground:hover       { color: hsl(var(--foreground)); }
a.hover\:text-primary:hover          { color: hsl(var(--primary)); }
a.hover\:text-muted-foreground:hover { color: hsl(var(--muted-foreground)); }

/* ---- `hidden` schlägt die später ausgegebenen Display-Utilities ------------
   Tailwind gibt .inline-*, .table-* und .list-item im Stylesheet NACH .hidden
   aus. Bei gleichem Gewicht gewinnt die spätere Regel — `class="hidden
   inline-flex …"` bleibt also sichtbar, obwohl `hidden` gesetzt ist (traf
   u. a. den Button „Alle gelesen" im Benachrichtigungs-Modal, der nach dem
   Markieren stehen blieb). Zwei Klassen im Selektor geben das nötige Gewicht —
   ohne !important und ohne die responsiven Muster (`hidden lg:inline-flex`)
   zu stören, denn dort heißt die Klasse `lg:inline-flex`. */
.hidden.inline, .hidden.inline-block, .hidden.inline-flex, .hidden.inline-grid,
.hidden.inline-table, .hidden.list-item, .hidden.table, .hidden.table-caption,
.hidden.table-cell, .hidden.table-column, .hidden.table-column-group,
.hidden.table-footer-group, .hidden.table-header-group, .hidden.table-row,
.hidden.table-row-group { display: none; }

/* ---- Nachgereichte Utility: .pl-3 ----------------------------------------
   tailwind.css ist ein vorgebautes Artefakt (im Repo liegt kein Build-Tool).
   Der letzte Build hat `pl-3` nicht erfasst — die Klasse fehlt im Stylesheet,
   während .pl-2/.pl-4 vorhanden sind. Folge: Buttons mit `pl-3 pr-2.5`
   (Mehrfachauswahl in der Mitarbeiter-Detailansicht, Filter in „Termine")
   hatten links gar keinen Innenabstand, das Symbol klebte am Rahmen.
   Beim nächsten Tailwind-Build kann dieser Block entfallen. */
.pl-3 { padding-left: calc(var(--spacing) * 3); }

/* ---- Nachgereichte Utilities (fehlen im vorgebauten tailwind.css) ---------
   tailwind.css ist ein andernorts gebautes Artefakt; im Repo liegt kein
   Build-Tool. Der letzte Build ist gegenüber den PHP-Quellen veraltet: die
   folgenden im Markup verwendeten Klassen sind NICHT einkompiliert und tun
   optisch nichts. Sichtbare Folgen u. a.:
     · `top-16 bottom-16` fehlt → das Statistik-Modal in news-detail.php hatte
       keine Höhenbegrenzung, wuchs über den Bildschirm hinaus und ließ sich
       nicht mehr schließen.
     · `pb-28` fehlt → die Inventur-Liste lief unter die fixierte Abschlussleiste.
     · `max-w-xl`, `max-w-[…]`, `max-h-…` fehlen → Panels und Spalten liefen
       auf volle Breite/Höhe.
   Ermittelt durch Abgleich aller class="…"-Tokens der Partials gegen
   tailwind.css + app.css. Beim nächsten Tailwind-Build kann der Block entfallen.
   Spacing-Skala wie Tailwind v4: calc(var(--spacing) * n), --spacing = .25rem. */

/* Abstände */
.mt-2\.5  { margin-top: calc(var(--spacing) * 2.5); }
.mb-2\.5  { margin-bottom: calc(var(--spacing) * 2.5); }
.mr-3    { margin-right: calc(var(--spacing) * 3); }
.pl-1    { padding-left: calc(var(--spacing) * 1); }
.pl-2\.5  { padding-left: calc(var(--spacing) * 2.5); }
.pl-6    { padding-left: calc(var(--spacing) * 6); }
.pb-1\.5  { padding-bottom: calc(var(--spacing) * 1.5); }
.pb-5    { padding-bottom: calc(var(--spacing) * 5); }
.pb-28   { padding-bottom: calc(var(--spacing) * 28); }
.py-3\.5  { padding-block: calc(var(--spacing) * 3.5); }
.gap-x-3   { column-gap: calc(var(--spacing) * 3); }
.gap-x-6   { column-gap: calc(var(--spacing) * 6); }
.gap-y-1\.5 { row-gap: calc(var(--spacing) * 1.5); }
.gap-y-2\.5 { row-gap: calc(var(--spacing) * 2.5); }

/* Vom Signage-Modul verwendet (Vollbildvorschau, Card-Editor, Zeitplan).
   Ohne sie ist die Vorschau-Auflage durchsichtig und die Bedienknöpfe darauf
   unsichtbar. Schreibweise bewusst wie im Build (Hex mit Alpha statt
   color-mix); der Alpha-Wert von .text-muted-foreground/70 folgt der
   Orbit-Markenfarbe --muted-foreground (#5f6b6e). */
.bg-white\/15              { background-color: #ffffff26; }
.hover\:bg-white\/25:hover { background-color: #ffffff40; }
.text-muted-foreground\/70 { color: hsl(var(--muted-foreground) / .7); } /* folgt dem Dunkelmodus (UI-Audit DARK-01) */
.ring-border               { --tw-ring-color: var(--color-border); }
@media (min-width:40rem) { .sm\:items-end { align-items: flex-end; } }

/* Vom Social-Media-Modul verwendet: `hidden lg:table-cell` blendet Tabellen-
   spalten (Typ, Ziel) auf kleinen Bildschirmen aus. Ohne die Regel blieben die
   Spalten auch auf großen Bildschirmen verborgen — die Kopfzeile hätte dann
   mehr Spalten als die Zeilen. Reihenfolge beachtet: steht nach .hidden.table-cell
   oben, gewinnt also innerhalb desselben Media-Query. */
@media (min-width:64rem) { .lg\:table-cell, .hidden.lg\:table-cell { display: table-cell; } }

/* Größen */
.w-44     { width: calc(var(--spacing) * 44); }
.w-48     { width: calc(var(--spacing) * 48); }
.h-52     { height: calc(var(--spacing) * 52); }
.max-h-12 { max-height: calc(var(--spacing) * 12); }
.max-h-36 { max-height: calc(var(--spacing) * 36); }
.max-h-44 { max-height: calc(var(--spacing) * 44); }
.max-h-52 { max-height: calc(var(--spacing) * 52); }
.max-w-12 { max-width: calc(var(--spacing) * 12); }
.max-w-xl { max-width: 36rem; }
.max-w-\[8rem\]  { max-width: 8rem; }
.max-w-\[10rem\] { max-width: 10rem; }
.max-w-\[12rem\] { max-width: 12rem; }
.max-w-\[220px\] { max-width: 220px; }
.min-w-\[720px\] { min-width: 720px; }
.min-w-\[44rem\] { min-width: 44rem; }
.min-h-\[7rem\]  { min-height: 7rem; }

/* Position & Sonstiges */
.top-10    { top: calc(var(--spacing) * 10); }
.top-16    { top: calc(var(--spacing) * 16); }
.bottom-10 { bottom: calc(var(--spacing) * 10); }
.bottom-16 { bottom: calc(var(--spacing) * 16); }
.bottom-36 { bottom: calc(var(--spacing) * 36); }
.left-0\.5  { left: calc(var(--spacing) * 0.5); }
.right-0\.5 { right: calc(var(--spacing) * 0.5); }
.z-\[55\]   { z-index: 55; }
.opacity-30 { opacity: .3; }
.border-t-2 { border-top-width: 2px; }
.border-l-2 { border-left-width: 2px; }
.border-primary\/50 { border-color: hsl(var(--primary) / 0.5); }

@media (min-width: 640px) {
  .sm\:w-56 { width: calc(var(--spacing) * 56); }
}
@media (min-width: 1024px) {
  .lg\:top-12    { top: calc(var(--spacing) * 12); }
  .lg\:bottom-12 { bottom: calc(var(--spacing) * 12); }
  .lg\:bottom-24 { bottom: calc(var(--spacing) * 24); }
}


/* ============================================================
   Design Tokens (aus React-UI-Demo übernommen)
   ============================================================ */
:root {
  /* ── Mobile Navigationsleiste ──────────────────────────────────────────────
     --extr-bottomnav-pb: unterer Innenabstand der Leiste. Von der Safe Area
       (Home-Indikator) wird der größere Teil des 0.75rem-Innenabstands der
       Einträge abgezogen, damit die Symbolzeile nicht zu hoch schwebt.
       Ohne Safe Area (Browser/Desktop) ist env() = 0. */
  --extr-bottomnav-pb: max(env(safe-area-inset-bottom, 0px) - 1.25rem, 0.25rem);

  /* ── Orbit / Am Zehnhoff-Söns – Markenfarben (HSL-Channels für hsl(var(--x)) Syntax) ── */
  /* #048072 */ --primary:            173 94% 26%;
  /* #048072 */ --primary-hsl:        hsl(173, 94%, 26%);
                --primary-foreground: 0 0% 100%;
  /* #048172 */ --primary-strong:     173 94% 26%; /* Fläche unter weißer Schrift, ≥ 4,5:1 (UI-Audit DARK-02) */
  /* #f6f9f8 */ --background:         168 16% 97%;
  /* #f6f9f8 */ --background-hsl:     hsl(168, 16%, 97%);
  /* #1d2a2e */ --foreground:         190 22% 14%;
  /* #ffffff */ --card:               0 0% 100%;
  /* #1d2a2e */ --card-foreground:    190 22% 14%;
  /* #1e3834 */ --secondary:          170 30% 17%;
  /* #1e3834 */ --secondary-hsl:      hsl(170, 30%, 17%);
                --secondary-foreground: 0 0% 100%;
  /* #eef4f1 */ --muted:              160 18% 95%;
  /* #5f6b6e */ --muted-foreground:   190 8% 40%;
  /* cool   */ --border:             168 18% 90%;
  /* #048072 */ --accent:             173 94% 26%;
  /* #d4183d */ --destructive:        350 73% 46%;
                --destructive-foreground: 0 0% 100%;

  /* Status-Töne für Hinweise, Pillen und Chips (UI-Audit CODE-08): Fläche und
     Schrift, im Dunkel-Scope umgesetzt — statt fester Hex-Werte im Partial.
     Nutzung ohne eigenen Alpha-Zusatz: background: hsl(var(--tone-warn-bg)). */
  /* #fffbeb */ --tone-warn-bg:       48 100% 96%;
  /* #92400e */ --tone-warn-fg:       23 83% 31%;
  /* #fcd34d */ --tone-warn-border:   46 97% 65%;
  /* #dcfce7 */ --tone-ok-bg:         141 84% 93%;
  /* #15803d */ --tone-ok-fg:         142 72% 29%;
  /* #fee2e2 */ --tone-bad-bg:        0 93% 94%;
  /* #b91c1c */ --tone-bad-fg:        0 74% 42%;
  /* #86efac */ --tone-ok-border:    142 77% 73%;   /* Rahmen ok/bad/info (UI-Audit DARK-03/04) */
  /* #fca5a5 */ --tone-bad-border:   0 94% 82%;
  /* #dbeafe */ --tone-info-bg:      214 95% 93%;
  /* #1d4ed8 */ --tone-info-fg:      224 76% 48%;
  /* #93c5fd */ --tone-info-border:  213 94% 78%;

  /* #ffffff */ --sidebar-bg:         0 0% 100%;
                --sidebar-border:     168 18% 90%;

  --radius:   1rem;
  /* Elevations-System (teal-getönt; im Dark-Scope gedämpft überschrieben) */
  --extr-shadow-sm: 0 1px 2px hsl(190 22% 14% / 0.05), 0 1px 3px hsl(190 22% 14% / 0.07);
  --extr-shadow-md: 0 2px 6px hsl(173 40% 18% / 0.08), 0 8px 20px hsl(173 40% 18% / 0.10);
  --extr-shadow-lg: 0 12px 32px hsl(173 40% 18% / 0.16);
  --font-sans: 'Inter', 'SF Pro Display', system-ui, -apple-system, sans-serif;
}

/* ============================================================
   Base
   ============================================================ */
body.extr-body {
  font-family: var(--font-sans);
  background-color: hsl(var(--background));   /* near-white, faint teal */
  color: hsl(var(--foreground));               /* dark slate */
  margin: 0;
  min-height: 100vh;
  -webkit-font-smoothing: antialiased;
}

/* ============================================================
   Shell Layout
   ============================================================ */
.extr-shell {
  display: flex;
  min-height: 100vh;
}

/* ---- Sidebar ---- */
.extr-sidebar {
  display: none; /* Mobile: hidden */
  width: 256px;
  flex-shrink: 0;
  background: hsl(var(--sidebar-bg));
  border-right: 1px solid hsl(var(--sidebar-border));
  flex-direction: column;
  position: fixed;
  top: 0;
  left: 0;
  height: 100vh;
  z-index: 40;
  overflow-y: auto;
}

@media (min-width: 1024px) {
  .extr-sidebar { display: flex; }
  .extr-main { padding-left: 256px; padding-bottom: 0; }
}

.extr-sidebar-logo {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 1.5rem;
  border-bottom: 1px solid hsl(var(--sidebar-border));
}

.extr-logo-icon {
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 9999px;
  background: hsl(var(--primary) / 0.1);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--primary-hsl);
  flex-shrink: 0;
}

.extr-logo-icon svg { width: 1.25rem; height: 1.25rem; }

.extr-logo-name {
  font-weight: 600;
  font-size: 0.9375rem;
  color: hsl(var(--foreground));
}
.extr-logo-sub {
  font-size: 0.75rem;
  color: hsl(var(--muted-foreground));
}

/* Sidebar User */
.extr-sidebar-user {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 1rem 1.5rem;
  border-bottom: 1px solid hsl(var(--sidebar-border));
}

.extr-sidebar-user-info { flex: 1; min-width: 0; }
.extr-sidebar-user-name {
  font-size: 0.875rem;
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.extr-sidebar-user-role {
  font-size: 0.75rem;
  color: hsl(var(--muted-foreground));
}

/* Sidebar Nav */
.extr-sidebar-nav {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 1rem;
  display: flex;
  flex-direction: column;
  gap: 0.125rem;
}
/* Dezente Zwischenüberschriften in der Seitenleisten-Navigation */
.extr-nav-heading {
  font-size: 0.6875rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: hsl(var(--muted-foreground));
  opacity: 0.65;
  padding: 0.75rem 0.75rem 0.2rem;
}

.extr-nav-item {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.65rem 1rem;
  border-radius: var(--radius);
  font-size: 0.875rem;
  font-weight: 500;
  text-decoration: none;
  color: hsl(var(--muted-foreground));
  transition: background 0.15s, color 0.15s;
}

.extr-nav-item:hover {
  background: hsl(var(--muted));
  color: hsl(var(--foreground));
}

.extr-nav-item--active {
  background: hsl(var(--primary) / 0.1);
  color: var(--primary-hsl);
}

.extr-nav-item--logout {
  color: hsl(var(--muted-foreground));
}
.extr-nav-item--logout:hover {
  background: hsl(0 84% 60% / 0.1);
  color: hsl(0, 84%, 60%);
}

.extr-nav-icon { width: 1.25rem; height: 1.25rem; flex-shrink: 0; }
/* Menütext kürzt mit „…", damit Icon und Badge ihre Breite behalten. */
.extr-nav-label { min-width: 0; flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Indikator-Badge (Sidebar). flex-shrink:0 + nowrap: ein langer Menütext darf das
   Badge nicht auf seine Mindestbreite drücken — sonst ragt „99+" aus dem Kreis. */
.extr-nav-badge {
  margin-left: auto;
  flex-shrink: 0;
  white-space: nowrap;
  min-width: 1.25rem;
  height: 1.25rem;
  padding: 0 0.375rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 9999px;
  background: hsl(0 84% 60%);
  color: #fff;
  font-size: 0.6875rem;
  font-weight: 700;
  line-height: 1;
  box-shadow: 0 0 0 2px hsl(var(--sidebar-background, var(--background)));
}
.extr-nav-badge.hidden { display: none; }
/* Warn-Indikator (2026-09-21): ein offener Vorgang verlangt Handeln — Krankmeldung trifft
   Schichtplan, Wachdienst mit Vorkommnissen. Amber statt Rot, mit Warnzeichen vor der Zahl;
   gesetzt von layout-shell.php beim Rendern und von app.js beim Pollen (.is-warn). */
.extr-nav-badge.is-warn,
.extr-bottom-nav-badge.is-warn,
.extr-quick-badge.is-warn { background: #d97706; }
.extr-nav-badge.is-warn::before,
.extr-bottom-nav-badge.is-warn::before { content: "!"; margin-right: 0.15rem; font-weight: 800; }

/* Sidebar Footer */
.extr-sidebar-footer {
  padding: 1rem;
  border-top: 1px solid hsl(var(--sidebar-border));
}
/* Profil-Block sitzt jetzt im Footer (über Abmelden): kompakt, ohne eigene Trennlinie */
.extr-sidebar-footer .extr-sidebar-user {
  padding: 0.5rem;
  border-bottom: none;
  margin-bottom: 0.5rem;
}
.extr-sidebar-version {
  font-size: 0.7rem;
  color: hsl(var(--muted-foreground));
  text-align: center;
  margin-top: 0.5rem;
}

/* ---- Main ---- */
.extr-main {
  flex: 1;
  min-height: 100vh;
  /* Platz für die fixierte Bottom-Nav. Die feste Reserve von 5rem war zu knapp:
     die Leiste ist im Browser bereits ~87px hoch und in der PWA mit Safe Area
     ~97px – bei zweizeiligen Beschriftungen noch mehr. Dadurch lag das letzte
     Element einer Seite (z. B. die Kachel „Weitere") unter der Navigation.
     app.js misst die Leiste und schreibt --extr-bottomnav-h (Höhe + 1rem Luft);
     der Fallback greift, solange das Skript noch nicht gelaufen ist. */
  padding-bottom: var(--extr-bottomnav-h, calc(6.5rem + env(safe-area-inset-bottom, 0px)));
  overflow-x: clip; /* clip statt hidden: bricht position:sticky der Header nicht */
  width: 100%;
  min-width: 0;
}

/* Desktop: keine Bottom-Nav → keine Reserve. Muss hier stehen (nach der
   Basisregel) und die Variable setzen, weil die frühere Media-Query weiter
   oben im Stylesheet bei gleicher Spezifität von der Basisregel überstimmt
   wurde und deshalb wirkungslos blieb. */
@media (min-width: 1024px) {
  .extr-main { --extr-bottomnav-h: 0px; padding-bottom: 0; }
}

/* Inhalts-Container (max. 1845px, linksbündig) */
.extr-content,
.extr-container {
  width: 100%;
  max-width: 1845px;
  margin-left: 0;
  margin-right: auto;
  padding-left: 1rem;
  padding-right: 1rem;
}

@media (min-width: 1024px) {
  .extr-content,
  .extr-container {
    padding-left: 1.5rem;
    padding-right: 1.5rem;
  }
}

/* Vollbreiter Header-Hintergrund; Inhalt in .extr-content */
/* ---- PWA: Statusleiste (Uhrzeit, Batterie) nicht aussparen ----
   Mit viewport-fit=cover und status-bar-style „black-translucent" reicht das
   App-Fenster bis unter die Statusleiste. Ohne Ausgleich läge der Inhalt unter
   der Uhr. Die obersten Elemente ziehen den Hintergrund deshalb bis an den
   Bildschirmrand und rücken ihren Inhalt um die Safe-Area ein. Im Browser und
   auf dem Desktop ist env(safe-area-inset-top) = 0 — dort ändert sich nichts. */
.extr-body { padding-left: env(safe-area-inset-left, 0px); padding-right: env(safe-area-inset-right, 0px); }


.extr-header-bar {
  position: sticky;
  top: 0;
  z-index: 40;
  padding-top: env(safe-area-inset-top, 0px);
  background-color: rgba(255, 255, 255, 0.8);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid hsl(var(--border));
  width: 100%;
}

/* Fallback: ohne Blur-Unterstützung deckend weiß, damit es lesbar bleibt */
@supports not ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
  .extr-header-bar {
    background-color: #fff;
  }
}

/* Dashboard-Willkommensbereich */
.extr-dashboard-hero {
  --extr-hero-grad: linear-gradient(120deg, #035e52 0%, #048072 55%, #06a890 100%);
  position: relative;
  background: var(--extr-hero-grad);
  /* Hero füllt in der PWA auch den Bereich hinter der Statusleiste (s. o.);
     der Inhalt rückt entsprechend nach unten (Basis: Tailwind pt-6 = 1.5rem). */
  padding-top: calc(1.5rem + env(safe-area-inset-top, 0px));
}
@media (min-width: 1024px) {
  /* Desktop: Hero liegt mit Abstand im Layout, kein Safe-Area-Ausgleich nötig. */
  .extr-dashboard-hero { padding-top: 1.5rem; }
}
/* Standort-Hintergrundbild als echtes <img class="extr-hero-photo"> (erstes Kind), NICHT
   als CSS-Hintergrund: ein dynamisch gesetztes Hintergrundbild (CSS-Variable ODER direkt,
   per JS-setProperty / innerHTML-Injektion) malt Chromium teils erst nach einem Reload.
   Ein echtes <img> malt zuverlässig. Darüber die 15%-Gradient-Maske via ::after. */
.extr-hero-photo {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; border-radius: inherit; z-index: 0;
}
.extr-dashboard-hero.has-photo::after {
  content: ""; position: absolute; inset: 0; z-index: 1;
  background: var(--extr-hero-grad);
  opacity: 0.85;
  border-radius: inherit;
}
.extr-dashboard-hero.has-photo > *:not(.extr-hero-photo) { position: relative; z-index: 2; }

/* Der Inhaltsbereich kann mobil per negativem Rand unter den Hero gezogen
   werden. Ohne eigene Ebene malt der positionierte Hero (bzw. seine
   Foto-Maske ::after) über die erste Karte. Der Hero bekommt darum eine
   eigene Stacking-Ebene, der Inhalt liegt darüber. */
.extr-dashboard-hero { z-index: 0; }
.extr-dashboard-body { position: relative; z-index: 1; }

/* ============================================================
   News-Artikel Detailansicht – Fließtext-Typografie
   ============================================================ */
.nd-article-body h1,
.nd-article-body h2,
.nd-article-body h3,
.nd-article-body h4 {
  color: hsl(var(--foreground));
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.25;
}

.nd-article-body h1 { font-size: 2rem;    margin-top: 2.5rem; margin-bottom: 0.875rem; }
.nd-article-body h2 { font-size: 1.5rem;  margin-top: 2.25rem; margin-bottom: 0.75rem;
                      padding-bottom: 0.4rem;
                      border-bottom: 2px solid hsl(var(--border)); }
.nd-article-body h3 { font-size: 1.125rem; margin-top: 1.75rem; margin-bottom: 0.5rem; font-weight: 600; }
.nd-article-body h4 { font-size: 1rem;    margin-top: 1.5rem;  margin-bottom: 0.375rem; font-weight: 600; }

/* Absätze, Listen, Links, Zitate, Bilder. Muss ungelayert hier stehen: `prose`
   liegt in Tailwinds `@layer utilities` und verliert gegen den Reset oben
   (p/ul/ol/li { margin:0; padding:0 }, ul/ol { list-style:none }) — Absätze
   klebten aneinander, Listen hatten keine Punkte. */
.nd-article-body p { margin: 0 0 1.25rem; line-height: 1.75; }
.nd-article-body ul,
.nd-article-body ol { margin: 0 0 1.25rem; padding-left: 1.5rem; }
.nd-article-body ul { list-style: disc; }
.nd-article-body ol { list-style: decimal; }
.nd-article-body li { line-height: 1.625; }
.nd-article-body li + li { margin-top: 0.375rem; }
.nd-article-body li > ul,
.nd-article-body li > ol { margin: 0.375rem 0 0; }
.nd-article-body li::marker { color: hsl(var(--muted-foreground)); }
.nd-article-body a { color: hsl(var(--primary)); text-decoration: underline; text-underline-offset: 2px; }
.nd-article-body strong,
.nd-article-body b { font-weight: 600; color: hsl(var(--foreground)); }
.nd-article-body blockquote { margin: 1.5rem 0; padding-left: 1rem; border-left: 4px solid hsl(var(--primary));
                              font-style: italic; color: hsl(var(--muted-foreground)); }
.nd-article-body img { border-radius: 0.75rem; margin: 1.5rem 0; }

/* Erstes Element braucht keinen Abstand nach oben, letztes keinen nach unten */
.nd-article-body > *:first-child { margin-top: 0; }
.nd-article-body > *:last-child { margin-bottom: 0; }

/* Eingebettete Bildergalerie im Beitrag (Summernote-Button „Bildergalerie einfügen").
   Der HTML-Sanitizer lässt nur eine Property-Allowlist im style-Attribut durch —
   das Layout darf deshalb nicht an Inline-Styles hängen, sondern kommt über die Klasse.
   Gilt in News-/Wissen-Detail UND im Editor (Summernote rendert im selben Dokument). */
.news-embed-gallery {
  display: flex;
  gap: 10px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  padding: 6px 0;
  margin: 16px 0;
}
.news-embed-gallery img,
.nd-article-body .news-embed-gallery img,
.wd-prose .news-embed-gallery img {
  flex: 0 0 auto;
  width: min(85%, 520px);
  max-height: 360px;
  object-fit: cover;
  scroll-snap-align: center;
  border-radius: 12px;
  margin: 0;
}

.extr-page {
  max-width: 1845px;
  margin-left: 0;
  margin-right: auto;
  padding: 1.5rem 1rem;
}

@media (min-width: 1024px) {
  .extr-page { padding: 2rem 2rem; }
}

/* ---- Bottom Nav (Mobile) ---- */
/* Schwebende Navigation im Glas-Look.
   Die Leiste klebt nicht mehr am Rand, sondern schwebt als freistehende Pille
   über dem Inhalt: Weichzeichner plus kräftigere Farben lassen den Inhalt
   durchscheinen, eine helle Innenkante wirkt als Lichtreflex, zwei weiche
   Schattenlagen heben die Pille ab. Farben kommen aus den Design-Tokens des
   Projekts, der Dunkelmodus wird weiter unten nachgezogen. */
.extr-bottom-nav {
  display: flex;
  justify-content: center;
  position: fixed;
  left: 0;
  right: 0;
  /* Abstand zum unteren Rand; auf Geräten mit Home-Indikator entsprechend mehr. */
  bottom: max(env(safe-area-inset-bottom, 0px) - 0.75rem, 1rem);
  /* Unter den Overlays (z-index ab 50): sonst deckt die Leiste die Fußzeile
     eines Modals ab, weil sie im DOM nach dem Seiteninhalt steht. */
  z-index: 45;
  /* Seitlicher Rand inkl. Sicherheitsbereich (Notch im Querformat). */
  padding: 0 max(0.875rem, env(safe-area-inset-left, 0px), env(safe-area-inset-right, 0px));
  pointer-events: none;   /* nur die Pille selbst nimmt Eingaben an */
}

.extr-bottom-nav-pill {
  position: relative;   /* Bezugsrahmen der gleitenden Kapsel */
  pointer-events: auto;
  display: flex;
  align-items: stretch;
  gap: 0.125rem;
  width: 100%;
  max-width: 27rem;
  padding: 0.375rem;
  border-radius: 1.625rem;
  background: hsl(var(--background) / 0.62);
  -webkit-backdrop-filter: blur(22px) saturate(180%);
  backdrop-filter: blur(22px) saturate(180%);
  border: 1px solid hsl(0 0% 100% / 0.55);
  box-shadow:
    0 1px 0 hsl(0 0% 100% / 0.7) inset,
    0 -1px 0 hsl(0 0% 0% / 0.03) inset,
    0 10px 30px hsl(0 0% 0% / 0.16),
    0 2px 8px hsl(0 0% 0% / 0.10);
}

/* Ohne Weichzeichner (ältere Browser) und bei „Transparenz reduzieren“ wird die
   Fläche deckend – sonst wäre die Leiste über hellem Inhalt schlecht lesbar. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .extr-bottom-nav-pill { background: hsl(var(--background) / 0.97); }
}
@media (prefers-reduced-transparency: reduce) {
  .extr-bottom-nav-pill {
    background: hsl(var(--background) / 0.97);
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }
}

@media (min-width: 1024px) {
  .extr-bottom-nav { display: none; }
}

.extr-bottom-nav-item {
  flex: 1;
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 0.5rem 0.25rem 0.4375rem;
  border-radius: 1.3125rem;
  text-decoration: none;
  color: hsl(var(--muted-foreground));
  font-size: 0.6875rem;
  gap: 0.25rem;
  transition: color 0.15s, background 0.25s ease;
}

/* Der aktive Eintrag trägt nur noch die Farbe – die Kapsel darunter ist ein
   eigenes Element (siehe .extr-bottom-nav-slider), damit sie beim Wechsel von
   einem Eintrag zum nächsten gleiten kann. */
.extr-bottom-nav-item--active { color: var(--primary-hsl); }
.extr-bottom-nav-item:active { transform: scale(0.97); }

/* Gleitende Kapsel: Position und Breite setzt app.js an den echten Maßen des
   aktiven Eintrags – so passt sie auch bei unterschiedlich breiten Texten. */
.extr-bottom-nav-slider {
  position: absolute;
  top: 0.375rem;
  bottom: 0.375rem;
  left: 0;
  width: 0;
  border-radius: 1.3125rem;
  background: hsl(0 0% 100% / 0.82);
  box-shadow: 0 1px 0 hsl(0 0% 100% / 0.9) inset, 0 2px 6px hsl(0 0% 0% / 0.10);
  transform: translateX(0);
  opacity: 0;
  pointer-events: none;
  transition: transform 0.42s cubic-bezier(0.34, 1.28, 0.42, 1),
              width 0.42s cubic-bezier(0.34, 1.28, 0.42, 1),
              opacity 0.2s ease;
}
.extr-bottom-nav-slider.is-on { opacity: 1; }
/* Beim ersten Zeichnen ohne Bewegung an die richtige Stelle setzen. */
.extr-bottom-nav-slider.is-instant { transition: none; }
/* Symbol und Text liegen über der Kapsel. */
.extr-bottom-nav-item { position: relative; z-index: 1; }
@media (prefers-reduced-motion: reduce) {
  .extr-bottom-nav-slider { transition: opacity 0.2s ease; }
}

.extr-bottom-nav-icon { width: 1.25rem; height: 1.25rem; }

/* Indikator-Badge (Mobile-Nav, über dem Icon) */
.extr-bottom-nav-icon-wrap {
  position: relative;
  display: inline-flex;
}
.extr-bottom-nav-badge {
  position: absolute;
  top: -0.4rem;
  left: 60%;
  white-space: nowrap;
  min-width: 1.05rem;
  height: 1.05rem;
  padding: 0 0.3rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 9999px;
  background: hsl(0 84% 60%);
  color: #fff;
  font-size: 0.625rem;
  font-weight: 700;
  line-height: 1;
  box-shadow: 0 0 0 2px #fff;
}
.extr-bottom-nav-badge.hidden { display: none; }

/* Indikator-Badge (Dashboard-Schnellaktionen) */
.extr-quick-badge {
  position: absolute;
  top: 0.5rem;
  right: 0.5rem;
  white-space: nowrap;
  min-width: 1.25rem;
  height: 1.25rem;
  padding: 0 0.375rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 9999px;
  background: hsl(0 84% 60%);
  color: #fff;
  font-size: 0.6875rem;
  font-weight: 700;
  line-height: 1;
  box-shadow: 0 0 0 2px #fff;
}
.extr-quick-badge.hidden { display: none; }

/* ── Mobiles „Weitere"-Overlay (Schnellaktionen-Überlauf) ── */
/* In @layer components: das Blatt trägt im Markup `hidden lg:hidden` — beide
   Utilities müssen den Baustein schlagen können. Ungeschichtet gewänne
   `display:flex`, und ein am Handy geöffnetes Blatt bliebe beim Drehen aufs
   Querformat über der Schreibtisch-Ansicht liegen (samt Scroll-Sperre). */
@layer components {
  .extr-more-overlay {
    position: fixed; inset: 0; z-index: 70;
    display: flex; align-items: flex-end;
    background: rgb(0 0 0 / 0.5);
    backdrop-filter: blur(2px);
  }
}
.extr-more-overlay.hidden { display: none; }
.extr-more-sheet {
  width: 100%;
  max-height: 75vh;
  background: #fff;
  border-radius: 1.25rem 1.25rem 0 0;
  box-shadow: 0 -8px 30px -8px rgb(0 0 0 / 0.25);
  display: flex; flex-direction: column;
  overflow: hidden;
  animation: extr-more-up 0.18s ease-out;
}
@keyframes extr-more-up { from { transform: translateY(100%); } to { transform: translateY(0); } }
.extr-more-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 1rem 1.25rem;
  border-bottom: 1px solid hsl(var(--border));
  flex-shrink: 0;
}
.extr-more-list { overflow-y: auto; padding: 0.5rem; padding-bottom: calc(0.5rem + env(safe-area-inset-bottom)); }
.extr-more-item {
  display: flex; align-items: center; gap: 0.75rem;
  padding: 0.75rem 0.75rem;
  border-radius: 0.75rem;
  color: hsl(var(--foreground));
  transition: background 0.15s;
}
.extr-more-item:hover, .extr-more-item:active { background: hsl(var(--muted)); }
.extr-more-ic {
  width: 2.25rem; height: 2.25rem; flex-shrink: 0;
  border-radius: 0.625rem;
  background: hsl(var(--primary) / 0.1);
  display: inline-flex; align-items: center; justify-content: center;
}
.extr-more-badge {
  flex-shrink: 0; white-space: nowrap;
  min-width: 1.25rem; height: 1.25rem; padding: 0 0.375rem;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 9999px;
  background: hsl(0 84% 60%); color: #fff;
  font-size: 0.6875rem; font-weight: 700; line-height: 1;
}
.extr-more-badge.hidden { display: none; }
body.extr-more-open { overflow: hidden; }

/* Das Sheet steht im Markup innerhalb von .extr-dashboard-body — und die spannt
   mit position:relative + z-index:1 einen eigenen Stapelkontext auf. Darin ist
   das z-index:70 des Overlays gegenüber der Bottom-Nav (z-index:45) wirkungslos,
   weil verglichen wird, was der Kontext insgesamt wiegt (1 gegen 45): die Leiste
   lag über dem geöffneten Sheet und schnitt die untersten Einträge ab. Solange
   das Sheet offen ist, hebt sich der Kontext deshalb über die Leiste. */
body.extr-more-open .extr-dashboard-body { z-index: 60; }

/* ============================================================
   Avatar
   ============================================================ */
.extr-avatar {
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 9999px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  font-weight: 600;
  font-size: 0.875rem;
  flex-shrink: 0;
  text-transform: uppercase;
}

.extr-avatar--lg {
  width: 4rem;
  height: 4rem;
  font-size: 1.25rem;
}

.extr-avatar--xl {
  width: 5rem;
  height: 5rem;
  font-size: 1.5rem;
}

/* Tailwind bg-* Klassen für Avatar-Farben */
.bg-blue-500   { background-color: #3b82f6; }
.bg-violet-500 { background-color: #8b5cf6; }
.bg-emerald-500{ background-color: #10b981; }
.bg-rose-500   { background-color: #f43f5e; }
.bg-amber-500  { background-color: #f59e0b; }
.bg-teal-500   { background-color: #14b8a6; }
.bg-indigo-500 { background-color: #6366f1; }
.bg-pink-500   { background-color: #ec4899; }

/* ============================================================
   Page Header
   ============================================================ */
.extr-page-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 1.5rem;
  flex-wrap: wrap;
  gap: 0.75rem;
}

.extr-page-header-left { display: flex; align-items: center; gap: 0.75rem; }
.extr-page-title { font-size: 1.375rem; font-weight: 700; color: hsl(var(--foreground)); margin: 0; }
.extr-breadcrumb {
  display: flex;
  align-items: center;
  gap: 0.375rem;
  font-size: 0.8125rem;
  color: hsl(var(--muted-foreground));
}
.extr-breadcrumb a { color: hsl(var(--muted-foreground)); text-decoration: none; }
.extr-breadcrumb a:hover { color: hsl(var(--foreground)); }

/* ============================================================
   Cards
   ============================================================ */
.extr-card {
  background: hsl(var(--card));
  border: 1px solid hsl(var(--border));
  border-radius: calc(var(--radius) * 1.5);
  overflow: hidden;
}

.extr-card-header {
  padding: 1rem 1.25rem 0.75rem;
  border-bottom: 1px solid hsl(var(--border));
}

.extr-card-title {
  font-size: 0.9375rem;
  font-weight: 600;
  color: hsl(var(--foreground));
}

.extr-card-body { padding: 1.25rem; }

/* ============================================================
   Buttons
   ============================================================ */
/* In @layer components: Utility-Klassen im selben class-Attribut
   (bg-muted/40, font-mono, pr-20 …) sollen die Vorgaben überschreiben
   können. tailwind.css meldet die Layer-Reihenfolge an. */
@layer components {
  .extr-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    padding: 0.5rem 1rem;
    /* rounded-lg dieses Builds (0.75rem) — die Radiusvariable (1rem) ist für
       Karten gedacht. */
    border-radius: var(--radius-lg, 0.75rem);
    /* Achtung: auf <button> bleiben font-size/-weight WIRKUNGSLOS —
       `button, input, select, textarea { font: inherit }` steht oben
       ungeschichtet und schlägt jede Regel aus einem @layer. Auf <a> greifen
       sie. Das war mit der alten Kette `text-sm font-medium` genauso; wer es
       ändern will, muss den Reset in einen Layer ziehen. */
    font-size: 0.875rem;
    font-weight: 500;
    /* Kein Rahmen in der Grundform — die Primärkette im Bestand hatte keinen.
       Nur .extr-btn--outline setzt einen, sonst wären alle Knöpfe 2 px höher. */
    border: 0;
    line-height: calc(1.25 / 0.875);
    cursor: pointer;
    text-decoration: none;
    transition: background 0.15s, color 0.15s, border-color 0.15s, opacity 0.15s, transform 0.12s, box-shadow 0.15s;
    white-space: nowrap;
  }
  .extr-btn svg, .extr-btn i { width: 1rem; height: 1rem; }
  .extr-btn:active { transform: scale(0.97); }
  .extr-btn--primary:hover, .extr-btn--danger:hover, .extr-btn--success:hover { box-shadow: var(--extr-shadow-md); }

  .extr-btn--primary {
    background: hsl(var(--primary-strong));
    color: hsl(var(--primary-foreground));
  }
  .extr-btn--primary:hover { filter: brightness(.93); }

  .extr-btn--outline {
    background: transparent;
    border: 1px solid hsl(var(--border));
    color: hsl(var(--foreground));
  }
  .extr-btn--outline:hover { background: hsl(var(--muted)); }
  /* Deckend weiß statt durchsichtig — für Leisten auf gemustertem Grund
     (im Bestand die Kette mit zusätzlichem bg-white). */
  .extr-btn--solid { background: hsl(var(--card)); }

  .extr-btn--ghost {
    background: transparent;
    color: hsl(var(--muted-foreground));
  }
  .extr-btn--ghost:hover { background: hsl(var(--muted)); color: hsl(var(--foreground)); }

  .extr-btn--danger {
    /* red-600 wie im Bestand (bg-red-600), nicht red-500. */
    background: var(--color-red-600, hsl(0 72% 51%));
    color: #fff;
  }
  .extr-btn--danger:hover { opacity: 0.9; }

  /* Bestätigende Aktion — Einbuchen, Freigeben, Abschließen (UI-Audit BTN-05).
     green-700: Weiß darauf ≈ 5:1. Das green-600 der ersetzten Ketten kam nur auf ≈ 3,3:1 (WCAG AA verlangt 4,5:1). */
  .extr-btn--success {
    background: var(--color-green-700, hsl(142 72% 29%));
    color: #fff;
  }
  .extr-btn--success:hover { opacity: 0.9; }

  .extr-btn--sm { padding: 0.375rem 0.75rem; font-size: 0.8125rem; gap: 0.375rem; }
  .extr-btn--icon { padding: 0.5rem; }
  /* Deckt die Kette „disabled:opacity-60 disabled:cursor-not-allowed" mit ab. */
  .extr-btn:disabled,
  .extr-btn[disabled],
  .extr-btn.is-disabled { opacity: 0.6; cursor: not-allowed; }
  .extr-btn:disabled:active { transform: none; }
  /* Breite Knöpfe (Modal-Fuß, mobile Formulare). */
  .extr-btn--block { width: 100%; }
}

/* ============================================================
   Form Elements
   ============================================================ */
/* In @layer components: Utility-Klassen im selben class-Attribut
   (bg-muted/40, font-mono, pr-20 …) sollen die Vorgaben überschreiben
   können. tailwind.css meldet die Layer-Reihenfolge an. */
@layer components {
  .extr-form-group { margin-bottom: 1rem; }
  .extr-label {
    display: block;
    font-size: var(--text-sm, 0.875rem);
    line-height: calc(1.25 / 0.875);
    font-weight: 500;
    margin-bottom: 0.25rem;   /* mb-1 wie im Bestand */
    color: hsl(var(--foreground));
  }
  /* Zweizeiliger Abstand, wo das Feld Luft braucht (mb-2 im Bestand). */
  .extr-label--roomy { margin-bottom: 0.5rem; }
  .extr-label--required::after { content: ' *'; color: hsl(0 84% 60%); }

  .extr-input,
  .extr-select,
  .extr-textarea {
    width: 100%;
    padding: 0.5rem 0.75rem;
    border: 1px solid hsl(var(--border));
    /* Exakt die Kette, die der Bestand hundertfach kopiert hatte (BTN-04):
       rounded-lg (0.75rem in diesem Build), durchsichtiger Grund, Fokusring. */
    border-radius: var(--radius-lg, 0.75rem);
    font-size: 0.875rem;
    color: hsl(var(--foreground));
    background: transparent;
    transition: border-color 0.15s, box-shadow 0.15s;
    font-family: inherit;
  }

  .extr-input:focus,
  .extr-select:focus,
  .extr-textarea:focus {
    outline: none;
    box-shadow: 0 0 0 2px hsl(var(--primary) / 0.2);
  }

  .extr-input:disabled,
  .extr-select:disabled,
  .extr-textarea:disabled {
    background: hsl(var(--muted) / 0.4);
    color: hsl(var(--muted-foreground));
    cursor: not-allowed;
  }

  .extr-input::placeholder,
  .extr-textarea::placeholder { color: hsl(var(--muted-foreground)); }

  .extr-input--error { border-color: hsl(0 84% 60%); }
  .extr-error-text { color: hsl(0 84% 60%); font-size: 0.8rem; margin-top: 0.25rem; }

  .extr-textarea { resize: vertical; }
  /* Auswahlfelder trugen im Bestand fast durchweg bg-white. */
  .extr-select { background-color: hsl(var(--card)); appearance: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 0.75rem center; padding-right: 2rem; }
}

/* ============================================================
   Badges
   ============================================================ */
.extr-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  padding: 0.2rem 0.6rem;
  border-radius: 9999px;
  font-size: 0.75rem;
  font-weight: 500;
}
/* Status über die Ton-Token — folgen dem Dunkelmodus (UI-Audit DARK-03) */
.extr-badge--green  { background: hsl(var(--tone-ok-bg));   color: hsl(var(--tone-ok-fg)); }
.extr-badge--red    { background: hsl(var(--tone-bad-bg));  color: hsl(var(--tone-bad-fg)); }
.extr-badge--yellow { background: hsl(var(--tone-warn-bg)); color: hsl(var(--tone-warn-fg)); }
.extr-badge--blue   { background: hsl(var(--tone-info-bg)); color: hsl(var(--tone-info-fg)); }
.extr-badge--gray   { background: hsl(var(--muted));        color: hsl(var(--muted-foreground)); }

/* ============================================================
   Tabs
   ============================================================ */
.extr-tabs {
  border-bottom: 1px solid hsl(var(--border));
  display: flex;
  gap: 0;
  margin-bottom: 1.5rem;
  overflow-x: auto;
}

.extr-tab {
  padding: 0.75rem 1.25rem;
  font-size: 0.875rem;
  font-weight: 500;
  color: hsl(var(--muted-foreground));
  border-bottom: 2px solid transparent;
  cursor: pointer;
  background: none;
  border-top: none;
  border-left: none;
  border-right: none;
  white-space: nowrap;
  transition: color 0.15s, border-color 0.15s;
  text-decoration: none;
  display: block;
}

.extr-tab:hover { color: hsl(var(--foreground)); }
.extr-tab--active { color: var(--primary-hsl); border-bottom-color: var(--primary-hsl); }

.extr-tab-panel { display: none; }
.extr-tab-panel--active { display: block; }

/* ============================================================
   Grid Utilities
   ============================================================ */
.extr-grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }
.extr-grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1rem; }
.extr-grid-4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1rem; }

@media (max-width: 767px) {
  .extr-grid-2, .extr-grid-3, .extr-grid-4 { grid-template-columns: 1fr; }
}
@media (min-width: 768px) and (max-width: 1023px) {
  .extr-grid-3, .extr-grid-4 { grid-template-columns: 1fr 1fr; }
}

/* ============================================================
   Employee Cards
   ============================================================ */
.extr-employee-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 1rem;
}

.extr-employee-card {
  background: hsl(var(--card));
  border: 1px solid hsl(var(--border));
  border-radius: calc(var(--radius) * 1.5);
  padding: 1.25rem;
  text-decoration: none;
  color: hsl(var(--foreground));
  display: flex;
  align-items: flex-start;
  gap: 1rem;
  transition: box-shadow 0.15s, border-color 0.15s, transform 0.15s cubic-bezier(.22,.61,.36,1);
  cursor: pointer;
}

.extr-employee-card:hover {
  border-color: var(--primary-hsl);
  box-shadow: var(--extr-shadow-md);
  transform: translateY(-2px);
}
.extr-employee-card:active { transform: translateY(0) scale(0.995); }

.extr-employee-card-body { flex: 1; min-width: 0; }
.extr-employee-card-name { font-weight: 600; font-size: 0.9375rem; margin-bottom: 0.125rem; }
.extr-employee-card-role { font-size: 0.8125rem; color: hsl(var(--muted-foreground)); margin-bottom: 0.5rem; }
.extr-employee-card-meta { display: flex; align-items: center; gap: 0.5rem; font-size: 0.75rem; color: hsl(var(--muted-foreground)); flex-wrap: wrap; }
.extr-employee-card-meta i { width: 0.875rem; height: 0.875rem; }

/* ============================================================
   Search & Filters
   ============================================================ */
.extr-search-bar {
  display: flex;
  gap: 0.75rem;
  margin-bottom: 1.25rem;
  flex-wrap: wrap;
}

.extr-search-wrap {
  position: relative;
  flex: 1;
  min-width: 200px;
}

.extr-search-wrap i {
  position: absolute;
  left: 0.75rem;
  top: 50%;
  transform: translateY(-50%);
  width: 1rem;
  height: 1rem;
  color: hsl(var(--muted-foreground));
}

.extr-search-input {
  width: 100%;
  padding: 0.5rem 0.75rem 0.5rem 2.25rem;
  border: 1px solid hsl(var(--border));
  border-radius: var(--radius);
  font-size: 0.875rem;
  background: hsl(var(--muted) / 0.5);
  color: hsl(var(--foreground));
  transition: border-color 0.15s;
}
.extr-search-input:focus { outline: none; border-color: var(--primary-hsl); background: hsl(var(--background)); }

/* ============================================================
   Detail: Profile Header
   ============================================================ */
.extr-profile-header {
  background: linear-gradient(135deg, hsl(var(--primary) / 0.08), hsl(var(--background)));
  border: 1px solid hsl(var(--border));
  border-radius: calc(var(--radius) * 1.5);
  padding: 1.5rem;
  margin-bottom: 1.5rem;
}

.extr-profile-header-inner {
  display: flex;
  align-items: flex-start;
  gap: 1.25rem;
  flex-wrap: wrap;
}

.extr-profile-info { flex: 1; min-width: 0; }
.extr-profile-name { font-size: 1.375rem; font-weight: 700; margin: 0 0 0.25rem; }
.extr-profile-role { font-size: 0.9375rem; color: hsl(var(--muted-foreground)); margin: 0 0 0.5rem; }
.extr-profile-meta {
  display: flex;
  gap: 0.75rem;
  flex-wrap: wrap;
  font-size: 0.8125rem;
  color: hsl(var(--muted-foreground));
}
.extr-profile-meta-item { display: flex; align-items: center; gap: 0.25rem; }
.extr-profile-meta-item i { width: 0.875rem; height: 0.875rem; }

.extr-profile-actions { display: flex; gap: 0.5rem; flex-wrap: wrap; }

/* ============================================================
   Detail Info Grid
   ============================================================ */
.extr-detail-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1rem;
}

@media (max-width: 600px) {
  .extr-detail-grid { grid-template-columns: 1fr; }
}

.extr-detail-field { }
.extr-detail-label {
  font-size: 0.75rem;
  font-weight: 500;
  color: hsl(var(--muted-foreground));
  text-transform: uppercase;
  letter-spacing: 0.05em;
  margin-bottom: 0.25rem;
}
.extr-detail-value { font-size: 0.9375rem; color: hsl(var(--foreground)); }
.extr-detail-value--empty { color: hsl(var(--muted-foreground)); font-style: italic; }

/* ============================================================
   Modal
   ============================================================ */
.extr-modal-backdrop {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.5);
  z-index: 100;
  align-items: center;
  justify-content: center;
  padding: 1rem;
  /* Safe-Area (PWA): Die Abdunklung bleibt vollflächig, das Modal selbst rückt
     um Dynamic Island bzw. Home-Indikator ein (s. Block „Safe-Area" unten). */
  padding-top: calc(1rem + env(safe-area-inset-top, 0px));
  padding-bottom: calc(1rem + env(safe-area-inset-bottom, 0px));
}
.extr-modal-backdrop--open { display: flex; }

/* ---- Safe-Area: Modale nicht unter Insel / Home-Indikator ------------------
   Mit viewport-fit=cover reicht das App-Fenster bis an die Bildschirmkanten.
   Overlays liegen als `fixed inset-0` über dem gesamten Bildschirm — Kopf- und
   Fußzeile eines Modals lägen damit unter der Kamera-Insel bzw. der Leiste am
   unteren Rand. Die Overlay-Wurzel wird deshalb oben und unten um die
   Safe-Area eingerückt: absolut positionierte Kinder (das Panel) beziehen sich
   auf deren Padding-Box und rücken automatisch mit. Nur die Abdunklung wird
   wieder auf volle Höhe gezogen, damit kein heller Streifen entsteht.
   Ausgenommen ist .extr-modal-backdrop – dort ist die Wurzel selbst die
   Abdunklung und rückt per Innenabstand ein (s. o.).
   Ohne Safe-Area (Browser, Desktop) ist env() = 0 → alles unverändert. */
[class~="fixed"][class~="inset-0"]:not(.extr-modal-backdrop),
.extr-dlg:not(.extr-modal-backdrop) {
  top: env(safe-area-inset-top, 0px);
  bottom: env(safe-area-inset-bottom, 0px);
}
[class~="fixed"][class~="inset-0"]:not(.extr-modal-backdrop) > [class*="bg-black/"],
.extr-dlg:not(.extr-modal-backdrop) > .extr-dlg-backdrop {
  top: calc(-1 * env(safe-area-inset-top, 0px));
  bottom: calc(-1 * env(safe-area-inset-bottom, 0px));
}
/* Panels, die ihre Höhe inline an der Viewport-Höhe festmachen
   (style="max-height: calc(100vh - 2rem)"), kennen die Safe-Area nicht:
   ohne Korrektur ragen sie über den eingerückten Bereich hinaus. */
[class~="fixed"][class~="inset-0"] [style*="100vh"],
.extr-dlg [style*="100vh"] {
  max-height: calc(100vh - 2rem
                   - env(safe-area-inset-top, 0px)
                   - env(safe-area-inset-bottom, 0px)) !important;
}

.extr-modal {
  background: hsl(var(--background));
  border-radius: calc(var(--radius) * 2);
  padding: 1.5rem;
  width: 100%;
  max-width: 540px;
  /* 100% = Höhe abzüglich der Safe-Area-Abstände des Backdrops */
  max-height: min(90vh, 100%);
  overflow-y: auto;
  box-shadow: 0 20px 60px rgba(0,0,0,0.2);
}

.extr-modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 1.25rem;
}

.extr-modal-title { font-size: 1.125rem; font-weight: 700; }
.extr-modal-close { background: none; border: none; cursor: pointer; color: hsl(var(--muted-foreground)); padding: 0.25rem; border-radius: var(--radius); }
.extr-modal-close:hover { background: hsl(var(--muted)); color: hsl(var(--foreground)); }
.extr-modal-close svg, .extr-modal-close i { width: 1.25rem; height: 1.25rem; }

.extr-modal-footer {
  display: flex;
  justify-content: flex-end;
  gap: 0.75rem;
  margin-top: 1.5rem;
  padding-top: 1rem;
  border-top: 1px solid hsl(var(--border));
}


/* ---- Modal-Panels: Höhe hart begrenzen, Scroll-Bereiche dürfen schrumpfen ---
   Zwei wiederkehrende Fehlerbilder in Overlays (`fixed inset-0` + absolut
   positioniertes Panel):
   1) Ein Flex-Kind mit `flex-1 overflow-y-auto` hat implizit `min-height:auto`
      und schrumpft deshalb NICHT unter seine Inhaltshöhe. Vor allem WebKit
      (iOS/PWA) zieht das Panel dadurch über den Bildschirmrand hinaus – der
      Inhalt scrollt nicht, Kopf-/Fußzeile samt Schließen-Knopf werden
      unerreichbar. `min-height: 0` ist der Standard-Gegengriff.
   2) Panels ohne top/bottom (oder mit einer Klasse, die im vorgebauten
      tailwind.css fehlt) wachsen mit ihrem Inhalt. `max-height: 100%` bezieht
      sich auf die bereits um die Safe-Area eingerückte Overlay-Wurzel und
      deckelt sie zuverlässig.
   Beides schränkt nur ein, was ohnehin passen sollte – Panels, die bereits
   korrekt begrenzt sind, ändern sich nicht. */
[class~="fixed"][class~="inset-0"] [class~="flex-col"] > [class~="flex-1"],
.extr-dlg [class~="flex-col"] > [class~="flex-1"],
.extr-dlg-panel > .extr-dlg-body { min-height: 0; }
[class~="fixed"][class~="inset-0"]:not(.extr-modal-backdrop) > [class~="absolute"]:not([class*="bg-black/"]) {
  max-height: 100%;
}

/* ============================================================
   Toast Notifications
   ============================================================ */
.extr-toasts {
  position: fixed;
  bottom: 5rem;
  right: 1rem;
  z-index: 200;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  pointer-events: none;
}

@media (min-width: 1024px) {
  .extr-toasts { bottom: 1.5rem; }
}

.extr-toast {
  position: relative;
  overflow: hidden;
  background: hsl(var(--foreground));
  color: hsl(var(--background));
  padding: 0.7rem 1rem 0.7rem 0.85rem;
  border-left: 3px solid hsl(var(--primary));
  border-radius: var(--radius);
  font-size: 0.875rem;
  max-width: 340px;
  pointer-events: all;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  box-shadow: var(--extr-shadow-lg);
  animation: extrToastIn 0.26s cubic-bezier(.22,.61,.36,1);
}
.extr-toast-icon { width: 1.05rem; height: 1.05rem; flex-shrink: 0; }
.extr-toast-msg  { flex: 1; min-width: 0; }
.extr-toast-bar  {
  position: absolute; left: 0; bottom: 0; height: 2px; width: 100%;
  background: rgba(255,255,255,0.5); transform-origin: left;
  animation: extrToastBar 3.5s linear forwards;
}
.extr-toast--success { background: hsl(152 56% 30%); border-left-color: hsl(142 71% 58%); }
.extr-toast--error   { background: hsl(0 55% 38%);  border-left-color: hsl(0 84% 66%); }
.extr-toast--info    { background: hsl(var(--foreground)); border-left-color: hsl(var(--primary)); }
.extr-toast--out     { animation: extrToastOut 0.26s ease forwards; }

@keyframes extrToastIn  { from { opacity: 0; transform: translateX(18px); } to { opacity: 1; transform: none; } }
@keyframes extrToastOut { to { opacity: 0; transform: translateX(18px); } }
@keyframes extrToastBar { from { transform: scaleX(1); } to { transform: scaleX(0); } }

/* ============================================================
   Loading Overlay
   ============================================================ */
.extr-loading {
  position: fixed;
  inset: 0;
  background: rgba(255,255,255,0.6);
  z-index: 90;
  display: flex;
  align-items: center;
  justify-content: center;
}

.extr-loading-spinner {
  width: 2.5rem;
  height: 2.5rem;
  border: 3px solid hsl(var(--border));
  border-top-color: var(--primary-hsl);
  border-radius: 9999px;
  animation: spin 0.6s linear infinite;
}

@keyframes spin { to { transform: rotate(360deg); } }

/* ============================================================
   Utilities
   ============================================================ */
.extr-divider { border: none; border-top: 1px solid hsl(var(--border)); margin: 1.25rem 0; }
.extr-text-muted { color: hsl(var(--muted-foreground)); }
.extr-text-sm { font-size: 0.875rem; }
.extr-flex { display: flex; align-items: center; }
.extr-flex-between { display: flex; align-items: center; justify-content: space-between; }
.extr-gap-2 { gap: 0.5rem; }
.extr-gap-3 { gap: 0.75rem; }
.extr-mt-1 { margin-top: 0.25rem; }
.extr-mt-2 { margin-top: 0.5rem; }
.extr-mt-4 { margin-top: 1rem; }
.extr-mb-4 { margin-bottom: 1rem; }
.extr-mb-6 { margin-bottom: 1.5rem; }
.extr-p-4 { padding: 1rem; }
.extr-w-full { width: 100%; }
.extr-hidden { display: none; }

/* Back Button */
.extr-back-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  color: hsl(var(--muted-foreground));
  font-size: 0.875rem;
  text-decoration: none;
  padding: 0.375rem 0;
  background: none;
  border: none;
  cursor: pointer;
  transition: color 0.15s;
}
.extr-back-btn:hover { color: hsl(var(--foreground)); }
.extr-back-btn i { width: 1rem; height: 1rem; }

/* Permissions Table */
.extr-perm-table { width: 100%; border-collapse: collapse; }
.extr-perm-table th, .extr-perm-table td { padding: 0.625rem 0.75rem; text-align: left; border-bottom: 1px solid hsl(var(--border)); font-size: 0.875rem; }
.extr-perm-table th { font-weight: 500; color: hsl(var(--muted-foreground)); }
.extr-toggle { position: relative; display: inline-block; width: 2.5rem; height: 1.375rem; }
.extr-toggle input { opacity: 0; width: 0; height: 0; }
.extr-toggle-slider {
  position: absolute; cursor: pointer; inset: 0;
  background: hsl(var(--border)); border-radius: 9999px; transition: background 0.2s;
}
.extr-toggle-slider::before {
  content: ''; position: absolute;
  width: 1rem; height: 1rem;
  left: 0.1875rem; top: 0.1875rem;
  background: #fff; border-radius: 9999px; transition: transform 0.2s;
}
.extr-toggle input:checked + .extr-toggle-slider { background: var(--primary-hsl); }
.extr-toggle input:checked + .extr-toggle-slider::before { transform: translateX(1.125rem); }

/* Custom Checkbox */
.extr-check {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  vertical-align: middle;
}

.extr-check input {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
  margin: 0;
}

.extr-check-box {
  width: 1.25rem;
  height: 1.25rem;
  border: 2px solid hsl(var(--border));
  border-radius: 0.375rem;
  background: #fff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background-color 0.15s, border-color 0.15s, box-shadow 0.15s;
}

.extr-check-box svg {
  width: 0.875rem;
  height: 0.875rem;
  color: #fff;
  opacity: 0;
  transform: scale(0.75);
  transition: opacity 0.15s, transform 0.15s;
}

.extr-check input:checked + .extr-check-box {
  background: var(--primary-hsl);
  border-color: var(--primary-hsl);
}

.extr-check input:checked + .extr-check-box svg {
  opacity: 1;
  transform: scale(1);
}

.extr-check input:focus-visible + .extr-check-box {
  box-shadow: 0 0 0 3px hsl(var(--primary) / 0.25);
}

.extr-check input:disabled + .extr-check-box {
  opacity: 0.45;
  cursor: not-allowed;
}

.extr-check:has(input:disabled) {
  cursor: not-allowed;
}

/* Team-Chats Zugriffstabelle */
.chat-access-grid {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.chat-access-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 4.5rem 4.5rem;
  gap: 0.75rem;
  align-items: center;
}

.chat-access-row--head {
  padding: 0 0.5rem 0.625rem;
  border-bottom: 1px solid hsl(var(--border));
  font-size: 0.75rem;
  font-weight: 500;
  color: hsl(var(--muted-foreground));
}

.chat-access-row--data {
  padding: 0.5rem;
  border: 1px solid hsl(var(--border));
  border-radius: 0.75rem;
}

.chat-access-col-check {
  display: flex;
  justify-content: center;
  align-items: center;
  text-align: center;
}

/* ============================================================
   Summernote – Design-Anpassungen (Lite-Version)
   ============================================================ */
.note-editor.note-frame {
  border: 1px solid hsl(var(--border)) !important;
  border-radius: 0.5rem !important;
  overflow: hidden;
  box-shadow: none !important;
}
.note-editor.note-frame .note-toolbar {
  background: hsl(var(--muted)) !important;
  border-bottom: 1px solid hsl(var(--border)) !important;
  padding: 4px 6px !important;
}
.note-editor.note-frame .note-editable {
  background: #fff !important;
  color: hsl(var(--foreground)) !important;
  font-family: var(--font-sans) !important;
  font-size: 0.9rem !important;
  line-height: 1.7 !important;
  padding: 1rem !important;
}
/* Formatierung IM Editor sichtbar machen – Tailwind-Preflight entfernt sonst
   Listenpunkte, Überschriftengrößen, Einrückungen etc. im Bearbeitungsbereich. */
.note-editor.note-frame .note-editable h1 { font-size: 1.6rem !important; font-weight: 700 !important; line-height: 1.3 !important; margin: 1.2rem 0 .6rem !important; }
.note-editor.note-frame .note-editable h2 { font-size: 1.35rem !important; font-weight: 700 !important; line-height: 1.3 !important; margin: 1.1rem 0 .5rem !important; }
.note-editor.note-frame .note-editable h3 { font-size: 1.1rem !important; font-weight: 600 !important; margin: 1rem 0 .4rem !important; }
.note-editor.note-frame .note-editable h4 { font-size: 1rem !important; font-weight: 600 !important; margin: .9rem 0 .35rem !important; }
.note-editor.note-frame .note-editable p { margin: 0 0 .75rem !important; }
.note-editor.note-frame .note-editable ul { list-style: disc !important; padding-left: 1.5rem !important; margin: .5rem 0 !important; }
.note-editor.note-frame .note-editable ol { list-style: decimal !important; padding-left: 1.5rem !important; margin: .5rem 0 !important; }
.note-editor.note-frame .note-editable li { margin: .25rem 0 !important; display: list-item !important; }
.note-editor.note-frame .note-editable strong, .note-editor.note-frame .note-editable b { font-weight: 700 !important; }
.note-editor.note-frame .note-editable em, .note-editor.note-frame .note-editable i { font-style: italic !important; }
.note-editor.note-frame .note-editable u { text-decoration: underline !important; }
.note-editor.note-frame .note-editable a { color: var(--primary-hsl) !important; text-decoration: underline !important; }
.note-editor.note-frame .note-editable blockquote { border-left: 3px solid hsl(var(--border)) !important; padding-left: 1rem !important; margin: .75rem 0 !important; color: hsl(var(--muted-foreground)) !important; }
/* Ergänzung: im Editor bislang ungestylte Elemente (h5/h6, Tabellen, Code, Trenner, Bilder) */
.note-editor.note-frame .note-editable h5,
.note-editor.note-frame .note-editable h6 { font-size: .95rem !important; font-weight: 600 !important; margin: .85rem 0 .3rem !important; }
.note-editor.note-frame .note-editable > :first-child { margin-top: 0 !important; }
.note-editor.note-frame .note-editable hr { margin: 1.2rem 0 !important; border: 0 !important; border-top: 1px solid hsl(var(--border)) !important; }
.note-editor.note-frame .note-editable img { display: inline-block !important; max-width: 100% !important; height: auto !important; border-radius: 8px !important; }
.note-editor.note-frame .note-editable table { border-collapse: collapse !important; margin: 0 0 .75rem !important; width: 100% !important; }
.note-editor.note-frame .note-editable th,
.note-editor.note-frame .note-editable td { border: 1px solid hsl(var(--border)) !important; padding: .4rem .6rem !important; }
.note-editor.note-frame .note-editable th { background: hsl(var(--muted)) !important; font-weight: 600 !important; }
.note-editor.note-frame .note-editable code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace !important; font-size: .875em !important; background: hsl(var(--muted)) !important; padding: .1em .35em !important; border-radius: 4px !important; }
.note-editor.note-frame .note-codable { font-family: ui-monospace, SFMono-Regular, Menlo, monospace !important; font-size: .8125rem !important; }
.note-editor.note-frame .note-statusbar {
  background: hsl(var(--muted)) !important;
  border-top: 1px solid hsl(var(--border)) !important;
}
/* Toolbar-Buttons — die Farbfelder der Farbknöpfe (.note-color-btn) ausgenommen: ihr Hintergrund
   ist die Farbe selbst (Inline-Stil) und wäre mit „transparent !important" unsichtbar. */
.note-btn:not(.note-color-btn) {
  border-radius: 0.375rem !important;
  border: 1px solid transparent !important;
  padding: 2px 6px !important;
  font-size: 0.8125rem !important;
  background: transparent !important;
  color: hsl(var(--foreground)) !important;
  transition: background 0.15s, color 0.15s !important;
}
.note-btn:not(.note-color-btn):hover, .note-btn:not(.note-color-btn):focus {
  background: hsl(var(--border)) !important;
  border-color: transparent !important;
}
.note-btn.active:not(.note-color-btn), .note-btn.active:not(.note-color-btn):hover {
  background: hsl(var(--primary-strong)) !important;
  color: hsl(var(--primary-foreground)) !important;
}
.note-color-palette .note-color-btn { width: 1.375rem !important; height: 1.375rem !important; padding: 0 !important; margin: 2px !important; border: 1px solid hsl(var(--border)) !important; border-radius: .3rem !important; }
.note-color-palette .note-color-btn:hover, .note-color-palette .note-color-btn:focus-visible { outline: 2px solid hsl(var(--primary) / .6) !important; outline-offset: 1px; }
.note-dropdown-menu {
  border: 1px solid hsl(var(--border)) !important;
  border-radius: 0.5rem !important;
  box-shadow: 0 4px 16px -4px rgb(0 0 0 / 0.12) !important;
  padding: 4px !important;
}
.note-dropdown-item {
  border-radius: 0.375rem !important;
  padding: 4px 10px !important;
  font-size: 0.875rem !important;
}
.note-dropdown-item:hover {
  background: hsl(var(--muted)) !important;
}
/* Toolbar-Gruppen */
.note-btn-group { gap: 2px !important; }
/* Fullscreen / Codeview z-Index */
.note-editor.note-fullscreen { z-index: 9999 !important; }
/* Überschriften-Dropdown sauber */
.note-style .dropdown-style blockquote,
.note-style .dropdown-style h1,
.note-style .dropdown-style h2,
.note-style .dropdown-style h3,
.note-style .dropdown-style h4,
.note-style .dropdown-style p {
  font-size: 0.875rem !important;
  margin: 0 !important;
}

/* ============================================================
   Chat – Vollhöhen-Layout
   ============================================================ */

/* Wenn Chat-Detail aktiv ist, kein Padding unten im Main */
.extr-main--chat {
  /* Chat auf Viewport-Höhe fixieren: sonst wächst der Wrapper mit dem Inhalt,
     die ganze Seite scrollt und Mitglieder-Leiste + Eingabezeile scrollen weg. */
  height: 100vh;
  height: 100dvh;
  padding-bottom: 0 !important;
  overflow: hidden !important;
}
.extr-main--chat #extr-main {
  height: 100%;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

/* Desktop-Chat-Raster: Zeilenhöhe an den Container binden (minmax(0,1fr)), sonst
   sprengt die Nachrichtenspalte das Raster, der Feed scrollt nicht intern und
   die Mitglieder-Leiste rechts scrollt mit der Seite weg. */
.extr-chat-grid { grid-template-rows: minmax(0, 1fr); }

/* Chat-Wrapper füllt verfügbare Höhe */
#extr-chat-page {
  display: flex;
  flex-direction: column;
  height: 100%;
  overflow: hidden;
}

/* Nachrichten-Feed */
#chat-messages-feed {
  flex: 1;
  overflow-y: auto;
  scroll-behavior: smooth;
  /* Überziehen am Verlaufsanfang nicht an die Seite weiterreichen — sonst löst ein
     Browser-Tab (Android-Chrome) sein eigenes Neuladen aus (vgl. ptrBlocked in app.js). */
  overscroll-behavior-y: contain;
}

/* Eingabeleiste: auf Mobile über der fixierten Bottom-Nav halten,
   damit Textfeld + Senden-Button sichtbar bleiben (PWA / iOS). */
@media (max-width: 1023px) {
  .extr-chat-composer {
    padding-bottom: calc(5.5rem + env(safe-area-inset-bottom, 0px));
  }
}

/* Eigene Nachrichten-Blase */
.chat-bubble-own {
  background: hsl(var(--primary-strong));
  color: hsl(var(--primary-foreground));
  border-radius: 1rem 1rem 0.25rem 1rem;
  padding: 0.625rem 1rem;
  min-width: 0;
  max-width: 100%;
  width: fit-content;
  overflow-wrap: anywhere;
  line-height: 1.5;
  font-size: 0.875rem;
}

/* Fremde Nachrichten-Blase */
.chat-bubble-other {
  background: #fff;
  border: 1px solid hsl(var(--border));
  border-radius: 1rem 1rem 1rem 0.25rem;
  padding: 0.625rem 1rem;
  min-width: 0;
  max-width: 100%;
  width: fit-content;
  overflow-wrap: anywhere;
  line-height: 1.5;
  font-size: 0.875rem;
}

/* Spalte einer Nachricht (Zitat, Blase, Zeit, Reaktionen). Die Breitengrenze sitzt
   hier, nicht an der Blase: mit width:fit-content bezog sich max-width:75 % der Blase
   auf die eigene Inhaltsbreite, deshalb brachen kurze Wörter wie „Hallo“ mitten im
   Wort um (Feedback CHAT-04). */
.chat-msg-col { max-width: min(75%, 32rem); min-width: 0; }

/* Avatar Initialen */
.chat-avatar {
  width: 2rem;
  height: 2rem;
  border-radius: 9999px;
  background: hsl(var(--primary) / 0.12);
  color: hsl(var(--primary));
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.6875rem;
  font-weight: 600;
  flex-shrink: 0;
}

/* Datum-Trennlinie */
.chat-date-divider {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin: 1rem 0;
  font-size: 0.75rem;
  color: hsl(var(--muted-foreground));
}
.chat-date-divider::before,
.chat-date-divider::after {
  content: '';
  flex: 1;
  height: 1px;
  background: hsl(var(--border));
}

/* Chat-Aktions-Icons & Reaktion-Hinzufügen: am Desktop nur bei Hover,
   auf Touch-Geräten (kein Hover → sonst unsichtbar) dauerhaft sichtbar. */
.chat-msg-actions {
  opacity: 0;
  transition: opacity 0.15s ease;
}
.group:hover .chat-msg-actions,
.chat-msg-actions:focus-within {
  opacity: 1;
}
@media (hover: none), (pointer: coarse) {
  .chat-msg-actions { opacity: 1; }
}

/* Like-Icon in News-Übersicht: filled-Zustand über currentColor (Lucide-path-Override) */
.news-like-icon.filled path {
  fill: currentColor;
  stroke: currentColor;
}

/* ---------------------------------------------------------------------------
   PWA: Installations-Overlay & Willkommens-Modal
   --------------------------------------------------------------------------- */
.extr-pwa-locked { overflow: hidden; }

.extr-pwa-overlay {
  position: fixed;
  inset: 0;
  z-index: 9999;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
  /* Safe-Area (PWA): Karte nicht unter Insel / Home-Indikator schieben */
  padding-top: calc(1.5rem + env(safe-area-inset-top, 0px));
  padding-bottom: calc(1.5rem + env(safe-area-inset-bottom, 0px));
  background: linear-gradient(160deg, hsl(173 94% 26% / 0.97), hsl(174 92% 18% / 0.98));
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
}
.extr-pwa-overlay.hidden { display: none; }

.extr-pwa-card {
  width: 100%;
  max-width: 420px;
  background: #fff;
  border-radius: 1.25rem;
  padding: 1.75rem;
  box-shadow: 0 24px 70px rgba(0, 0, 0, 0.3);
  /* 100% = Höhe abzüglich der Safe-Area-Abstände des Overlays */
  max-height: min(calc(100vh - 3rem), 100%);
  overflow-y: auto;
}
.extr-pwa-card--welcome { text-align: center; }

.extr-pwa-logo {
  width: 4rem;
  height: 4rem;
  margin: 0 auto 1rem;
  border-radius: 1rem;
  background: hsl(var(--primary) / 0.1);
  display: flex;
  align-items: center;
  justify-content: center;
}
.extr-pwa-logo img { width: 2.75rem; height: 2.75rem; object-fit: contain; }

.extr-pwa-title {
  font-size: 1.35rem;
  font-weight: 700;
  color: hsl(222 47% 11%);
  margin: 0 0 0.5rem;
  text-align: center;
}
.extr-pwa-sub {
  color: hsl(215 16% 47%);
  font-size: 0.925rem;
  line-height: 1.5;
  margin: 0 0 1.25rem;
  text-align: center;
}

.extr-pwa-list {
  list-style: none;
  counter-reset: pwa;
  margin: 0;
  padding: 0;
}
.extr-pwa-list li {
  position: relative;
  counter-increment: pwa;
  padding: 0.7rem 0 0.7rem 2.5rem;
  border-bottom: 1px solid hsl(214 32% 91%);
  font-size: 0.9rem;
  line-height: 1.45;
  color: hsl(222 47% 20%);
}
.extr-pwa-list li:last-child { border-bottom: none; }
.extr-pwa-list li::before {
  content: counter(pwa);
  position: absolute;
  left: 0;
  top: 0.6rem;
  width: 1.65rem;
  height: 1.65rem;
  border-radius: 50%;
  background: hsl(var(--primary-strong));
  color: hsl(var(--primary-foreground));
  font-weight: 700;
  font-size: 0.8rem;
  display: flex;
  align-items: center;
  justify-content: center;
}
.extr-pwa-ic {
  width: 1rem;
  height: 1rem;
  display: inline-block;
  vertical-align: -0.18rem;
  color: var(--primary-hsl);
}
.extr-pwa-note {
  margin: 1rem 0 0;
  font-size: 0.8rem;
  color: hsl(215 16% 47%);
  background: hsl(var(--primary) / 0.08);
  border-radius: 0.5rem;
  padding: 0.6rem 0.75rem;
}
.extr-pwa-dismiss {
  display: block;
  width: 100%;
  margin-top: 1.25rem;
  background: none;
  border: none;
  color: hsl(215 16% 47%);
  font-size: 0.85rem;
  cursor: pointer;
  padding: 0.5rem;
}
.extr-pwa-dismiss:hover { color: hsl(222 47% 20%); text-decoration: underline; }

.extr-pwa-welcome-icon {
  width: 4.5rem;
  height: 4.5rem;
  margin: 0 auto 1.25rem;
  border-radius: 50%;
  background: hsl(var(--primary) / 0.12);
  display: flex;
  align-items: center;
  justify-content: center;
}
.extr-pwa-welcome-icon i { width: 2.25rem; height: 2.25rem; color: var(--primary-hsl); }

/* ── Trennlinien: nur noch .extr-divided (UI-Audit CODE-05, 2026-09-22) ──────
   Hier stand der Ausgleich für Tailwinds divide-y: dessen Linie hängt als
   border-bottom an „> :not(:last-child)" und stand ohne passende Farbregel auf
   currentColor. Seit CODE-05 trägt keine Liste mehr divide-y — alle nutzen
   .extr-divided (weiter unten), und der Wächter bausteine-semantik.php hält das
   so. divide-y wieder einzusetzen hieße: schwarze Linien. */

/* ============================================================
   UX-Überarbeitung 2026 — Dark Mode, Navigations-Feedback,
   Interaktions-Politur, A11y. Additiv, ohne Bestehendes zu ändern.
   ============================================================ */

/* ---- Dark Mode (über data-theme am <html>; gleiche Token-Namen) ------------ */
:root { color-scheme: light; }
html[data-theme="dark"] {
  color-scheme: dark;
  /* Status-Töne (siehe :root): durchscheinende Fläche, helle Schrift */
  --tone-warn-bg:         43 96% 56% / .14;
  --tone-warn-fg:         43 96% 56%;
  --tone-warn-border:     43 96% 56% / .4;
  --tone-ok-bg:           142 69% 58% / .16;
  --tone-ok-fg:           142 77% 73%;
  --tone-bad-bg:          0 91% 71% / .18;
  --tone-bad-fg:          0 94% 82%;
  --tone-ok-border:       142 69% 58% / .4;
  --tone-bad-border:      0 91% 71% / .4;
  --tone-info-bg:         213 94% 68% / .16;
  --tone-info-fg:         213 97% 80%;
  --tone-info-border:     213 94% 68% / .4;
  --primary:              173 70% 42%;
  --primary-hsl:          hsl(173, 70%, 42%);
  --primary-foreground:   195 26% 9%; /* dunkle Schrift auf der aufgehellten Primärfarbe (UI-Audit DARK-02) */
  --primary-strong:       173 70% 42%;
  --background:           195 26% 9%;
  --background-hsl:       hsl(195, 26%, 9%);
  --foreground:           168 16% 92%;
  --card:                 196 22% 13%;
  --card-foreground:      168 16% 92%;
  --secondary:            170 24% 24%;
  --secondary-hsl:        hsl(170, 24%, 24%);
  --secondary-foreground: 0 0% 100%;
  --muted:                196 16% 18%;
  --muted-foreground:     190 10% 64%;
  --border:               196 14% 24%;
  --accent:               173 70% 42%;
  --destructive:          350 75% 68%; /* ≥ 4,5:1 auf Karte und Muted (UI-Audit DARK-02) */
  --destructive-foreground: 195 26% 9%;
  --sidebar-bg:           196 24% 11%;
  --sidebar-border:       196 14% 24%;
  --extr-shadow-sm: 0 1px 2px rgba(0,0,0,0.40);
  --extr-shadow-md: 0 4px 16px rgba(0,0,0,0.48);
  --extr-shadow-lg: 0 14px 36px rgba(0,0,0,0.58);

  /* Tailwind-Token (--color-*, tailwind.css :root) aus den HSL-Token ableiten — sonst bleiben
     text-primary, bg-primary/10, border-border … beim Hellwert (UI-Audit DARK-01). */
  --color-primary:                 hsl(var(--primary));
  --color-primary-foreground:      hsl(var(--primary-foreground));
  --color-accent:                  hsl(var(--accent));
  --color-accent-foreground:       hsl(var(--primary-foreground));
  --color-background:              hsl(var(--background));
  --color-foreground:              hsl(var(--foreground));
  --color-card:                    hsl(var(--card));
  --color-card-foreground:         hsl(var(--card-foreground));
  --color-secondary:               hsl(var(--secondary));
  --color-secondary-foreground:    hsl(var(--secondary-foreground));
  --color-muted:                   hsl(var(--muted));
  --color-muted-foreground:        hsl(var(--muted-foreground));
  --color-border:                  hsl(var(--border));
  --color-input:                   hsl(var(--card));
  --color-ring:                    hsl(var(--primary));
  --color-destructive:             hsl(var(--destructive));
  --color-destructive-foreground:  hsl(var(--destructive-foreground));
}

/* Literale Tailwind-Flächen-Utilities im Dark-Scope auf Tokens umlenken
   (die App nutzt vielerorts bg-white/bg-*-50 statt semantischer Klassen). */
html[data-theme="dark"] .bg-white { background-color: hsl(var(--card)); }
html[data-theme="dark"] .bg-gray-50,
html[data-theme="dark"] .bg-gray-100,
html[data-theme="dark"] .bg-slate-50,
html[data-theme="dark"] .bg-neutral-50 { background-color: hsl(var(--muted)); }
html[data-theme="dark"] .text-gray-900,
html[data-theme="dark"] .text-slate-900,
html[data-theme="dark"] .text-black { color: hsl(var(--foreground)); }
html[data-theme="dark"] .text-gray-500,
html[data-theme="dark"] .text-gray-600,
html[data-theme="dark"] .text-gray-700 { color: hsl(var(--muted-foreground)); }
html[data-theme="dark"] .border-gray-100,
html[data-theme="dark"] .border-gray-200,
html[data-theme="dark"] .border-slate-200 { border-color: hsl(var(--border)); }
/* Pastell-Tints (Icon-Chips) auf dezente Transluzenz statt greller Pastelle */
html[data-theme="dark"] .bg-red-50     { background-color: rgba(248,113,113,0.14); }
html[data-theme="dark"] .bg-amber-50   { background-color: rgba(251,191,36,0.14); }
html[data-theme="dark"] .bg-yellow-50  { background-color: rgba(250,204,21,0.14); }
html[data-theme="dark"] .bg-green-50,
html[data-theme="dark"] .bg-emerald-50 { background-color: rgba(52,211,153,0.14); }
html[data-theme="dark"] .bg-blue-50,
html[data-theme="dark"] .bg-sky-50     { background-color: rgba(96,165,250,0.14); }
html[data-theme="dark"] .bg-violet-50,
html[data-theme="dark"] .bg-purple-50  { background-color: rgba(167,139,250,0.14); }
/* Auf Dark dezentere Schlagschatten */
html[data-theme="dark"] .shadow-lg,
html[data-theme="dark"] .shadow-xl,
html[data-theme="dark"] .shadow-2xl { box-shadow: 0 10px 30px rgba(0,0,0,0.45); }

/* ---- Dark-Mode-Vervollständigung 2026 -------------------------------------
   App nutzt vielerorts slate-/zinc-/Pastell-Utilities statt semantischer
   Klassen. Im Dark-Scope auf Tokens bzw. Transluzenz umlenken, sonst bleiben
   Flächen hell und Texte dunkel-auf-dunkel. */
/* Flächen (helle Grautöne) → Muted */
html[data-theme="dark"] .bg-slate-100,
html[data-theme="dark"] .bg-zinc-100 { background-color: hsl(var(--muted)); }
html[data-theme="dark"] .hover\:bg-white:hover,
html[data-theme="dark"] .hover\:bg-slate-100:hover,
html[data-theme="dark"] .hover\:bg-slate-50:hover,
html[data-theme="dark"] .hover\:bg-gray-100:hover { background-color: hsl(var(--muted)); }
/* Sekundärtext (mittlere Grautöne) → Muted-Foreground */
html[data-theme="dark"] .text-slate-400,
html[data-theme="dark"] .text-slate-500,
html[data-theme="dark"] .text-slate-600,
html[data-theme="dark"] .text-gray-400,
html[data-theme="dark"] .text-zinc-500,
html[data-theme="dark"] .text-zinc-600 { color: hsl(var(--muted-foreground)); }
/* Primärtext (dunkle Grautöne) → Foreground */
html[data-theme="dark"] .text-slate-700,
html[data-theme="dark"] .text-slate-800,
html[data-theme="dark"] .text-zinc-700,
html[data-theme="dark"] .text-zinc-800,
html[data-theme="dark"] .text-gray-800 { color: hsl(var(--foreground)); }
/* Rahmen */
html[data-theme="dark"] .border-slate-100,
html[data-theme="dark"] .border-slate-300,
html[data-theme="dark"] .border-gray-300,
html[data-theme="dark"] .border-zinc-200 { border-color: hsl(var(--border)); }
/* Pastell-Tints vollständig (-50 + -100, alle Familien) → dezente Transluzenz */
html[data-theme="dark"] .bg-red-50,     html[data-theme="dark"] .bg-red-100     { background-color: rgba(248,113,113,0.13); }
html[data-theme="dark"] .bg-orange-50,  html[data-theme="dark"] .bg-orange-100,
html[data-theme="dark"] .bg-amber-50,   html[data-theme="dark"] .bg-amber-100,
html[data-theme="dark"] .bg-yellow-50,  html[data-theme="dark"] .bg-yellow-100  { background-color: rgba(251,191,36,0.14); }
html[data-theme="dark"] .bg-lime-50,    html[data-theme="dark"] .bg-lime-100,
html[data-theme="dark"] .bg-green-50,   html[data-theme="dark"] .bg-green-100,
html[data-theme="dark"] .bg-emerald-50, html[data-theme="dark"] .bg-emerald-100,
html[data-theme="dark"] .bg-teal-50,    html[data-theme="dark"] .bg-teal-100    { background-color: rgba(52,211,153,0.13); }
html[data-theme="dark"] .bg-cyan-50,    html[data-theme="dark"] .bg-cyan-100,
html[data-theme="dark"] .bg-sky-50,     html[data-theme="dark"] .bg-sky-100,
html[data-theme="dark"] .bg-blue-50,    html[data-theme="dark"] .bg-blue-100    { background-color: rgba(96,165,250,0.14); }
html[data-theme="dark"] .bg-indigo-50,  html[data-theme="dark"] .bg-indigo-100,
html[data-theme="dark"] .bg-violet-50,  html[data-theme="dark"] .bg-violet-100,
html[data-theme="dark"] .bg-purple-50,  html[data-theme="dark"] .bg-purple-100  { background-color: rgba(167,139,250,0.14); }
html[data-theme="dark"] .bg-pink-50,    html[data-theme="dark"] .bg-pink-100,
html[data-theme="dark"] .bg-rose-50,    html[data-theme="dark"] .bg-rose-100,
html[data-theme="dark"] .bg-fuchsia-50, html[data-theme="dark"] .bg-fuchsia-100 { background-color: rgba(244,114,182,0.14); }
/* Custom-Komponenten mit hartkodiertem Weiß → im Dark-Scope auf Tokens */
html[data-theme="dark"] .extr-header-bar { background-color: hsl(var(--card) / 0.85); }
html[data-theme="dark"] .chat-bubble-other { background: hsl(var(--card)); color: hsl(var(--foreground)); }
html[data-theme="dark"] .extr-more-sheet,
html[data-theme="dark"] .extr-pwa-card,
html[data-theme="dark"] .extr-check-box { background: hsl(var(--card)); }
/* PWA-Install/Welcome-Texte im Dark Mode lesbar (Basisfarben sind hart auf Hell-Mode kodiert) */
html[data-theme="dark"] .extr-pwa-title { color: hsl(var(--foreground)); }
html[data-theme="dark"] .extr-pwa-sub,
html[data-theme="dark"] .extr-pwa-note,
html[data-theme="dark"] .extr-pwa-dismiss { color: hsl(var(--muted-foreground)); }
html[data-theme="dark"] .extr-pwa-note { background: hsl(var(--primary) / 0.12); }
html[data-theme="dark"] .extr-pwa-list li { color: hsl(var(--foreground)); border-bottom-color: hsl(var(--border)); }
html[data-theme="dark"] .extr-pwa-dismiss:hover { color: hsl(var(--foreground)); }
html[data-theme="dark"] .note-editor.note-frame .note-editable { background: hsl(var(--card)) !important; }
html[data-theme="dark"] .note-dropdown-menu { background: hsl(var(--card)) !important; }
/* Farbiger Text (Badges/Labels/Icons): dunkle -600/-700/-800-Töne auf Dunkel
   unlesbar → auf helle -400-Töne derselben Farbe umlenken (inkl. Hover). */
html[data-theme="dark"] .text-red-500,html[data-theme="dark"] .text-red-600,html[data-theme="dark"] .text-red-700,html[data-theme="dark"] .text-red-800,html[data-theme="dark"] .text-red-900,html[data-theme="dark"] .hover\:text-red-600:hover,html[data-theme="dark"] .hover\:text-red-700:hover{color:#f87171}
html[data-theme="dark"] .text-orange-500,html[data-theme="dark"] .text-orange-600,html[data-theme="dark"] .text-orange-700,html[data-theme="dark"] .text-orange-800,html[data-theme="dark"] .hover\:text-orange-600:hover{color:#fb923c}
html[data-theme="dark"] .text-amber-500,html[data-theme="dark"] .text-amber-600,html[data-theme="dark"] .text-amber-700,html[data-theme="dark"] .text-amber-800,html[data-theme="dark"] .text-amber-900,html[data-theme="dark"] .hover\:text-amber-600:hover{color:#fbbf24}
html[data-theme="dark"] .text-yellow-500,html[data-theme="dark"] .text-yellow-600,html[data-theme="dark"] .text-yellow-700,html[data-theme="dark"] .text-yellow-800{color:#facc15}
html[data-theme="dark"] .text-lime-500,html[data-theme="dark"] .text-lime-600,html[data-theme="dark"] .text-lime-700{color:#a3e635}
html[data-theme="dark"] .text-green-500,html[data-theme="dark"] .text-green-600,html[data-theme="dark"] .text-green-700,html[data-theme="dark"] .text-green-800,html[data-theme="dark"] .text-green-900,html[data-theme="dark"] .hover\:text-green-600:hover,html[data-theme="dark"] .hover\:text-green-700:hover{color:#4ade80}
html[data-theme="dark"] .text-emerald-500,html[data-theme="dark"] .text-emerald-600,html[data-theme="dark"] .text-emerald-700,html[data-theme="dark"] .text-emerald-800{color:#34d399}
html[data-theme="dark"] .text-teal-500,html[data-theme="dark"] .text-teal-600,html[data-theme="dark"] .text-teal-700{color:#2dd4bf}
html[data-theme="dark"] .text-cyan-500,html[data-theme="dark"] .text-cyan-600,html[data-theme="dark"] .text-cyan-700{color:#22d3ee}
html[data-theme="dark"] .text-sky-500,html[data-theme="dark"] .text-sky-600,html[data-theme="dark"] .text-sky-700{color:#38bdf8}
html[data-theme="dark"] .text-blue-500,html[data-theme="dark"] .text-blue-600,html[data-theme="dark"] .text-blue-700,html[data-theme="dark"] .text-blue-800,html[data-theme="dark"] .hover\:text-blue-600:hover,html[data-theme="dark"] .hover\:text-blue-700:hover{color:#60a5fa}
html[data-theme="dark"] .text-indigo-500,html[data-theme="dark"] .text-indigo-600,html[data-theme="dark"] .text-indigo-700{color:#a5b4fc}
html[data-theme="dark"] .text-violet-500,html[data-theme="dark"] .text-violet-600,html[data-theme="dark"] .text-violet-700,html[data-theme="dark"] .text-violet-800{color:#a78bfa}
html[data-theme="dark"] .text-purple-500,html[data-theme="dark"] .text-purple-600,html[data-theme="dark"] .text-purple-700,html[data-theme="dark"] .text-purple-800{color:#c084fc}
html[data-theme="dark"] .text-fuchsia-500,html[data-theme="dark"] .text-fuchsia-600,html[data-theme="dark"] .text-fuchsia-700{color:#e879f9}
html[data-theme="dark"] .text-pink-500,html[data-theme="dark"] .text-pink-600,html[data-theme="dark"] .text-pink-700,html[data-theme="dark"] .hover\:text-pink-600:hover{color:#f472b6}
html[data-theme="dark"] .text-rose-500,html[data-theme="dark"] .text-rose-600,html[data-theme="dark"] .text-rose-700{color:#fb7185}
/* ── KERNFIX: semantische Tailwind-Utilities sind im precompiled CSS mit
   HELL-Werten gebacken (reagieren NICHT auf data-theme). Im Dark-Scope auf die
   im Dark überschriebenen CSS-Variablen zurückführen — sonst hell-auf-dunkel
   (Flächen) bzw. dunkel-auf-dunkel (Text) in allen Modulen. */
html[data-theme="dark"] .bg-card,
html[data-theme="dark"] .bg-popover { background-color: hsl(var(--card)); }
html[data-theme="dark"] .bg-background { background-color: hsl(var(--background)); }
html[data-theme="dark"] .bg-muted { background-color: hsl(var(--muted)); }
html[data-theme="dark"] .bg-muted\/10 { background-color: hsl(var(--muted) / 0.1); }
html[data-theme="dark"] .bg-muted\/20 { background-color: hsl(var(--muted) / 0.2); }
html[data-theme="dark"] .bg-muted\/30 { background-color: hsl(var(--muted) / 0.3); }
html[data-theme="dark"] .bg-muted\/40 { background-color: hsl(var(--muted) / 0.4); }
html[data-theme="dark"] .bg-muted\/50 { background-color: hsl(var(--muted) / 0.5); }
html[data-theme="dark"] .bg-muted\/60 { background-color: hsl(var(--muted) / 0.6); }
html[data-theme="dark"] .bg-muted\/70 { background-color: hsl(var(--muted) / 0.7); }
html[data-theme="dark"] .hover\:bg-muted:hover { background-color: hsl(var(--muted)); }
html[data-theme="dark"] .hover\:bg-muted\/40:hover { background-color: hsl(var(--muted) / 0.4); }
html[data-theme="dark"] .hover\:bg-muted\/50:hover { background-color: hsl(var(--muted) / 0.5); }
html[data-theme="dark"] .hover\:bg-muted\/60:hover { background-color: hsl(var(--muted) / 0.6); }
html[data-theme="dark"] .text-foreground,
html[data-theme="dark"] .text-card-foreground,
html[data-theme="dark"] .text-popover-foreground { color: hsl(var(--foreground)); }
html[data-theme="dark"] .text-muted-foreground { color: hsl(var(--muted-foreground)); }
html[data-theme="dark"] .hover\:text-foreground:hover { color: hsl(var(--foreground)); }
html[data-theme="dark"] .placeholder\:text-muted-foreground::placeholder { color: hsl(var(--muted-foreground)); }
html[data-theme="dark"] .border-border,
html[data-theme="dark"] .border-input { border-color: hsl(var(--border)); }
/* Der Ring-Ersatz oben nutzt das Tailwind-Token, das im Dunkel-Scope nicht
   umgesetzt wird — hier nachziehen. */
html[data-theme="dark"] .ring-border { --tw-ring-color: hsl(var(--border)); }

/* ---- Navigations-Feedback: Top-Progressbar ------------------------------- */
.extr-progress {
  position: fixed; top: 0; left: 0; height: 3px; width: 0;
  background: hsl(var(--primary));
  z-index: 300; opacity: 0;
  transition: width .2s ease, opacity .3s ease;
  box-shadow: 0 0 8px hsl(var(--primary) / 0.6);
}
.extr-progress--active { opacity: 1; }

/* Sanftes Einblenden frisch geladener Inhalte */
@keyframes extrFadeIn { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }
.extr-fade-in { animation: extrFadeIn .22s ease both; }

/* ---- Skeleton-Loader ------------------------------------------------------ */
.extr-skel { position: relative; overflow: hidden; background: hsl(var(--muted)); border-radius: .5rem; }
.extr-skel::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(90deg, transparent, hsl(var(--card) / 0.6), transparent);
  transform: translateX(-100%); animation: extrShimmer 1.3s infinite;
}
@keyframes extrShimmer { 100% { transform: translateX(100%); } }
.extr-skel-line { height: .8rem; border-radius: .375rem; margin: .5rem 0; }
.extr-skel-card { height: 5rem; border-radius: 1rem; margin: .75rem 0; }
.extr-skel-avatar { height: 2.5rem; width: 2.5rem; border-radius: 9999px; flex: 0 0 auto; }
.extr-skel-row { display: flex; gap: .75rem; align-items: center; padding: .5rem 0; }
.extr-skel-tile { height: 6.5rem; border-radius: 1rem; }

/* ---- Empty-State (Helfer extr_empty_state) -------------------------------- */
.extr-empty { text-align: center; padding: 2.5rem 1rem; }
.extr-empty-icon {
  height: 3rem; width: 3rem; margin: 0 auto .75rem;
  border-radius: 9999px; display: flex; align-items: center; justify-content: center;
  background: hsl(var(--muted)); color: hsl(var(--muted-foreground));
}
.extr-empty-title { font-weight: 600; margin-bottom: .25rem; }
.extr-empty-text { font-size: .875rem; color: hsl(var(--muted-foreground)); max-width: 24rem; margin: 0 auto; }
.extr-empty-cta { margin-top: 1rem; }

/* ---- Command-Palette: aktiver (tastaturgewählter) Eintrag ----------------- */
.extr-cmd-item--active { background: hsl(var(--muted)); }

/* ---- Button-Spinner (extrBtnBusy) ----------------------------------------- */
.extr-btn-spin {
  display: inline-block; height: 1em; width: 1em; vertical-align: -0.15em;
  border: 2px solid currentColor; border-right-color: transparent;
  border-radius: 9999px; animation: spin .6s linear infinite;
}

/* ---- Auswahlkästchen und Radios: Markenfarbe (UI-Audit BTN-03) -------------
   Vorher trugen 337 Stellen `accent-primary` im Markup und 132 nicht — die
   erschienen im Browser-Standardblau neben den grünen. Eine Regel löst das
   für alle; `accent-primary` im Markup ist damit überflüssig (schadet aber
   nicht, es setzt denselben Wert). */
input[type="checkbox"],
input[type="radio"] { accent-color: hsl(var(--primary)); }

/* ---- A11y: sichtbarer Fokusring für Tastaturnutzer ------------------------ */
a:focus-visible, button:focus-visible, input:focus-visible, select:focus-visible,
textarea:focus-visible, [tabindex]:focus-visible, [role="button"]:focus-visible {
  outline: 2px solid hsl(var(--primary));
  outline-offset: 2px;
  border-radius: 4px;
}

/* ---- Pull-to-Refresh Indikator -------------------------------------------- */
.extr-ptr {
  position: fixed; top: 0; left: 50%; transform: translate(-50%, -120%);
  z-index: 250; height: 2.25rem; width: 2.25rem; border-radius: 9999px;
  background: hsl(var(--card)); color: hsl(var(--primary));
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 4px 14px rgba(0,0,0,0.18); transition: transform .15s ease;
}

/* ---- Reduced Motion respektieren ------------------------------------------ */
@media (prefers-reduced-motion: reduce) {
  .extr-fade-in, .extr-skel::after, .extr-progress { animation: none !important; transition: none !important; }
}

/* ============================================================
   Motion & Delight 2026 — Mikro-Interaktionen (additiv)
   Richtungs-Übergänge, Stagger, Hover-Lift, Erfolgs-Häkchen,
   Konfetti, Skeleton-Dissolve. Dark- + reduced-motion-fest.
   ============================================================ */

/* ---- Richtungsabhängiger View-Übergang (vor/zurück) ---------------------- */
@keyframes extrSlideFwd  { from { opacity: 0; transform: translateX(16px); }  to { opacity: 1; transform: none; } }
@keyframes extrSlideBack { from { opacity: 0; transform: translateX(-16px); } to { opacity: 1; transform: none; } }
.extr-view-fwd  { animation: extrSlideFwd  .26s cubic-bezier(.22,.61,.36,1) both; }
.extr-view-back { animation: extrSlideBack .26s cubic-bezier(.22,.61,.36,1) both; }

/* ---- Skeleton → Content Dissolve ----------------------------------------- */
.extr-fading-out { opacity: 0 !important; transition: opacity .13s ease; }

/* ---- Stagger-Reveal für Listen/Grids (Opt-in-Klasse .extr-stagger) ------- */
@keyframes extrRise { from { opacity: 0; transform: translateY(9px); } to { opacity: 1; transform: none; } }
.extr-stagger > * { animation: extrRise .34s cubic-bezier(.22,.61,.36,1) both; animation-delay: calc(var(--extr-i, 0) * 28ms); }

/* ---- Hover-Lift für klickbare Kacheln (Opt-in-Klasse .extr-lift) --------- */
.extr-lift { transition: transform .15s cubic-bezier(.22,.61,.36,1), box-shadow .15s; }
.extr-lift:hover  { transform: translateY(-2px); box-shadow: var(--extr-shadow-md); }
.extr-lift:active { transform: translateY(0) scale(.995); }

/* ---- Erfolgs-Häkchen-Morph (extrBtnSuccess) ------------------------------ */
.extr-btn-success { background: hsl(142 64% 38%) !important; color: #fff !important; border-color: transparent !important; opacity: 1 !important; }
.extr-btn-check { display: inline-block; width: 1.15em; height: 1.15em; position: relative; vertical-align: -0.2em; }
.extr-btn-check::after {
  content: ""; position: absolute; left: 0.42em; top: 0.1em;
  width: 0.3em; height: 0.62em; border: solid #fff; border-width: 0 2px 2px 0;
  transform: rotate(45deg) scale(0); transform-origin: center;
  animation: extrCheckPop .42s cubic-bezier(.2,1.25,.4,1) .05s forwards;
}
@keyframes extrCheckPop { to { transform: rotate(45deg) scale(1); } }

/* ---- Konfetti-Burst (extrBurst) ------------------------------------------ */
.extr-burst { position: fixed; inset: 0; pointer-events: none; z-index: 400; }
.extr-burst > span {
  position: absolute; width: 8px; height: 8px; border-radius: 2px; opacity: 0;
  animation: extrBurstFly .9s cubic-bezier(.2,.7,.3,1) forwards;
}
@keyframes extrBurstFly {
  0%   { opacity: 1; transform: translate(-50%, -50%) scale(.4) rotate(0); }
  70%  { opacity: 1; }
  100% { opacity: 0; transform: translate(calc(-50% + var(--dx)), calc(-50% + var(--dy))) scale(1) rotate(200deg); }
}

/* ---- Reduced Motion: alle neuen Bewegungen aus --------------------------- */
@media (prefers-reduced-motion: reduce) {
  .extr-view-fwd, .extr-view-back, .extr-stagger > *,
  .extr-lift, .extr-lift:hover, .extr-lift:active,
  .extr-btn:active, .extr-employee-card:hover, .extr-employee-card:active,
  .extr-btn-check::after, .extr-toast, .extr-toast-bar, .extr-burst > span {
    animation: none !important;
    transition: none !important;
    transform: none !important;
  }
  .extr-fading-out { transition: none !important; }
}

/* ── Signage-Layout ─────────────────────────────────────────────────────────
   Eigenständige responsive Klassen, da die vorgebaute tailwind.css keine
   responsiven Varianten (lg:*, sm:grid-cols-*, xl:*) enthält. */
.sg-ed-row{display:flex;flex-direction:column;flex:1 1 auto;overflow:hidden;min-height:0}
.sg-ed-canvas{min-width:0}
.sg-ed-props{width:100%;border-top:1px solid hsl(var(--border))}
@media(min-width:1024px){
  .sg-ed-row{flex-direction:row}
  .sg-ed-canvas{flex:1 1 auto}
  .sg-ed-props{width:24rem;flex:0 0 24rem;overflow-y:auto;border-top:0;border-left:1px solid hsl(var(--border))}
}
.sg-cards-grid{display:grid;gap:1rem;grid-template-columns:1fr}
@media(min-width:640px){.sg-cards-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media(min-width:1024px){.sg-cards-grid{grid-template-columns:repeat(3,minmax(0,1fr))}}
@media(min-width:1280px){.sg-cards-grid{grid-template-columns:repeat(4,minmax(0,1fr))}}
.sg-mon-grid{display:grid;gap:1rem;grid-template-columns:1fr}
@media(min-width:768px){.sg-mon-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media(min-width:1280px){.sg-mon-grid{grid-template-columns:repeat(3,minmax(0,1fr))}}
.sg-pl-grid{display:grid;gap:1rem;grid-template-columns:1fr}
@media(min-width:768px){.sg-pl-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media(min-width:1280px){.sg-pl-grid{grid-template-columns:repeat(3,minmax(0,1fr))}}
/* Playlist-Editor: Reihenfolge schmal, Bibliothek breit. minmax(0,…) statt
   fester Breite, damit lange Card-Namen die Spalte nicht aufblähen (truncate
   greift nur in einer Spalte mit min-width 0). align-items:start verhindert,
   dass die kurze Reihenfolge-Spalte auf Bibliothekshöhe gestreckt wird. */
.sg-ple-grid{display:grid;gap:1.5rem;grid-template-columns:1fr}
@media(min-width:1024px){.sg-ple-grid{grid-template-columns:minmax(0,20rem) minmax(0,1fr);align-items:start}}
@media(min-width:1440px){.sg-ple-grid{grid-template-columns:minmax(0,22rem) minmax(0,1fr)}}
/* Card-Bibliothek: drei Cards nebeneinander ab 640px. repeat(3,minmax(0,17rem))
   statt 1fr — sonst werden die Kacheln auf sehr breiten Monitoren übergroß.
   justify-content:start hält sie linksbündig. */
.sg-lib-grid{display:grid;gap:.75rem;grid-template-columns:repeat(2,minmax(0,1fr))}
@media(min-width:640px){.sg-lib-grid{grid-template-columns:repeat(3,minmax(0,17rem));justify-content:start}}
.sg-2col{display:grid;gap:.75rem;grid-template-columns:1fr}
@media(min-width:640px){.sg-2col{grid-template-columns:1fr 1fr}}

/* ---- Wissen: Dokumentansicht — Reihenfolge auf schmalen Bildschirmen --------
   Auf dem Desktop stehen Zusammenfassung, Inhaltsverzeichnis, Aktionen und
   verwandte Inhalte gesammelt in der rechten Spalte. In der PWA (eine Spalte)
   sollen Zusammenfassung und Inhaltsverzeichnis ÜBER dem Artikeltext stehen,
   Aktionen und verwandte Inhalte darunter — deshalb drei eigene Rasterbereiche
   statt eines Sidebar-Blocks. Eigene Klassen, weil das vorgebaute tailwind.css
   weder grid-template-areas noch `order-*` in den nötigen Stufen kennt. */
.wd-doc-grid{display:grid;gap:1.5rem;grid-template-columns:minmax(0,1fr);
  grid-template-areas:"sidetop" "main" "sidebottom"}
.wd-doc-main      {grid-area:main;min-width:0}
.wd-doc-side-top  {grid-area:sidetop;min-width:0}
.wd-doc-side-bot  {grid-area:sidebottom;min-width:0}
@media(min-width:1024px){
  .wd-doc-grid{grid-template-columns:minmax(0,3fr) minmax(0,1fr);
    grid-template-areas:"main sidetop" "main sidebottom"}
  /* Die Nebenspalte klebt oben — sie darf dabei NICHT höher als das Fenster
     werden. Bei langen Dokumenten wuchs das Inhaltsverzeichnis auf mehrere
     tausend Pixel: der untere Teil war nie erreichbar (sticky schiebt ihn immer
     mit nach unten), und die überhohe Sticky-Ebene hinterließ beim Scrollen
     Geisterbilder über dem Artikeltext. Deshalb auf Fensterhöhe begrenzen und
     bei Bedarf INNEN scrollen. */
  .wd-doc-side-top{
    position:sticky;
    top:6rem;
    align-self:start;
    max-height:calc(100vh - 7.5rem);
    overflow-y:auto;
    overscroll-behavior:contain;
    /* eigene Compositing-Ebene: verhindert Restbilder beim Scrollen */
    transform:translateZ(0);
  }
  /* Der Scroll-Schatten darf die abgerundeten Karten nicht abschneiden. */
  .wd-doc-side-top{padding-right:.25rem;margin-right:-.25rem}
}

/* ---- Dashboard: Schichtkarte überlappt die Hero-Kante ---------------------
   Nur die Schichtkarte schiebt sich unter die abgerundete Unterkante des
   Hero-Headers — das sieht dort gewollt aus. Früher trug der ganze
   .extr-dashboard-body diesen negativen Abstand; ohne Planzuweisung entfällt
   die Karte, und der nächste Block (Schnellaktionen) rutschte unter den Header.
   Der Nachbar-Selektor greift nur, solange der Favoriten-Block ausgeblendet ist:
   wird er sichtbar, steht er ganz oben und die Karte darf nicht mehr ziehen. */
@media (max-width: 1023px) {
  /* ~ statt +: zwischen beiden liegt das (mobil ausgeblendete) Desktop-Raster. */
  #dash-personal.hidden ~ .dash-shift-lead { margin-top: -2rem; }
}

/* ---- Signage: Bildschirm-Kacheln & Segment-Schalter -----------------------
   Eigene Klassen, weil die vorgebaute tailwind.css `focus-visible:ring-primary`
   und `focus-visible:outline-none` nicht enthält — ein Fokusring über Utilities
   wäre unsichtbar. Farben über Design-Token, damit der Dark Mode ohne
   Zusatzregel greift. */
.sg-mon-tile{display:block;width:100%;text-align:left;cursor:pointer}
.sg-mon-tile:hover{border-color:hsl(var(--primary) / .35)}
.sg-mon-tile:focus-visible{outline:2px solid hsl(var(--primary));outline-offset:2px}

.sg-seg{display:inline-flex;align-items:center;gap:.25rem;padding:.25rem;border-radius:.75rem;
  background:hsl(var(--muted) / .6);max-width:100%;overflow-x:auto;scrollbar-width:none}
.sg-seg::-webkit-scrollbar{display:none}
.sg-seg-btn{flex:0 0 auto;padding:.35rem .85rem;border-radius:.5rem;border:0;background:transparent;
  font-size:.875rem;font-weight:500;color:hsl(var(--muted-foreground));cursor:pointer;white-space:nowrap}
.sg-seg-btn:hover{color:hsl(var(--foreground))}
.sg-seg-btn.is-active{background:hsl(var(--card));color:hsl(var(--foreground));
  box-shadow:0 1px 2px 0 rgb(0 0 0 / .05)}
/* Volle Breite mit gleich breiten Feldern und Symbol vor dem Wort (Card-Editor). */
.sg-seg--fill{display:flex;width:100%}
.sg-seg--fill .sg-seg-btn{flex:1 1 0;min-width:0;display:inline-flex;align-items:center;justify-content:center;
  gap:.35rem;padding:.4rem .35rem;font-size:.8125rem;transition:background-color .15s,color .15s,box-shadow .15s}
.sg-seg-btn svg{width:.95rem;height:.95rem;flex:0 0 auto}
.sg-seg-btn:focus-visible{outline:2px solid hsl(var(--primary));outline-offset:1px}
.sg-seg--fill .sg-seg-btn.is-active{color:var(--primary-hsl);
  box-shadow:0 1px 2px 0 rgb(0 0 0 / .08),0 0 0 1px hsl(var(--border) / .7)}

/* ---- Signage: Card-Editor ---------------------------------------------------
   Ab 1024 px steht der Editor auf Fensterhöhe: die Vorschau bleibt stehen, die
   Eigenschaften scrollen in ihrer eigenen Spalte. Darunter liegen beide
   übereinander und die Seite scrollt wie gewohnt. */
@media(min-width:1024px){
  .sg-ed-page{height:100vh;height:100dvh;min-height:0;overflow:hidden}
  .sg-ed-page .sg-ed-props{overscroll-behavior:contain;scrollbar-gutter:stable}
}
.sg-ed-props input[type=range]{width:100%;accent-color:hsl(var(--primary));cursor:pointer}
.sg-ed-sec + .sg-ed-sec{border-top:1px solid hsl(var(--border));padding-top:1.1rem}
.sg-ed-h{display:flex;align-items:center;gap:.5rem;margin:0 0 .6rem;font-size:.875rem;font-weight:600}
.sg-ed-h svg{width:1rem;height:1rem;color:hsl(var(--muted-foreground));flex:0 0 auto}
.sg-ed-h-note{margin-left:auto;font-size:.72rem;font-weight:400;color:hsl(var(--muted-foreground))}
.sg-ed-hint{margin:0;font-size:.75rem;line-height:1.45;color:hsl(var(--muted-foreground))}
.sg-ed-fields{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:.6rem .6rem}
.sg-ed-fields > .is-wide{grid-column:1 / -1}
.sg-ed-lbl{display:flex;align-items:baseline;justify-content:space-between;gap:.5rem;margin-bottom:.25rem;
  font-size:.75rem;font-weight:500;color:hsl(var(--muted-foreground))}
.sg-ed-lbl .sg-ed-val{font-variant-numeric:tabular-nums;color:hsl(var(--foreground))}
.sg-ed-panel{display:flex;flex-direction:column;gap:.7rem;margin-top:.75rem}
.sg-ed-panel.hidden{display:none}
.sg-ed-stack{display:flex;flex-direction:column;gap:.7rem}
.sg-ed-stack.hidden{display:none}

/* Farbfeld: Farbfläche öffnet den Farbwähler, daneben der Hex-Wert zum Eintippen. */
.sg-color{display:flex;align-items:center;gap:.4rem;height:2.375rem;padding:0 .4rem 0 .3rem;
  border-radius:var(--radius-lg, .75rem);border:1px solid hsl(var(--border));background:hsl(var(--card))}
.sg-color:focus-within{box-shadow:0 0 0 2px hsl(var(--primary) / .2)}   /* wie .extr-input:focus */
.sg-color input[type=color]{appearance:none;-webkit-appearance:none;flex:0 0 auto;width:1.6rem;height:1.6rem;padding:0;
  border:1px solid hsl(var(--foreground) / .22);border-radius:.4rem;background:none;cursor:pointer;overflow:hidden}
.sg-color input[type=color]::-webkit-color-swatch-wrapper{padding:0}
.sg-color input[type=color]::-webkit-color-swatch{border:0;border-radius:0}
.sg-color input[type=color]::-moz-color-swatch{border:0}
.sg-color input[type=text]{flex:1 1 auto;min-width:0;width:100%;height:100%;border:0;outline:0;background:transparent;
  font-size:.8125rem;font-variant-numeric:tabular-nums;text-transform:uppercase;letter-spacing:.02em;color:hsl(var(--foreground))}
.sg-color.is-bad{border-color:hsl(var(--destructive))}

/* Hochladen (leer) und hinterlegte Datei (Miniatur + Aktionen). */
.sg-drop{display:flex;align-items:center;justify-content:center;gap:.5rem;width:100%;padding:.85rem .75rem;
  border:1px dashed hsl(var(--border));border-radius:.75rem;background:hsl(var(--muted) / .35);
  font-size:.8125rem;font-weight:500;color:hsl(var(--foreground));cursor:pointer;transition:border-color .15s,background-color .15s}
.sg-drop svg{width:1rem;height:1rem;color:hsl(var(--muted-foreground))}
.sg-drop:hover{border-color:hsl(var(--primary) / .55);background:hsl(var(--primary) / .05)}
.sg-drop:focus-visible{outline:2px solid hsl(var(--primary));outline-offset:2px}
.sg-drop:disabled{opacity:.6;cursor:progress}
.sg-asset{display:flex;align-items:center;gap:.65rem;padding:.4rem;border:1px solid hsl(var(--border));
  border-radius:.75rem;background:hsl(var(--card))}
.sg-asset.hidden{display:none}
.sg-asset-thumb{flex:0 0 auto;width:4.5rem;height:3rem;border-radius:.5rem;overflow:hidden;
  background:hsl(var(--muted)) center / cover no-repeat;display:flex;align-items:center;justify-content:center;
  color:hsl(var(--muted-foreground))}
.sg-asset-thumb img{width:100%;height:100%;object-fit:contain}
.sg-asset-txt{flex:1 1 auto;min-width:0;font-size:.8125rem;line-height:1.3}
.sg-asset-txt b{display:block;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sg-asset-txt span{display:block;font-size:.72rem;color:hsl(var(--muted-foreground))}

/* Elemente: hinzufügen, Ebenenliste (oben = vorn), Eigenschaften des gewählten Elements. */
.sg-add{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:.4rem}
.sg-layers{display:flex;flex-direction:column;gap:.25rem;margin:.75rem 0 .35rem;padding:0;list-style:none}
.sg-layer{position:relative;display:flex;align-items:center;gap:.45rem;min-height:2.5rem;padding:.2rem .3rem .2rem .15rem;
  border:1px solid hsl(var(--border));border-radius:.65rem;background:hsl(var(--card));cursor:pointer;
  transition:border-color .15s,background-color .15s,box-shadow .15s}
.sg-layer:hover{border-color:hsl(var(--primary) / .4)}
.sg-layer.is-sel{border-color:var(--primary-hsl);background:hsl(var(--primary) / .06)}
.sg-layer:focus-visible{outline:2px solid hsl(var(--primary));outline-offset:1px}
.sg-layer-grip{flex:0 0 auto;display:flex;align-items:center;justify-content:center;width:1.1rem;height:1.75rem;
  color:hsl(var(--muted-foreground) / .7);cursor:grab}
.sg-layer-grip:active{cursor:grabbing}
.sg-layer-grip svg{width:.9rem;height:.9rem}
.sg-layer-ico{flex:0 0 auto;display:flex;align-items:center;justify-content:center;width:1.6rem;height:1.6rem;
  border-radius:.45rem;background:hsl(var(--muted));color:hsl(var(--muted-foreground));line-height:0;overflow:hidden}
.sg-layer-ico img{width:100%;height:100%;object-fit:cover}
.sg-layer.is-sel .sg-layer-ico{background:hsl(var(--primary) / .14);color:var(--primary-hsl)}
.sg-layer-txt{flex:1 1 auto;min-width:0;font-size:.8125rem;line-height:1.25}
.sg-layer-txt b{display:block;font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sg-layer-txt span{display:block;font-size:.7rem;color:hsl(var(--muted-foreground))}
.sg-layer-act{flex:0 0 auto;display:flex;align-items:center;gap:.1rem;opacity:0;transition:opacity .15s}
.sg-layer:hover .sg-layer-act,.sg-layer:focus-within .sg-layer-act,.sg-layer.is-sel .sg-layer-act{opacity:1}
@media (pointer:coarse){.sg-layer-act{opacity:1}}
.sg-layer.is-drag{opacity:.4}
.sg-layer.is-over-before::before,.sg-layer.is-over-after::after{content:"";position:absolute;left:.25rem;right:.25rem;
  height:2px;border-radius:2px;background:var(--primary-hsl);pointer-events:none}
.sg-layer.is-over-before::before{top:-.22rem}
.sg-layer.is-over-after::after{bottom:-.22rem}
.sg-el{margin-top:.85rem;border:1px solid hsl(var(--border));border-radius:.85rem;background:hsl(var(--muted) / .25);overflow:hidden}
.sg-el.hidden{display:none}
.sg-el-head{display:flex;align-items:center;gap:.5rem;padding:.5rem .55rem .5rem .75rem;
  border-bottom:1px solid hsl(var(--border));background:hsl(var(--card))}
.sg-el-title{flex:1 1 auto;min-width:0;font-size:.8125rem;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sg-el-body{display:flex;flex-direction:column;gap:.7rem;padding:.75rem}
.sg-el-sub{display:flex;flex-direction:column;gap:.7rem;padding-top:.7rem;border-top:1px solid hsl(var(--border))}
/* Hinweise, die nur mit Maus/Tastatur bzw. nur bei Fingerbedienung stimmen. */
.sg-coarse{display:none}
@media (pointer:coarse){.sg-fine{display:none}.sg-coarse{display:inline}}
.sg-pos{display:grid;grid-template-columns:minmax(0,1fr) auto minmax(0,1fr) auto;gap:.35rem;align-items:end}

/* ---- Signage: Zeitplan-Editor (Tagesleiste + Zeilen) -----------------------
   Löst die alte flex-wrap-Zeile (.sg-slot-row) ab. Eigene Klassen, weil die
   vorgebaute tailwind.css weder grid-template-areas noch die benötigten
   responsiven Varianten enthält (CLAUDE-UI §2.1).
   Die Balkenfarben stehen bewusst als feste Hex-Werte hier — gleiche Konvention
   wie .shift-st-* weiter unten: Pastellfläche + dunkle Schrift ist in beiden
   Themes lesbar, deshalb gibt es (wie dort) keinen data-theme="dark"-Zweig. */

/* Kopfzeile ---------------------------------------------------------------- */
.sg-sched-head{display:flex;align-items:center;justify-content:space-between;
  gap:.5rem;flex-wrap:wrap;margin-bottom:.4rem}
.sg-sched-head-act{display:flex;align-items:center;gap:.85rem}

/* Tagesleiste (24 h) ------------------------------------------------------- */
.sg-sched-bar{position:relative;padding-top:1rem;margin-bottom:.15rem}
.sg-sched-track{position:relative;height:2.25rem;overflow:hidden;
  border:1px solid hsl(var(--border));border-radius:.6rem;background:hsl(var(--muted))}
.sg-sched-seg{position:absolute;top:0;bottom:0;display:flex;align-items:center;
  padding:0 .35rem;overflow:hidden;white-space:nowrap;cursor:pointer;
  border-left:1px solid rgba(255,255,255,.6);
  background:var(--sg-c,hsl(var(--muted)));color:var(--sg-cs,hsl(var(--muted-foreground)));
  font-size:.66rem;font-weight:600;line-height:1}
.sg-sched-seg:first-child{border-left:0}
.sg-sched-seg:hover{filter:brightness(.95)}
.sg-sched-seg-lbl{overflow:hidden;text-overflow:ellipsis}
/* Lücke = Standard-Playlist: schraffiert, nicht anklickbar */
.sg-sched-seg.is-default{cursor:default;color:hsl(var(--muted-foreground));
  background:repeating-linear-gradient(135deg,
    hsl(var(--muted)) 0 6px, hsl(var(--border)) 6px 7px)}
.sg-sched-seg.is-default:hover{filter:none}
/* 3-Stunden-Raster über den Segmenten */
.sg-sched-ticks{position:absolute;inset:0;pointer-events:none;
  background:repeating-linear-gradient(to right,
    transparent 0, transparent calc(100% / 8 - 1px),
    hsl(var(--foreground) / .11) calc(100% / 8 - 1px), hsl(var(--foreground) / .11) calc(100% / 8))}
/* „jetzt"-Marker */
.sg-sched-now{position:absolute;top:1rem;height:2.25rem;width:0;z-index:3;
  border-left:2px solid hsl(var(--destructive));pointer-events:none}
.sg-sched-now-lbl{position:absolute;bottom:100%;left:0;transform:translateX(-50%);
  margin-bottom:.15rem;padding:.05rem .28rem;border-radius:.25rem;
  background:hsl(var(--destructive));color:hsl(var(--destructive-foreground));
  font-size:.6rem;font-weight:700;line-height:1.35;white-space:nowrap}
.sg-sched-now.is-start .sg-sched-now-lbl{transform:none}
.sg-sched-now.is-end   .sg-sched-now-lbl{transform:translateX(-100%)}
/* Stundenachse */
.sg-sched-axis{position:relative;height:.95rem;margin-bottom:.55rem}
.sg-sched-axis span{position:absolute;top:0;transform:translateX(-50%);
  font-size:.6rem;line-height:1;color:hsl(var(--muted-foreground));
  font-variant-numeric:tabular-nums}
.sg-sched-axis span:first-child{transform:none}
.sg-sched-axis span:last-child{transform:translateX(-100%)}

/* Zeilen-Editor ------------------------------------------------------------ */
.sg-sched-rows{display:flex;flex-direction:column;gap:.5rem}
.sg-sched-row{display:grid;align-items:end;gap:.35rem .5rem;padding:.55rem .6rem;
  border:1px solid hsl(var(--border));border-radius:.75rem;background:hsl(var(--card));
  grid-template-columns:1fr 1fr 2rem;
  grid-template-areas:"from to act" "pl pl pl" "msg msg msg"}
@media(min-width:640px){
  .sg-sched-row{grid-template-columns:7.25rem 7.25rem minmax(0,1fr) 2rem;
    grid-template-areas:"from to pl act" "msg msg msg msg"}
}
.sg-sched-row.is-live {border-color:hsl(var(--primary) / .45);background:hsl(var(--primary) / .05)}
.sg-sched-row.is-error{border-color:hsl(var(--destructive) / .5);background:hsl(var(--destructive) / .05)}
.sg-sched-row.is-flash{animation:sgSchedFlash 1s ease-out 1}
@keyframes sgSchedFlash{0%{box-shadow:0 0 0 3px hsl(var(--primary) / .35)}100%{box-shadow:0 0 0 3px hsl(var(--primary) / 0)}}
.sg-sched-f-from{grid-area:from}
.sg-sched-f-to  {grid-area:to}
.sg-sched-f-pl  {grid-area:pl;min-width:0}
.sg-sched-f-act {grid-area:act;display:flex;align-items:center;justify-content:flex-end}
.sg-sched-msgs  {grid-area:msg;display:flex;flex-direction:column;gap:.15rem}
.sg-sched-msgs:empty{display:none}
.sg-sched-lbl{display:flex;align-items:center;justify-content:space-between;gap:.35rem;
  margin-bottom:.22rem;font-size:.66rem;font-weight:500;line-height:1;
  color:hsl(var(--muted-foreground))}
.sg-sched-lbl-txt{display:inline-flex;align-items:center;gap:.3rem;min-width:0}
.sg-sched-swatch{flex:0 0 auto;width:.6rem;height:.6rem;border-radius:.15rem;
  background:var(--sg-c,hsl(var(--muted)))}
.sg-sched-inp{width:100%;min-width:0;height:2.25rem;padding:0 .5rem;
  font-size:.875rem;color:hsl(var(--foreground));background:hsl(var(--card));
  border:1px solid hsl(var(--border));border-radius:.5rem}
.sg-sched-inp:focus{outline:none;border-color:var(--primary-hsl);
  box-shadow:0 0 0 3px hsl(var(--primary) / .18)}
.sg-sched-inp.is-bad{border-color:hsl(var(--destructive));
  box-shadow:0 0 0 3px hsl(var(--destructive) / .14)}
.sg-sched-del{display:flex;align-items:center;justify-content:center;
  height:2.25rem;width:2rem;border:0;border-radius:.5rem;background:transparent;
  color:hsl(var(--muted-foreground));cursor:pointer}
.sg-sched-del:hover{background:hsl(var(--destructive) / .12);color:hsl(var(--destructive))}
.sg-sched-msg{display:flex;align-items:flex-start;gap:.3rem;font-size:.68rem;line-height:1.3}
.sg-sched-msg.is-err {color:hsl(var(--destructive))}
.sg-sched-msg.is-warn{color:#b45309}      /* amber-700, wie .shift-st-*-Konvention */
.sg-sched-live{display:inline-flex;align-items:center;gap:.25rem;flex:0 0 auto;
  padding:.08rem .4rem;border-radius:9999px;
  font-size:.62rem;font-weight:700;text-transform:uppercase;letter-spacing:.03em;
  background:hsl(var(--primary) / .12);color:var(--primary-hsl)}   /* NICHT hsl(var(--primary-hsl)) */
.sg-sched-live::before{content:"";width:.35rem;height:.35rem;border-radius:9999px;
  background:var(--primary-hsl)}
.sg-sched-empty{padding:.8rem;border:1px dashed hsl(var(--border));border-radius:.75rem;
  font-size:.75rem;line-height:1.4;color:hsl(var(--muted-foreground));text-align:center}
.sg-sched-foot{display:flex;align-items:flex-start;justify-content:space-between;
  gap:.75rem;flex-wrap:wrap;margin-top:.6rem}
.sg-sched-hint{margin:0;font-size:.68rem;line-height:1.4;color:hsl(var(--muted-foreground))}

/* Balkenpalette: deterministisch aus playlist_id (id % 8), siehe sgSchedColor().
   Fläche = Tailwind-*-100/200-Niveau, Schrift = *-800 → in Light wie Dark lesbar. */
.sg-sched-c0{--sg-c:#dbeafe;--sg-cs:#1e40af}  /* blau    */
.sg-sched-c1{--sg-c:#d1fae5;--sg-cs:#065f46}  /* emerald */
.sg-sched-c2{--sg-c:#fef3c7;--sg-cs:#92400e}  /* amber   */
.sg-sched-c3{--sg-c:#ede9fe;--sg-cs:#6d28d9}  /* violett */
.sg-sched-c4{--sg-c:#ffe4e6;--sg-cs:#9f1239}  /* rosé    */
.sg-sched-c5{--sg-c:#ccfbf1;--sg-cs:#115e59}  /* türkis  */
.sg-sched-c6{--sg-c:#e0e7ff;--sg-cs:#4338ca}  /* indigo  */
.sg-sched-c7{--sg-c:#ffedd5;--sg-cs:#9a3412}  /* orange  */

/* ---- Signage: Icon-Auswahl im Card-Editor ---------------------------------- */
.sg-ico-grid{display:grid;grid-template-columns:repeat(6,minmax(0,1fr));gap:.25rem;
  max-height:11rem;overflow-y:auto;padding:.25rem;border:1px solid hsl(var(--border));border-radius:.6rem}
.sg-ico-btn{display:flex;align-items:center;justify-content:center;aspect-ratio:1/1;
  border-radius:.4rem;border:1px solid transparent;color:hsl(var(--foreground));background:transparent;cursor:pointer}
.sg-ico-btn:hover{background:hsl(var(--muted))}
/* --primary-hsl ist bereits eine fertige hsl()-Funktion — hsl(var(--primary-hsl))
   ergäbe hsl(hsl(…)) und fiele ersatzlos aus. */
.sg-ico-btn.is-active{border-color:hsl(var(--primary));background:hsl(var(--primary) / 0.1);color:var(--primary-hsl)}
.sg-ico-grp{grid-column:1/-1;font-size:.65rem;text-transform:uppercase;letter-spacing:.04em;
  color:hsl(var(--muted-foreground));padding:.35rem .15rem .1rem}

/* ---- Signage: Card-Vorschauflächen ----------------------------------------
   `bg-slate-900` fehlt im vorgebauten tailwind.css (nur bg-slate-900/55 ist
   kompiliert) — die Letterbox hinter den Thumbnails war deshalb transparent.
   Eigene Klasse statt Utility. */
.sg-thumb{background:#0f172a}

/* ---- Signage: Playlist-Reihenfolge (kompakte, sortierbare Liste) ----------- */
.sg-items-list{display:flex;flex-direction:column;gap:.5rem}
.sg-item-row{display:flex;align-items:center;gap:.5rem;background:hsl(var(--card));
  border:1px solid hsl(var(--border));border-radius:.75rem;padding:.5rem;
  -webkit-user-select:none;user-select:none}
.sg-item-grip{display:flex;align-items:center;justify-content:center;
  width:1.25rem;flex:0 0 1.25rem;align-self:stretch;border-radius:.3rem;border:0;
  color:hsl(var(--muted-foreground));cursor:grab;touch-action:none;background:transparent}
.sg-item-grip:hover{background:hsl(var(--muted))}
.sg-item-grip:focus-visible{outline:2px solid hsl(var(--primary));outline-offset:1px}
.sg-item-row.is-dragging{position:relative;z-index:30;cursor:grabbing;
  box-shadow:0 14px 30px -12px rgba(0,0,0,.38);border-color:hsl(var(--primary))}
.sg-item-row.is-dragging .sg-item-grip{cursor:grabbing}
/* Platzhalter, der beim Ziehen die Ziellücke zeigt. */
.sg-item-ph{border:2px dashed hsl(var(--primary) / .5);border-radius:.75rem;
  background:hsl(var(--primary) / .06)}
/* Thumbnail-Box mit fester Höhe: der Renderer skaliert die Card hinein und
   letterboxt selbst (Math.min(cw/w, ch/h) in signage-render.js). */
.sg-item-th{position:relative;flex:0 0 auto;border-radius:.4rem;overflow:hidden;background:#0f172a}
.sg-item-th.is-land{width:5.25rem;height:2.95rem}
.sg-item-th.is-port{width:2.15rem;height:3.75rem}
.sg-item-idx{position:absolute;left:0;top:0;z-index:2;
  font-size:.6rem;font-weight:700;line-height:1;padding:.15rem .25rem;
  border-bottom-right-radius:.3rem;background:rgba(0,0,0,.55);color:#fff}
/* Bibliothekskachel: `hover:border-primary` fehlt im Build (nur /50 ist da). */
.sg-lib-tile:hover{border-color:hsl(var(--primary) / .5)}

/* ---- Signage: Meta-Zeilen der Card-Kacheln --------------------------------
   Eigene Klasse statt Utilities: Schriftgrad, Icon-Größe und Zeilenabstand in
   einem — und der ungelayerte Reset p{margin:0} greift hier sonst. */
.sg-card-meta{display:flex;align-items:center;gap:.3rem;min-width:0;
  margin-top:.25rem;font-size:11px;line-height:1.35;color:hsl(var(--muted-foreground))}
.sg-card-meta svg{height:.75rem;width:.75rem;flex:0 0 auto}
.sg-card-meta-txt{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sg-card-dot{opacity:.5;flex:0 0 auto}

/* ---- Signage: Fanglinien beim Ziehen im Card-Editor ------------------------
   Feste Farben statt Design-Token: Die Linien liegen auf der Bühne, also über
   fremder Grafik — sie müssen sich gegen jeden Hintergrund behaupten (der weiße
   Halo macht das auf hellen wie dunklen Cards). */
.sg-guide{position:absolute;display:none;pointer-events:none;z-index:5;
  background:#f43f5e;box-shadow:0 0 0 1px rgba(255,255,255,.45)}
.sg-guide.is-on{display:block}
.sg-guide-v{top:0;height:100%;width:1px}
.sg-guide-h{left:0;width:100%;height:1px}

/* ---- Signage: Playlist-Kacheln (Übersicht) --------------------------------
   Die ganze Kachel ist klickbar — nicht über ein <a> um die Aktionsknöpfe herum
   (verschachtelte Klickziele), sondern über ein Pseudo-Element auf dem Titel-
   Link. Die Aktionen liegen per z-index darüber und bleiben erreichbar. */
.sg-pl-card{position:relative;display:flex;flex-direction:column;gap:.75rem}
.sg-pl-title{display:block;min-width:0;font-weight:600;text-decoration:none;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sg-pl-title::after{content:'';position:absolute;inset:0;border-radius:1rem;z-index:0}
.sg-pl-card:hover .sg-pl-title{color:var(--primary-hsl)}
.sg-pl-actions{position:relative;z-index:1;display:flex;align-items:center;gap:.25rem;flex:0 0 auto}
.sg-pl-desc{margin:.15rem 0 0;font-size:.875rem;color:hsl(var(--muted-foreground));
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.sg-pl-meta{display:flex;flex-direction:column;gap:.35rem;margin-top:auto;
  padding-top:.75rem;border-top:1px solid hsl(var(--border))}
.sg-pl-meta-row{margin:0;display:flex;align-items:center;gap:.5rem;min-width:0;
  font-size:.75rem;line-height:1.3;color:hsl(var(--muted-foreground))}
.sg-pl-meta-row > i, .sg-pl-meta-row > svg{flex:0 0 auto}
.sg-pl-meta-txt{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* Warnton (leere Playlist) — eigene Klasse, weil ein Utility gegen die
   ungelayerte .sg-pl-meta-row verlöre. */
.sg-pl-meta-row.is-warn{color:#b45309}
html[data-theme="dark"] .sg-pl-meta-row.is-warn{color:#fbbf24}
/* „läuft"-Pille. NICHT hsl(var(--primary-hsl)) — das ergäbe hsl(hsl(…)). */
.sg-pl-live{display:inline-flex;align-items:center;gap:.25rem;padding:.1rem .45rem;
  border-radius:9999px;font-size:.68rem;font-weight:600;flex:0 0 auto;
  background:hsl(var(--primary) / 0.1);color:var(--primary-hsl)}
.sg-pl-dot{width:.4rem;height:.4rem;border-radius:9999px;background:hsl(var(--primary));flex:0 0 auto}
/* Feldfehler in den Signage-Modalen (kein Toast-Only) */
.sg-field-err{border-color:hsl(var(--destructive))}
.sg-field-msg{margin:.3rem 0 0;font-size:.75rem;color:hsl(var(--destructive))}

/* ---- Signage: System-Cards (fest eingebaut, Inhalt aus „Ereignisse") --------
   Kennzeichen „System" an Kacheln und im Kopf der Vorschau, dazu die Vorschauseite
   mit Bühne (Hoch/Quer) und Seitenleiste. Die Card selbst zeichnet der Renderer
   (assets/js/signage-render.js) mit festen Farben — sie läuft auf dem Kiosk ohne
   dieses Stylesheet. */
.sg-sys-badge{display:inline-flex;align-items:center;gap:.25rem;padding:.1rem .5rem;border-radius:9999px;
  font-size:.68rem;font-weight:600;line-height:1.4;flex:0 0 auto;white-space:nowrap;
  background:hsl(var(--muted));color:hsl(var(--muted-foreground))}
.sg-sys-badge svg{height:.7rem;width:.7rem;flex:0 0 auto}
.sg-sys-grid{display:grid;gap:1.5rem;grid-template-columns:minmax(0,1fr)}
@media(min-width:1024px){.sg-sys-grid{grid-template-columns:minmax(0,1fr) minmax(0,22rem);align-items:start}}
.sg-sys-preview{display:flex;align-items:center;justify-content:center;padding:1rem;border-radius:1rem;background:#0f172a}
.sg-sys-stage{position:relative;width:100%;border-radius:.5rem;overflow:hidden;background:#0f172a}
.sg-sys-stage.is-land{aspect-ratio:16/9}
.sg-sys-stage.is-port{width:auto;height:min(72vh,48rem);aspect-ratio:9/16}
.sg-sys-steps{display:flex;flex-direction:column;gap:.6rem;margin:0;padding:0;list-style:none}
.sg-sys-steps li{display:flex;gap:.6rem;align-items:flex-start;font-size:.875rem;line-height:1.45}
.sg-sys-steps svg{height:1rem;width:1rem;flex:0 0 auto;margin-top:.15rem;color:var(--primary-hsl)}
.sg-sys-mon{display:flex;align-items:center;justify-content:space-between;gap:.75rem;padding:.55rem 0;font-size:.875rem}
.sg-sys-mon-meta{display:inline-flex;align-items:center;gap:.3rem;flex:0 0 auto;font-size:.75rem;color:hsl(var(--muted-foreground))}
.sg-sys-mon-meta svg{height:.8rem;width:.8rem}
.sg-sys-warn{color:#b45309}
html[data-theme="dark"] .sg-sys-warn{color:#fbbf24}

/* ---- Schichtplanung: Status-Farben (Arbeitsplan-Farbkonvention) ----------
   Eigene Klassen statt Tailwind-Utilities: das vorkompilierte tailwind.css
   enthält nicht alle benötigten Farbstufen. Verwendung über den Statuskatalog
   extr_shift_statuses() (bg-Feld trägt die komplette Klasse). */
.shift-st-frueh        { background:#dbeafe; color:#1e40af; border-color:#93c5fd; } /* Frühschicht: blau */
.shift-st-mittel       { background:#ffedd5; color:#9a3412; border-color:#fdba74; } /* Mittelschicht: orange (2026-09-21) */
.shift-st-spaet        { background:#ffffff; color:#334155; border-color:#94a3b8; } /* Spätschicht: weiß */
.shift-st-nacht        { background:#1e293b; color:#e2e8f0; border-color:#0f172a; } /* Nachtschicht: nachtblau (2026-09-21) */
.shift-st-arbeitstag   { background:#e0f2fe; color:#0369a1; border-color:#7dd3fc; } /* Arbeitstag: hellblau */
.shift-st-frei         { background:#fef9c3; color:#854d0e; border-color:#fde047; } /* Freier Rolltag: gelb */
.shift-st-urlaub       { background:#dcfce7; color:#166534; border-color:#86efac; } /* Urlaub: grün */
.shift-st-krank        { background:#fee2e2; color:#b91c1c; border-color:#fca5a5; } /* Krank: rot */
.shift-st-schule       { background:#ede9fe; color:#6d28d9; border-color:#c4b5fd; } /* Schule/Studium: violett */
.shift-st-dienstreise  { background:#e0e7ff; color:#4338ca; border-color:#a5b4fc; } /* Dienstreise: indigo */
.shift-st-sonntag      { background:#e2e8f0; color:#64748b; border-color:#cbd5e1; } /* Sonntag (frei): grau, ≠ gelber Rolltag */

/* Zellmarker: Einsatz (Depot/Intermodal), Schlüsseldienst, Bereitschaft */
.shift-badge { position:absolute; bottom:1px; left:50%; transform:translateX(-50%);
  font-size:8px; line-height:1; font-weight:700; letter-spacing:.02em; padding:1px 3px;
  border-radius:4px; background:rgba(15,23,42,.78); color:#fff; white-space:nowrap; }
/* Split-Kürzel (logische Unterteilung des Plans) — unten rechts in der Zelle */
.shift-split { position:absolute; bottom:1px; right:2px;
  font-size:8px; line-height:1; font-weight:700; letter-spacing:.02em;
  color:currentColor; opacity:.75; white-space:nowrap; }
.shift-flag  { position:absolute; top:2px; left:2px; display:flex; gap:1px; }
.shift-flag i, .shift-flag svg { width:9px; height:9px; }
/* Eingereichter, noch nicht genehmigter Urlaub im Raster: gleiche Farbe wie genehmigt, gestrichelt (Feedback PLAN-07) */
.shift-abs-pending { border-style: dashed; opacity: .8; }
/* Summenzeile „Anwesend“ (Feedback PLAN-10) — klebt im scrollenden Gesamtplan am unteren Rand */
.shift-sum-row td { background: #f1f5f9; border-top: 2px solid hsl(var(--border)); }
.shift-gesamt-scroll tfoot td { position: sticky; bottom: 0; z-index: 20; }
.shift-gesamt-scroll tfoot td:first-child { z-index: 30; }
.shift-cell-time { position:absolute; bottom:1px; left:50%; transform:translateX(-50%);
  font-size:8px; line-height:1; white-space:nowrap; opacity:.75; }

/* Mein Profil → „Kontakte aufs Handy“: QR-Code links, Anleitung rechts (vorher <style> im Partial).
   Feste Breite für die QR-Spalte: mit „auto“ dehnte die Bildunterschrift die Spalte und drückte die
   Anleitung auf wenige Zeichen zusammen. */
.cd-cols { display:grid; grid-template-columns:minmax(0,1fr); gap:1rem; align-items:start; }
@media (min-width:1024px) { .cd-cols { grid-template-columns:12.5rem minmax(0,1fr); gap:1.5rem; } }

/* ---- Schichtarten: Visualisierungshilfen (2026-09-21) ---------------------
   Kennbuchstabe (F/M/S/N) neben dem Symbol — Farbe allein trägt die Schichtart nicht
   (Farbfehlsichtigkeit, Ausdruck). */
.shift-code { font-size:10px; line-height:1; font-weight:800; letter-spacing:.02em; margin-left:2px; }
/* Zeitband: je Schichtart eine Spur über 24 Stunden — zeigt in der Planübersicht und in der
   Legende, wann die Schicht liegt (Nachtschicht läuft über Mitternacht: zwei Segmente). */
.shift-band { display:grid; gap:.3rem; }
.shift-band-row { display:grid; grid-template-columns:3.4rem minmax(0,1fr) 5.4rem; align-items:center; gap:.5rem; font-size:.75rem; }
.shift-band-label { display:inline-flex; align-items:center; gap:.3rem; font-weight:600; white-space:nowrap; }
.shift-band-label svg, .shift-band-label i { width:.8rem; height:.8rem; flex:0 0 auto; }
.shift-band-track { position:relative; height:.7rem; border-radius:9999px; background:hsl(var(--muted)); overflow:hidden;
  background-image:linear-gradient(to right, hsl(var(--border)) 1px, transparent 1px); background-size:25% 100%; }
.shift-band-seg { position:absolute; top:0; bottom:0; border:1px solid; border-radius:9999px; }
.shift-band-time { text-align:right; white-space:nowrap; color:hsl(var(--muted-foreground)); font-variant-numeric:tabular-nums; }
.shift-band-time.is-missing { font-style:italic; opacity:.7; }
.shift-band-scale { display:grid; grid-template-columns:3.4rem minmax(0,1fr) 5.4rem; gap:.5rem; font-size:.625rem; color:hsl(var(--muted-foreground)); }
.shift-band-scale > div { display:flex; justify-content:space-between; }
/* Wochenansicht: geräumige Zellen mit Symbol, Kennbuchstabe und Uhrzeit */
.shift-week-cell { min-height:3.6rem; height:auto; flex-direction:column; gap:.15rem; padding:.3rem .2rem; }
.shift-week-cell .shift-week-time { font-size:.6875rem; line-height:1.1; font-variant-numeric:tabular-nums; white-space:nowrap; opacity:.85; }
.shift-week-cell .shift-week-label { font-size:.6875rem; line-height:1.1; font-weight:600; white-space:nowrap; }
/* Zuständigkeiten unter dem Namen in den Plänen */
.shift-resp { font-size:.6875rem; line-height:1.2; color:hsl(var(--muted-foreground)); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }

/* ---- Dienstplan-Ansicht „Farben" (Einstellungen → Dienstplan-Ansicht, 2026-10-07) ---------
   Ohne Symbole: die Zelle trägt nur die Farbe des Status, die Legende erklärt sie. Schalter ist
   die Klasse .shift-view-colors auf #extr-main (app.js, aus der Marke extr_shift_view_marker());
   die Farben kommen als --shift-c-<status>-bg/-fg/-bd aus extr_shift_view_css() im Seitenkopf —
   hier stehen die Standardwerte (extr_shift_view_color_defaults(), Wächter: Test
   schichten-ansicht-farben.php). Schlüsseldienst/Bereitschaft erscheinen als Kürzel SD/BD
   (<b> neben dem Symbol in .shift-flag und .shift-mark) statt als Symbol. */
:root {
  --shift-c-frueh-bg:#8db4e8; --shift-c-frueh-fg:#0f172a; --shift-c-frueh-bd:#6e8db9;
  --shift-c-mittel-bg:#f2b47e; --shift-c-mittel-fg:#0f172a; --shift-c-mittel-bd:#b98d69;
  --shift-c-spaet-bg:#a3adbd; --shift-c-spaet-fg:#0f172a; --shift-c-spaet-bd:#7e8898;
  --shift-c-nacht-bg:#5d6494; --shift-c-nacht-fg:#ffffff; --shift-c-nacht-bd:#4a517a;
  --shift-c-frei-bg:#f0dd82; --shift-c-frei-fg:#0f172a; --shift-c-frei-bd:#b8ac6c;
  --shift-c-urlaub-bg:#9ad4a3; --shift-c-urlaub-fg:#0f172a; --shift-c-urlaub-bd:#77a585;
  --shift-c-krank-bg:#ec9c9c; --shift-c-krank-fg:#0f172a; --shift-c-krank-bd:#b57b80;
  --shift-c-schule-bg:#c0b0ea; --shift-c-schule-fg:#0f172a; --shift-c-schule-bd:#948aba;
  --shift-c-dienstreise-bg:#a9b4e6; --shift-c-dienstreise-fg:#0f172a; --shift-c-dienstreise-bd:#838db7;
  --shift-c-arbeitstag-bg:#8ed0e6; --shift-c-arbeitstag-fg:#0f172a; --shift-c-arbeitstag-bd:#6ea2b7;
  --shift-c-sonntag-bg:#e2e8f0; --shift-c-sonntag-fg:#0f172a; --shift-c-sonntag-bd:#adb4bf;
  --shift-c-termin-bg:#cfb3ea; --shift-c-termin-fg:#0f172a; --shift-c-termin-bd:#9f8cba;
}
.shift-st-termin { background:#f5f3ff; color:#6d28d9; border-color:#ddd6fe; } /* Termin (Abwesenheit), wie bg-violet-50/text-violet-700/border-violet-200 */
.shift-view-colors [class*="shift-st-"] i, .shift-view-colors [class*="shift-st-"] svg,
.shift-view-colors [class*="shift-ak-"] i, .shift-view-colors [class*="shift-ak-"] svg,
.shift-view-colors .shift-mark i, .shift-view-colors .shift-mark svg { display:none; }
.shift-view-colors .shift-st-frueh { background:var(--shift-c-frueh-bg); color:var(--shift-c-frueh-fg); border-color:var(--shift-c-frueh-bd); }
.shift-view-colors .shift-st-mittel { background:var(--shift-c-mittel-bg); color:var(--shift-c-mittel-fg); border-color:var(--shift-c-mittel-bd); }
.shift-view-colors .shift-st-spaet { background:var(--shift-c-spaet-bg); color:var(--shift-c-spaet-fg); border-color:var(--shift-c-spaet-bd); }
.shift-view-colors .shift-st-nacht { background:var(--shift-c-nacht-bg); color:var(--shift-c-nacht-fg); border-color:var(--shift-c-nacht-bd); }
.shift-view-colors .shift-st-frei { background:var(--shift-c-frei-bg); color:var(--shift-c-frei-fg); border-color:var(--shift-c-frei-bd); }
.shift-view-colors .shift-st-urlaub, .shift-view-colors .shift-ak-urlaub { background:var(--shift-c-urlaub-bg); color:var(--shift-c-urlaub-fg); border-color:var(--shift-c-urlaub-bd); }
.shift-view-colors .shift-st-krank, .shift-view-colors .shift-ak-krankheit { background:var(--shift-c-krank-bg); color:var(--shift-c-krank-fg); border-color:var(--shift-c-krank-bd); }
.shift-view-colors .shift-st-schule { background:var(--shift-c-schule-bg); color:var(--shift-c-schule-fg); border-color:var(--shift-c-schule-bd); }
.shift-view-colors .shift-st-dienstreise { background:var(--shift-c-dienstreise-bg); color:var(--shift-c-dienstreise-fg); border-color:var(--shift-c-dienstreise-bd); }
.shift-view-colors .shift-st-arbeitstag { background:var(--shift-c-arbeitstag-bg); color:var(--shift-c-arbeitstag-fg); border-color:var(--shift-c-arbeitstag-bd); }
.shift-view-colors .shift-st-sonntag { background:var(--shift-c-sonntag-bg); color:var(--shift-c-sonntag-fg); border-color:var(--shift-c-sonntag-bd); }
.shift-view-colors .shift-st-termin, .shift-view-colors .shift-ak-termin { background:var(--shift-c-termin-bg); color:var(--shift-c-termin-fg); border-color:var(--shift-c-termin-bd); }
.shift-flag b, .shift-mark b { display:none; font-size:8px; line-height:1; font-weight:800; letter-spacing:.02em; }
.shift-view-colors .shift-flag b, .shift-view-colors .shift-mark b { display:inline; }
.shift-view-colors .shift-badge { background:rgba(255,255,255,.92); color:#0f172a; } /* Einsatz-Kürzel auch auf dunkler Fläche lesbar */
.shift-view-colors .shift-abs-pending { opacity:.7; }
/* ---- Legende der Plan-Raster (Plan-Editor, Gesamtplan, Wochenplan) ---------------------------
   Desktop (ab 1024 px): Leiste, die am unteren Fensterrand klebt und sich per Pfeil einklappen
   lässt (Zustand je Gerät in localStorage, app.js: shiftLegendInit). app.js bemisst dazu die Höhe
   des Rasters (data-shift-legend-fit = Id des Scrollbereichs) so, dass Raster und Legende
   zusammen in den Bildschirm passen — die Leiste überdeckt keine Zeile, und die Seite muss nicht
   nachscrollen (Feedback 2026-10-07; die fixe Leiste vom 29.09. überdeckte die letzten Zeilen,
   die Karte unter dem Raster war erst nach dessen Ende zu sehen).
   Mobil: mitlaufender Knopf (.shift-legend-mbtn) öffnet ein Modal (.shift-legend-modal). */
.shift-legend-stick { position: relative; }
.shift-legend-toggle { position: absolute; top: .4rem; right: .4rem; }
.shift-legend-toggle svg { transition: transform .15s ease; }
.shift-legend-mini { display: none; font-size: .75rem; font-weight: 600; line-height: 1.75rem; }
.shift-legend-stick.is-collapsed { padding-top: .3rem; padding-bottom: .3rem; }
.shift-legend-stick.is-collapsed .shift-legend-body { display: none; }
.shift-legend-stick.is-collapsed .shift-legend-mini { display: block; }
.shift-legend-stick.is-collapsed .shift-legend-toggle { top: .2rem; }
.shift-legend-stick.is-collapsed .shift-legend-toggle svg { transform: rotate(180deg); }
.shift-legend-body { padding-right: 2.25rem; }   /* Platz für den Pfeil */
@media (max-width: 1023px) {
  .shift-legend-desktop { display: none; }
}
@media (min-width: 1024px) {
  .shift-legend-mbtn, .shift-legend-modal-wrap { display: none !important; }
  /* z-index über den klebenden Kopf-/Summenzellen der Raster (30), unter Kopfleiste (40) und Modalen (60) */
  .shift-legend-stick { position: sticky; bottom: 0; z-index: 32; box-shadow: 0 -8px 18px -10px rgba(15, 23, 42, .3); }
}
/* Legende im Modal: je Kategorie ein Block mit Überschrift statt einer Zeile mit Beschriftung links */
.shift-legend-modal .flex.flex-wrap { display: block; margin-bottom: .85rem; }
.shift-legend-modal .flex.flex-wrap:last-child { margin-bottom: 0; }
.shift-legend-modal .flex.flex-wrap > span:first-child { display: block; min-width: 0 !important; margin-bottom: .45rem; font-weight: 600; color: hsl(var(--muted-foreground)); text-transform: uppercase; letter-spacing: .03em; font-size: .68rem; }
.shift-legend-modal .flex.flex-wrap > *:not(:first-child) { display: inline-flex; margin: 0 .4rem .45rem 0; }

/* Raumbuchung: Überhang (Reinigung/Räumung) hinter einer Buchung — schraffiert in der Primärfarbe,
   damit er als „belegt, aber kein Termin“ lesbar bleibt (Tages- und Wochen-Zeitleiste). */
.rb-buffer {
  border-radius:.125rem;
  background-image:repeating-linear-gradient(135deg,
    color-mix(in oklab, var(--color-primary) 55%, transparent) 0 3px,
    color-mix(in oklab, var(--color-primary) 18%, transparent) 3px 6px);
}

/* ---- Umschalter-Streifen (Reiter) ------------------------------------------
   Reiter wie „Dokumente / Lernstrecken / Assistent" passen auf schmalen
   Bildschirmen nicht nebeneinander. Ohne Scrollmöglichkeit ragen sie aus dem
   Bildschirm und die hinteren Reiter sind nicht erreichbar. Der Streifen
   scrollt deshalb seitlich; die Bildlaufleiste bleibt verborgen, die Reiter
   selbst schrumpfen nicht und brechen nicht um.
   min-width:0 ist nötig, weil Flex-Elemente sonst nicht unter ihre
   Inhaltsbreite schrumpfen und der Streifen die Seite breiter machen würde. */
.extr-tab-strip {
  max-width: 100%;
  min-width: 0;
  overflow-x: auto;
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  flex-wrap: nowrap;          /* sonst brechen Streifen mit flex-wrap um, statt zu scrollen */
}
.extr-tab-strip::-webkit-scrollbar { display: none; }
.extr-tab-strip > * { flex: 0 0 auto; white-space: nowrap; }

/* ── Dashboard-Konfiguration ────────────────────────────────────────────────
   Platzhalter-Widgets: „Widget wechseln"-Knopf erscheint erst beim Überfahren
   der Karte. Der Raster-Editor (Einstellungen → Dashboard-Ansicht) nutzt
   HTML5-Drag&Drop; die Klassen markieren Zieh-Quellen und Einfüge-Position. */
.dash-ph-swap {
  position: absolute;
  top: -0.5rem;
  right: -0.5rem;
  z-index: 5;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 1.75rem;
  width: 1.75rem;
  border-radius: 9999px;
  background: #fff;
  border: 1px solid hsl(var(--border));
  color: hsl(var(--muted-foreground));
  box-shadow: 0 4px 12px -4px rgba(0, 0, 0, 0.25);
  opacity: 0;
  transition: opacity 0.15s ease, color 0.15s ease;
}
.dash-ph-card:hover .dash-ph-swap { opacity: 1; }
.dash-ph-swap:hover { color: hsl(var(--primary)); }

.dashcfg-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0.5rem;
  align-content: start;
  min-height: 14rem;
  padding: 0.75rem;
  border-radius: 1rem;
  border: 1px solid hsl(var(--border));
  background-color: hsl(var(--muted) / 0.3);
  /* Spalten-Hilfslinien: 1px-Linie je 25%-Kachel (kein repeating-gradient —
     das kippt bei %-Stops in WebKit in endlose Mini-Wiederholungen) */
  background-image: linear-gradient(to left, hsl(var(--border) / 0.35) 1px, transparent 1px);
  background-size: 25% 100%;
  background-repeat: repeat-x;
  /* Am Handy ist die Vorschau breiter als die Karte (vier Spalten, Kacheln mit Mindestbreite): sie
     scrollt in ihrem Rahmen, statt die Seite zu verbreitern; die Hilfslinien laufen mit (2026-10-05). */
  overflow-x: auto;
  background-attachment: local;
}
.dashcfg-item {
  position: relative;
  border-radius: 0.75rem;
  border: 1px solid hsl(var(--border));
  background: hsl(var(--card)); /* UI-Audit DARK-03 */
  padding: 0.6rem 0.6rem;
  min-height: 4.5rem;
  cursor: grab;
  user-select: none;
}
.dashcfg-item.is-ph { border-style: dashed; background: hsl(var(--muted) / 0.4); }
.dashcfg-item.drag-src { opacity: 0.35; }
.dashcfg-item .dashcfg-actions { display: flex; gap: 0.25rem; }
.dashcfg-drop-before::before,
.dashcfg-drop-after::after {
  content: '';
  position: absolute;
  top: 0.2rem;
  bottom: 0.2rem;
  width: 3px;
  border-radius: 2px;
  background: hsl(var(--primary));
}
.dashcfg-drop-before::before { left: -0.35rem; }
.dashcfg-drop-after::after { right: -0.35rem; }
.dashcfg-grid.drag-over-empty { outline: 2px dashed hsl(var(--primary) / 0.5); outline-offset: -6px; }
.dashcfg-src { cursor: grab; user-select: none; }
.dashcfg-src.is-used { opacity: 0.45; cursor: not-allowed; }

/* Abstände der Beschreibungstexte im Dashboard-Editor: der globale Reset oben
   (p{margin:0}, ungelayert) sticht Tailwinds mb-*-Utilities auf <p> aus —
   deshalb eigene, ebenfalls ungelayerte Klassen. */
.dashcfg-h { margin-bottom: 0.4rem; }
.dashcfg-desc { margin-bottom: 1rem; }
.dashcfg-desc-lg { margin-bottom: 1.5rem; }
.dashcfg-item > p { margin-top: 0.4rem; }
.dash-ph-chooser h3 { margin-bottom: 0.3rem; }
.dash-ph-chooser > p { margin-bottom: 0.85rem; }

/* Safe-Area (Notch) additiv zum py-Utility der Seite: ohne diese Regeln ersetzt
   das padding-top oben ein gesetztes py-* (Header wäre oben bündig, unten gepolstert). */
.extr-header-bar.py-3 { padding-top: calc(0.75rem + env(safe-area-inset-top, 0px)); }
.extr-header-bar.py-4 { padding-top: calc(1rem    + env(safe-area-inset-top, 0px)); }
.extr-header-bar.py-5 { padding-top: calc(1.25rem + env(safe-area-inset-top, 0px)); }
.extr-header-bar.py-6 { padding-top: calc(1.5rem  + env(safe-area-inset-top, 0px)); }

/* ============================================================
   Gesamtplan (Zeitkonto/Schichten): Datumszeile beim Scrollen
   anheften. Das Raster scrollt vertikal selbst (begrenzte Höhe) –
   nur so kann der Tabellenkopf im horizontal scrollbaren
   Container kleben bleiben; die Namensspalte bleibt sticky links.
   ============================================================ */
.shift-gesamt-scroll { max-height: max(420px, calc(100vh - 240px)); overflow: auto; }
.shift-gesamt-scroll thead th {
  position: sticky;
  top: 0;
  z-index: 20;
  /* Opak: durchscheinende Utility-Hintergründe ließen sonst die
     darunter scrollenden Zeilen durchschimmern */
  background: linear-gradient(hsl(var(--muted) / 0.4), hsl(var(--muted) / 0.4)) #fff;
  /* border-collapse-Rahmen wandern beim Kleben nicht mit → Linie als Schatten */
  box-shadow: inset 0 -1px 0 hsl(var(--border));
}
.shift-gesamt-scroll thead th:first-child { z-index: 30; }
.shift-gesamt-scroll thead th.bg-slate-100 { background: linear-gradient(#f1f5f9, #f1f5f9) #fff; }
.shift-gesamt-scroll thead th.bg-primary\/10 { background: linear-gradient(hsl(var(--primary) / 0.1), hsl(var(--primary) / 0.1)) #fff; }

/* Planraster der Schichtplanung (schichten-plan.php, Feedback GADORO 29.09.2026):
   - Am Rasterende scrollt die Seite weiter. Der Baustein hält das Scrollen sonst fest
     (overscroll-behavior: contain) — über dem Raster ließ sich die Seite nicht weiterschieben.
     Nur Desktop; mobil bleibt es beim Baustein.
   - Die Kopfzelle „Mitarbeiter“ liegt über den klebenden Namen (z-10) und den Tagesköpfen;
     mit z-index 3 aus .extr-table-sticky schoben sich beim Scrollen die Namen darüber. */
@media (min-width: 1024px) {
  .extr-table-sticky--scroll.shift-plan-scroll { overscroll-behavior-y: auto; }
}
.shift-plan-scroll thead th:first-child { z-index: 12; }
/* Gesamtplan: die klebende Planzelle der Trennzeile braucht einen deckenden Grund — seit die Zeile
   die Anwesenden je Plan zeigt, laufen beim waagerechten Scrollen Zahlen darunter durch
   (Muster Rechtematrix: Tönung als Verlaufsschicht über dem Kartengrund). */
.shift-gesamt-scroll .shift-group-row > td:first-child {
  background: linear-gradient(hsl(var(--muted) / .6), hsl(var(--muted) / .6)), hsl(var(--card));
}

/* ============================================================
   Chat: Nachrichten-Spalte auf volle Zeilenbreite ziehen.
   Ohne feste Breite ist die Spalte shrink-to-fit — die 75%-
   max-width der Bubbles bezog sich dann auf die eigene Inhalts-
   breite, wodurch schon kurze Nachrichten grundlos umbrachen
   („Hallo wie geht's" brach nach „wie" um). Volle Breite lässt
   die Prozent-Angabe auf die Zeile wirken; die Ausrichtung
   übernehmen items-end (eigene) bzw. items-start (fremde).
   ============================================================ */
#chat-messages-feed [data-msg-id] > .flex-col { flex: 1 1 auto; min-width: 0; }

/* Schwebende Navigation im Dunkelmodus: dieselbe Glasoptik, aber mit dunkler
   Fläche und zurückgenommenen Lichtkanten. */
html[data-theme="dark"] .extr-bottom-nav-pill {
  background: hsl(var(--card) / 0.60);
  border-color: hsl(0 0% 100% / 0.10);
  box-shadow:
    0 1px 0 hsl(0 0% 100% / 0.10) inset,
    0 -1px 0 hsl(0 0% 0% / 0.30) inset,
    0 12px 34px hsl(0 0% 0% / 0.55),
    0 2px 10px hsl(0 0% 0% / 0.40);
}
html[data-theme="dark"] .extr-bottom-nav-slider {
  background: hsl(0 0% 100% / 0.10);
  box-shadow: 0 1px 0 hsl(0 0% 100% / 0.12) inset, 0 2px 6px hsl(0 0% 0% / 0.35);
}
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  html[data-theme="dark"] .extr-bottom-nav-pill { background: hsl(var(--card) / 0.97); }
}
@media (prefers-reduced-transparency: reduce) {
  html[data-theme="dark"] .extr-bottom-nav-pill { background: hsl(var(--card) / 0.97); }
}

/* ============================================================
   Header-Aktionen — EINHEITLICH FÜR ALLE MODULE (CLAUDE-UI §3.2)
   ------------------------------------------------------------
   Genau zwei Bedienelemente, immer oben rechts im Modul-Header:
     „+"  legt neuen Inhalt an (nur wenn der Nutzer das darf)
     „⋮"  öffnet das Kontextmenü mit allen weiteren Optionen
   Das Menü klappt auf Höhe des Buttons nach unten auf, wiederholt
   die Neu-Anlegen-Aktion und animiert die drei Punkte zu einem X.
   Markup ausschließlich über extr_page_actions() (page-header.php),
   Verhalten in app.js — NICHT je Modul nachbauen.
   ============================================================ */

.extr-page-actions {
  display: flex;
  align-items: center;
  gap: .5rem;
  flex-shrink: 0;
  margin-left: auto;
}

/* Tap-Ziel 44 px — auf dem Handy waren die alten Icon-Buttons zu klein. */
.extr-action-primary,
.extr-action-more {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 2.75rem;
  width: 2.75rem;
  flex-shrink: 0;
  border-radius: .75rem;
  /* Kein Rahmen in der Grundform: die Primärkette im Bestand hatte keinen,
     nur die Outline-Variante setzt einen (sonst wären alle Knöpfe 2 px höher). */
  border: 0;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: background-color .18s ease, color .18s ease, border-color .18s ease;
}

.extr-action-primary {
  background: hsl(var(--primary-strong));
  color: hsl(var(--primary-foreground));
}
.extr-action-primary:hover { filter: brightness(.93); }
.extr-action-primary svg   { height: 1.375rem; width: 1.375rem; }

.extr-action-more {
  background: hsl(var(--card));
  color: hsl(var(--muted-foreground));
  border-color: hsl(var(--border));
}
.extr-action-more:hover,
.extr-action-more[aria-expanded="true"] {
  background: hsl(var(--muted));
  color: hsl(var(--foreground));
}

.extr-action-primary:focus-visible,
.extr-action-more:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px hsl(var(--primary) / .25);
}

/* Drei Punkte → X. Die Punkte werden zu zwei gekreuzten Balken, der
   mittlere blendet aus; alles über transform/width/height animierbar. */
.extr-action-dots {
  position: relative;
  display: block;
  height: 1.25rem;
  width: 1.25rem;
}
.extr-action-dots span {
  position: absolute;
  left: 50%;
  top: 50%;
  height: .25rem;
  width: .25rem;
  border-radius: 999px;
  background: currentColor;
  transition: transform .22s cubic-bezier(.4, 0, .2, 1),
              width .22s cubic-bezier(.4, 0, .2, 1),
              height .22s cubic-bezier(.4, 0, .2, 1),
              border-radius .22s cubic-bezier(.4, 0, .2, 1),
              opacity .14s linear;
}
.extr-action-dots span:nth-child(1) { transform: translate(-50%, -50%) translateY(-.4375rem); }
.extr-action-dots span:nth-child(2) { transform: translate(-50%, -50%); }
.extr-action-dots span:nth-child(3) { transform: translate(-50%, -50%) translateY(.4375rem); }

.extr-action-more[aria-expanded="true"] .extr-action-dots span:nth-child(1) {
  height: .125rem;
  width: 1.0625rem;
  border-radius: 1px;
  transform: translate(-50%, -50%) rotate(45deg);
}
.extr-action-more[aria-expanded="true"] .extr-action-dots span:nth-child(2) {
  opacity: 0;
  transform: translate(-50%, -50%) scale(.3);
}
.extr-action-more[aria-expanded="true"] .extr-action-dots span:nth-child(3) {
  height: .125rem;
  width: 1.0625rem;
  border-radius: 1px;
  transform: translate(-50%, -50%) rotate(-45deg);
}

/* Kontextmenü — klappt auf Höhe des Buttons nach unten auf, rechtsbündig. */
.extr-action-menu-wrap { position: relative; }

.extr-action-menu {
  display: none;
  position: absolute;
  right: 0;
  top: calc(100% + .5rem);
  min-width: 15rem;
  max-width: min(22rem, calc(100vw - 2rem));
  padding: .375rem;
  z-index: 60;
  background: hsl(var(--card));
  border: 1px solid hsl(var(--border));
  border-radius: .875rem;
  box-shadow: var(--extr-shadow-lg);
}
.extr-action-menu-wrap.is-open .extr-action-menu {
  display: block;
  animation: extr-action-menu-in .16s cubic-bezier(.2, .7, .3, 1);
}
@keyframes extr-action-menu-in {
  from { opacity: 0; transform: translateY(-.375rem) scale(.98); }
  to   { opacity: 1; transform: none; }
}

.extr-action-item {
  display: flex;
  align-items: center;
  gap: .625rem;
  width: 100%;
  padding: .5rem .625rem;
  border: 0;
  border-radius: .5rem;
  background: none;
  color: hsl(var(--foreground));
  font-size: .875rem;
  font-weight: 500;
  line-height: 1.35;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
  transition: background-color .15s ease, color .15s ease;
}
.extr-action-item:hover  { background: hsl(var(--muted)); }
.extr-action-item svg    { height: 1rem; width: 1rem; flex-shrink: 0; opacity: .7; }
.extr-action-item-label  { flex: 1 1 auto; min-width: 0; }

.extr-action-item--primary     { color: hsl(var(--primary)); font-weight: 600; }
.extr-action-item--primary svg { opacity: 1; }

.extr-action-item--danger        { color: hsl(var(--destructive)); }
.extr-action-item--danger:hover  { background: hsl(var(--destructive) / .1); }
.extr-action-item--danger svg    { opacity: 1; }

.extr-action-sep {
  height: 1px;
  margin: .375rem .25rem;
  background: hsl(var(--border));
}

/* Live-Zaehler am „+"-Button (z. B. Warenkorb) */
.extr-action-primary { position: relative; }
.extr-action-count {
  position: absolute;
  top: -.25rem;
  right: -.25rem;
  white-space: nowrap;
  min-width: 1.25rem;
  height: 1.25rem;
  padding: 0 .25rem;
  border-radius: 999px;
  border: 2px solid hsl(var(--background));
  background: hsl(var(--card));
  color: hsl(var(--primary));
  font-size: .6875rem;
  font-weight: 700;
  line-height: 1rem;
  text-align: center;
  font-variant-numeric: tabular-nums;
}
.extr-action-count.hidden { display: none; }

.extr-action-badge {
  flex-shrink: 0;
  white-space: nowrap;
  min-width: 1.25rem;
  padding: 0 .3125rem;
  border-radius: 999px;
  background: hsl(var(--primary) / .12);
  color: hsl(var(--primary));
  font-size: .6875rem;
  font-weight: 600;
  line-height: 1.25rem;
  text-align: center;
  font-variant-numeric: tabular-nums;
}
.extr-action-badge.hidden { display: none; }

@media (prefers-reduced-motion: reduce) {
  .extr-action-dots span,
  .extr-action-primary,
  .extr-action-more { transition: none; }
  .extr-action-menu-wrap.is-open .extr-action-menu { animation: none; }
}

/* ── Desktop ab 1024 px: dieselben Elemente als Button-Reihe ────────────────
   In der PWA/auf dem Handy bleibt es bei „+" und „⋮" mit Kontextmenü; am
   Desktop stehen die Aktionen wieder als beschriftete Buttons nebeneinander.
   Bewusst dasselbe DOM, nur anders layoutet — zwei getrennte Markup-Varianten
   würden IDs doppeln (Zähler-Badges, Modul-JS per getElementById). */
.extr-action-primary-label { display: none; }

@media (min-width: 1024px) {
  /* Sekundäre Aktionen links, Neu-Anlegen rechts — wie vor der Vereinheitlichung. */
  /* Die Reihe darf schrumpfen und umbrechen — sonst ragt sie über den Fensterrand
     (UI-Audit HDR-05: Recruiting 1339 px bei 1280 px Fenster). */
  .extr-page-actions { flex-shrink: 1; min-width: 0; max-width: 100%; }
  .extr-page-actions > .extr-action-menu-wrap { flex: 0 1 auto; }
  .extr-page-actions > .extr-action-menu-wrap { order: 1; min-width: 0; }
  .extr-page-actions > .extr-action-primary   { order: 2; }

  /* „⋮", Trenner und der wiederholte Neu-Eintrag sind hier überflüssig. */
  .extr-action-more,
  .extr-action-sep,
  .extr-action-item--primary { display: none; }

  /* Aus dem Popover wird eine Inline-Reihe. */
  .extr-action-menu-wrap { position: static; }
  .extr-page-actions .extr-action-menu-wrap .extr-action-menu {
    display: flex;
    position: static;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-end;
    gap: .5rem;
    min-width: 0;
    max-width: none;
    padding: 0;
    background: none;
    border: 0;
    border-radius: 0;
    box-shadow: none;
    animation: none;
  }

  /* Aus jedem Menüeintrag wird ein Umriss-Button. */
  .extr-action-item {
    width: auto;
    height: 2.5rem;
    padding: 0 .875rem;
    gap: .5rem;
    border: 1px solid hsl(var(--border));
    border-radius: .5rem;
    background: hsl(var(--card));
    color: hsl(var(--muted-foreground));
    white-space: nowrap;
  }
  .extr-action-item:hover {
    background: hsl(var(--muted));
    color: hsl(var(--foreground));
  }
  .extr-action-item:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px hsl(var(--primary) / .25);
  }
  .extr-action-item svg { opacity: 1; }
  .extr-action-item-label { flex: 0 0 auto; }
  .extr-action-item--danger {
    border-color: hsl(var(--destructive) / .35);
    color: hsl(var(--destructive));
  }

  /* Primärbutton mit Label statt reinem Icon. */
  .extr-action-primary {
    width: auto;
    height: 2.5rem;
    padding: 0 1rem;
    gap: .5rem;
    border-radius: .5rem;
  }
  .extr-action-primary svg { height: 1rem; width: 1rem; }
  .extr-action-primary-label {
    display: inline;
    font-size: .875rem;
    font-weight: 500;
    white-space: nowrap;
  }
}

/* ---------------------------------------------------------------------------
   Listen: Tabellenkopf bleibt beim Scrollen stehen (2026-08-28)

   Es scrollt die SEITE — die Tabelle bekommt bewusst KEINEN eigenen
   Scrollbereich: Das nutzte die Fensterhöhe nicht aus und erzeugte bei
   niedrigen Fenstern zwei Scrollleisten übereinander.

   Damit `position: sticky` gegenüber dem Fenster wirkt, darf zwischen Zelle
   und Fenster kein Scroll-Container liegen. Die Listen stecken aber in
   overflow-Containern (runde Kartenecken bzw. waagerechtes Scrollen). Lösung:
   `overflow: clip` statt `hidden`/`auto` — das schneidet genauso ab, ist aber
   KEIN Scroll-Container, `sticky` bezieht sich dadurch aufs Fenster.

   Der Kopf hält unterhalb der App-Kopfleiste (selbst sticky, variable Höhe);
   deren Höhe liefert syncStickyTop() in app.js als --extr-sticky-top.

   Der Kopf braucht eine DECKENDE Fläche — die übliche Tönung bg-muted/50 ist
   halbtransparent, darunter würden die Zeilen durchscheinen. Die Trennlinie
   kommt als inset-Schatten, weil echte Rahmen an sticky-Zellen bei
   border-collapse nicht mitgezeichnet werden.
--------------------------------------------------------------------------- */
/* Karte, die nur ihre runden Ecken beschneiden soll. `clip` statt `hidden`:
   clippt identisch, ist aber KEIN Scroll-Container — sonst rechnet ein
   position:sticky im Inneren gegen die Karte statt gegen das Fenster und der
   Tabellenkopf bleibt nicht stehen. */
.extr-clip {
    overflow: clip;
}

.extr-table-sticky {
    overflow: clip;
}
.extr-table-sticky thead th {
    position: sticky;
    top: var(--extr-sticky-top, 0px);
    z-index: 3;
    background-color: hsl(var(--muted));
    box-shadow: inset 0 -1px 0 hsl(var(--border));
}

/* Schmale Schirme: Tabellen müssen waagerecht schiebbar bleiben. Dort ist der
   Container wieder ein Scroll-Container, der Kopf haftet folglich nicht —
   auf Mobilgeräten ist das verschmerzbar (viele Listen sind dort ohnehin
   durch Karten ersetzt). */
@media (max-width: 1023px) {
    /* Als Scroll-Container ist der Kasten selbst der Bezugsrahmen des Kopfes:
       der Fenster-Versatz (Höhe der Kopfleiste) schob den Kopf sonst mitten in
       die Tabelle (sichtbar seit den echten 390-px-Aufnahmen, 2026-09-16). */
    .extr-table-sticky { overflow-x: auto; --extr-sticky-top: 0px; }
}

/* ---- Fixierter Kopf im EIGENEN Scrollbereich (UI-Audit LST-03) -------------
   Für Raster, die selbst scrollen (Wochendetails, Monatsraster, Statistik-
   Tabellen). Sie setzen den Fenster-Versatz auf 0 zurück und begrenzen ihre
   Höhe — sonst hat `position: sticky` nichts, woran es kleben könnte.
   Anwenden zusammen mit .extr-table-sticky:
     <div class="extr-table-sticky extr-table-sticky--local"> … </div> */
/* Nur der Bezugsrahmen: der Kopf klebt am nächsten scrollenden Vorfahren
   (z. B. am Modalkörper) statt am Fenster. Kein eigener Scrollbereich. */
.extr-table-sticky--local { --extr-sticky-top: 0px; }

/* Eigener Scrollbereich in BEIDE Richtungen, mit begrenzter Höhe — sonst
   hat `position: sticky` nichts, woran es kleben könnte. Zusammen mit
   --local verwenden. Nicht mit .extr-table-scroll kombinieren: dessen
   `overflow: clip` steht ungeschichtet und würde hier gewinnen. */
.extr-table-sticky--scroll {
  overflow: auto;
  max-height: var(--extr-table-max, calc(100vh - 16rem));
  overscroll-behavior: contain;
}
/* Erste Spalte trägt die Bezeichnung der Zeile und bleibt stehen. */
.extr-table-sticky--scroll .extr-table th:first-child,
.extr-table-sticky--scroll .extr-table td:first-child {
  position: sticky; left: 0; z-index: 2;
  background: hsl(var(--card));
  box-shadow: 1px 0 0 hsl(var(--border));
}
.extr-table-sticky--scroll .extr-table thead th:first-child { z-index: 4; }
/* ---- Team: Rechtematrix ---------------------------------------------------
   Namensspalte klebt links, Kopfzeile oben (extr-table-sticky). Nur Desktop:
   das Markup ist hidden lg:block, die installierte App blendet zusätzlich per
   JS aus (display-mode: standalone). */
/* Das Raster scrollt in BEIDE Richtungen selbst (Höhe setzt das Partial-JS
   auf den sichtbaren Rest des Fensters, hier nur der Rückfall). Ein Container
   mit overflow wird zum Sticky-Bezugsrahmen — deshalb kleben Kopfzeile und
   Namensspalte hier bewusst am Container (top/left: 0) und NICHT über
   .extr-table-sticky am Fenster: der dort gesetzte App-Header-Versatz
   (--extr-sticky-top) würde den Kopf mitten ins Raster schieben. */
.emp-matrix-wrap { overflow: auto; max-height: calc(100vh - 16rem); overscroll-behavior: contain; }
.emp-matrix { border-collapse: separate; border-spacing: 0; }
.emp-matrix th, .emp-matrix td { white-space: nowrap; }
.emp-matrix thead th {
  position: sticky; top: 0; z-index: 3;
  background: hsl(var(--muted));
  box-shadow: inset 0 -1px 0 hsl(var(--border));
}
.emp-matrix .emp-matrix-name {
  position: sticky; left: 0; z-index: 2;
  background: hsl(var(--card));
  box-shadow: inset -1px 0 0 hsl(var(--border));
  min-width: 15rem;
}
.emp-matrix thead .emp-matrix-name { z-index: 4; background: hsl(var(--muted)); }
.emp-matrix th.emp-matrix-mod { min-width: 4.75rem; font-weight: 500; text-transform: none; letter-spacing: 0; }
.emp-matrix th.emp-matrix-mod > span { display: flex; flex-direction: column; align-items: center; gap: .25rem; font-size: .6875rem; line-height: 1.15; max-width: 5.5rem; white-space: normal; text-align: center; }
.emp-matrix td.emp-matrix-cell { text-align: center; }
.emp-matrix-mark { display: inline-flex; align-items: center; justify-content: center; height: 1.5rem; width: 1.5rem; border-radius: .5rem; }
.emp-matrix-mark--manage { background: hsl(var(--primary) / .12); color: hsl(var(--primary)); }
.emp-matrix-mark--access { color: hsl(var(--muted-foreground)); }
.emp-matrix-mark--none   { color: hsl(var(--border)); }
.emp-matrix-mark svg { height: .95rem; width: .95rem; }
/* Die Namensspalte klebt links; die Modulzellen scrollen UNTER ihr durch. Ihr Hintergrund
   muss deshalb deckend sein — eine Tönung allein (6 % Primärfarbe) ließe die Symbole
   durchscheinen. Daher: Tönung als Verlaufsschicht ÜBER dem deckenden Kartenweiß. */
.emp-matrix tr.is-admin .emp-matrix-name {
  background: linear-gradient(hsl(var(--primary) / .06), hsl(var(--primary) / .06)), hsl(var(--card));
}
.emp-matrix tbody tr:hover .emp-matrix-name {
  background: linear-gradient(hsl(var(--muted) / .4), hsl(var(--muted) / .4)), hsl(var(--card));
}
.emp-matrix tbody tr.is-admin:hover .emp-matrix-name {
  background: linear-gradient(hsl(var(--muted) / .4), hsl(var(--muted) / .4)), linear-gradient(hsl(var(--primary) / .06), hsl(var(--primary) / .06)), hsl(var(--card));
}

/* ============================================================
   Aufklappende Suche (extr_search_field, CLAUDE-UI.md §3.4)
   Ein Icon-Knopf, der sich per Animation zu einem Suchfeld öffnet und die
   Inhalte rechts daneben (Filter-Pills, Selects) überlagert, statt sie zu
   verschieben. Klick daneben oder Esc schließt das Feld; ein gesetzter
   Begriff bleibt aktiv und als Chip am Knopf sichtbar. Höhe 38px = Höhe
   der Filter-Selects (py-2), damit die Zeile bündig bleibt.
   ============================================================ */
.extr-sf { position: relative; flex: 0 0 auto; height: 2.375rem; }
.extr-sf-toggle {
  display: inline-flex; align-items: center; gap: .45rem;
  height: 2.375rem; min-width: 2.375rem; max-width: 16rem; padding: 0 .625rem;
  border: 1px solid hsl(var(--border)); border-radius: .5rem; background: #fff;
  color: hsl(var(--muted-foreground)); font-size: .875rem; font-weight: 500; white-space: nowrap;
  cursor: pointer; transition: background-color .15s, color .15s, border-color .15s;
}
.extr-sf-toggle:hover { background: hsl(var(--muted)); color: hsl(var(--foreground)); }
.extr-sf-toggle:focus-visible { outline: 2px solid hsl(var(--primary) / .5); outline-offset: 2px; }
.extr-sf-toggle svg { height: 1rem; width: 1rem; flex: 0 0 auto; }
.extr-sf.has-value .extr-sf-toggle { background: hsl(var(--primary-strong)); border-color: hsl(var(--primary-strong)); color: hsl(var(--primary-foreground)); }
.extr-sf.has-value .extr-sf-toggle:hover { background: hsl(var(--primary) / .9); }
.extr-sf-chip { display: none; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.extr-sf.has-value .extr-sf-chip { display: block; }
.extr-sf-panel {
  position: absolute; top: 0; left: 0; z-index: 30;
  display: flex; align-items: center;
  height: 2.375rem; width: 2.375rem; opacity: 0; pointer-events: none; overflow: hidden;
  border: 1px solid hsl(var(--border)); border-radius: .5rem; background: #fff;
  box-shadow: 0 10px 30px -12px rgba(15, 23, 42, .25);
  transition: width .28s cubic-bezier(.22, .61, .36, 1), opacity .16s ease;
}
.extr-sf.is-open .extr-sf-panel { width: var(--extr-sf-open, 28rem); opacity: 1; pointer-events: auto; }
.extr-sf--right .extr-sf-panel { left: auto; right: 0; }   /* öffnet nach links (Feld am rechten Rand) */
.extr-sf-panel:focus-within {
  border-color: hsl(var(--primary));
  box-shadow: 0 0 0 3px hsl(var(--primary) / .15), 0 10px 30px -12px rgba(15, 23, 42, .25);
}
.extr-sf-icon { position: absolute; left: .75rem; height: 1rem; width: 1rem; color: hsl(var(--muted-foreground)); pointer-events: none; }
.extr-sf-input {
  flex: 1 1 auto; min-width: 0; height: 100%; border: 0; outline: 0; background: transparent;
  padding: 0 2.25rem 0 2.5rem; font-size: .875rem; color: hsl(var(--foreground));
}
.extr-sf-input::-webkit-search-cancel-button,
.extr-sf-input::-webkit-search-decoration { -webkit-appearance: none; appearance: none; }
.extr-sf-clear {
  position: absolute; right: .3rem; display: none; align-items: center; justify-content: center;
  height: 1.75rem; width: 1.75rem; border-radius: .375rem; color: hsl(var(--muted-foreground)); cursor: pointer;
}
.extr-sf-clear svg { height: 1rem; width: 1rem; }
.extr-sf-clear:hover { background: hsl(var(--muted)); color: hsl(var(--foreground)); }
.extr-sf.has-value .extr-sf-clear { display: inline-flex; }
/* Inline-Suche: das Leeren-„x" folgt dem Feldinhalt selbst — auch wenn ein Modul
   den Wert per Skript zurücksetzt, ohne ein input-Ereignis auszulösen (UI-Audit CODE-03). */
.extr-sf--inline .extr-sf-input:not(:placeholder-shown) ~ .extr-sf-clear { display: inline-flex; }
.extr-sf--inline.has-value .extr-sf-input:placeholder-shown ~ .extr-sf-clear { display: none; }
.extr-sf-spinner {
  position: absolute; left: .8rem; display: none; height: .9rem; width: .9rem; border-radius: 9999px;
  border: 2px solid hsl(var(--border)); border-top-color: hsl(var(--primary)); animation: extrSfSpin .7s linear infinite;
}
.extr-sf.is-loading .extr-sf-spinner { display: block; }
.extr-sf.is-loading .extr-sf-icon { visibility: hidden; }
@keyframes extrSfSpin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .extr-sf-panel { transition: none; } }

/* Suche im „⋮“-Menü (Detailköpfe am Handy, Feedback CHAT-05): unter 1024 px ist der
   Suchknopf ausgeblendet, ein Menüeintrag (extr-action-item--mobile) öffnet das Feld;
   ein gesetzter Begriff bleibt als Chip sichtbar. Der Menüeintrag verschwindet auf dem
   Desktop, dort steht der Knopf wie gewohnt im Kopf. */
@media (max-width: 1023px) {
  .extr-sf--menu:not(.is-open):not(.has-value) { width: 0; min-width: 0; margin-right: -.5rem; }
  .extr-sf--menu:not(.is-open):not(.has-value) .extr-sf-toggle { display: none; }
}
@media (min-width: 1024px) { .extr-action-item--mobile { display: none; } }

/* Filter-Pills mit Zähler (extr_filter_pill): Badge folgt dem Aktivzustand des Knopfs. */
.extr-pill-count {
  display: inline-flex; align-items: center; padding: .1rem .4rem; border-radius: 9999px;
  font-size: .75rem; font-weight: 500; line-height: 1.1;
  background: hsl(var(--muted)); color: hsl(var(--muted-foreground));
}
/* Zähler auf aktiver Pille: heller Kreis, Schrift in der Flächenfarbe (UI-Audit DARK-02) */
.bg-primary .extr-pill-count, .extr-pill.is-active .extr-pill-count { background: hsl(var(--primary-foreground)); color: hsl(var(--primary-strong)); }

/* Leerzustand in Inhalts-Containern mit eigenen p-Regeln (z. B. .ut-output p { margin:0 })
   bleibt zentriert: die Automargins hier binden stärker als eine Element-Regel. */
.extr-empty .extr-empty-text { margin-left: auto; margin-right: auto; }
.extr-empty .extr-empty-icon { margin-left: auto; margin-right: auto; }

/* ============================================================
   Filterzeile & Wechsler — vereinheitlicht (UI-Audit 2026-09)
   FLT-01: eine Höhe für Suche, Selects und Sortierknopf (38 px).
   SW-02:  ein Markup für alle Segment-Wechsler (extr_tab_strip).
   FLT-04: immer offenes Suchfeld für Auswahl-Fenster (Picker).
   Alles hier, nicht in Tailwind: der Build ist gepurged.
   ============================================================ */

/* Selects der Filterzeile — bündig zur aufklappenden Suche (2.375rem = 38 px).
   Vorher standen 34-px-Selects (py-1.5) neben 38-px-Suchfeldern.
   Eigener Name: .extr-select gehört dem Formular-Baustein weiter oben (width:100%,
   gefüllter Hintergrund) — der würde die Filterzeile über die volle Breite ziehen. */
/* Mehrfachauswahl-Listen (multiple) behalten ihre Höhe — dort ist size="n" gewollt. */
select.extr-filter-select:not([multiple]) {
  height: 2.375rem;
  line-height: 1.25;
}
/* Form und Farbe des Filter-Selects stehen hier, nicht als Kette im Markup:
   die Kette stand 76-mal in vier Fassungen (px-2 / px-2.5 / px-3, teils ohne
   Fokusring), der Innenabstand driftete um 4 px. In @layer components, damit
   ein w-full oder eine Modulklasse daneben weiter greift. */
@layer components {
  .extr-filter-select {
    border: 1px solid hsl(var(--border));
    border-radius: var(--radius-lg, .75rem);
    padding: .5rem .75rem;
    font-size: .875rem;
    background: hsl(var(--card));
    color: hsl(var(--foreground));
    flex-shrink: 0;
  }
  .extr-filter-select:focus {
    outline: none;
    box-shadow: 0 0 0 2px hsl(var(--primary) / 0.2);
  }
}

/* Richtungsknopf der Sortierung — quadratisch, gleiche Höhe wie Select+Suche. */
.extr-sort-dir {
  height: 2.375rem;
  width: 2.375rem;
}
.extr-sort-dir svg { height: 1rem; width: 1rem; }

/* „Filter zurücksetzen" erscheint nur bei aktivem Filter (extr_filter_reset). */
.extr-filter-reset svg { height: 1rem; width: 1rem; }

/* ---- Reiter im Streifen (extr_tab_strip) ---------------------------------
   Der Streifen selbst (.extr-tab-strip) scrollt bereits seitlich. Unter
   640 px zeigen die Reiter nur ihr Symbol — die Beschriftung steckt in
   title/aria-label. Streifen mit mehrdeutigen Symbolen setzen
   'labels' => 'always' und behalten den Text. */
/* Eigener Name: .extr-tab gehört dem Design-System-Tabsystem (§3.7, Unterstrich-
   Reiter mit display:block) — dessen Regeln würden den Streifen zerlegen. */
.extr-tab-strip-btn { cursor: pointer; }
.extr-tab-strip-btn svg { height: 1rem; width: 1rem; flex: 0 0 auto; }
.extr-tab-strip-label { min-width: 0; }

@media (max-width: 639px) {
  .extr-tab-strip:not(.extr-tab-strip--labels) .extr-tab-strip-label {
    position: absolute;
    width: 1px; height: 1px;
    margin: -1px; padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
  }
  /* Ohne Text braucht der Reiter kein waagerechtes Polster mehr. */
  .extr-tab-strip:not(.extr-tab-strip--labels) .extr-tab-strip-btn {
    padding-left: .625rem;
    padding-right: .625rem;
  }
}

/* ---- Immer offenes Suchfeld für Auswahl-Fenster (Picker) -----------------
   Gleiche Bausteine wie die aufklappende Suche, nur ohne Knopf: das Feld
   steht offen in der Zeile und wächst mit. Damit verschwinden die letzten
   rohen <input type="search"> aus den Modalen. */
.extr-sf--inline { flex: 1 1 auto; min-width: 0; width: 100%; }
.extr-sf--inline .extr-sf-toggle { display: none; }
.extr-sf--inline .extr-sf-panel {
  position: static;
  width: 100%;
  opacity: 1;
  pointer-events: auto;
  box-shadow: none;
  transition: border-color .15s ease, box-shadow .15s ease;
}
.extr-sf--inline.is-open .extr-sf-panel { width: 100%; }
.extr-sf--inline .extr-sf-panel:focus-within {
  box-shadow: 0 0 0 3px hsl(var(--primary) / .15);
}

/* Ungespeicherte Änderungen am Speichern-Knopf einer Detailseite (UI-Audit HDR-03). */
.extr-action-primary.is-dirty::after {
  content: '';
  position: absolute;
  top: .45rem;
  right: .45rem;
  height: .5rem;
  width: .5rem;
  border-radius: 9999px;
  background: hsl(var(--primary-foreground));
}

/* Die Zwischenlösung .extr-modal-wide / .extr-modal-xwide (Ersatz für die
   im gepurgten Build fehlenden lg:max-w-3xl/4xl) ist entfallen: die Breiten
   stecken jetzt in .extr-dlg-panel--wide / --xwide (siehe MOD-02 unten). */

/* ============================================================
   UI-Audit Charge 2 (2026-09-09) — Tabellen, Kacheln, Zeilen-
   Aktionen, Modal-Ebenen. Alles handgeschrieben, also purge-fest.
   Namen bewusst neu: .extr-btn, .extr-input, .extr-modal*,
   .extr-empty*, .extr-table-sticky und .extr-card gibt es bereits
   weiter oben — die werden hier NICHT umdefiniert.
   ============================================================ */

/* ---- LST-01: Tabellen ------------------------------------------------------
   Der Bestand zählte 14 verschiedene th-Klassenketten. Eine Tabelle sieht
   jetzt überall gleich aus; die Dichtevariante --dense ist für Datenraster
   (Zeitkonto, Schichtplan), in denen p-4 die Zeilen zu hoch macht. */
.extr-table { width: 100%; border-collapse: collapse; }
.extr-table thead { background: hsl(var(--muted) / .5); border-bottom: 1px solid hsl(var(--border)); }
.extr-table th {
  text-align: left;
  padding: 1rem;
  font-weight: 500;
  font-size: .875rem;
  color: hsl(var(--foreground));
  white-space: nowrap;
}
.extr-table td { padding: 1rem; font-size: .875rem; vertical-align: middle; }
.extr-table tbody tr { border-bottom: 1px solid hsl(var(--border)); }
.extr-table tbody tr:last-child { border-bottom: 0; }
.extr-table tbody tr:hover { background: hsl(var(--muted) / .5); }
.extr-table th.is-right, .extr-table td.is-right { text-align: right; }
.extr-table th.is-center, .extr-table td.is-center { text-align: center; }

/* Dichter: halbe Polsterung, für Raster mit vielen Spalten. */
.extr-table--dense th,
.extr-table--dense td { padding: .5rem .625rem; }
.extr-table--dense th { font-size: .8125rem; }

/* ---- LST-04: Leerzustand INNERHALB einer Liste -----------------------------
   Nicht zu verwechseln mit .extr-empty (ganze Ansicht leer, extr_empty_state).
   Hier: „Filter/Suche liefert nichts" — eine Zeile, immer gleich formuliert. */
.extr-empty-inline {
  padding: 2rem 1rem;
  text-align: center;
  font-size: .875rem;
  color: hsl(var(--muted-foreground));
}
/* Dichter: in Auswahl-Aufklappern (Personensuche, Ticketsuche) ist die Liste
   nur ein paar Zeilen hoch — gleicher Wortlaut, weniger Polsterung. */
.extr-empty-inline--sm { padding: .5rem .75rem; font-size: .75rem; text-align: left; }

/* ---- Dashboard-Widget (UI-Audit CON-03) ------------------------------------
   Das Dashboard folgt bewusst NICHT dem Listenmuster der Module: es ist ein
   Raster aus Kacheln. Damit die Ausnahme trotzdem eine feste Form hat, sind
   Hülle, Kopf und Leerzustand hier benannt — vorher stand die Kette 39-mal
   im Partial. Der leichte Schatten ist gewollt: die Kacheln schweben über
   dem Raster, anders als die Karten in den Listen (§3.3).
     <div class="extr-dash-widget">
       <div class="extr-dash-widget-head"><h3>…</h3><a …>Alle</a></div>
       <div class="extr-dash-empty">…</div>  ODER  <div class="extr-divided">…</div>
     </div> */
/* In @layer components: Utility-Klassen im selben class-Attribut — die
   Mobil-Kachel trägt lg:hidden und muss den Baustein schlagen können. */
@layer components {
  .extr-dash-widget {
    display: flex; flex-direction: column; height: 100%;
    background: hsl(var(--card));
    border: 1px solid hsl(var(--border));
    border-radius: 1rem;
    /* Tailwinds shadow-md — dieselbe Zahl wie in der abgelösten Kette. */
    box-shadow: var(--shadow-md, 0 4px 6px -1px #0000001a, 0 2px 4px -2px #0000001a);
    padding: 1.25rem;
  }
  .extr-dash-widget-head {
    display: flex; align-items: center; justify-content: space-between;
    margin-bottom: 1rem;
  }
  .extr-dash-widget-head h3 {
    display: flex; align-items: center; gap: .5rem;
    font-size: .875rem; font-weight: 600;
  }
  .extr-dash-widget-head h3 svg,
  .extr-dash-widget-head h3 i { height: 1rem; width: 1rem; color: hsl(var(--primary)); }
  .extr-dash-empty {
    flex: 1 1 auto;
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    text-align: center; padding: 1.5rem 0;
  }
  .extr-dash-empty svg, .extr-dash-empty i { height: 2rem; width: 2rem; margin-bottom: .5rem; }
  .extr-dash-empty p { font-size: .875rem; color: hsl(var(--muted-foreground)); }
}
/* ---- Getrennte Liste (UI-Audit CODE-01) ------------------------------------
   Eine feine Linie zwischen aufeinanderfolgenden Einträgen. Stand vorher
   53-mal als eigener <style>-Block in den Partials — jedes Dashboard-Widget,
   jede Auswahlliste brachte ihre eigene Kopie mit.
   Anwenden am Container, nicht an den Kindern:
     <div class="extr-divided"> <a …>…</a> <a …>…</a> </div> */
.extr-divided > * + * { border-top: 1px solid hsl(var(--border) / 0.45); }
/* Kräftigere Linie, wo die Einträge Karten sind. */
.extr-divided--strong > * + * { border-top-color: hsl(var(--border)); }
/* ---- LST-06: Nachladen ----------------------------------------------------
   Vier Arten standen nebeneinander: Seitenzahlen, „Mehr laden“, Endlos-Scroll
   und alles auf einmal. Regel jetzt: Tabellen blättern (.extr-pager),
   Kartenraster laden nach (.extr-more, Endlos-Scroll hängt zentral in app.js). */
.extr-pager {
  display: flex; justify-content: center; align-items: center;
  gap: .5rem; flex-wrap: wrap; padding-top: .5rem;
}
.extr-pager-btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 2.25rem; height: 2.25rem; padding: 0 .625rem;
  border: 1px solid hsl(var(--border));
  border-radius: var(--radius-lg, .75rem);
  background: hsl(var(--card));
  color: hsl(var(--muted-foreground));
  font-size: .875rem; font-weight: 500;
  cursor: pointer;
  transition: background-color .15s ease, color .15s ease, border-color .15s ease;
}
.extr-pager-btn:hover { background: hsl(var(--muted)); color: hsl(var(--foreground)); }
.extr-pager-btn.is-active {
  background: hsl(var(--primary-strong));
  border-color: hsl(var(--primary-strong));
  color: hsl(var(--primary-foreground));
}
.extr-pager-btn:focus-visible { outline: none; box-shadow: 0 0 0 3px hsl(var(--primary) / .25); }
.extr-pager-gap { color: hsl(var(--muted-foreground)); padding: 0 .125rem; }

.extr-more { display: flex; justify-content: center; margin-top: 1.5rem; }
/* `.hidden` kommt aus @layer utilities und verliert gegen diese ungeschichteten
   Regeln — deshalb ausdrücklich (Muster wie .extr-nav-badge weiter oben). */
.extr-row-btn.hidden,
.extr-more.hidden,
.extr-pager.hidden { display: none; }
/* ---- BTN-02: Symbolknöpfe --------------------------------------------------
   Der Bestand mischte h-9 w-9 rounded-md mit h-8 w-8 rounded-lg — zwei Größen
   und zwei Rundungen nebeneinander. Jetzt: eine Größe je Ort.
     .extr-icon-btn      36 px, ohne Rahmen — Kopfzeilen und Werkzeugleisten
     .extr-icon-btn--sm  32 px, ohne Rahmen — innerhalb von Karten
     .extr-icon-btn--outline  mit Rahmen, wo der Knopf allein steht
   In Listenzeilen gilt weiter .extr-row-btn (32 px mit Rahmen, LST-05) — die
   Rolle ist eine andere, deshalb bleibt es eine eigene Klasse. */
@layer components {
  .extr-icon-btn {
    display: inline-flex; align-items: center; justify-content: center;
    height: 2.25rem; width: 2.25rem; flex: 0 0 auto;
    border: 0;
    /* rounded-lg wie bei .extr-btn — der Bestand mischte rounded-md (6 px)
       und rounded-lg (12 px); 12 px ist die Mehrheit und passt zu den
       übrigen Knöpfen (Befund aus der Prüfung von Charge 3). */
    border-radius: var(--radius-lg, .75rem);
    background: transparent;
    color: hsl(var(--muted-foreground));
    cursor: pointer;
    transition: background-color .15s ease, color .15s ease, border-color .15s ease;
  }
  .extr-icon-btn svg, .extr-icon-btn i { height: 1.25rem; width: 1.25rem; }
  .extr-icon-btn:hover { background: hsl(var(--muted)); color: hsl(var(--foreground)); }
  .extr-icon-btn:focus-visible { outline: none; box-shadow: 0 0 0 3px hsl(var(--primary) / .25); }
  .extr-icon-btn:disabled { opacity: .5; cursor: not-allowed; }
  .extr-icon-btn--sm { height: 2rem; width: 2rem; }
  .extr-icon-btn--sm svg, .extr-icon-btn--sm i { height: 1rem; width: 1rem; }
  .extr-icon-btn--outline {
    border: 1px solid hsl(var(--border));
  }
  /* Deckend weiß nur, wo der Knopf auf gemustertem Grund steht. */
  .extr-icon-btn--solid { background: hsl(var(--card)); }
  .extr-icon-btn--danger { color: hsl(var(--destructive)); }
  .extr-icon-btn--danger:hover { background: hsl(var(--destructive) / .1); color: hsl(var(--destructive)); }
  /* Leise Gefahr: gedämpft, erst beim Überfahren rot — für das „x"/Papierkorb
     in Karten und Auswahllisten, wo ein dauerhaft rotes Symbol zu laut wäre
     (Gegenstück zu .extr-row-btn--danger, UI-Audit CODE-03). */
  .extr-icon-btn--danger-hover:hover { background: hsl(var(--destructive) / .1); color: hsl(var(--destructive)); }
  /* Kompakt (24 px) für gestapelte Reihenfolge-Pfeile und dichte Zeilen, in denen
     32 px die Zeile aufblähen würden — WCAG 2.5.8 verlangt 24 px (UI-Audit CODE-03). */
  .extr-icon-btn--xs { height: 1.5rem; width: 1.5rem; border-radius: var(--radius-md, .375rem); }
  .extr-icon-btn--xs svg, .extr-icon-btn--xs i { height: .875rem; width: .875rem; }
  /* 40 px — neben Eingabefeldern der Höhe h-10 (Kopieren, Anhängen) (UI-Audit BTN-06). */
  .extr-icon-btn--lg { height: 2.5rem; width: 2.5rem; }
  .extr-icon-btn--lg svg, .extr-icon-btn--lg i { height: 1.25rem; width: 1.25rem; }
  /* Hell auf dunkler Vollbildfläche (Vorschau, Bildbetrachter). */
  .extr-icon-btn--overlay { background: rgb(255 255 255 / .15); color: #fff; border-radius: 9999px; }
  .extr-icon-btn--overlay:hover { background: rgb(255 255 255 / .25); color: #fff; }
  /* „x" in einem Chip (Personen, Filter): erbt die Chipfarbe, rund, 18 px. */
  .extr-chip-x {
    display: inline-flex; align-items: center; justify-content: center;
    height: 1.125rem; width: 1.125rem; flex: 0 0 auto;
    border: 0; border-radius: 9999px; background: transparent; color: inherit; cursor: pointer;
  }
  .extr-chip-x svg, .extr-chip-x i { height: .75rem; width: .75rem; }
  .extr-chip-x:hover { background: color-mix(in srgb, currentColor 18%, transparent); }
  .extr-chip-x:focus-visible { outline: none; box-shadow: 0 0 0 2px hsl(var(--primary) / .35); }
}
/* ---- UX-05: Tipp-Ziele bei Fingerbedienung ----------------------------------
   Symbolknöpfe messen 32–36 px; mit dem Finger sind 44 px das Maß (Apple/Material,
   WCAG 2.5.8 verlangt mindestens 24 px). Bei grobem Zeiger wachsen deshalb alle
   Symbol-Bausteine auf 2.75rem — ungeschichtet, damit auch h-8/w-8 im Markup
   sie nicht kleiner halten. Mit Maus und Trackpad bleibt alles wie gehabt. */
@media (pointer: coarse) {
  .extr-icon-btn:not(.extr-icon-btn--xs),
  .extr-row-btn,
  .extr-dlg-x { min-width: 2.75rem; min-height: 2.75rem; }
}
/* ---- LST-05: Aktionen in einer Listenzeile ---------------------------------
   Zwei Stile, mehr nicht: Symbolknopf (bis drei Aktionen) und „⋮"-Menü. */
.extr-row-actions { display: inline-flex; align-items: center; gap: .25rem; }
.extr-row-btn {
  display: inline-flex; align-items: center; justify-content: center;
  height: 2rem; width: 2rem; flex: 0 0 auto;
  border: 1px solid hsl(var(--border));
  /* Dieselbe Rundung wie .extr-btn, .extr-icon-btn, .extr-input und
     .extr-pager-btn — BTN-02 wollte genau eine, nicht zwei. */
  border-radius: var(--radius-lg, .75rem);
  background: hsl(var(--card));
  color: hsl(var(--muted-foreground));
  cursor: pointer;
  transition: background-color .15s ease, color .15s ease, border-color .15s ease;
}
.extr-row-btn svg, .extr-row-btn i { height: 1rem; width: 1rem; }
.extr-row-btn:hover { background: hsl(var(--muted)); color: hsl(var(--foreground)); }
.extr-row-btn:focus-visible { outline: none; box-shadow: 0 0 0 3px hsl(var(--primary) / .25); }
.extr-row-btn--danger:hover {
  background: hsl(var(--destructive) / .1);
  border-color: hsl(var(--destructive) / .35);
  color: hsl(var(--destructive));
}
/* Die eine Hauptaktion einer Zeile darf beschriftet sein („Abruf", „Buchen"). */
.extr-row-btn--text { width: auto; padding: 0 .75rem; gap: .375rem; font-size: .8125rem; font-weight: 500; }

/* ---- MOD-01: Ebenen-Skala --------------------------------------------------
   Vorher: z-40, z-50, z-[55], z-[60], z-[70], z-[80], z-[200] querbeet — ein
   verschachtelter Dialog lag mal über, mal unter seinem Auslöser.
   Kopfzeile 40, Menüs 30 bleiben, wie in CLAUDE-UI.md §3.4 beschrieben. */
.extr-z-modal   { z-index: 60; }   /* Modal über der Ansicht          */
.extr-z-modal-2 { z-index: 70; }   /* Modal, das über einem Modal liegt */
.extr-z-preview { z-index: 80; }   /* Vollbild-Vorschau über den Modalen */
.extr-z-confirm { z-index: 250; }  /* Bestätigen/Verwerfen — MUSS über  */
                                   /* Ladeschleier (90), Lightbox (100)  */
                                   /* und Fotoeditor liegen: die Rück-   */
                                   /* frage kommt aus diesen heraus.     */
.extr-z-toast   { z-index: 400; }  /* Kurzmeldungen über allem        */

/* ---- MOD-02: Modal-Skelett (extr_modal_open/-close) ------------------------
   Eigene Namen: .extr-modal* gehört dem älteren, zentrierten Dialog des
   Design-Systems (max-width 540px, display:flex am Backdrop). Das hier ist
   das Skelett aus §3.4, das die Partials tatsächlich verwenden. */
.extr-dlg { position: fixed; inset: 0; }
.extr-dlg-backdrop { position: absolute; inset: 0; background: rgba(0,0,0,.5); backdrop-filter: blur(4px); }
.extr-dlg-panel {
  position: absolute;
  left: 1rem; right: 1rem; top: 2rem; bottom: 2rem;
  /* Deckel wie im Altbestand: bezieht sich auf die bereits um die Safe-Area
     eingerückte Wurzel .extr-dlg. */
  max-height: 100%;
  display: flex; flex-direction: column;
  background: hsl(var(--card));
  border-radius: 1rem;
  overflow: hidden;
  box-shadow: 0 25px 50px -12px rgba(0,0,0,.25);
}
/* Kompaktes Dialogfenster: Höhe nach Inhalt statt fester Rahmen — für
   Rückfragen und kurze Formulare. `--auto` sitzt mittig, `--top` oben.
   Beide begrenzen die Höhe und scrollen selbst; enthält das Panel den
   Baustein .extr-dlg-body, übernimmt der das Scrollen und die eigene
   Scrollleiste erscheint gar nicht erst. */
.extr-dlg-panel--auto,
.extr-dlg-panel--top {
  bottom: auto;
  /* 100 % der Wurzel .extr-dlg — die ist bereits um die Safe-Area eingerückt.
     100vh wüsste davon nichts und ließe das Panel unter die Insel ragen. */
  max-height: 100%;
  overflow-y: auto;
}
.extr-dlg-panel--auto {
  top: 50%;
  transform: translateY(-50%);
}
/* Dialoge, die auch UNTER 1024 px schmal bleiben. Im Altbestand stand dort
   `max-w-*` ohne lg:-Präfix — ohne diesen Zusatz füllt der Dialog auf dem
   Tablet fast die ganze Breite. */
.extr-dlg-panel--compact { margin-left: auto; margin-right: auto; }
/* Dialog mit Luft nach oben und unten: das mittige --auto-Panel darf sonst die ganze
   Höhe füllen und klebt an den Rändern (Zuweisungsdialog der Schichtplanung). */
.extr-dlg-panel--inset { max-height: calc(100% - 2rem); }
/* Zuweisungsdialog: zwei Ansichten als Flex-Spalten, damit ihr Körper (.extr-dlg-body)
   scrollt; umgeschaltet wird per style.display — nicht .hidden, das verlöre display:flex. */
.sm-view { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; }
/* Über dem Körper steht je Ansicht eine Kopfzeile (Hinweis bzw. Suche + Filter) — der Körper
   beginnt deshalb knapper als die üblichen 1.25rem, sonst klafft eine Lücke (2026-09-18). */
.sm-view > .extr-dlg-body { padding-top: .75rem; }
.sm-grip { cursor: grab; touch-action: none; }
.sm-row.is-dragging { opacity: .45; }
@media (max-width: 1023px) {
  .extr-dlg-panel--compact                        { max-width: 32rem; }
  .extr-dlg-panel--compact.extr-dlg-panel--narrow { max-width: 24rem; }
  .extr-dlg-panel--compact.extr-dlg-panel--md     { max-width: 28rem; }
  .extr-dlg-panel--compact.extr-dlg-panel--xl     { max-width: 36rem; }
  .extr-dlg-panel--compact.extr-dlg-panel--2xl    { max-width: 42rem; }
}

/* Unten angeschlagenes Blatt (Legende, mobile Auswahl). */
.extr-dlg-panel--sheet {
  top: auto;
  bottom: 1rem;
  max-height: calc(100% - 4.5rem);
  overflow-y: auto;
}
@media (min-width: 1024px) {
  .extr-dlg-panel { left: 50%; right: auto; transform: translateX(-50%); width: 100%; max-width: 32rem; }
  .extr-dlg-panel--narrow { max-width: 24rem; }   /* sm  */
  .extr-dlg-panel--md     { max-width: 28rem; }   /* md  */
  .extr-dlg-panel--xl     { max-width: 36rem; }   /* xl  */
  .extr-dlg-panel--2xl    { max-width: 42rem; }   /* 2xl */
  .extr-dlg-panel--wide   { max-width: 48rem; }   /* 3xl */
  .extr-dlg-panel--xwide  { max-width: 56rem; }   /* 4xl */
  .extr-dlg-panel--full   { max-width: 72rem; }   /* Verwaltungsraster */
  .extr-dlg-panel--auto   { transform: translate(-50%, -50%); }
}
.extr-dlg-head {
  display: flex; align-items: center; justify-content: space-between; gap: .75rem;
  padding: 1rem 1.25rem;
  border-bottom: 1px solid hsl(var(--border));
  flex: 0 0 auto;
}
.extr-dlg-head-title { display: flex; align-items: center; gap: .625rem; min-width: 0; }
.extr-dlg-head-title h2 { font-size: 1.125rem; font-weight: 600; }
.extr-dlg-head-title svg, .extr-dlg-head-title i { height: 1.25rem; width: 1.25rem; color: hsl(var(--primary)); flex: 0 0 auto; }
.extr-dlg-sub { font-size: .75rem; color: hsl(var(--muted-foreground)); }
.extr-dlg-x {
  display: inline-flex; align-items: center; justify-content: center;
  height: 2.25rem; width: 2.25rem; flex: 0 0 auto;
  border-radius: .5rem; color: hsl(var(--muted-foreground)); cursor: pointer;
}
.extr-dlg-x:hover { background: hsl(var(--muted)); color: hsl(var(--foreground)); }
.extr-dlg-body { flex: 1 1 auto; overflow-y: auto; padding: 1.25rem; }
.extr-dlg-foot {
  display: flex; align-items: center; justify-content: flex-end; gap: .75rem;
  padding: 1rem 1.25rem;
  border-top: 1px solid hsl(var(--border));
  flex: 0 0 auto;
}

/* ---- KPI-01: Kennzahl-Kachel ----------------------------------------------
   Muster Aufgaben/Inventar: Symbolkreis links, Wert, Beschriftung darunter.
   --compact für Reihen mit sechs bis acht Kacheln (Zeitkonto, Google Ads). */
.extr-stat {
  display: flex; align-items: center; gap: .75rem;
  background: hsl(var(--card));
  border: 1px solid hsl(var(--border));
  border-radius: 1rem;
  padding: 1rem;
}
.extr-stat-icon {
  display: flex; align-items: center; justify-content: center;
  height: 2.5rem; width: 2.5rem; flex: 0 0 auto;
  border-radius: 9999px;
  background: hsl(var(--primary) / .1);
  color: hsl(var(--primary));
}
.extr-stat-icon svg, .extr-stat-icon i { height: 1.25rem; width: 1.25rem; }
.extr-stat-body { min-width: 0; }
.extr-stat-value { font-size: 1.125rem; font-weight: 600; line-height: 1.1; }
.extr-stat-label { font-size: .75rem; color: hsl(var(--muted-foreground)); margin-top: .125rem; }
.extr-stat-hint  { font-size: .6875rem; color: hsl(var(--muted-foreground)); margin-top: .125rem; }

.extr-stat--compact { padding: .75rem; gap: .5rem; }
.extr-stat--compact .extr-stat-icon { height: 2rem; width: 2rem; }
.extr-stat--compact .extr-stat-icon svg, .extr-stat--compact .extr-stat-icon i { height: 1rem; width: 1rem; }
.extr-stat--compact .extr-stat-value { font-size: 1rem; }

/* Farbtöne — bewusst wenige, alle über Tokens (dataviz: eine Serie, eine Farbe). */
.extr-stat--muted   .extr-stat-icon { background: hsl(var(--muted)); color: hsl(var(--muted-foreground)); }
.extr-stat--good    .extr-stat-icon { background: hsl(var(--tone-ok-bg));   color: hsl(var(--tone-ok-fg)); }
.extr-stat--warn    .extr-stat-icon { background: hsl(var(--tone-warn-bg)); color: hsl(var(--tone-warn-fg)); }
.extr-stat--danger  .extr-stat-icon { background: hsl(var(--destructive) / .12); color: hsl(var(--destructive)); }
.extr-stat--good   .extr-stat-value { color: hsl(var(--tone-ok-fg)); }
.extr-stat--warn   .extr-stat-value { color: hsl(var(--tone-warn-fg)); }
.extr-stat--danger .extr-stat-value { color: hsl(var(--destructive)); }

/* Kachelreihe: 2 Spalten mobil, 4 am Desktop (wie Aufgaben/Inventar). */
.extr-stat-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1rem; }
@media (min-width: 1024px) { .extr-stat-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.extr-stat-grid.hidden { display: none; }
.extr-stat-grid--6 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (min-width: 640px)  { .extr-stat-grid--6 { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 1024px) { .extr-stat-grid--6 { grid-template-columns: repeat(6, minmax(0, 1fr)); } }

/* ---- LST-02: breite Tabellen am Handy -------------------------------------
   Erste Wahl ist die Kartenliste (lg:hidden Karten + hidden lg:block Tabelle,
   Muster Inventar/Kundeninfo). Wo ein Raster keine Karte hergibt (Zeitkonto,
   Gesamtplan, Auswertungen), sorgt dieser Container dafür, dass die Tabelle
   seitlich scrollt, die erste Spalte stehen bleibt und ein Schatten am Rand
   zeigt, dass rechts noch etwas kommt. */
/* Waagerechter Rückfall für Raster, die als Karte keinen Sinn ergeben.
   Wichtig: `overflow: clip` erzeugt KEINEN Scroll-Container — der klebende
   Tabellenkopf aus .extr-table-sticky bezieht sich also weiter auf das
   Fenster. Erst unter 1024 px wird hier waagerecht gescrollt; dort haftet der
   Kopf ohnehin nicht (siehe .extr-table-sticky). */
.extr-table-scroll {
  overflow: clip;
}
@media (max-width: 1023px) {
  .extr-table-scroll {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    /* Schatten nur, solange nicht ganz nach rechts gescrollt ist. */
    background:
      linear-gradient(to right, hsl(var(--card)) 30%, hsl(var(--card) / 0)) left / 2rem 100% no-repeat,
      linear-gradient(to left,  hsl(var(--card)) 30%, hsl(var(--card) / 0)) right / 2rem 100% no-repeat,
      radial-gradient(farthest-side at 0 50%, rgba(15,23,42,.14), rgba(15,23,42,0)) left / .75rem 100% no-repeat,
      radial-gradient(farthest-side at 100% 50%, rgba(15,23,42,.14), rgba(15,23,42,0)) right / .75rem 100% no-repeat;
    background-attachment: local, local, scroll, scroll;
  }
}
/* Erste Spalte bleibt stehen — sie trägt die Bezeichnung der Zeile. */
@media (max-width: 1023px) {
  .extr-table-scroll--sticky1 .extr-table th:first-child,
  .extr-table-scroll--sticky1 .extr-table td:first-child {
    position: sticky;
    left: 0;
    z-index: 2;
    background: hsl(var(--card));
    box-shadow: 1px 0 0 hsl(var(--border));
  }
  .extr-table-scroll--sticky1 .extr-table thead th:first-child { z-index: 4; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   Social Media (Modul aus RP Orbit übernommen). Lag dort in <style>-Blöcken
   der Partials; hier zentral, weil Partial-CSS an dieser Datei vorbei wächst
   und der Konventionswächter (workspace/tests/cases/kopfzeile-komponente.php,
   CSS-Haushalt CODE-01/CODE-02) es sonst zu Recht anzeigt.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Social Media — Kalender/Listen-Ansicht (social-media.php) ── */
  .sm-cal-nav{display:flex;align-items:center;gap:.5rem}
  .sm-cal-btn{display:inline-flex;align-items:center;justify-content:center;width:2.25rem;height:2.25rem;border-radius:.5rem;border:1px solid hsl(var(--border));background:hsl(var(--card));color:hsl(var(--foreground));cursor:pointer}
  .sm-cal-btn:hover{background:hsl(var(--muted))}
  .sm-grid{display:none}
  .sm-agenda{display:block}
  @media(min-width:1024px){.sm-grid{display:grid;grid-template-columns:repeat(7,minmax(0,1fr));gap:1px;background:hsl(var(--border));border:1px solid hsl(var(--border));border-radius:1rem;overflow:hidden}.sm-agenda{display:none}}
  .sm-grid-head{background:hsl(var(--muted));padding:.5rem;font-size:.75rem;font-weight:600;color:hsl(var(--muted-foreground));text-align:center;text-transform:uppercase;letter-spacing:.04em}
  .sm-cell{background:hsl(var(--card));min-height:7.5rem;padding:.4rem;display:flex;flex-direction:column;gap:.25rem;position:relative}
  .sm-cell-off{background:hsl(var(--muted)/.35)}
  .sm-cell-day{font-size:.75rem;font-weight:600;color:hsl(var(--muted-foreground));display:flex;align-items:center;justify-content:space-between}
  .sm-cell-today .sm-cell-day span {background:hsl(var(--primary-strong));color:hsl(var(--primary-foreground));border-radius:999px;width:1.5rem;height:1.5rem;display:inline-flex;align-items:center;justify-content:center}
  .sm-cell-add{opacity:0;color:hsl(var(--muted-foreground));border-radius:.375rem;padding:.1rem}
  .sm-cell:hover .sm-cell-add{opacity:1}
  .sm-cell-add:hover{background:hsl(var(--muted))}
  .sm-chip{display:flex;align-items:center;gap:.35rem;font-size:.72rem;line-height:1.2;padding:.25rem .4rem;border-radius:.4rem;border-left:3px solid;background:hsl(var(--muted)/.6);color:hsl(var(--foreground));text-decoration:none;overflow:hidden}
  .sm-chip:hover{background:hsl(var(--muted))}
  .sm-chip-time{font-variant-numeric:tabular-nums;color:hsl(var(--muted-foreground));flex-shrink:0}
  .sm-chip-txt{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0}
  .sm-chip-draft{border-color:#9ca3af}.sm-chip-review{border-color:#f59e0b}.sm-chip-scheduled{border-color:#3b82f6}.sm-chip-publishing{border-color:#3b82f6}
  .sm-chip-published{border-color:#16a34a}.sm-chip-partial{border-color:#f59e0b}.sm-chip-failed{border-color:#dc2626}
  .sm-ti{display:inline-flex;align-items:center;justify-content:center;width:1.25rem;height:1.25rem;border-radius:.3rem;background:hsl(var(--muted));color:hsl(var(--muted-foreground))}
  .sm-ti-ok{background:hsl(var(--tone-ok-bg));color:hsl(var(--tone-ok-fg))}.sm-ti-bad{background:hsl(var(--tone-bad-bg));color:hsl(var(--tone-bad-fg))}
  .sm-thumb{width:2.75rem;height:2.75rem;border-radius:.5rem;background:hsl(var(--muted)) center/cover no-repeat;flex-shrink:0}
  .sm-thumb-empty{display:flex;align-items:center;justify-content:center;color:hsl(var(--muted-foreground))}
  .sm-agenda-day{display:flex;gap:.75rem;padding:.75rem 0;border-top:1px solid hsl(var(--border))}
  .sm-agenda-day:first-child{border-top:0}
  .sm-agenda-date{width:3.25rem;flex-shrink:0;text-align:center}
  .sm-agenda-date b{display:block;font-size:1.25rem;line-height:1.1}
  .sm-agenda-date span{font-size:.7rem;color:hsl(var(--muted-foreground));text-transform:uppercase}
  .sm-kpis{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:.75rem}
  @media(min-width:768px){.sm-kpis{grid-template-columns:repeat(4,minmax(0,1fr))}}
  .sm-bars{display:flex;align-items:flex-end;gap:2px;height:160px;border-bottom:1px solid hsl(var(--border));position:relative}
  .sm-bar-col{flex:1;display:flex;flex-direction:column;justify-content:flex-end;align-items:center;height:100%;min-width:0;cursor:default}
  .sm-bar-col:hover .sm-bar{opacity:.75}
  .sm-bar{width:100%;max-width:24px;background:hsl(var(--primary));border-radius:4px 4px 0 0}
  .sm-bar-lbl{font-size:.65rem;color:hsl(var(--muted-foreground));margin-top:.25rem;white-space:nowrap}
  .sm-hbar{height:.6rem;border-radius:.3rem;background:hsl(var(--primary))}
  .sm-two{display:grid;grid-template-columns:1fr;gap:1rem}
  @media(min-width:1024px){.sm-two{grid-template-columns:1fr 1fr}}
  .sm-idea{border:1px solid hsl(var(--border));border-radius:.75rem;padding:.75rem;display:flex;gap:.75rem;align-items:flex-start}
  .sm-idea-cap{white-space:pre-wrap;font-size:.8125rem;color:hsl(var(--muted-foreground));margin-top:.25rem;max-height:6.5rem;overflow:hidden}
  .sm-chip[draggable="true"]{cursor:grab}
  .sm-cell.is-over{outline:2px dashed hsl(var(--primary));outline-offset:-2px;background:hsl(var(--primary)/.06)}
  .sm-chip.is-dragging{opacity:.4}
  .sm-cmt{border:1px solid hsl(var(--border));border-radius:.75rem;padding:.75rem;background:hsl(var(--card))}
  .sm-cmt.is-open{border-left:3px solid hsl(var(--primary))}
  .sm-cmt-reply{margin-left:1.25rem;padding-left:.6rem;border-left:2px solid hsl(var(--border));margin-top:.4rem;font-size:.8125rem}
  .sm-cmt-act{display:inline-flex;align-items:center;gap:.25rem;border:1px solid hsl(var(--border));border-radius:.4rem;padding:.2rem .5rem;font-size:.72rem;font-weight:500;cursor:pointer;background:hsl(var(--card))}
  .sm-cmt-act:hover{background:hsl(var(--muted))}
  .sm-sugg{border:1px solid hsl(var(--primary)/.3);background:hsl(var(--primary)/.05);border-radius:.5rem;padding:.4rem .6rem;font-size:.8125rem;cursor:pointer;text-align:left}
  .sm-sugg:hover{background:hsl(var(--primary)/.12)}
  .sm-heat{display:grid;grid-template-columns:2.2rem repeat(24,minmax(0,1fr));gap:2px;font-size:.6rem}
  .sm-heat-cell{aspect-ratio:1/1;border-radius:2px;background:hsl(var(--muted));position:relative}
  .sm-heat-lbl{color:hsl(var(--muted-foreground));display:flex;align-items:center;justify-content:center}
  .sm-line{width:100%;height:120px;display:block}
  .sm-series{border:1px solid hsl(var(--border));border-radius:.75rem;padding:.75rem}
  .sm-wd{display:inline-flex;align-items:center;justify-content:center;width:2.2rem;height:2.2rem;border:1px solid hsl(var(--border));border-radius:.5rem;font-size:.75rem;font-weight:500;cursor:pointer}
  .sm-wd.is-on {background:hsl(var(--primary-strong));color:hsl(var(--primary-foreground));border-color:hsl(var(--primary-strong))}

/* ── Social Media — Beitrags-Editor (social-media-editor.php) ── */
  .sme-cols{display:grid;grid-template-columns:1fr;gap:1rem;align-items:start}
  @media(min-width:1024px){.sme-cols{grid-template-columns:minmax(0,1fr) 22rem}}
  @media(min-width:1280px){.sme-cols{grid-template-columns:minmax(0,1fr) 24rem}}
  .sme-tiles{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:.5rem}
  .sme-tile{border:1px solid hsl(var(--border));border-radius:.75rem;padding:.6rem .5rem;text-align:center;cursor:pointer;font-size:.8125rem;display:flex;flex-direction:column;align-items:center;gap:.25rem;background:hsl(var(--card))}
  .sme-tile input{position:absolute;opacity:0;pointer-events:none}
  .sme-tile.is-on{border-color:hsl(var(--primary));background:hsl(var(--primary)/.08);color:hsl(var(--primary))}
  .sme-tile.is-off{opacity:.6;cursor:not-allowed}
  .sme-ch{display:flex;align-items:center;gap:.6rem;border:1px solid hsl(var(--border));border-radius:.75rem;padding:.5rem .75rem;cursor:pointer;background:hsl(var(--card))}
  .sme-ch.is-on{border-color:hsl(var(--primary));background:hsl(var(--primary)/.06)}
  .sme-ch input{accent-color:hsl(var(--primary))}
  .sme-avatar{width:2rem;height:2rem;border-radius:999px;background:hsl(var(--muted)) center/cover no-repeat;flex-shrink:0;display:flex;align-items:center;justify-content:center;color:hsl(var(--muted-foreground))}
  .sme-ai-bar{display:flex;gap:.5rem;flex-wrap:wrap;margin-bottom:.5rem}
  .sme-ai-btn{display:inline-flex;align-items:center;gap:.35rem;border:1px solid hsl(var(--primary)/.35);background:hsl(var(--primary)/.06);color:hsl(var(--primary));border-radius:.5rem;padding:.35rem .6rem;font-size:.75rem;font-weight:500;cursor:pointer}
  .sme-ai-btn:hover{background:hsl(var(--primary)/.12)}
  .sme-ai-btn:disabled{opacity:.5;cursor:not-allowed}
  .sme-counter{font-size:.7rem;color:hsl(var(--muted-foreground));display:flex;gap:.75rem;justify-content:flex-end;margin-top:.25rem}
  .sme-counter .over{color:hsl(var(--tone-bad-fg));font-weight:600}
  .sme-media{display:grid;grid-template-columns:repeat(auto-fill,minmax(7.5rem,1fr));gap:.5rem}
  .sme-m{position:relative;border:1px solid hsl(var(--border));border-radius:.75rem;overflow:hidden;background:hsl(var(--muted))}
  .sme-m-img{aspect-ratio:1/1;background:center/cover no-repeat;display:flex;align-items:center;justify-content:center;color:hsl(var(--muted-foreground))}
  .sme-m-acts{display:flex;justify-content:space-between;gap:.15rem;padding:.25rem;background:hsl(var(--card))}
  .sme-m-acts button{padding:.2rem;border-radius:.3rem;color:hsl(var(--muted-foreground))}
  .sme-m-acts button:hover{background:hsl(var(--muted))}
  /* Bild-Overlays und Plattform-Vorschau: bewusst feste Farben (über dem Foto bzw. wie auf
     Facebook/Instagram), in beiden Themen gleich — Marke „feste Farbe“ (UI-Audit CODE-08). */
  .sme-m-hint{/*feste Farbe*/position:absolute;top:.3rem;left:.3rem;background:#f59e0b;color:#fff;border-radius:999px;width:1.25rem;height:1.25rem;display:flex;align-items:center;justify-content:center}
  .sme-m-n{/*feste Farbe*/position:absolute;top:.3rem;right:.3rem;background:rgba(0,0,0,.55);color:#fff;border-radius:999px;font-size:.65rem;padding:.1rem .4rem}
  .sme-drop{border:2px dashed hsl(var(--border));border-radius:.75rem;padding:1rem;text-align:center;color:hsl(var(--muted-foreground));font-size:.8125rem;cursor:pointer}
  .sme-drop.is-over{border-color:hsl(var(--primary));background:hsl(var(--primary)/.05)}
  .sme-prev{/*feste Farbe*/border:1px solid hsl(var(--border));border-radius:1rem;overflow:hidden;background:#fff;color:#111;font-size:.8125rem}
  .sme-prev-head{display:flex;align-items:center;gap:.5rem;padding:.6rem .75rem}
  .sme-prev-img{/*feste Farbe*/aspect-ratio:1/1;background:#e5e7eb center/cover no-repeat;display:flex;align-items:center;justify-content:center;color:#9ca3af}
  .sme-prev-img.r45{aspect-ratio:4/5}.sme-prev-img.r916{aspect-ratio:9/16}
  .sme-prev-body{padding:.6rem .75rem;white-space:pre-wrap;word-break:break-word;line-height:1.35}
  .sme-prev-more{/*feste Farbe*/color:#6b7280}
  .sme-prev-icons{/*feste Farbe*/display:flex;gap:.75rem;padding:.4rem .75rem 0;color:#111}
  .sme-prev-link{/*feste Farbe*/border:1px solid #e5e7eb;background:#f3f4f6;padding:.5rem .75rem;font-size:.75rem;color:#6b7280;word-break:break-all}
  .sme-story{/*feste Farbe*/position:relative;aspect-ratio:9/16;border-radius:1rem;overflow:hidden;background:#111 center/cover no-repeat;max-width:16rem;margin:0 auto}
  .sme-story-bar{/*feste Farbe*/position:absolute;top:.5rem;left:.5rem;right:.5rem;height:3px;background:rgba(255,255,255,.5);border-radius:2px}
  .sme-story-head{/*feste Farbe*/position:absolute;top:1rem;left:.6rem;display:flex;align-items:center;gap:.4rem;color:#fff;font-size:.75rem;text-shadow:0 1px 2px rgba(0,0,0,.6)}
  .sme-tabs{display:inline-flex;gap:.25rem;background:hsl(var(--muted)/.6);padding:.2rem;border-radius:.6rem}
  .sme-tabs button{padding:.25rem .6rem;border-radius:.45rem;font-size:.75rem;font-weight:500;color:hsl(var(--muted-foreground))}
  .sme-tabs button.is-on{background:hsl(var(--card));color:hsl(var(--foreground));box-shadow:0 1px 2px rgba(0,0,0,.08)}
  .sme-res{border:1px solid hsl(var(--border));border-radius:.75rem;padding:.75rem}
  .sme-stat{display:inline-flex;align-items:center;gap:.25rem;font-size:.75rem;color:hsl(var(--muted-foreground))}
  .sme-cmt{border-top:1px solid hsl(var(--border));padding:.5rem 0}
  .sme-cmt-reply{margin-left:1.25rem;padding-left:.5rem;border-left:2px solid hsl(var(--border));margin-top:.35rem}
  .sme-chip{display:inline-flex;align-items:center;gap:.25rem;border:1px solid hsl(var(--border));border-radius:999px;padding:.2rem .6rem;font-size:.75rem;cursor:pointer;background:hsl(var(--card))}
  .sme-chip.is-on{border-color:hsl(var(--primary));background:hsl(var(--primary)/.1);color:hsl(var(--primary))}
  .sme-warn{border:1px solid hsl(var(--tone-warn-border));background:hsl(var(--tone-warn-bg));color:hsl(var(--tone-warn-fg));border-radius:.75rem;padding:.6rem .75rem;font-size:.8125rem}
  .sme-warn ul{padding-left:1.1rem;list-style:disc}
  .sme-promo{border:1px dashed hsl(var(--primary)/.4);background:hsl(var(--primary)/.04);border-radius:.6rem;padding:.5rem .6rem}
  .sme-note{border-top:1px solid hsl(var(--border));padding:.5rem 0}
  .sme-note:first-child{border-top:0;padding-top:0}
  .sme-hist{font-size:.75rem;color:hsl(var(--muted-foreground));padding:.25rem 0;border-top:1px solid hsl(var(--border)/.5)}
  .sme-m-alt{/*feste Farbe*/position:absolute;bottom:2.4rem;left:.3rem;background:rgba(0,0,0,.55);color:#fff;border-radius:.3rem;font-size:.6rem;padding:.05rem .3rem}

/* ── Social Media — Meta-Anleitung (Modal) (_meta-anleitung-modal.php) ── */
  .mg-body{font-size:.875rem;line-height:1.55}
  .mg-body h3{font-size:1rem;font-weight:600;margin:1.75rem 0 .5rem;padding-top:.25rem;display:flex;align-items:center;gap:.5rem;scroll-margin-top:.5rem}
  .mg-body h3:first-child{margin-top:0}
  .mg-body h3 .mg-num{display:inline-flex;align-items:center;justify-content:center;width:1.5rem;height:1.5rem;border-radius:999px;background:hsl(var(--primary)/.12);color:hsl(var(--primary));font-size:.75rem;font-weight:600;flex-shrink:0}
  .mg-body p{margin:0 0 .6rem}
  .mg-body ol,.mg-body ul{margin:0 0 .75rem;padding-left:1.35rem}
  .mg-body ol{list-style:decimal}.mg-body ul{list-style:disc}
  .mg-body li{margin:0 0 .35rem}
  .mg-body code{font-size:.8rem;background:hsl(var(--muted));padding:.05rem .35rem;border-radius:.3rem;word-break:break-all}
  .mg-body .mg-path{font-weight:500;color:hsl(var(--foreground))}
  .mg-note{border-left:3px solid hsl(var(--primary));background:hsl(var(--primary)/.06);padding:.6rem .75rem;border-radius:.5rem;margin:0 0 .75rem}
  .mg-warn{border-left:3px solid #f59e0b;background:hsl(var(--tone-warn-bg));color:hsl(var(--tone-warn-fg));padding:.6rem .75rem;border-radius:.5rem;margin:0 0 .75rem}
  .mg-toc{display:flex;flex-wrap:wrap;gap:.4rem;margin-bottom:1rem}
  .mg-toc button{border:1px solid hsl(var(--border));border-radius:999px;padding:.25rem .7rem;font-size:.75rem;font-weight:500;color:hsl(var(--muted-foreground));background:hsl(var(--card));cursor:pointer}
  .mg-toc button:hover{background:hsl(var(--muted));color:hsl(var(--foreground))}
  .mg-table{width:100%;border-collapse:collapse;font-size:.8125rem;margin:0 0 .75rem}
  .mg-table th,.mg-table td{text-align:left;padding:.45rem .6rem;border-top:1px solid hsl(var(--border));vertical-align:top}
  .mg-table th{background:hsl(var(--muted)/.5);font-weight:500;border-top:0}
  .mg-check li{list-style:none;position:relative;padding-left:1.5rem}
  .mg-check li::before{content:'';position:absolute;left:0;top:.2rem;width:.9rem;height:.9rem;border:1.5px solid hsl(var(--border));border-radius:.25rem}

/* ============================================================================
   Build-Nachtrag (UI-Audit CODE-06, 2026-09-16)
   Tailwind ist vorkompiliert und gepurged (CLAUDE-UI.md §2.1): Klassen, die beim
   letzten Build nicht im Quelltext standen, hatten keine Regel — Hover-Töne,
   Fokusringe und Dateiknopf-Stile passierten im Browser still nicht. Hier stehen
   genau diese Utilities, so wie Tailwind v4 sie erzeugen würde, in derselben
   Ebene (@layer utilities), damit Varianten und Reihenfolge stimmen.
   Neue Utility, die im Build fehlt? HIER ergänzen (in allen drei Installationen
   gleich) — der Wächter „Utilities ohne Regel im Build" steht auf 0.
   Farben der Schema-Tokens über hsl(var(--…)), damit der Dunkelmodus folgt (§2.5).
   ============================================================================ */
@layer utilities {
  /* Maße und Abstände */
  .h-0\.5 { height: calc(var(--spacing) * .5); }
  .w-28 { width: calc(var(--spacing) * 28); }
  .w-56 { width: calc(var(--spacing) * 56); }
  .max-h-60 { max-height: calc(var(--spacing) * 60); }
  .left-6 { left: calc(var(--spacing) * 6); }
  .right-6 { right: calc(var(--spacing) * 6); }
  .mt-px { margin-top: 1px; }
  .pb-2\.5 { padding-bottom: calc(var(--spacing) * 2.5); }
  .bottom-4 { bottom: calc(var(--spacing) * 4); }
  .mr-auto { margin-right: auto; }
  .pl-1\.5 { padding-left: calc(var(--spacing) * 1.5); }
  .pr-0\.5 { padding-right: calc(var(--spacing) * .5); }
  .py-7 { padding-block: calc(var(--spacing) * 7); }
  .gap-x-5 { column-gap: calc(var(--spacing) * 5); }
  .gap-y-3 { row-gap: calc(var(--spacing) * 3); }
  .rounded-l-lg { border-top-left-radius: var(--radius-lg); border-bottom-left-radius: var(--radius-lg); }
  .rounded-r-lg { border-top-right-radius: var(--radius-lg); border-bottom-right-radius: var(--radius-lg); }
  .first\:mt-0:first-child { margin-top: 0; }
  .focus-visible\:underline:focus-visible { text-decoration-line: underline; }
  .last\:mb-0:last-child { margin-bottom: 0; }
  .font-sans { font-family: var(--font-sans); }
  .cursor-grab { cursor: grab; }
  .active\:cursor-grabbing:active { cursor: grabbing; }

  /* Flächen- und Schrifttöne */
  .bg-amber-50\/50 { background-color: color-mix(in oklab, var(--color-amber-50) 50%, transparent); }
  .bg-amber-50\/60 { background-color: color-mix(in oklab, var(--color-amber-50) 60%, transparent); }
  .bg-amber-50\/70 { background-color: color-mix(in oklab, var(--color-amber-50) 70%, transparent); }
  .bg-green-50\/50 { background-color: color-mix(in oklab, var(--color-green-50) 50%, transparent); }
  .bg-green-50\/60 { background-color: color-mix(in oklab, var(--color-green-50) 60%, transparent); }
  .bg-blue-400\/60 { background-color: color-mix(in oklab, var(--color-blue-400) 60%, transparent); }
  .bg-primary\/70 { background-color: color-mix(in oklab, var(--color-primary) 70%, transparent); }
  .bg-white\/95 { background-color: color-mix(in oklab, var(--color-white) 95%, transparent); }
  .bg-white\/70 { background-color: color-mix(in oklab, var(--color-white) 70%, transparent); }
  .bg-amber-50\/40 { background-color: color-mix(in oklab, var(--color-amber-50) 40%, transparent); }
  .border-cyan-200 { border-color: var(--color-cyan-200); }
  .text-muted-foreground\/30 { color: hsl(var(--muted-foreground) / .3); }
  .disabled\:opacity-30:disabled { opacity: .3; }
  .text-muted-foreground\/40 { color: hsl(var(--muted-foreground) / .4); }
  .text-muted-foreground\/50 { color: hsl(var(--muted-foreground) / .5); }
  .text-muted-foreground\/60 { color: hsl(var(--muted-foreground) / .6); }
  .text-muted-foreground\/70 { color: hsl(var(--muted-foreground) / .7); }
  .text-red-600\/90 { color: color-mix(in oklab, var(--color-red-600) 90%, transparent); }
  .active\:bg-primary\/10:active { background-color: color-mix(in oklab, var(--color-primary) 10%, transparent); }


  /* Ringe */
  .ring-amber-200 { --tw-ring-color: var(--color-amber-200); }
  .ring-primary\/15 { --tw-ring-color: color-mix(in oklab, var(--color-primary) 15%, transparent); }
  .ring-primary\/20 { --tw-ring-color: color-mix(in oklab, var(--color-primary) 20%, transparent); }
  .focus\:ring-amber-400\/40:focus { --tw-ring-color: color-mix(in oklab, var(--color-amber-400) 40%, transparent); }
  .focus\:ring-primary\/30:focus { --tw-ring-color: color-mix(in oklab, var(--color-primary) 30%, transparent); }

  /* Dateiauswahl-Knopf (input type=file) */
  .file\:mr-3::file-selector-button { margin-right: calc(var(--spacing) * 3); }
  .file\:px-3::file-selector-button { padding-inline: calc(var(--spacing) * 3); }
  .file\:py-1\.5::file-selector-button { padding-block: calc(var(--spacing) * 1.5); }
  .file\:rounded-lg::file-selector-button { border-radius: var(--radius-lg); }
  .file\:border-border::file-selector-button { border-color: hsl(var(--border)); }
  .file\:bg-white::file-selector-button { background-color: var(--color-white); }
  .file\:bg-muted::file-selector-button { background-color: hsl(var(--muted)); }

  /* Hover-Rückmeldungen (nur bei Zeigegeräten, wie Tailwind v4) */
  @media (hover: hover) {
    .hover\:bg-primary\/5:hover { background-color: color-mix(in oklab, var(--color-primary) 5%, transparent); }
    .hover\:bg-primary\/20:hover { background-color: color-mix(in oklab, var(--color-primary) 20%, transparent); }
    .hover\:bg-amber-700:hover { background-color: var(--color-amber-700); }
    .hover\:bg-violet-100:hover { background-color: var(--color-violet-100); }
    .hover\:bg-violet-700:hover { background-color: var(--color-violet-700); }
    .hover\:border-primary\/40:hover { border-color: color-mix(in oklab, var(--color-primary) 40%, transparent); }
    .hover\:border-primary\/60:hover { border-color: color-mix(in oklab, var(--color-primary) 60%, transparent); }
    .hover\:border-red-200:hover { border-color: var(--color-red-200); }
    .disabled\:hover\:bg-white:disabled:hover { background-color: var(--color-white); }
    .hover\:file\:bg-muted:hover::file-selector-button { background-color: hsl(var(--muted)); }
    .hover\:file\:bg-muted\/70:hover::file-selector-button { background-color: hsl(var(--muted) / .7); }
    .group-hover\:text-primary:is(:where(.group):hover *) { color: var(--color-primary); }
  }

  /* Bruchstellen: sm = 40rem, lg = 64rem (wie im Build) */
  @media (min-width: 40rem) {
    .sm\:w-8 { width: calc(var(--spacing) * 8); }
    .sm\:col-span-3 { grid-column: span 3 / span 3; }
  }
  @media (min-width: 64rem) {
    .lg\:p-5 { padding: calc(var(--spacing) * 5); }
    .lg\:w-56 { width: calc(var(--spacing) * 56); }
    .lg\:table-cell { display: table-cell; }
    .lg\:max-w-4xl { max-width: var(--container-4xl); }
  }
}


/* ---- Mein Profil → Benachrichtigungen: Raster Modul × Kanal ------------------
   Eine Zeile je Modul, drei Schalter (Mitteilung, Badge, Push). Auf dem Handy
   bleiben die Schalter als Symbole mit 44-px-Trefferfläche neben dem Modulnamen,
   statt wie früher in umbrechenden Pillen. Die Spaltenköpfe schalten die ganze
   Spalte um. Bewusst ohne .extr-Präfix (Klassenmenge der Bausteine bleibt gleich). */
.notif-grid { display:flex; flex-direction:column; }
.notif-head, .notif-row { display:grid; grid-template-columns:minmax(0,1fr) repeat(3, 3.25rem); align-items:center; column-gap:.25rem; }
.notif-head { padding-bottom:.375rem; border-bottom:1px solid hsl(var(--border)); color:hsl(var(--muted-foreground)); }
.notif-head-mod { font-size:.6875rem; font-weight:600; letter-spacing:.04em; text-transform:uppercase; }
.notif-col { display:flex; flex-direction:column; align-items:center; gap:.125rem; padding:.25rem 0; border:0; border-radius:.5rem; background:none; color:inherit; font:inherit; font-size:.625rem; line-height:1.15; cursor:pointer; }
.notif-col:hover, .notif-col:focus-visible { background:hsl(var(--muted) / .6); color:hsl(var(--foreground)); }
.notif-col svg, .notif-col i { width:1rem; height:1rem; }
.notif-row { padding:.25rem 0; }
.notif-row + .notif-row { border-top:1px solid hsl(var(--border)); }
.notif-mod { display:flex; align-items:center; gap:.5rem; min-width:0; font-size:.875rem; font-weight:500; }
.notif-mod > svg, .notif-mod > i { width:1rem; height:1rem; flex-shrink:0; color:hsl(var(--primary)); }
.notif-mod > span { min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.notif-tog { position:relative; display:flex; align-items:center; justify-content:center; height:2.75rem; cursor:pointer; }
.notif-tog input { position:absolute; inset:0; width:100%; height:100%; margin:0; opacity:0; cursor:pointer; }
.notif-tog > span { display:flex; align-items:center; justify-content:center; width:2.5rem; height:2.25rem; border-radius:.625rem; border:1px solid hsl(var(--border)); color:hsl(var(--muted-foreground)); opacity:.55; transition:background-color .15s, border-color .15s, color .15s, opacity .15s; }
.notif-tog > span svg, .notif-tog > span i { width:1rem; height:1rem; }
.notif-tog:hover > span { opacity:.85; }
.notif-tog input:checked + span { background:hsl(var(--primary) / .1); border-color:hsl(var(--primary) / .4); color:hsl(var(--primary)); opacity:1; }
.notif-tog input:focus-visible + span { outline:2px solid hsl(var(--primary) / .5); outline-offset:2px; }
.notif-legend { list-style:none; margin:.875rem 0 0; padding:0; display:flex; flex-wrap:wrap; gap:.25rem 1.25rem; font-size:.75rem; color:hsl(var(--muted-foreground)); }
.notif-legend li { display:flex; align-items:center; gap:.375rem; margin:0; }
.notif-legend svg, .notif-legend i { width:.875rem; height:.875rem; flex-shrink:0; }
.notif-actions { display:flex; justify-content:flex-end; margin-top:1rem; }
@media (max-width:639px) {
  .notif-actions > .extr-btn { width:100%; justify-content:center; }
}
@media (min-width:640px) {
  .notif-head, .notif-row { grid-template-columns:minmax(0,1fr) repeat(3, 5.5rem); }
  .notif-col { font-size:.6875rem; }
}

/* ---- Helpdesk-Ausbau 2026-09 (Feedback AZS) ---------------------------------
   In allen Installationen gleich (azs, rp, aurum, vbm).
   .hd-rich: Ticket-Text und Kommentare aus dem Editor (HD-01) — bereinigtes HTML
   mit Bildern; .hd-rich--plain: Altbestand als Text mit Zeilenumbrüchen. */
.hd-rich { font-size:.875rem; line-height:1.6; overflow-wrap:anywhere; }
.hd-rich > :first-child { margin-top:0; }
.hd-rich > :last-child { margin-bottom:0; }
.hd-rich p { margin:0 0 .5rem; }
.hd-rich h2 { font-size:1.05rem; font-weight:650; margin:1rem 0 .4rem; }
.hd-rich h3, .hd-rich h4 { font-size:.95rem; font-weight:600; margin:.85rem 0 .35rem; }
.hd-rich ul { list-style:disc; padding-left:1.25rem; margin:.25rem 0 .6rem; }
.hd-rich ol { list-style:decimal; padding-left:1.25rem; margin:.25rem 0 .6rem; }
.hd-rich li { margin:.125rem 0; }
.hd-rich a { color:hsl(var(--primary)); text-decoration:underline; text-underline-offset:2px; }
.hd-rich strong, .hd-rich b { font-weight:600; }
.hd-rich blockquote { border-left:3px solid hsl(var(--border)); padding-left:.75rem; color:hsl(var(--muted-foreground)); margin:.5rem 0; }
.hd-rich pre, .hd-rich code { font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:.8125rem; background:hsl(var(--muted)); border-radius:.375rem; }
.hd-rich pre { padding:.5rem .75rem; overflow-x:auto; white-space:pre-wrap; }
.hd-rich code { padding:0 .25rem; }
.hd-rich table { border-collapse:collapse; margin:.5rem 0; font-size:.8125rem; }
.hd-rich th, .hd-rich td { border:1px solid hsl(var(--border)); padding:.3rem .5rem; text-align:left; vertical-align:top; }
.hd-rich img { display:inline-block; max-width:100%; height:auto !important; border-radius:.625rem; border:1px solid hsl(var(--border)); margin:.25rem 0; cursor:zoom-in; }
.hd-rich a:has(> img) { text-decoration:none; }
.hd-rich--plain { white-space:normal; }
/* HD-03: Unterkategorie in der Kategorieverwaltung eingerückt */
.hd-cat-row--sub { margin-left:1.5rem; }
/* HD-07: Auswahlliste zum Tippen (window.extrSelectSearch in app.js) — das Eingabefeld
   trägt die Klassen des versteckten Selects (.extr-select bzw. .extr-filter-select). */
.extr-combo { position:relative; }
.extr-combo--inline { display:inline-block; flex-shrink:0; }
.extr-combo--inline .extr-combo-input { width:13rem; }
.extr-combo-input.extr-filter-select { height:2.375rem; padding-right:2rem; background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E"); background-repeat:no-repeat; background-position:right .75rem center; }
.extr-combo-input { text-overflow:ellipsis; }
.extr-combo-list { position:absolute; left:0; right:0; top:calc(100% + 4px); z-index:70; min-width:14rem; max-height:16rem; overflow-y:auto; padding:.25rem; background:hsl(var(--card)); border:1px solid hsl(var(--border)); border-radius:.75rem; box-shadow:0 12px 32px -12px rgb(0 0 0 / .25); }
.extr-combo-group { padding:.45rem .6rem .2rem; font-size:.6875rem; font-weight:600; letter-spacing:.04em; text-transform:uppercase; color:hsl(var(--muted-foreground)); }
.extr-combo-opt { padding:.45rem .6rem; border-radius:.5rem; font-size:.875rem; cursor:pointer; color:hsl(var(--foreground)); }
.extr-combo-opt--in-group { padding-left:1.1rem; }
.extr-combo-opt.is-current { font-weight:600; }
.extr-combo-opt.is-active, .extr-combo-opt:hover { background:hsl(var(--primary) / .08); color:hsl(var(--primary)); }
.extr-combo-empty { padding:.5rem .6rem; font-size:.8125rem; color:hsl(var(--muted-foreground)); }
/* HD-05: Ticket-Suche (Verwaltung) — Treffer und KI-Antwort */
.hd-ks-hit { border:1px solid hsl(var(--border)); border-radius:.75rem; padding:.625rem .75rem; background:hsl(var(--card)); }
.hd-ks-hit-head { display:flex; align-items:baseline; gap:.5rem; min-width:0; }
.hd-ks-ref { font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:.75rem; color:hsl(var(--primary)); text-decoration:none; white-space:nowrap; }
.hd-ks-ref:hover { text-decoration:underline; }
.hd-ks-hit-title { font-size:.875rem; font-weight:600; color:hsl(var(--foreground)); text-decoration:none; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; min-width:0; }
.hd-ks-hit-title:hover { text-decoration:underline; }
.hd-ks-hit-meta { font-size:.75rem; color:hsl(var(--muted-foreground)); margin-top:.125rem; }
.hd-ks-sol { display:inline-block; padding:0 .4rem; border-radius:999px; background:hsl(var(--tone-ok-bg, 141 84% 93%)); color:hsl(var(--tone-ok-fg, 142 72% 29%)); font-weight:600; }
.hd-ks-snip { font-size:.8125rem; color:hsl(var(--muted-foreground)); margin:.35rem 0 0; overflow-wrap:anywhere; }
.hd-ks-ai { border:1px solid hsl(var(--primary) / .25); background:hsl(var(--primary) / .05); border-radius:.75rem; padding:.75rem .875rem; font-size:.875rem; }
.hd-ks-ai-head { font-size:.6875rem; font-weight:600; letter-spacing:.04em; text-transform:uppercase; color:hsl(var(--primary)); margin:0 0 .35rem; }
.hd-ks-ai-text { margin:0; line-height:1.6; white-space:pre-line; }
.hd-ks-ai-note { margin:.5rem 0 0; font-size:.75rem; color:hsl(var(--muted-foreground)); }
/* HD-10: Tabellenansicht des Helpdesks */
.hd-list-row.is-done .hd-list-title a { color:hsl(var(--muted-foreground)); }
.hd-list-title { min-width:14rem; }
.hd-sla { display:inline-block; padding:.05rem .45rem; border-radius:999px; font-size:.75rem; font-weight:500; border:1px solid transparent; }
.hd-sla--ok { background:hsl(var(--tone-ok-bg, 141 84% 93%)); color:hsl(var(--tone-ok-fg, 142 72% 29%)); }
.hd-sla--warning { background:hsl(var(--tone-warn-bg, 48 100% 96%)); color:hsl(var(--tone-warn-fg, 23 83% 31%)); border-color:hsl(var(--tone-warn-border, 46 97% 65%)); }
.hd-sla--breached { background:hsl(var(--tone-bad-bg, 0 93% 94%)); color:hsl(var(--tone-bad-fg, 0 74% 42%)); }
/* HD-11: Helpdesk-Statistik — Säulen und Balken nach CLAUDE-UI §3.15 (wie KI-Verbrauch) */
.hd-st-plot { position:relative; height:220px; margin:1rem 0 0 2.5rem; }
.hd-st-grid { position:absolute; left:0; right:0; border-top:1px solid hsl(var(--border)); }
.hd-st-grid span { position:absolute; right:100%; margin-right:.5rem; transform:translateY(-50%); font-size:11px; color:hsl(var(--muted-foreground)); white-space:nowrap; }
.hd-st-cols { position:absolute; inset:0; display:flex; align-items:flex-end; gap:2px; }
.hd-st-col { flex:1 1 0; min-width:0; height:100%; display:flex; align-items:flex-end; justify-content:center; position:relative; cursor:default; }
.hd-st-colbar { width:100%; max-width:24px; border-radius:4px 4px 0 0; background:hsl(var(--primary)); transition:opacity .12s; }
.hd-st-col:hover .hd-st-colbar, .hd-st-col:focus .hd-st-colbar { opacity:.75; }
.hd-st-peak { position:absolute; bottom:100%; left:50%; transform:translateX(-50%); font-size:11px; color:hsl(var(--foreground)); white-space:nowrap; margin-bottom:2px; }
.hd-st-xaxis { display:flex; gap:2px; margin:.4rem 0 0 2.5rem; }
.hd-st-xaxis span { flex:1 1 0; min-width:0; font-size:11px; color:hsl(var(--muted-foreground)); text-align:center; white-space:nowrap; overflow:visible; }
.hd-st-bar { height:18px; border-radius:0 4px 4px 0; background:hsl(var(--primary)); transition:opacity .12s; }
.hd-st-brow:hover .hd-st-bar, .hd-st-brow:focus .hd-st-bar { opacity:.75; }
.hd-st-blabel { width:11rem; }
.hd-st-bval { width:3.5rem; }
#hd-st-tip { position:absolute; z-index:50; pointer-events:none; transform:translate(-50%, calc(-100% - 8px)); background:hsl(var(--foreground)); color:hsl(var(--background)); font-size:12px; line-height:1.3; padding:.35rem .6rem; border-radius:.4rem; white-space:nowrap; box-shadow:0 6px 20px -8px rgba(0,0,0,.4); }
@media (max-width:639px) { .hd-st-blabel { width:7.5rem; } }
/* HD-12: Antwortvorlagen im Kommentarfeld */
.hd-tpl-pop { position:absolute; left:0; bottom:calc(100% + 6px); z-index:60; width:min(22rem, 80vw); padding:.5rem; background:hsl(var(--card)); border:1px solid hsl(var(--border)); border-radius:.75rem; box-shadow:0 12px 32px -12px rgb(0 0 0 / .25); }
.hd-tpl-list { max-height:16rem; overflow-y:auto; margin-top:.4rem; display:flex; flex-direction:column; gap:2px; }
.hd-tpl-item { display:flex; flex-direction:column; align-items:flex-start; text-align:left; padding:.45rem .55rem; border-radius:.5rem; border:0; background:none; cursor:pointer; color:hsl(var(--foreground)); }
.hd-tpl-item:hover, .hd-tpl-item:focus-visible { background:hsl(var(--primary) / .08); }
.hd-tpl-item-title { font-size:.875rem; font-weight:600; }
.hd-tpl-item-text { font-size:.75rem; color:hsl(var(--muted-foreground)); }
/* HD-02: Personensuche „Ticket für dritte Person anlegen" */
.hd-proxy-opt { display:flex; flex-direction:column; width:100%; text-align:left; padding:.5rem .75rem; font-size:.875rem; border:0; background:none; cursor:pointer; color:hsl(var(--foreground)); }
.hd-proxy-opt:hover, .hd-proxy-opt:focus-visible { background:hsl(var(--muted)); }
.hd-proxy-opt-name { font-weight:500; }
.hd-proxy-opt-meta { font-size:.75rem; color:hsl(var(--muted-foreground)); }
.hd-proxy-empty { padding:.5rem .75rem; font-size:.875rem; color:hsl(var(--muted-foreground)); }

/* ---- Helpdesk Runde 2 (Feedback AZS 28.09.2026) — in allen Installationen gleich ----
   HD-27 Textfarben und Hervorhebungen aus einer festen Palette (im Editor gewählt, gespeichert als
   Klasse, im Dunkelmodus eigene Töne), HD-28 angehaltene SLA-Frist, Systemeinträge im Verlauf,
   HD-23 Beteiligte als Chips, HD-21 Sammelleiste der Tabellenansicht. */
:root {
  --hd-c-red: 0 74% 45%; --hd-c-orange: 21 90% 40%; --hd-c-green: 142 72% 29%; --hd-c-blue: 224 76% 48%;
  --hd-hl-red: 0 93% 94%; --hd-hl-orange: 34 100% 92%; --hd-hl-green: 141 84% 93%; --hd-hl-blue: 214 95% 93%; --hd-hl-yellow: 55 97% 77%;
}
html[data-theme="dark"] {
  --hd-c-red: 0 94% 78%; --hd-c-orange: 27 96% 67%; --hd-c-green: 142 70% 64%; --hd-c-blue: 213 94% 74%;
  --hd-hl-red: 0 91% 71% / .22; --hd-hl-orange: 27 96% 61% / .22; --hd-hl-green: 142 69% 58% / .2; --hd-hl-blue: 213 94% 68% / .22; --hd-hl-yellow: 50 98% 64% / .3;
}
.hd-tc-red { color:hsl(var(--hd-c-red)); }
.hd-tc-orange { color:hsl(var(--hd-c-orange)); }
.hd-tc-green { color:hsl(var(--hd-c-green)); }
.hd-tc-blue { color:hsl(var(--hd-c-blue)); }
.hd-hl-red, .hd-hl-orange, .hd-hl-green, .hd-hl-blue, .hd-hl-yellow { border-radius:.2rem; padding:0 .12em; -webkit-box-decoration-break:clone; box-decoration-break:clone; }
.hd-hl-red { background:hsl(var(--hd-hl-red)); }
.hd-hl-orange { background:hsl(var(--hd-hl-orange)); }
.hd-hl-green { background:hsl(var(--hd-hl-green)); }
.hd-hl-blue { background:hsl(var(--hd-hl-blue)); }
.hd-hl-yellow { background:hsl(var(--hd-hl-yellow)); }
/* Editor im Helpdesk: nur die feste Palette, kein freier Farbwähler */
.hd-editor .note-color-select, .hd-editor .note-color-select-btn, .hd-editor .note-holder-custom { display:none !important; }
.hd-sla--paused { background:hsl(var(--muted)); color:hsl(var(--muted-foreground)); }
/* Systemeintrag im Verlauf (Weitergabe, Zurückstellung, Beteiligte, KI-Zuordnung …) */
.hd-event { display:flex; align-items:flex-start; gap:.5rem; padding:.55rem 1.25rem; font-size:.8125rem; line-height:1.5; color:hsl(var(--muted-foreground)); background:hsl(var(--muted) / .35); }
.hd-event svg, .hd-event i { width:.875rem; height:.875rem; flex-shrink:0; margin-top:.2rem; }
.hd-event-text { flex:1 1 auto; min-width:0; overflow-wrap:anywhere; }
.hd-event-time { flex-shrink:0; white-space:nowrap; font-size:.75rem; }
/* HD-23: Beteiligte */
.hd-chip { display:inline-flex; align-items:center; gap:.35rem; max-width:100%; padding:.2rem .3rem .2rem .65rem; border-radius:999px; border:1px solid hsl(var(--border)); background:hsl(var(--card)); font-size:.8125rem; }
.hd-chip-meta { font-size:.75rem; color:hsl(var(--muted-foreground)); }
.hd-chip-x { display:inline-flex; align-items:center; justify-content:center; width:1.35rem; height:1.35rem; border-radius:999px; border:0; background:none; color:hsl(var(--muted-foreground)); cursor:pointer; }
.hd-chip-x:hover, .hd-chip-x:focus-visible { background:hsl(var(--muted)); color:hsl(var(--foreground)); }
.hd-chip-x svg, .hd-chip-x i { width:.8rem; height:.8rem; }
/* HD-21: Sammelleiste (Auswahl in der Tabellenansicht) und Zielwahl im Dialog */
.hd-bulk { position:sticky; bottom:1rem; z-index:20; }
.hd-pick-row { display:flex; align-items:center; gap:.75rem; padding:.625rem; border-radius:.5rem; border:1px solid hsl(var(--border)); cursor:pointer; }
.hd-pick-row:hover { background:hsl(var(--muted) / .5); }
.hd-pick-ref { flex-shrink:0; font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:.75rem; color:hsl(var(--muted-foreground)); }
.hd-pick-title { flex:1 1 auto; min-width:0; font-size:.875rem; font-weight:500; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
/* HD-02/HD-23: Vorschlagsliste der Personensuche (Höhe begrenzt) */
.hd-people-list { max-height:15rem; overflow-y:auto; }

/* ---- Helpdesk: Aufgaben am Ticket + Checklisten (2026-10-08, nur azs_orbit) ----
   Ticketansicht zweispaltig ab 1024 px: links das Ticket, rechts die Arbeitsspalte mit Checkliste und
   verknüpften Aufgaben (bleibt beim Scrollen stehen). Darunter einspaltig, Arbeitsspalte unter dem Ticket. */
.hd-detail-grid { display:grid; grid-template-columns:minmax(0,1fr); gap:1.5rem; align-items:start; }
.hd-detail-main { min-width:0; }
.hd-detail-side { min-width:0; }
@media (min-width:1024px) {
  .hd-detail-grid--split { grid-template-columns:minmax(0,42rem) minmax(19rem,26rem); }
  .hd-detail-side { position:sticky; top:1rem; max-height:calc(100vh - 2rem); overflow-y:auto; overscroll-behavior:contain; }
}
.hd-progress { height:.375rem; border-radius:999px; background:hsl(var(--muted)); overflow:hidden; }
.hd-progress > span { display:block; height:100%; border-radius:inherit; background:hsl(var(--primary)); transition:width .2s; }
.hd-progress--done > span { background:hsl(var(--tone-ok-fg, 142 72% 29%)); }
.hd-cl-item { display:flex; align-items:flex-start; gap:.6rem; padding:.4rem .25rem; border-radius:.5rem; font-size:.875rem; line-height:1.4; cursor:pointer; }
.hd-cl-item:hover { background:hsl(var(--muted) / .5); }
.hd-cl-item input { margin-top:.15rem; flex-shrink:0; width:1rem; height:1rem; }
.hd-cl-item input:disabled { cursor:default; }
.hd-cl-item--done .hd-cl-text { color:hsl(var(--muted-foreground)); text-decoration:line-through; }
.hd-cl-meta { display:block; font-size:.7rem; color:hsl(var(--muted-foreground)); text-decoration:none; }
.hd-cl-block { display:flex; gap:.5rem; align-items:flex-start; padding:.55rem .7rem; border-radius:.6rem; font-size:.8125rem; background:hsl(var(--tone-warn-bg, 48 100% 96%)); color:hsl(var(--tone-warn-fg, 23 83% 31%)); border:1px solid hsl(var(--tone-warn-border, 46 97% 65%)); }
.hd-cl-block.hidden { display:none; }   /* sonst schlägt display:flex die Utility (app.css lädt nach tailwind.css) */
.hd-cl-block svg, .hd-cl-block i { width:1rem; height:1rem; flex-shrink:0; margin-top:.1rem; }
.hd-task { border:1px solid hsl(var(--border)); border-radius:.85rem; padding:.75rem; background:hsl(var(--card)); }
.hd-task + .hd-task { margin-top:.6rem; }
.hd-task--done { background:hsl(var(--muted) / .35); }
.hd-task--done .hd-task-title { text-decoration:line-through; color:hsl(var(--muted-foreground)); }
.hd-task-head { display:flex; align-items:flex-start; gap:.5rem; }
.hd-task-title { flex:1 1 auto; min-width:0; font-size:.875rem; font-weight:600; line-height:1.35; overflow-wrap:anywhere; }
.hd-task-meta { display:flex; flex-wrap:wrap; gap:.3rem .75rem; margin-top:.4rem; font-size:.75rem; color:hsl(var(--muted-foreground)); }
.hd-task-meta span { display:inline-flex; align-items:center; gap:.25rem; }
.hd-task-meta svg, .hd-task-meta i { width:.8rem; height:.8rem; }
.hd-task-meta .hd-task-late { color:hsl(var(--tone-bad-fg, 0 74% 42%)); font-weight:600; }
.hd-task-subs { margin-top:.45rem; }
.hd-task-foot { display:flex; align-items:center; gap:.5rem; margin-top:.6rem; flex-wrap:wrap; }
.hd-task-foot .extr-select { width:auto; flex:1 1 8rem; min-width:0; }
.hd-origin { display:inline-flex; align-items:center; gap:.25rem; padding:.1rem .5rem; border-radius:999px; font-size:.7rem; font-weight:600; white-space:nowrap; background:hsl(var(--primary) / .1); color:hsl(var(--primary)); }
.hd-origin svg, .hd-origin i { width:.75rem; height:.75rem; }
.hd-origin--muted { background:hsl(var(--muted)); color:hsl(var(--muted-foreground)); }
a.hd-origin:hover, a.hd-origin:focus-visible { text-decoration:underline; }
.hd-sub-row { display:flex; align-items:center; gap:.5rem; }
.hd-sub-row + .hd-sub-row { margin-top:.4rem; }
.hd-sub-row input[type="checkbox"] { width:1rem; height:1rem; flex-shrink:0; }
.hd-sub-row .extr-input { flex:1 1 auto; min-width:0; }
/* Titel der Aufgabenkarte öffnet die Ansicht im Dialog (2026-10-08) */
button.hd-task-title { display:block; padding:0; border:0; background:none; text-align:left; cursor:pointer; color:inherit; font-size:.875rem; font-weight:600; line-height:1.35; }
button.hd-task-title:hover, button.hd-task-title:focus-visible { color:hsl(var(--primary)); text-decoration:underline; }
/* Aufgabe ansehen (Dialog) */
.hd-tv-badges { display:flex; flex-wrap:wrap; align-items:center; gap:.4rem; }
.hd-tv-pill { display:inline-flex; align-items:center; padding:.15rem .6rem; border-radius:999px; font-size:.75rem; font-weight:600; background:hsl(var(--muted)); color:hsl(var(--muted-foreground)); }
.hd-tv-pill--in-bearbeitung { background:hsl(var(--primary) / .1); color:hsl(var(--primary)); }
.hd-tv-pill--erledigt { background:hsl(var(--tone-ok-bg, 141 84% 93%)); color:hsl(var(--tone-ok-fg, 142 72% 29%)); }
.hd-tv-desc { margin-top:1rem; font-size:.875rem; line-height:1.6; white-space:pre-line; overflow-wrap:anywhere; }
.hd-tv-meta { display:grid; grid-template-columns:repeat(2, minmax(0, 1fr)); gap:.75rem 1.25rem; margin:1rem 0 0; padding:.85rem 1rem; border:1px solid hsl(var(--border)); border-radius:.75rem; }
.hd-tv-meta dt { font-size:.75rem; color:hsl(var(--muted-foreground)); }
.hd-tv-meta dd { margin:.15rem 0 0; font-size:.875rem; font-weight:500; }
.hd-tv-sec { margin-top:1.25rem; }
.hd-tv-h { margin:0 0 .4rem; font-size:.8125rem; font-weight:600; }
.hd-tv-files { display:flex; flex-wrap:wrap; gap:.4rem; }
.hd-tv-files .hd-chip { padding-right:.65rem; }
.hd-tv-files .hd-chip svg { width:.8rem; height:.8rem; }
.hd-tv-comment { padding:.6rem .75rem; border-radius:.6rem; background:hsl(var(--muted) / .45); }
.hd-tv-comment + .hd-tv-comment { margin-top:.4rem; }
.hd-tv-comment-head { display:flex; flex-wrap:wrap; align-items:baseline; gap:.15rem .5rem; font-size:.75rem; color:hsl(var(--muted-foreground)); }
.hd-tv-comment-head strong { color:hsl(var(--foreground)); font-weight:600; }
.hd-tv-comment-text { margin-top:.2rem; font-size:.875rem; white-space:pre-line; overflow-wrap:anywhere; }
.hd-tv-note { margin-top:1rem; font-size:.75rem; color:hsl(var(--muted-foreground)); }
@media (max-width:639px) { .hd-tv-meta { grid-template-columns:minmax(0, 1fr); } }
/* Aufgabenset laden (Dialog im Ticket) */
.hd-set-preview { margin-top:.6rem; padding:.7rem .85rem; border:1px solid hsl(var(--border)); border-radius:.75rem; background:hsl(var(--muted) / .35); }
.hd-set-preview:empty { display:none; }
.hd-set-desc { margin-bottom:.4rem; font-size:.8125rem; color:hsl(var(--muted-foreground)); }
.hd-set-list { margin:0; padding-left:1.15rem; list-style:decimal; font-size:.875rem; }
.hd-set-list li { padding:.15rem 0; }
.hd-set-due { margin-left:.4rem; font-size:.75rem; color:hsl(var(--muted-foreground)); }
.hd-set-modes { display:grid; grid-template-columns:repeat(2, minmax(0, 1fr)); gap:.5rem; }
.hd-set-mode { display:flex; align-items:center; gap:.5rem; padding:.55rem .7rem; border:1px solid hsl(var(--border)); border-radius:.6rem; font-size:.875rem; cursor:pointer; }
.hd-set-mode:has(input:checked) { border-color:hsl(var(--primary)); background:hsl(var(--primary) / .06); }
.hd-set-mode input { width:1rem; height:1rem; flex-shrink:0; }
.hd-set-mode--off { opacity:.5; cursor:not-allowed; }
@media (max-width:639px) { .hd-set-modes { grid-template-columns:minmax(0, 1fr); } }
/* Helpdesk verwalten: ein Dialog mit Reitern (Kategorien, Antwortvorlagen, Checklisten, Aufgabensets, Externe Personen).
   Der Reiterinhalt hält die Kette Panel → Körper (scrollt) → Fuß zusammen: flex-Spalte mit min-height:0. */
.hd-admin-tabs { flex-shrink:0; padding:.75rem 1.5rem 0; overflow-x:auto; }
.hd-admin-pane { display:flex; flex-direction:column; flex:1 1 auto; min-height:0; }
.hd-admin-intro { margin-bottom:.85rem; font-size:.8125rem; color:hsl(var(--muted-foreground)); }
@media (max-width:639px) { .hd-admin-tabs { padding:.6rem 1rem 0; } }
/* Aufgabenset-Formular: je Aufgabe Titel · Priorität · Tage · Entfernen, darunter die Beschreibung */
.hd-setf-row { display:grid; gap:.4rem; padding:.6rem; border:1px solid hsl(var(--border)); border-radius:.65rem; background:hsl(var(--card)); }
.hd-setf-line { display:grid; grid-template-columns:minmax(0, 1fr) 8.5rem 5.5rem auto; gap:.4rem; align-items:center; }
@media (max-width:639px) {
  .hd-setf-line { grid-template-columns:minmax(0, 1fr) 5rem auto; }
  .hd-setf-line > :first-child { grid-column:1 / -1; }
}

/* ---- SCHUL-01: Bilder in Tests (Feedback AZS 2026-09) ----------------------
   In azs, rp und aurum gleich. Editor: Bild zur Frage + Bild je Antwortoption;
   Ablauf/Ergebnis/Vorschau: Bild unter der Frage, Antwortbilder als Kachel. */
.sch-img-add { display:inline-flex; align-items:center; gap:.4rem; margin:-.25rem 0 .75rem; padding:.3rem .6rem; border:1px dashed hsl(var(--border)); border-radius:.6rem; font-size:.8125rem; color:hsl(var(--muted-foreground)); background:none; cursor:pointer; }
.sch-img-add:hover { color:hsl(var(--primary)); border-color:hsl(var(--primary) / .5); }
.sch-q-img { display:flex; align-items:flex-end; gap:.75rem; margin:-.25rem 0 .75rem; flex-wrap:wrap; }
.sch-q-img img, .sch-view-img { max-width:100%; max-height:16rem; border-radius:.75rem; border:1px solid hsl(var(--border)); background:hsl(var(--muted) / .4); }
.sch-view-img { display:block; margin:.5rem 0 .75rem; cursor:zoom-in; }
.sch-img-remove { display:inline-flex; align-items:center; gap:.3rem; font-size:.75rem; color:hsl(var(--muted-foreground)); background:none; border:0; cursor:pointer; }
.sch-img-remove:hover { color:hsl(0 74% 42%); }
.sch-ans-img { position:relative; display:inline-flex; flex-shrink:0; }
.sch-ans-img img { height:2.5rem; width:2.5rem; object-fit:cover; border-radius:.5rem; border:1px solid hsl(var(--border)); }
.sch-img-x { position:absolute; top:-.4rem; right:-.4rem; height:1.25rem; width:1.25rem; display:flex; align-items:center; justify-content:center; border-radius:999px; border:1px solid hsl(var(--border)); background:hsl(var(--card)); color:hsl(var(--muted-foreground)); cursor:pointer; }
.sch-img-x:hover { color:hsl(0 74% 42%); }
.sch-opt-img { display:block; max-height:9rem; max-width:100%; border-radius:.5rem; border:1px solid hsl(var(--border)); margin-top:.35rem; }
.sch-opt-thumb { height:2rem; width:2rem; object-fit:cover; border-radius:.35rem; border:1px solid hsl(var(--border)); flex-shrink:0; }

/* ---- Signage: Gerätezustand im Bildschirm-Modal (Feedback AZS 09/2026) -----
   „Anzeige hängt", Gerätedienst, letzter Befehl mit Bestätigung, Wächter,
   abgerufene Protokolle (_geraete-signage-modal.php, smonDevState). */
.smon-ds { display:flex; flex-direction:column; gap:.4rem; margin-top:.75rem; }
.smon-ds-line { display:flex; align-items:flex-start; gap:.5rem; font-size:.8125rem; line-height:1.35; padding:.45rem .6rem; border-radius:.5rem; background:hsl(var(--muted)); color:hsl(var(--foreground)); }
.smon-ds-line--ok { background:hsl(var(--tone-ok-bg, 141 84% 93%)); color:hsl(var(--tone-ok-fg, 142 72% 29%)); }
.smon-ds-line--warn { background:hsl(var(--tone-warn-bg, 48 100% 96%)); color:hsl(var(--tone-warn-fg, 23 83% 31%)); border:1px solid hsl(var(--tone-warn-border, 46 97% 65%)); }
.smon-ds-icon { height:1rem; width:1rem; flex-shrink:0; margin-top:.1rem; }
.smon-ds-text { min-width:0; overflow-wrap:anywhere; }
.smon-ds-sub { font-size:.75rem; color:hsl(var(--muted-foreground)); margin-top:.15rem; }
.smon-ds-line--ok .smon-ds-sub, .smon-ds-line--warn .smon-ds-sub { color:inherit; opacity:.85; }
.smon-ds-logs { display:flex; flex-direction:column; gap:.2rem; }
.smon-ds-log { display:flex; flex-wrap:wrap; align-items:center; gap:.75rem; font-size:.8125rem; }
.smon-ds-log a { color:hsl(var(--primary)); font-weight:500; }
.smon-ds-log a:hover { text-decoration:underline; }
.smon-status--warn { color:hsl(var(--tone-warn-fg, 23 83% 31%)); font-weight:600; }
/* Übersichten: Bildschirm online, Anzeige hängt */
.sg-hung-pill { display:inline-flex; align-items:center; gap:.25rem; border-radius:9999px; padding:.1rem .45rem; font-size:.68rem; font-weight:600; flex:0 0 auto; background:hsl(var(--tone-warn-bg, 48 100% 96%)); color:hsl(var(--tone-warn-fg, 23 83% 31%)); border:1px solid hsl(var(--tone-warn-border, 46 97% 65%)); }

/* ── Einstellungen: Karten in einer Spalte (2026-10-05) ─────────────────────
   Die Einstellungsseite zeigt ihre Karten in einer Spalte statt im Raster – eine
   Kante, keine Lücken. Kategorie, Gruppe und Reihenfolge legt $settingsOrdnung in
   partials/einstellungen.php fest; die Zwischenüberschriften (.settings-gruppe)
   setzt das Skript der Seite – nur in Kategorien ab fünf Karten. */
.settings-liste { display: flex; flex-direction: column; gap: 1rem; max-width: 64rem; }
@media (min-width: 1024px) { .settings-liste { gap: 1.25rem; } }
.settings-liste > * { min-width: 0; }
.settings-liste > .settings-gruppe {
  margin: .75rem 0 -.25rem;
  font-size: .75rem;
  line-height: 1rem;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: hsl(var(--muted-foreground));
}
.settings-liste > .settings-gruppe.is-erste { margin-top: 0; }

/* ── Öffentliche Seiten für Externe (UI-Audit CODE-10) ─────────────────────────
   Bewerber-Einwilligung/-Termin/-Upload, Formular-Kurzlink f.php, Startcode,
   Freigabe: ein Gerüst statt je eines <style>-Blocks. Farben über Token, damit
   Marke und Akzent der jeweiligen Installation gelten (vorher fest hsl(173 …)). */
.extr-public-body { margin: 0; padding: 0; min-height: 100vh; background: linear-gradient(160deg, hsl(var(--card)) 0%, hsl(var(--muted)) 100%); }
.extr-public-wrap { max-width: 600px; margin: 0 auto; padding: 1.5rem 1rem 4rem; }
.extr-public-wrap--narrow { max-width: 460px; }
.extr-public-wrap--doc { max-width: 860px; }
.extr-public-logo { text-align: center; margin: 1.5rem 0 2rem; }
.extr-public-logo img { width: 3rem; height: 3rem; object-fit: contain; margin: 0 auto .5rem; display: block; }
.extr-public-name { font-size: 1.125rem; font-weight: 700; color: hsl(var(--foreground)); }
.extr-public-sub { color: hsl(var(--primary)); font-size: .8125rem; font-weight: 600; }
.extr-public-card { background: hsl(var(--card)); border-radius: 1rem; padding: 1.75rem; box-shadow: 0 12px 40px rgba(0,0,0,.08); }
.extr-public-card + .extr-public-card { margin-top: 1rem; }
.extr-public-hp { position: absolute; left: -9999px; top: -9999px; width: 1px; height: 1px; overflow: hidden; }
.extr-public-slot input:checked + span { border-color: hsl(var(--primary)); box-shadow: 0 0 0 2px hsl(var(--primary) / .2); }
@media print { .extr-public-body { background: #fff; } .extr-public-card { box-shadow: none; padding: 0; } }

/* ── Kopfaktionen: Überlauf-„⋮“ am Desktop (UI-Audit HDR-05) ───────────────────
   extr_page_actions() legt Einträge über EXTR_PAGE_ACTIONS_INLINE_MAX (oder mit
   'overflow' => true) in einen eigenen Block am Ende der Reihe. Mobil gibt es nur
   ein Menü — der Block löst sich dort auf. */
@media (max-width: 1023.98px) {
  .extr-action-menu-wrap .extr-action-overflow,
  .extr-action-menu-wrap .extr-action-overflow > .extr-action-menu { display: contents; }
  .extr-action-menu-wrap .extr-action-overflow > .extr-action-more { display: none; }
}
@media (min-width: 1024px) {
  .extr-page-actions .extr-action-overflow { position: relative; display: inline-flex; }
  .extr-page-actions .extr-action-overflow > .extr-action-more {
    display: inline-flex;
    height: 2.5rem;
    width: 2.5rem;
    border: 1px solid hsl(var(--border));
    border-radius: .5rem;
    background: hsl(var(--card));
    color: hsl(var(--muted-foreground));
  }
  .extr-page-actions .extr-action-overflow > .extr-action-menu {
    display: none;
    position: absolute;
    right: 0;
    top: calc(100% + .5rem);
    min-width: 15rem;
    max-width: min(22rem, calc(100vw - 2rem));
    padding: .375rem;
    z-index: 60;
    background: hsl(var(--card));
    border: 1px solid hsl(var(--border));
    border-radius: .875rem;
    box-shadow: var(--extr-shadow-lg);
  }
  .extr-page-actions .extr-action-overflow.is-open > .extr-action-menu { display: block; }
  .extr-page-actions .extr-action-overflow .extr-action-item {
    width: 100%;
    height: auto;
    padding: .5rem .625rem;
    border: 0;
    border-radius: .5rem;
    background: none;
    color: hsl(var(--foreground));
    white-space: normal;
  }
  .extr-page-actions .extr-action-overflow .extr-action-item:hover { background: hsl(var(--muted)); }
  .extr-page-actions .extr-action-overflow .extr-action-item--danger { color: hsl(var(--destructive)); }
  .extr-page-actions .extr-action-overflow .extr-action-sep { display: block; }
  .extr-page-actions .extr-action-overflow .extr-action-sep--mobile { display: none; }
}
/* ── UI-Audit DARK-04: Pastellrahmen und helle Hover-Flächen im Dunkelmodus ──────
   Status-Chips „bg-*-50 border-*-200 text-*-800“ bekommen im Dunkel-Scope schon
   getönte Fläche und helle Schrift; die Rahmen blieben pastellhell. Jetzt über die
   Ton-Rahmen (--tone-*-border). Neue Chips besser gleich mit --tone-* bauen. */
html[data-theme="dark"] .border-amber-200,
html[data-theme="dark"] .border-amber-300,
html[data-theme="dark"] .border-yellow-200,
html[data-theme="dark"] .border-yellow-300,
html[data-theme="dark"] .border-orange-200,
html[data-theme="dark"] .border-orange-300 { border-color: hsl(var(--tone-warn-border)); }
html[data-theme="dark"] .border-green-200,
html[data-theme="dark"] .border-green-300,
html[data-theme="dark"] .border-emerald-200,
html[data-theme="dark"] .border-emerald-300,
html[data-theme="dark"] .border-teal-200,
html[data-theme="dark"] .border-teal-300 { border-color: hsl(var(--tone-ok-border)); }
html[data-theme="dark"] .border-red-200,
html[data-theme="dark"] .border-red-300,
html[data-theme="dark"] .border-rose-200,
html[data-theme="dark"] .border-rose-300,
html[data-theme="dark"] .border-pink-200,
html[data-theme="dark"] .border-pink-300 { border-color: hsl(var(--tone-bad-border)); }
html[data-theme="dark"] .border-blue-200,
html[data-theme="dark"] .border-blue-300,
html[data-theme="dark"] .border-sky-200,
html[data-theme="dark"] .border-sky-300,
html[data-theme="dark"] .border-indigo-200,
html[data-theme="dark"] .border-indigo-300,
html[data-theme="dark"] .border-cyan-200,
html[data-theme="dark"] .border-cyan-300 { border-color: hsl(var(--tone-info-border)); }
html[data-theme="dark"] .border-violet-200,
html[data-theme="dark"] .border-violet-300,
html[data-theme="dark"] .border-purple-200,
html[data-theme="dark"] .border-purple-300,
html[data-theme="dark"] .border-fuchsia-200,
html[data-theme="dark"] .border-fuchsia-300 { border-color: rgba(167,139,250,.4); }
html[data-theme="dark"] .hover\:bg-red-50:hover,
html[data-theme="dark"] .hover\:bg-red-100:hover,
html[data-theme="dark"] .hover\:bg-rose-50:hover { background-color: rgba(248,113,113,.14); }
html[data-theme="dark"] .hover\:bg-amber-50:hover,
html[data-theme="dark"] .hover\:bg-amber-100:hover,
html[data-theme="dark"] .hover\:bg-yellow-50:hover { background-color: rgba(251,191,36,.14); }
html[data-theme="dark"] .hover\:bg-green-50:hover,
html[data-theme="dark"] .hover\:bg-green-100:hover,
html[data-theme="dark"] .hover\:bg-emerald-50:hover { background-color: rgba(52,211,153,.14); }
html[data-theme="dark"] .hover\:bg-blue-50:hover,
html[data-theme="dark"] .hover\:bg-blue-100:hover,
html[data-theme="dark"] .hover\:bg-sky-50:hover { background-color: rgba(96,165,250,.14); }
html[data-theme="dark"] .text-sky-800 { color: #38bdf8; }
html[data-theme="dark"] .text-purple-900 { color: #c084fc; }
html[data-theme="dark"] .bg-green-50\/40 { background-color: rgba(52,211,153,.08); }
html[data-theme="dark"] .bg-slate-200 { background-color: hsl(var(--border)); }

/* Getönte Pastellflächen (bg-*-50/NN) und Glasflächen auf Fotos (bg-white/NN) (UI-Audit DARK-04) */
html[data-theme="dark"] .bg-green-50\/50,
html[data-theme="dark"] .bg-green-50\/60 { background-color: rgba(52,211,153,.10); }
html[data-theme="dark"] .bg-amber-50\/40,
html[data-theme="dark"] .bg-amber-50\/50,
html[data-theme="dark"] .bg-amber-50\/60,
html[data-theme="dark"] .bg-amber-50\/70 { background-color: rgba(251,191,36,.10); }
html[data-theme="dark"] .bg-white\/70 { background-color: hsl(var(--card) / .7); }
html[data-theme="dark"] .bg-white\/90 { background-color: hsl(var(--card) / .9); }
html[data-theme="dark"] .bg-white\/95 { background-color: hsl(var(--card) / .95); }
html[data-theme="dark"] .text-red-600\/90 { color: rgba(248,113,113,.9); }
html[data-theme="dark"] .hover\:border-red-200:hover { border-color: hsl(var(--tone-bad-border)); }
html[data-theme="dark"] .hover\:bg-violet-100:hover { background-color: rgba(167,139,250,.14); }
/* Blasse Alpha-Stufen der Nebenschrift erreichen auf dunkler Karte nur 2–3:1 (UI-Audit DARK-01). */
html[data-theme="dark"] .text-muted-foreground\/50 { color: hsl(var(--muted-foreground) / .8); }
html[data-theme="dark"] .text-muted-foreground\/60,
html[data-theme="dark"] .text-muted-foreground\/70,
html[data-theme="dark"] .text-muted-foreground\/80 { color: hsl(var(--muted-foreground) / .92); }

/* ── UI-Audit DARK-02: Flächen in Primärfarbe mit Schrift ─────────────────────
   Weiße Schrift erreicht auf der Markenfarbe nicht überall 4,5:1 (rp, Aurum hell;
   alle drei dunkel). Flächen unter Schrift nutzen deshalb --primary-strong
   (hell: abgedunkelte Marke, dunkel: aufgehellte Primärfarbe) und
   --primary-foreground (hell: weiß, dunkel: dunkel). Reine Akzente (Balken,
   Punkte, Fortschritt) bleiben bei --primary. Ungeschichtet, damit es die
   Tailwind-Utilities bg-primary/text-white schlägt. */
.bg-primary.text-white { background-color: hsl(var(--primary-strong)); color: hsl(var(--primary-foreground)); }
.bg-primary.text-white:is(.hover\:bg-primary\/90, .hover\:opacity-90):hover:not(:disabled) { background-color: hsl(var(--primary-strong)); opacity: 1; filter: brightness(.93); }
/* Rand aktiver Pillen/Flächen passend zur Fläche */
.bg-primary.text-white.border-primary { border-color: hsl(var(--primary-strong)); }
