/* Chat Tower Companion -- pages/admin.css
 * P6-Kette Glied 6/8 (web-241). Reine Verschiebung aus web/public/style.css.
 * Scope: Admin-/Read-only-Flaechen -- Slot x Waffe-Kreuztabelle (web-180,
 * dev-techtree/admin.js), System-Health-Panel, Audio-SFX Admin-Panel,
 * Admin-Aktivitaets-Sektion (web-090), Perf-View (/admin/perf, web-152),
 * FG/BG-Split (web-158), Kaeufe-Uebersicht (/admin/kaeufe, web-300). Keine
 * Kaskaden-Abhaengigkeit zu anderen pages/*.css-Dateien bekannt (kein
 * geteilter Selektor gefunden).
 *
 * web-302 AK5: in Bereichs-Abschnitte gegliedert, Reihenfolge wie die
 * Module unter src/{routes,views}/admin/*.js (Shared -> Dashboard -> Users
 * -> Kuendigungen -> Kaeufe -> Steuerung -> Health -> Audio -> Perf ->
 * Balance -> Statuslog; "Kaeufe" kam mit web-300 dazu, s. dortiger
 * Abschnitt). Reine Umsortierung + Kommentar-Ueberschriften -- KEIN Wert
 * geaendert (Diff = nur Zeilen-Position, byte-identische Deklarationen).
 * Grep-Audit gegen alle views/admin/*.js + client/admin-audio.js (Klassen-
 * Konstruktion teils dynamisch per Template-Literal, s. z.B. admin-badge--
 * ${cls}, health-state--${x}, bar-slot${b.noData?'--nodata':''}) ergab
 * KEINEN toten Selektor -- jede Klasse hat mindestens einen Renderer. */


/* =====================================================================
   SHARED — Klassen, die von MEHR ALS EINEM Bereich verwendet werden
   (Grep-verifiziert gegen views/admin/*.js, s. Datei-Kopf):
     - .admin-subnav/.admin-subtab*      AK4, alle Bereiche
     - .perf-filters/-fgroup/-flabel/-seg  Perf (Filter-Leiste) UND Balance
       (Versions-Filter-Pillen, renderBalanceTable()) -- Name historisch
       aus Perf, NICHT umbenannt (Lock: keine Wertaenderung/kein Rename).
     - .bs-track/.bs-fill                Perf (.bg-share-Kontext) UND
       Balance (.share-cell-Kontext, renderBalanceRow() DMG-Anteil-Balken)
       -- beide Bereiche nutzen die BLANKEN Klassen ohne Eltern-Scope.
       .bg-share .bs-num (Compound-Selektor, NUR Perf) bleibt bewusst im
       Perf-Abschnitt: Balance scoped seinen bs-num-Wert unter .share-cell
       (anderer Elternname), die Compound-Regel greift dort NICHT --
       Balance-bs-num bleibt unfarbig/Default (Bestandsverhalten, nicht
       hier geaendert).
     - .admin-health-grid/-pill/-state(--mini)/-detail, .health-state--*
       Health (System-Health-Panel) UND Steuerung (Queue-Gate/Draw-Tier-
       Panels reused dasselbe Status-Pillen-Muster, s. controls.js) --
       "Health" ist trotz Namens kein reiner Health-Only-Namespace.
     - .admin-badge/-badge--ok/-warn/-bad     web-300: urspruenglich NUR
       Kuendigungen (cancellationStatusBadge()), jetzt zusaetzlich Kaeufe
       (Club-Status-/Bestaetigungs-Pille, s. dortiger Abschnitt) -- hierher
       verschoben (war vorher im KUENDIGUNGEN-Block).
     - .expand-link       web-300: urspruenglich NUR Perf (Recent-Liste-
       Expand), jetzt zusaetzlich Users (Pending-Row -> Kaeufe-Link) UND
       Kaeufe (Spieler-Detail-/Kuendigungs-Link) -- rein visuelle
       Sekundaer-Link-Optik (klein, cyan), Bedeutung variiert je Bereich
       (Inline-Expand bei Perf, Cross-Bereich-Navigation bei Users/Kaeufe) --
       hierher verschoben (war vorher im PERF-Block).
   ===================================================================== */

/* AK4: einheitliche Bereichs-Leiste ueber allen /admin/*-Seiten
   (views/admin/layout.js renderAdminSubNav()). Optik angelehnt an
   .shop-subtab (pages/shop.css) — ABER eigener Klassen-Namespace
   .admin-subtab*: admin-Tabs sind ECHTE <a href>-Links (Server-Navigation
   zwischen Routen), keine JS-Client-Tabs wie im Shop (dort EIN Route-Load,
   Tabs schalten Panels per onclick um) — deshalb kein <button>, keine
   :hover-Spezifitaets-Klemme wie dort (s. shop.css-Kommentar zu
   .shop-subtab--active:hover) noetig, `a` traegt ohnehin keine
   button:hover-Basisregel aus base.css. */
.admin-subnav { display: flex; gap: var(--sp-xs); flex-wrap: wrap; }
.admin-subtab {
  display: inline-flex; align-items: center;
  padding: 0.5em 0.95em; min-height: 44px;
  border-radius: 99px; border: 1px solid var(--line-2);
  background: none; color: var(--muted);
  font-size: var(--fs-small); font-weight: 700;
  text-decoration: none;
  transition: background 0.12s, color 0.12s, border-color 0.12s;
}
.admin-subtab:hover {
  border-color: var(--cyan); color: var(--text);
  background: rgba(56, 225, 255, 0.08);
  text-decoration: none;
}
.admin-subtab--active,
.admin-subtab--active:hover {
  color: var(--bg); background: var(--cyan); border-color: var(--cyan);
}

/* Filter-Leiste (Segmented-Control als Query-Param-Links, kein Client-JS) --
   web-152 Perf UND balance.js renderBalanceTable() (Versions-Filter). */
.perf-filters {
  display: flex;
  flex-wrap: wrap;
  gap: 1.4em;
  align-items: flex-end;
  margin: .2em 0 .4em;
}
.perf-fgroup {
  display: flex;
  flex-direction: column;
  gap: .35em;
}
.perf-flabel {
  /* ui-507 (M4, K1): .7em (~10.5px) -> var(--fs-caption). "Gruppieren"/"Modus"/
     "Zeitfenster"/"App-Version" sind Filter-Gruppen-Labels -- echter Lese-Text,
     keine Deko (Analogie .hs-group-label, ui-505). */
  font-size: var(--fs-caption);
  text-transform: uppercase;
  letter-spacing: .08em;
  color: var(--muted);
}
.perf-seg {
  display: inline-flex;
  border: 1px solid var(--line-2);
  border-radius: 999px;
  overflow: hidden;
}
.perf-seg a {
  padding: .34em .9em;
  font-size: .85em;
  color: var(--text-dim);
  border-right: 1px solid var(--line-2);
  transition: background .15s, color .15s;
}
.perf-seg a:last-child { border-right: none; }
.perf-seg a:hover {
  background: rgba(56, 225, 255, .06);
  color: var(--cyan);
  text-decoration: none;
}
.perf-seg a.active {
  background: var(--cyan);
  color: var(--text-on-accent);
  font-weight: 600;
}

/* Mini-Balken (DMG-/Hintergrund-Anteil) -- Perf .bg-share-Kontext UND
   Balance .share-cell-Kontext (renderBalanceRow()) nutzen dieselben
   blanken .bs-track/.bs-fill-Klassen ohne Eltern-Scope. */
.bs-track {
  width: 54px;
  height: 5px;
  border-radius: 999px;
  background: var(--line-2);
  overflow: hidden;
}
.bs-fill {
  height: 100%;
  background: var(--text-dim);
  border-radius: 999px;
}

/* Status-Pillen-Muster (System-Health-Panel UND Queue-Gate/Draw-Tier auf
   dem Dashboard, s. controls.js renderQueueGate()/renderDrawTierControl()
   -- feat/admin-token-status, 2026-05-28). */
.admin-health-grid {
  /* Etwas breitere Pillen als die KPI-Karten weiter unten — wir packen
     hier 2-3 Zeilen Detail-Text rein, nicht nur Zahlen. */
  align-items: stretch;
}
.admin-health-pill {
  /* Linksbündig statt zentriert, damit der lange Detail-Text gut lesbar bleibt. */
  align-items: flex-start;
  text-align: left;
  min-width: 14em;
  max-width: 22em;
  gap: 0.25em;
  padding: 0.7em 1em;
}
.admin-health-state {
  font-size: 1.1em;
  letter-spacing: 0.02em;
}
.admin-health-state--mini {
  font-size: 0.95em;
  font-weight: 500;
}
.admin-health-detail {
  font-size: 0.8em;
  color: var(--muted);
  line-height: 1.35;
}
.health-state--ok .admin-health-state {
  color: var(--green, #5eff8a);
}
.health-state--warn .admin-health-state {
  color: var(--yellow, #ffd84a);
}
.health-state--error .admin-health-state {
  color: var(--red, #ff4d6e);
}
.health-state--ok    { border-left: 3px solid var(--green, #5eff8a); }
.health-state--warn  { border-left: 3px solid var(--yellow, #ffd84a); }
.health-state--error { border-left: 3px solid var(--red, #ff4d6e); }

/* Status-Badge (urspruenglich web-270, /admin/kuendigungen -- gleiche
   Pill-Form wie .mode-badge, Perf-Abschnitt, Muster wiederverwendet statt
   neu erfunden), Ampel-Farben wie .val-ok/.val-warn/.val-bad (eine Farbe =
   eine Rolle). web-300: zweiter Konsument (Kaeufe-Uebersicht Club-Status-/
   Bestaetigungs-Pille) -- hierher verschoben (war vorher im
   KUENDIGUNGEN-Abschnitt). */
.admin-badge {
  font-size: var(--fs-caption);
  padding: .12em .6em;
  border-radius: 999px;
  border: 1px solid var(--line-2);
  letter-spacing: .02em;
  white-space: nowrap;
}
.admin-badge--ok   { color: var(--green); border-color: var(--green); }
.admin-badge--warn { color: var(--yellow); border-color: var(--yellow); }
.admin-badge--bad  { color: var(--red); border-color: var(--red); }

/* Kleiner Sekundaer-Link (klein, cyan) -- urspruenglich NUR Perf (Recent-
   Liste-Expand-Link), web-300: zweiter/dritter Konsument (Users:
   Pending-Row -> Kaeufe-Link; Kaeufe: Spieler-Detail-/Kuendigungs-Link) --
   hierher verschoben (war vorher im PERF-Abschnitt). Bedeutung variiert je
   Bereich (Inline-Expand bei Perf, Cross-Bereich-Navigation bei Users/
   Kaeufe), Optik identisch. */
.expand-link {
  font-size: .82em;
  color: var(--cyan);
}


/* =====================================================================
   DASHBOARD (GET /admin, views/admin/dashboard.js)
   web-090: Admin Aktivitäts-Sektion — DAU/MAU Kacheln + CSS-Säulencharts.
   ===================================================================== */

/* Kachel-Reihe: BEWUSST eigene Klasse statt .hexa-totals — dort färbt
   .stat-pill.big den Wert magenta (Hexa-Rolle). Aktivität = Cyan (primär). */
.activity-kpis {
  display: flex;
  gap: 1em;
  margin: 1em 0 1.5em;
  flex-wrap: wrap;
}
.activity-kpis .stat-pill.big .stat-num {
  color: var(--cyan);
  text-shadow: 0 0 16px rgba(56, 225, 255, 0.45);
  font-size: 2.2em;
}

/* Chart-Block: Kopfzeile (Untertitel + Peak-Anker) + Säulenleiste + X-Labels */
.activity-chart { margin: 0 0 1.4em; }
.activity-chart:last-of-type { margin-bottom: 1em; }
.activity-chart-head {
  display: flex; justify-content: space-between; align-items: baseline;
  margin-bottom: 0.4em;
}
.activity-chart-title { font-size: 0.85em; color: var(--text-dim); font-weight: 600; }
.activity-chart-peak  { font-size: 0.75em; color: var(--muted); }

.activity-bars {
  display: flex;
  align-items: flex-end;
  gap: 3px;
  height: 120px;
  border-bottom: 1px solid var(--line);
  padding-bottom: 1px;
}
.activity-bars--months { height: 100px; }

/* Slot = volle Höhe, Balken wächst von unten */
.bar-slot {
  flex: 1;
  min-width: 4px;
  height: 100%;
  display: flex;
  align-items: flex-end;
  position: relative;
}
.bar {
  width: 100%;
  background: rgba(56, 225, 255, 0.55);
  border-radius: 2px 2px 0 0;
  transition: background 0.15s ease;
  min-height: 2px;
}
.bar-slot:hover .bar { background: var(--cyan); }

/* heutiger Tag / laufender Monat: Glow = „aktiv" (Guide-Rolle) */
.bar--current {
  background: var(--cyan);
  box-shadow: 0 0 8px rgba(56, 225, 255, 0.6);
}

/* Bucket vor Datenbeginn: Schraffur statt Balken — „keine Daten" ≠ 0 */
.bar-slot--nodata {
  background: repeating-linear-gradient(
    -45deg,
    transparent, transparent 3px,
    rgba(28, 39, 66, 0.9) 3px, rgba(28, 39, 66, 0.9) 5px
  );
  border-radius: 2px;
}

/* X-Achsen-Labels: gleiche Flex-Geometrie wie die Bars, Label nur an Ankerpunkten */
.activity-xlabels {
  display: flex;
  gap: 3px;
  margin-top: 0.3em;
}
.activity-xlabels span {
  flex: 1;
  min-width: 4px;
  /* ui-507 (M4, K2): 0.62em (~9.3px) -> var(--fs-micro), NICHT --fs-caption.
     Whitelist-Kategorie "Achsen-Beschriftungen in Graphen" (Analogie ui-505
     .dg-axis-lbl/.dg-axis-title-Verdikt) -- redundant zum title-Tooltip auf
     .bar-slot (voller Wochentag+Datum+Zahl) UND zur Balkenhoehe selbst. */
  font-size: var(--fs-micro);
  color: var(--muted);
  text-align: center;
  white-space: nowrap;
  overflow: visible;
}

/* ui-214: 600px-Phablet-Stufe, s. Kanon-Master-Kommentar in der Mobile-Sektion. */
@media (max-width: 600px) {
  .activity-bars { gap: 2px; }
  .activity-xlabels { gap: 2px; }
}


/* =====================================================================
   USERS (GET /admin/pending-users, views/admin/users.js)
   Keine eigenen Regeln — die Seite nutzt ausschließlich Shared-/globale
   Klassen (.panel/.hexa-table/.stat-pill/.admin-kpis aus components.css,
   .expand-link fuer den web-300-Kaeufe-Link je Pending-Row s. SHARED oben).
   ===================================================================== */


/* =====================================================================
   KÜNDIGUNGEN (GET /admin/kuendigungen, views/admin/kuendigungen.js)
   .admin-badge* fuer den Status-/Bearbeitet-Pillen ist SHARED (s. oben,
   web-300 zweiter Konsument) -- kein eigener Abschnitt hier mehr noetig.
   ===================================================================== */

/* Kuendigungs-Queue (web-270-Review-Fix, 2026-08-31): "Bestaetigen"/
   "Ablehnen" sind ZWEI getrennte <form>-Elemente (getrennte POST-Targets,
   kein gemeinsames Formular) in derselben Tabellenzelle -- ohne diesen
   Wrapper fallen zwei Block-Level-<form>s untereinander. Jedes Formular
   traegt bereits .pu-limit-form (Button-Optik, gleiches Muster wie "Als
   bearbeitet markieren" daneben) -- dieser Wrapper macht nur das
   Nebeneinander-Layout.
   flex-wrap:wrap (urspruenglicher Stand) NICHT nebeneinander (web-270
   Nachhol-Verifikation, 2026-08-31, selbst gemessen): die Aktionsspalte
   der Kuendigungs-Queue-Tabelle (table-layout:auto, .admin-table) bekam
   unter den 7 Spalten nur ~159px zugeteilt (die "Status"-Spalte allein
   braucht ~208px fuer den laengsten Badge-Text "Ausstehend
   (Admin-Pruefung)"), zwei Buttons mit dem globalen 0.3em/1.1em-Padding
   brauchen aber ~180px kombiniert -> fielen trotz flex-wrap untereinander.
   Root Cause: table-layout:auto behandelt einen WRAPPBAREN Flex-Container
   als "kann auf 1 Item schrumpfen" und reserviert dieser Spalte deshalb nur
   die Breite des breiteren EINZELNEN Buttons -- Padding allein enger machen
   half NICHT (die Spalte schrumpfte proportional mit, selbst verifiziert
   mit mehreren Zwischenschritten). Fix: flex-wrap:nowrap macht den
   Kombiniert-Breitenbedarf beider Buttons zum harten Minimum, das
   table-layout:auto jetzt reserviert -- PLUS engeres Padding unten, damit
   dieser Minimalbedarf klein genug bleibt um den anderen Spalten nicht zu
   viel wegzunehmen. min-height:44px (ui-394-Touch-Target-Lock) bleibt von
   .pu-limit-form button GEERBT, hier NICHT angefasst -- nur horizontales
   Padding + white-space werden spezifischer ueberschrieben. */
.admin-cancel-actions { display: flex; gap: .4em; flex-wrap: nowrap; }
/* Selector bewusst ".admin-cancel-actions .pu-limit-form button" (2 Klassen +
   1 Element, Spezifitaet 0-2-1) statt nur ".admin-cancel-actions button"
   (0-1-1) -- admin.css laedt VOR profile.css (s. views/layout.js
   Link-Reihenfolge-Lock), bei GLEICHER Spezifitaet haette .pu-limit-form
   button aus profile.css (spaeter im Cascade) gewonnen und dieses Override
   wirkungslos gemacht (selbst verifiziert). */
.admin-cancel-actions .pu-limit-form button { padding: 0.3em 0.5em; white-space: nowrap; }


/* =====================================================================
   KÄUFE (GET /admin/kaeufe, views/admin/kaeufe.js — web-300)
   Filter-Leiste nutzt SHARED .perf-filters/-fgroup/-flabel/-seg (s. oben) +
   eigenen .adm-filter-form-Zusatz NUR fuer die Input-/Button-CSS unten
   (bewusst nicht auf .perf-filters selbst, damit Perf/Balance unberuehrt
   bleiben, s. Klassen-Kommentar in views/admin/kaeufe.js filterFormHtml()).
   ===================================================================== */

/* Text-/Datums-Eingaben + Submit -- Optik/Masse an .pu-limit-form
   (profile.css, Monatslimit-Formular) angelehnt, ui-394-Touch-Target-Lock
   (min-height 44px) uebernommen. web-306 (Massen-Gutschrift, Gutschriften-
   Bereich): `textarea` zur Selektor-Liste ergaenzt -- die Pflicht-Nachricht
   an die Spieler ist das ERSTE Mehrzeilen-Feld in diesem Formular-Muster
   (Gutschriften/web-301 selbst fuegte hier keine neue Regel hinzu, reuste
   ausschliesslich die bestehenden Klassen -- s. Datei-Kopfkommentar
   "Grep-Audit ... KEINEN toten Selektor"). */
.adm-filter-form input[type="text"],
.adm-filter-form input[type="date"],
.adm-filter-form textarea {
  min-height: 44px;
  background: var(--bg);
  border: 1px solid var(--line-2);
  color: var(--text);
  border-radius: 8px;
  padding: 0.4em 0.6em;
  font-size: 0.9em;
  font-family: inherit;
}
.adm-filter-form input[type="text"] { width: 220px; }
.adm-filter-form input[type="date"] { width: 155px; }
.adm-filter-form textarea { width: 320px; max-width: 100%; resize: vertical; }
.adm-filter-form button[type="submit"] {
  min-height: 44px;
  background: transparent;
  border: 1px solid var(--line-2);
  border-radius: 999px;
  color: var(--text-dim);
  padding: 0.3em 1.3em;
  font: inherit;
  font-size: 0.9em;
  cursor: pointer;
}
.adm-filter-form button[type="submit"]:hover { border-color: var(--cyan); color: var(--cyan); }

/* Übersichts-Kachel "Offene Bestätigungs-Mails" bei konfiguriertem Mailer +
   Zähler > 0 (AK4) -- eigene Klasse statt Wiederverwendung von
   .admin-health-pill/.health-state--warn (deren Farbregel haengt am
   .admin-health-state-Kindelement, nicht am hier genutzten .stat-num/
   .stat-label-Paar aus .hexa-totals -- neue, hoeher-spezifische Regel statt
   Risiko einer Cascade-Fehlannahme). */
.adm-tile-warn .stat-num { color: var(--yellow); }

/* web-304: Modifier fuer die 5-spaltige Monetarisierungs-KPI-Zeile ganz oben
   auf der Seite (Kachelzeile "Kennzahlen", views/admin/kaeufe.js
   monetarisierungKpisHtml()) -- jede Kachel traegt zusaetzlich zu
   .stat-num/.stat-label bis zu drei weitere .stat-label-Unterzeilen
   (Vorwoche/4-Wochen/Zusatzwerte) statt nur einer, reiner Layout-Tweak auf
   .hexa-totals (Flex-Basis + Row-Gap) -- KEINE neue Pillen-Optik/-Farbe.
   Mobile-Umbruch = geerbtes flex-wrap von .hexa-totals (Muster
   .activity-kpis), kein eigener Media-Query noetig. */
/* Live-Messung (Ticket-Notes): .panel-Content ist ~891-935px breit (Admin-
   Layout begrenzt die Lesebreite, unabhaengig vom Viewport) -- 5 Kacheln a
   170px Flex-Basis + 1em-Gap (.hexa-totals) ueberschreiten das (914px), die
   fuenfte Kachel wich dadurch IMMER in eine zweite Zeile aus. Kleinere Basis
   + engerer Row-Gap (NUR fuer diese Zeile, nicht .hexa-totals global) halten
   5 Kacheln zuverlaessig auf einer Zeile; min-width:0 ueberschreibt den
   Flex-Default min-width:auto (Content-Mindestbreite), damit lange
   Unterzeilen (z.B. "Beitritte W · Vorw. · 4W: 3 · 0 · 3") normal umbrechen
   statt die Kachel zu verbreitern. */
.adm-kpi-row {
  gap: 0.6em;
}
.adm-kpi-row .stat-pill {
  flex: 1 1 150px;
  min-width: 0;
  gap: 0.2em;
}

/* Horizontal-Scroll-Wrapper fuer die 9-Spalten-Tabelle (Muster
   .sw-matrix-scroll, Balance-Abschnitt weiter unten) -- schmalere Viewports
   scrollen die Tabelle statt Spalten zu quetschen. */
.adm-table-scroll { overflow-x: auto; }

/* Referenz-Spalte: "Klick kopiert" -- Optik angelehnt an einen dezenten
   Mono-Chip, gestrichelter Rahmen signalisiert "klickbar, kein Fließtext". */
.adm-copy-btn {
  background: transparent;
  border: 1px dashed var(--line-2);
  color: var(--text-dim);
  border-radius: 4px;
  padding: 0.15em 0.5em;
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: 0.82em;
  cursor: pointer;
}
.adm-copy-btn:hover { border-color: var(--cyan); color: var(--cyan); }
.adm-copy-btn.ok { border-color: var(--green); border-style: solid; color: var(--green); }

/* Pager (Prev/Next + "Seite X von Y") -- V1-Pagination-Debut in diesem
   Admin-Panel (bisherige Bereiche zeigten IMMER die volle Liste), Optik an
   .queue-gate-btn angelehnt (gleiche Pillen-Familie). */
.adm-pager {
  display: flex;
  align-items: center;
  gap: 1em;
  margin: 1em 0 0;
}
.adm-pager-btn {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0.4em 1.1em;
  border: 1px solid var(--line-2);
  border-radius: 999px;
  color: var(--text-dim);
  text-decoration: none;
}
.adm-pager-btn:hover { border-color: var(--cyan); color: var(--cyan); text-decoration: none; }
.adm-pager-btn--disabled { opacity: 0.4; pointer-events: none; }
.adm-pager-info { color: var(--muted); font-size: 0.9em; }


/* =====================================================================
   STEUERUNG (GET/POST /admin/queue-gate, POST /admin/draw-tier,
   views/admin/controls.js — inline auf dem Dashboard gerendert, KEINE
   eigene Route/Seite; AK4-Sub-Nav-Tab "Steuerung" springt per Anchor
   #steuerung auf den Wrapper in dashboard.js)
   ===================================================================== */

/* Queue-Gate-Buttons (game-101) — Broadcaster-Control im /admin-Panel */
.queue-gate-btn {
  display: inline-flex;
  align-items: center;
  padding: 0.45em 1.1em;
  border: 1px solid var(--line-2);
  border-radius: 4px;
  background: transparent;
  color: var(--text);
  font-family: inherit;
  font-size: 0.95em;
  cursor: pointer;
  transition: border-color 0.15s, color 0.15s, box-shadow 0.15s;
  white-space: nowrap;
}
.queue-gate-btn:hover:not(:disabled) {
  border-color: var(--cyan);
  color: var(--cyan);
  box-shadow: 0 0 10px rgba(56, 225, 255, 0.25);
}
/* Aktiver Zustand — zeigt den aktuell gesetzten State (disabled) */
.queue-gate-btn--active {
  border-color: var(--green, #5eff8a);
  color: var(--green, #5eff8a);
  background: rgba(94, 255, 138, 0.08);
  opacity: 0.85;
}
/* Close-Button: hover + aktiver Close-Zustand in Rot */
.queue-gate-btn--close:hover:not(:disabled) {
  border-color: var(--red, #ff4d6e);
  color: var(--red, #ff4d6e);
  box-shadow: 0 0 10px rgba(255, 77, 110, 0.25);
}
.queue-gate-btn--close.queue-gate-btn--active {
  border-color: var(--red, #ff4d6e);
  color: var(--red, #ff4d6e);
  background: rgba(255, 77, 110, 0.08);
}
/* web-320: "starten"-Button (Happy Draw Hour) — grüne Go-Variante, bisher nur
   im Prototyp (.claude/sprint/prototypes/web-320.html), hier erstmals in Prod-CSS. */
.queue-gate-btn--go:hover:not(:disabled) {
  border-color: var(--green, #5eff8a);
  color: var(--green, #5eff8a);
  box-shadow: 0 0 10px rgba(94, 255, 138, 0.25);
}

/* web-320: Happy-Draw-Hour-Formular (Admin-Control, unter dem
   Draw-Tier-Upgrade-Panel, views/admin/controls.js renderDrawTierEventControl()).
   Klassen 1:1 aus dem abgenommenen Prototyp übernommen. */
.hdh-form { margin-top: 1rem; display: grid; gap: 0.8rem; }
.hdh-row { display: grid; gap: 0.35rem; }
.hdh-label {
  font-size: var(--fs-caption);
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.07em;
}
.hdh-chips { display: flex; gap: 0.45rem; flex-wrap: wrap; align-items: center; }
.hdh-chip {
  border: 1px solid var(--line-2);
  background: transparent;
  color: var(--text-dim);
  border-radius: 999px;
  padding: 0.28em 0.8em;
  font-size: 0.88em;
  font-family: inherit;
  cursor: pointer;
  transition: border-color 0.15s, color 0.15s;
}
.hdh-chip:hover { border-color: var(--cyan); color: var(--cyan); }
.hdh-chip.is-on { border-color: var(--cyan); color: var(--cyan); background: rgba(56, 225, 255, 0.08); }
.hdh-hours { width: 5.2rem; }
.hdh-hours-unit { font-size: 0.85em; color: var(--muted); }
.hdh-msg-wrap { display: flex; gap: 0.6rem; align-items: center; flex-wrap: wrap; }
.hdh-msg-input { flex: 1; min-width: 0; max-width: 34rem; }
.hdh-msg-count {
  font-size: 0.78em;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  min-width: 3.6em;
  text-align: right;
}
.hdh-msg-count.is-max { color: var(--yellow); }
.hdh-preview { font-size: 0.86em; color: var(--text-dim); }
.hdh-preview b { color: var(--text); }
.hdh-msg-quote {
  margin: 0.7rem 0 0;
  padding: 0.55em 0.9em;
  border-left: 3px solid var(--magenta);
  background: rgba(255, 69, 181, 0.06);
  border-radius: 0 4px 4px 0;
  font-size: 0.95em;
}
.hdh-msg-quote.is-default { color: var(--text-dim); font-style: italic; }
.hdh-admin-actions { display: flex; gap: 0.75rem; align-items: center; flex-wrap: wrap; margin-top: 0.9rem; }
/* AK8: Hinweis-Zeile im (bestehenden) Draw-Tier-Upgrade-Panel bei aktivem Event. */
.adm-hint { font-size: 0.8em; color: var(--text-dim); margin-top: 0.5em; }
.adm-hint .hl { color: var(--magenta); font-weight: 600; }
/* AK7: "Effektives Max-Tier: N" — Fußzeile in beiden Zuständen. */
.eff-line { margin-top: 0.9em; font-size: 0.9em; color: var(--text-dim); }
.eff-line b { color: var(--text); font-size: 1.1em; }


/* =====================================================================
   HEALTH (System-Health-Panel, views/admin/health.js — inline auf dem
   Dashboard gerendert, KEINE eigene Route/Seite)
   Keine eigenen Regeln — das Status-Pillen-Muster (.admin-health- und
   .health-state--Klassen) ist mit Steuerung (controls.js) geteilt, s.
   SHARED oben. Eigener Marker-Abschnitt trotzdem, damit die Bereichs-Reihenfolge
   (== Modul-Reihenfolge) lueckenlos sichtbar bleibt.
   ===================================================================== */


/* =====================================================================
   AUDIO (Audio-SFX Admin-Panel, views/admin/audio.js — inline auf dem
   Dashboard gerendert, KEINE eigene Route/Seite; web-053, 2026-06-04)
   DL-6: alle Farben über var(--*), neue Klassen audio-Prefix.
   ===================================================================== */

/* Panel-Title-Row: Titel + Saved-Chip nebeneinander */
.audio-panel-title-row {
  display: flex;
  align-items: center;
  gap: 0.8em;
  margin-bottom: 0.8em;
}
.audio-panel-title-row .panel-title { margin: 0; }

/* Master-Steuerung-Zeile */
.audio-master-row {
  display: flex;
  align-items: center;
  gap: 1.2em;
  flex-wrap: wrap;
}

/* Mute-Button */
.audio-mute-btn {
  display: flex;
  align-items: center;
  gap: 0.5em;
  padding: 0.5em 1em;
  border: 1px solid var(--line-2);
  border-radius: 4px;
  background: transparent;
  color: var(--text);
  font-family: inherit;
  font-size: 0.95em;
  cursor: pointer;
  transition: border-color 0.15s, color 0.15s, box-shadow 0.15s;
  white-space: nowrap;
}
.audio-mute-btn.muted {
  border-color: var(--red);
  color: var(--red);
  background: rgba(255, 77, 110, 0.08);
  box-shadow: 0 0 10px rgba(255, 77, 110, 0.3);
}
.audio-mute-btn:not(.muted):hover {
  border-color: var(--red);
  color: var(--red);
}

/* Volume-Control (Master) */
.audio-volume-control {
  display: flex;
  align-items: center;
  gap: 0.7em;
  flex: 1;
  min-width: 180px;
}
.audio-volume-label {
  color: var(--muted);
  font-size: 0.85em;
  white-space: nowrap;
}
.audio-volume-control input[type="range"] {
  flex: 1;
  accent-color: var(--cyan);
  height: 4px;
  cursor: pointer;
}
.audio-volume-value {
  min-width: 3.5em;
  text-align: right;
  font-variant-numeric: tabular-nums;
  color: var(--cyan);
  font-weight: 600;
  font-size: 1em;
}

/* Tier-Gruppe (collapsible Sektion) */
.audio-tier-group {
  margin-bottom: 0.8em;
}
.audio-tier-head {
  display: flex;
  align-items: center;
  gap: 0.6em;
  padding: 0.45em 0.8em;
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-radius: 5px 5px 0 0;
  border-bottom: none;
  cursor: pointer;
  user-select: none;
}
.audio-tier-head.collapsed { border-radius: 5px; border-bottom: 1px solid var(--line); }
.audio-tier-collapse-icon {
  color: var(--muted);
  font-size: 0.85em;
  transition: transform 0.2s;
  margin-left: auto;
}
.audio-tier-head.collapsed .audio-tier-collapse-icon { transform: rotate(-90deg); }

/* Tier-Badge */
.audio-tier-badge {
  /* ui-507 (M4, K1): 0.72em (~10.8px, war eine der 17 Audit-0.72em-Treppen-
     Fundstellen, admin.css:261 -- explizit dem M4-Scope ueberlassen, s.
     ui-505 (M3) ## Notes "3 NICHT gemappt") -> var(--fs-caption). "Tier 1/2/3"
     ist die einzige Anzeige der numerischen Tier-Prioritaet, kein Deko-
     Kandidat (Name-Span daneben zeigt einen ANDEREN Text). */
  font-size: var(--fs-caption);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 0.15em 0.5em;
  border-radius: 3px;
}
.audio-tier-badge.tier-1 {
  background: rgba(255, 216, 74, 0.15);
  color: var(--yellow);
  border: 1px solid rgba(255, 216, 74, 0.3);
}
.audio-tier-badge.tier-2 {
  background: rgba(56, 225, 255, 0.08);
  color: var(--cyan);
  border: 1px solid rgba(56, 225, 255, 0.2);
}
.audio-tier-badge.tier-3 {
  background: rgba(92, 100, 121, 0.3);
  color: var(--muted);
  border: 1px solid var(--line);
}
.audio-tier-name {
  font-weight: 600;
  color: var(--text);
}
.audio-tier-hint {
  font-size: 0.82em;
  color: var(--muted);
}

/* Events-Container */
.audio-tier-events {
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-top: none;
  border-radius: 0 0 5px 5px;
  overflow: hidden;
}
.audio-tier-events.hidden { display: none; }

/* Event-Zeile: Grid 4-spaltig (DL-7) */
.audio-event-row {
  display: grid;
  grid-template-columns: 2.4em 1fr 80px 2.8em;
  align-items: center;
  gap: 0.6em;
  padding: 0.55em 0.9em;
  border-bottom: 1px solid var(--line);
  transition: background 0.1s;
}
.audio-event-row:last-child { border-bottom: none; }
.audio-event-row:hover { background: rgba(56, 225, 255, 0.03); }

/* Disabled-State (DL-10) */
.audio-event-row.disabled .audio-event-label { color: var(--muted); }
.audio-event-row.disabled .audio-vol-ctrl {
  opacity: 0.4;
  pointer-events: none;
}

/* Toggle-Switch (DL-5): Custom CSS, kein JS-Library */
.audio-toggle-label {
  position: relative;
  display: inline-block;
  width: 36px;
  height: 20px;
  flex-shrink: 0;
}
/* Touch-Area via Padding (DL-7: 44×44 min-target) */
.audio-toggle-label::before {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 44px;
  height: 44px;
}
.audio-toggle-label input {
  opacity: 0;
  width: 0;
  height: 0;
  position: absolute;
}
.audio-toggle-track {
  position: absolute;
  inset: 0;
  background: var(--line-2);
  border-radius: 20px;
  cursor: pointer;
  transition: background 0.2s;
}
.audio-toggle-track::before {
  content: '';
  position: absolute;
  height: 14px;
  width: 14px;
  left: 3px;
  top: 3px;
  background: var(--muted);
  border-radius: 50%;
  transition: transform 0.2s, background 0.2s;
}
.audio-toggle-label input:checked + .audio-toggle-track {
  background: rgba(56, 225, 255, 0.25);
  border: 1px solid var(--cyan);
}
.audio-toggle-label input:checked + .audio-toggle-track::before {
  transform: translateX(16px);
  background: var(--cyan);
}
.audio-toggle-label input:focus-visible + .audio-toggle-track {
  outline: 2px solid var(--cyan);
  outline-offset: 2px;
}

/* Event-Label */
.audio-event-label {
  font-size: 0.92em;
  color: var(--text);
  line-height: 1.3;
}
.audio-event-label small {
  display: block;
  font-size: 0.8em;
  color: var(--muted);
  margin-top: 0.1em;
}

/* Volume-Control pro Event (DL-3) */
.audio-vol-ctrl {
  display: flex;
  align-items: center;
  gap: 0.4em;
}
.audio-vol-ctrl input[type="range"] {
  width: 80px;
  accent-color: var(--cyan);
}
.audio-vol-val {
  font-size: 0.82em;
  color: var(--muted);
  min-width: 2.8em;
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* Saved-Chip / Fehler-Chip (DL-1) */
.audio-saved-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.35em;
  padding: 0.25em 0.65em;
  background: rgba(94, 255, 138, 0.12);
  border: 1px solid rgba(94, 255, 138, 0.35);
  border-radius: 4px;
  color: var(--green);
  font-size: 0.82em;
  font-weight: 600;
  opacity: 0;
  transition: opacity 0.2s;
  pointer-events: none;
}
.audio-saved-chip.visible { opacity: 1; }
.audio-saved-chip.error {
  background: rgba(255, 77, 110, 0.12);
  border-color: rgba(255, 77, 110, 0.35);
  color: var(--red);
}

/* Mobile (DL-7): Vol-Ctrl ausblenden, Grid vereinfachen (< 560px).
   ui-214: 560px bewusst beibehalten (kein Kanon-Schritt). Auf 480px wäre
   das Audio-Panel auf mittelgroßen Phablets (≈520–560px) noch Desktop-Layout —
   zu breit. Auf 768px würde der Collapse zu früh einsetzen. Eigene Semantik. */
@media (max-width: 560px) {
  .audio-master-row { flex-direction: column; align-items: stretch; }
  .audio-event-row  { grid-template-columns: 2.4em 1fr; }
  .audio-vol-ctrl   { display: none; }
}


/* =====================================================================
   PERF (GET /admin/perf, views/admin/perf.js — web-152)
   Neue Klassen fuer Filter-Leiste (s. SHARED), Ampel, Drill-down.
   Tokens: var(--*), kein Hex-Hardcode (Design-Lock web-152).
   ===================================================================== */

/* Ampel-Farben (eine Farbe = eine Rolle — Design-Lock). ampel()-Helfer
   lebt in views/admin/shared.js (EINE Quelle, AK3), aktuell einziger
   Aufrufer ist perf.js -- bei Bedarf durch weitere Bereiche wiederverwendbar. */
.val-ok  { color: var(--green); }
.val-warn { color: var(--yellow); }
.val-bad  { color: var(--red); }

/* Ampel-Bullet (Inline-Indikator vor dem Wert) */
.bullet {
  display: inline-block;
  width: .55em;
  height: .55em;
  border-radius: 999px;
  margin-right: .45em;
  vertical-align: middle;
}
.b-ok   { background: var(--green); }
.b-warn { background: var(--yellow); }
.b-bad  { background: var(--red); }

/* Modus-Badge (Lite / Stichprobe / Voll, web-334) */
.mode-badge {
  /* ui-507 (M4, K1): .7em -- effektiv NICHT 10.5px wie der ui-489-Audit annahm
     (dessen Statik geht von direkter 15px-Root aus), sondern 9.66px: das Badge
     lebt in einer Report-Tabellenzeile innerhalb `.hexa-table` (collection.css,
     0.92em=13.8px-Kontext), DOM-verifiziert. Beide Zahlen sind Haertefall,
     var(--fs-caption) macht den Wert root-relativ (rem-Clamp) und damit
     unabhaengig vom umschliessenden .hexa-table-em-Kontext. "Voll"/"Stichprobe"/
     "Lite" ist die einzige Anzeige des Report-Modus je Zeile, kein Deko-Kandidat. */
  font-size: var(--fs-caption);
  padding: .12em .5em;
  border-radius: 999px;
  border: 1px solid var(--line-2);
  letter-spacing: .04em;
}
.mode-lite { color: var(--text-dim); }
.mode-full { color: var(--magenta); border-color: rgba(255, 69, 181, .4); }
/* web-334: Stichprobe (PERF_PHASES ohne ?perf) -- zwischen Lite (dim) und
   Voll (magenta): traegt Phasen-Daten, aber kein Memory/Overlay. */
.mode-sampled { color: var(--yellow); border-color: rgba(255, 216, 74, .4); }

/* Geraete-Icon-Placeholder */
.dev-ic {
  margin-right: .5em;
  opacity: .75;
  font-size: .85em;
}

/* .expand-link ist SHARED (s. Datei-Kopf-Abschnitt oben, web-300) --
   frueher hier definiert, jetzt dort (weitere Konsumenten: Users, Kaeufe). */

/* Aufgeklappte Zeile (Highlight) */
.row-expanded {
  background: rgba(56, 225, 255, .06);
}
.row-expanded td { border-bottom-color: transparent; }

/* Drill-down-Zelle */
.detail-cell {
  background: var(--bg-2);
  padding: 1em 1.1em !important;
}
.detail-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.2em;
}
/* ui-214: 680px → 768px (Kanon-Tablet): Trigger-Shift +88px. Detail-Grid ist ein
   reines Layout-Helper (2 Spalten → 1 Spalte), der frühere Collapse auf Phablets
   schadet nicht — more defensive layout. */
@media (max-width: 768px) {
  .detail-grid { grid-template-columns: 1fr; }
}
.detail-block h4 {
  margin: 0 0 .5em;
  color: var(--cyan);
  font-size: .85em;
  text-transform: uppercase;
  letter-spacing: .06em;
}
.kv {
  display: flex;
  justify-content: space-between;
  padding: .22em 0;
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: .85em;
  border-bottom: 1px dotted var(--line);
}
.kv .k { color: var(--muted); }

/* Phasen-Balken (ui-197: gestapeltes Layout — Zeile 1: Name+Wert, Zeile 2: Track full-width) */
.phase-bar-wrap {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  column-gap: .6em;
  row-gap: .28em;
  padding: .34em 0;
  font-family: ui-monospace, monospace;
  font-size: .82em;
}
.phase-bar-wrap + .phase-bar-wrap {
  border-top: 1px solid var(--line);
}
.phase-name {
  order: 1;
  flex: 1 1 auto;
  min-width: 0;
  color: var(--text-dim);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.phase-val {
  order: 2;
  flex: 0 0 auto;
  color: var(--muted);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.phase-track {
  order: 3;
  flex: 0 0 100%;
  height: .5em;
  background: var(--line);
  border-radius: 999px;
  overflow: hidden;
}
.phase-fill {
  height: 100%;
  background: var(--cyan);
  border-radius: 999px;
}

/* web-158: Vordergrund/Hintergrund-Split (fg/bg-Ergaenzungen fuer /admin/perf)
   Tokens: var(--*), kein Hex-Hardcode (Design-Lock web-158). */

/* KPI-Pillen: VG/HG-Gruppen-Marker (Border-Akzent + Tag) */
.stat-pill.vg { border-color: rgba(56, 225, 255, .28); }
.stat-pill.hg { border-color: var(--line-2); }
.pill-tag {
  font-size: .75em; /* ui-344: .58em→.75em, war ~8.7px */
  letter-spacing: .1em;
}
.pill-tag.vg { color: var(--cyan); }
.pill-tag.hg { color: var(--text-dim); }

/* Hintergrund-Anteil: neutraler Fakt, KEINE Ampel — gedaempft + Mini-Balken.
   .bs-track/.bs-fill selbst sind SHARED (s. Datei-Kopf) -- dieser Compound-
   Selektor (.bg-share .bs-num) ist NUR fuer Perfs eigenen .bg-share-Wrapper
   scoped und greift NICHT bei Balance (dort .share-cell als Elternklasse). */
.bg-share {
  display: inline-flex;
  align-items: center;
  gap: .5em;
  justify-content: flex-end;
}
.bg-share .bs-num {
  color: var(--text-dim);
  font-variant-numeric: tabular-nums;
}

/* Drilldown: full-width Block (spannt beide Grid-Spalten) */
.detail-block.full {
  grid-column: 1 / -1;
}

/* fg/bg-Vergleichstabelle im Drilldown */
.fgbg {
  width: 100%;
  font-size: .85em;
}
.fgbg th,
.fgbg td {
  padding: .35em .5em;
  border-bottom: 1px solid var(--line);
}
.fgbg td.num,
.fgbg th.num {
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.fgbg .row-vg td:first-child { color: var(--cyan); }
.fgbg .row-hg td:first-child { color: var(--text-dim); }

/* Farb-Dots fuer VG/HG-Zeilen in der fg/bg-Tabelle */
.tag-dot {
  display: inline-block;
  width: .5em;
  height: .5em;
  border-radius: 999px;
  margin-right: .45em;
  vertical-align: middle;
}
.tag-dot.vg { background: var(--cyan); }
.tag-dot.hg { background: var(--text-dim); }

/* Viewer-Filter-Chip */
.filter-chip {
  display: inline-flex;
  align-items: center;
  gap: .4em;
  background: var(--bg-2);
  border: 1px solid var(--line-2);
  border-radius: 999px;
  padding: .2em .7em;
  font-size: .82em;
  margin-left: .6em;
  font-weight: 400;
}
.filter-chip a { color: var(--muted); }
.filter-chip a:hover { color: var(--cyan); text-decoration: none; }


/* =====================================================================
   BALANCE (GET /admin/balance, views/admin/balance.js — web-160/web-180)
   Slot × Waffe Kreuztabelle. Eigener Klassen-Namespace .sw-matrix* —
   .hexa-table nicht überladen.
   ===================================================================== */
.sw-matrix-scroll { overflow-x: auto; }

table.sw-matrix {
  border-collapse: collapse;
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-variant-numeric: tabular-nums;
  font-size: 0.85em;
  width: 100%;
}

/* Kopf: Waffen-Spalten */
table.sw-matrix thead th {
  color: var(--muted);
  font-size: 0.88em; /* ui-344: 0.72em→0.88em, war ~9.18px (0.72em x 0.85em-Tabellenkontext) */
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-weight: 500;
  padding: 0.45em 0.5em;
  border-bottom: 1px solid var(--line);
  text-align: center;
  white-space: nowrap;
  vertical-align: bottom;
}
table.sw-matrix thead th.sw-matrix-corner { text-align: left; }
.sw-matrix-wlabel {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.25em;
}
table.sw-matrix thead th.sw-matrix-unknown-col,
table.sw-matrix tbody tr.sw-matrix-unknown-row > th {
  color: var(--muted);
  font-style: italic;
}

/* Slot-Zeilen-Header */
table.sw-matrix tbody th {
  color: var(--text);
  font-weight: 600;
  text-align: left;
  white-space: nowrap;
  padding: 0.3em 0.8em 0.3em 0.2em;
  border-bottom: 1px solid var(--line);
  font-size: 0.92em;
}
.sw-matrix-slot-sub {
  color: var(--muted);
  font-weight: 400;
  /* ui-507 (M4, K1): 0.82em (~9.62px effektiv im 0.85em-table x 0.92em-tbody-th-
     Kontext, DOM-verifiziert -- vom ui-489-Audit uebersehen, da es die JS-
     Laufzeit-Verschachtelung `table.sw-matrix tbody th > span` nicht kennt)
     -> var(--fs-caption). "Zentral-Tower" ist echter Lese-Text (Slot-Sublabel),
     kein Deko-Kandidat -- gleiche Begruendung wie ui-503 .cs-card-sub. */
  font-size: var(--fs-caption);
  margin-left: 0.3em;
}

/* Daten-Zellen */
table.sw-matrix td {
  padding: 0.3em 0.4em;
  border-bottom: 1px solid var(--line);
  text-align: center;
  vertical-align: middle;
  min-width: 62px;
}
td.sw-matrix-empty { color: var(--line-2); }
.sw-matrix-picks {
  font-weight: 700;
  font-size: 1.05em;
  color: var(--text);
  display: block;
}
.sw-matrix-out {
  /* ui-507 (M4, K1): 0.78em (~9.945px effektiv im 0.85em-table-Kontext,
     DOM-verifiziert -- selber Audit-Blind-Fleck wie .sw-matrix-slot-sub oben)
     -> var(--fs-caption). Zeigt Oe-Rang/#1-Quote -- echte Analyse-Daten, nur
     im title-Tooltip redundant (Hover-only, kein K2-Kandidat -- Tooltip
     ersetzt keinen immer-sichtbaren Text). */
  font-size: var(--fs-caption);
  color: var(--text-dim);
  display: block;
  margin-top: 1px;
  white-space: nowrap;
}
.sw-matrix-nodata { color: var(--muted); }

/* Rand-Summen-Spalte/-Zeile */
table.sw-matrix th.sw-matrix-sigma,
table.sw-matrix td.sw-matrix-sigma { color: var(--text-dim); }
table.sw-matrix .sw-matrix-sigma-sep {
  border-left: 2px solid var(--line-2);
}

/* Fußzeile */
table.sw-matrix tfoot th,
table.sw-matrix tfoot td {
  border-top: 2px solid var(--line-2);
  padding: 0.4em 0.5em;
  color: var(--text-dim);
  text-align: center;
}
table.sw-matrix tfoot th {
  text-align: left;
  color: var(--muted);
  text-transform: uppercase;
  font-size: 0.88em; /* ui-344: 0.72em→0.88em, gleiche Kette/gleicher Wert wie thead th (s.o.) */
  letter-spacing: 0.05em;
}


/* =====================================================================
   STATUSLOG (GET /admin/statuslog, routes/admin/statuslog.js)
   Keine eigenen Regeln — status.html ist ein vollstaendiges Standalone-
   Dokument (eigenes <!DOCTYPE>, eigenes Inline-<style>), laedt admin.css
   gar nicht (Architektur-Lock: kein Admin-Layout-Wrap, kein Doppel-<html>).
   ===================================================================== */

/* =====================================================================
   RAUMKAPAZITÄT (GET /admin/perf, Panel "Raumkapazität", srv-169)
   Eigener, klar abgegrenzter Abschnitt am Dateiende (Rebase-Hygiene —
   web-319 arbeitet parallel an anderen Teilen von /admin/perf). Präfix
   'perf-' ist bereits in css-namespaces.mjs registriert (pages/admin.css),
   kein neuer Präfix nötig. Nur var(--*)/color-mix(var(--*)) — kein
   Hex-Hardcode (Design-Lock, s. Datei-Kopf).
   ===================================================================== */
/* Kacheln (Tag/7 Tage/30 Tage) reusen bewusst die SHARED .hexa-totals/
   .admin-kpis/.stat-pill-Komponenten (.hexa-totals liefert das eigentliche
   display:flex/flex-wrap, s. pages/collection.css -- Muster dashboard.js/
   users.js/kuendigungen.js/sperren.js/controls.js/health.js/kaeufe.js: alle
   kombinieren "hexa-totals admin-kpis", NICHT das bare .admin-kpis allein,
   das in dieser Datei KEINE eigene Layout-Regel hat) statt eines eigenen
   Kachel-Layouts -- nur die Gruppierung (Fenster-Label + Reihe aus 3
   Pillen) ist neu. */
.perf-cap-groups {
  display: flex;
  flex-wrap: wrap;
  gap: 18px;
  margin: 10px 0 16px;
}
.perf-cap-group-title {
  font-size: var(--fs-caption);
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: .04em;
  margin: 0 0 6px;
  font-weight: 600;
}
.perf-cap-group .hexa-totals { margin: 0; }

/* Heatmap: 7 Tage (Zeilen) × 24 Stunden (Spalten), Berlin-Zeit. Zell-Intensität
   per Inline-style (color-mix, Datenwert-abhängig, s. views/admin/perf.js
   renderRoomCapacityHeatmap()) — keine 24 Ampel-Klassen nötig. */
.perf-cap-heatmap-wrap {
  overflow-x: auto;
}
table.perf-cap-heatmap {
  border-collapse: collapse;
  font-size: .72rem;
  width: 100%;
}
table.perf-cap-heatmap th,
table.perf-cap-heatmap td {
  padding: 0;
  text-align: center;
}
table.perf-cap-heatmap th {
  color: var(--muted);
  font-weight: 600;
  font-size: .68rem;
  padding-bottom: 3px;
}
table.perf-cap-heatmap td.perf-cap-daylabel {
  color: var(--text-dim);
  text-align: right;
  padding-right: 8px;
  white-space: nowrap;
  font-size: .74rem;
}
table.perf-cap-heatmap td.perf-cap-cell {
  width: 22px;
  height: 20px;
  border: 1px solid var(--bg);
  color: var(--text-dim);
}
table.perf-cap-heatmap td.perf-cap-cell.perf-cap-cell-empty {
  color: transparent;
}
