/* 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,
 * 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 -> Perf ->
 * Balance -> Statuslog; "Kaeufe" kam mit web-300 dazu, s. dortiger
 * Abschnitt; der vormalige Audio-Abschnitt ist mit ui-660 ersatzlos
 * entfallen, Admin-Audio-Seite nie genutzt). Reine Umsortierung +
 * Kommentar-Ueberschriften -- KEIN Wert geaendert (Diff = nur
 * Zeilen-Position, byte-identische Deklarationen).
 * Grep-Audit gegen alle views/admin/*.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.
 *
 * ui-673: alle vormals bare Top-Level-Selektoren dieser Datei sitzen jetzt
 * hinter `:where(.admin)` (admin/layout.js adminLayout() wrappt JEDEN
 * /admin/*-Bereich in <section class="admin">) statt einem normalen
 * Vorfahren -- ein normaler Vorfahre haette die Spezifitaet ueber mehrere
 * generische <td>/<table>-Regeln aus collection.css (.hexa-table td u.ae.)
 * gehoben und live nachweislich Padding/Optik veraendert (CDP-Fund, Details
 * in pages/highscore.css bei .earner-details-cell + Ticket ## Notes). Diese
 * Datei hat MEHRERE eigene Tabellen (.hexa-table/table.sw-matrix), dasselbe
 * Risiko gilt hier strukturell fuer jede Zellen-/Zeilen-Klasse -- deshalb
 * `:where()` durchgaengig statt einer Fall-fuer-Fall-Pruefung. */


/* =====================================================================
   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 */
:where(.admin) .bar-slot {
  flex: 1;
  min-width: 4px;
  height: 100%;
  display: flex;
  align-items: flex-end;
  position: relative;
}
:where(.admin) .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) */
:where(.admin) .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 */
:where(.admin) .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.
   ===================================================================== */


/* =====================================================================
   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. */
:where(.admin) .val-ok  { color: var(--green); }
:where(.admin) .val-warn { color: var(--yellow); }
:where(.admin) .val-bad  { color: var(--red); }

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

/* Modus-Badge (Lite / Stichprobe / Voll, web-334) */
:where(.admin) .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;
}
:where(.admin) .mode-lite { color: var(--text-dim); }
:where(.admin) .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. */
:where(.admin) .mode-sampled { color: var(--yellow); border-color: rgba(255, 216, 74, .4); }

/* Geraete-Icon-Placeholder */
:where(.admin) .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) */
:where(.admin) .row-expanded {
  background: rgba(56, 225, 255, .06);
}
.row-expanded td { border-bottom-color: transparent; }

/* Drill-down-Zelle */
:where(.admin) .detail-cell {
  background: var(--bg-2);
  padding: 1em 1.1em !important;
}
:where(.admin) .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) {
  :where(.admin) .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;
}
:where(.admin) .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) */
:where(.admin) .stat-pill.vg { border-color: rgba(56, 225, 255, .28); }
:where(.admin) .stat-pill.hg { border-color: var(--line-2); }
:where(.admin) .pill-tag {
  font-size: .75em; /* ui-344: .58em→.75em, war ~8.7px */
  letter-spacing: .1em;
}
:where(.admin) .pill-tag.vg { color: var(--cyan); }
:where(.admin) .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) */
:where(.admin) .detail-block.full {
  grid-column: 1 / -1;
}

/* fg/bg-Vergleichstabelle im Drilldown */
:where(.admin) .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 */
:where(.admin) .tag-dot {
  display: inline-block;
  width: .5em;
  height: .5em;
  border-radius: 999px;
  margin-right: .45em;
  vertical-align: middle;
}
:where(.admin) .tag-dot.vg { background: var(--cyan); }
:where(.admin) .tag-dot.hg { background: var(--text-dim); }

/* Viewer-Filter-Chip */
:where(.admin) .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.
   ===================================================================== */
:where(.admin) .sw-matrix-scroll { overflow-x: auto; }

:where(.admin) 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; }
:where(.admin) .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;
}
:where(.admin) .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;
}
:where(.admin) td.sw-matrix-empty { color: var(--line-2); }
:where(.admin) .sw-matrix-picks {
  font-weight: 700;
  font-size: 1.05em;
  color: var(--text);
  display: block;
}
:where(.admin) .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;
}
:where(.admin) .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;
}


/* =====================================================================
   RAUM-BALANCER (GET /admin/raum-balancer, views/admin/raum-balancer.js +
   public/admin-raum-balancer.js — ui-668). DL-8: nur die dort gelisteten
   var(--*) (cyan/cyan-a55/green/red/red-light/red-a12/red-a42/muted/
   text-dim/line/line-2/panel/bg-2), keine neuen Farben. Seit srv-212 zusaetzlich
   orange (bereits bestehender, an anderer Stelle etablierter Token, s.
   tokens.css) — die Zeitlupe-Warnung braucht eine von Fehler(rot)/
   Vorwarnung(rot-hell) unterscheidbare Warnfarbe. Pillen/Chips aus
   EINEM Baustein (.rb-chip + Farb-Modifier), Muster .mode-badge oben.
   ===================================================================== */

.rb-fresh {
  margin-left: auto;
  color: var(--muted);
  font-size: var(--fs-caption);
  font-weight: 400;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.rb-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--green);
  box-shadow: 0 0 6px var(--green);
}
.rb-dot--stale {
  background: var(--muted);
  box-shadow: none;
}

.rb-queue {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 14px;
  align-items: center;
  padding: 8px 12px;
  margin-bottom: 12px;
  border: 1px solid var(--red-a42);
  background: var(--red-a12);
  border-radius: 8px;
  color: var(--red-light);
  font-size: .93rem;
}
.rb-queue strong { color: var(--red); }

.rb-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: 10px;
}
/* ui-684 (AK1): die Karte ist jetzt ein <a> (Link auf die Worker-Detail-
   Ansicht) statt eines <div> -- display:block/text-decoration/color heben
   die Link-Bestandsoptik auf, :hover/:focus-visible signalisieren die neue
   Klickbarkeit (nur Ausschlag der Randfarbe, keine neue Farbe: cyan-a55). */
.rb-card {
  display: block;
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 10px 12px;
  background: var(--bg-2);
  text-decoration: none;
  color: inherit;
}
.rb-card:hover,
.rb-card:focus-visible {
  border-color: var(--cyan-a55);
}
.rb-card--full { border-color: var(--red-a42); }
.rb-card-head {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 8px;
}
.rb-card-name { font-weight: 600; }
.rb-card-rooms { color: var(--muted); font-size: var(--fs-caption); }
.rb-card-foot { font-size: var(--fs-caption); color: var(--muted); margin-top: 6px; }

/* srv-212: Wrapper fuer mehrere Chips im Kartenkopf — DER Wrapper traegt den
   margin-left:auto (schiebt die GRUPPE nach rechts), nicht die einzelnen
   .rb-chip mehr (zwei auto-Raender nebeneinander wuerden sich sonst je zur
   Haelfte den Leerraum teilen, statt aneinander zu kleben). */
.rb-card-chips { margin-left: auto; display: flex; align-items: center; gap: 6px; }
.rb-card-chips .rb-chip { margin-left: 0; }

/* Pillen/Chips: EIN Baustein, Farbe je Rolle per Modifier (DL-8). */
.rb-chip {
  margin-left: auto;
  font-size: var(--fs-caption);
  padding: 1px 8px;
  border-radius: 999px;
  border: 1px solid var(--line-2);
  color: var(--text-dim);
}
.rb-chip--free  { color: var(--green); border-color: var(--green); }
.rb-chip--full  { color: var(--red); border-color: var(--red-a42); background: var(--red-a12); }
.rb-chip--stream { color: var(--cyan); border-color: var(--cyan-a55); margin-right: 4px; }
.rb-chip--warn   { color: var(--red-light); border-color: var(--red-a42); }
.rb-chip--override { color: var(--cyan); border-color: var(--cyan-a55); }
.rb-chip--wait      { color: var(--red-light); border-color: var(--red-a42); }
/* srv-212: Zeitlupe-Warnung — orange statt rot (Warnung, kein Fehler). */
.rb-chip--slow      { color: var(--orange); border-color: var(--orange); }

.rb-meter { margin: 6px 0; }
.rb-meter-label {
  display: flex;
  justify-content: space-between;
  font-size: var(--fs-caption);
  color: var(--text-dim);
  margin-bottom: 3px;
}
.rb-meter-label b { color: var(--text); font-variant-numeric: tabular-nums; font-weight: 600; }
/* srv-211 (Design-Lock 2): kurzer grauer Hinweis unter dem "gemessen"-Balken. */
.rb-meter-hint { font-size: var(--fs-caption); color: var(--muted); margin-top: 3px; }
.rb-meter-track {
  position: relative;
  height: 8px;
  border-radius: 4px;
  background: var(--line);
  overflow: visible;
}
.rb-meter-fill {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  border-radius: 4px;
  transition: width .22s;
}
.rb-meter-fill--reserved {
  background: repeating-linear-gradient(135deg, var(--cyan-a55) 0 4px, transparent 4px 8px);
  border: 1px solid var(--cyan-a55);
}
.rb-meter-fill--measured { background: var(--cyan); }
.rb-meter-fill--over { background: var(--red); }
.rb-meter-fill--reserved.rb-meter-fill--over {
  background: repeating-linear-gradient(135deg, var(--red-a42) 0 4px, transparent 4px 8px);
  border-color: var(--red-a42);
}
.rb-mark {
  position: absolute;
  top: -3px;
  bottom: -3px;
  width: 2px;
  background: var(--text-dim);
  opacity: .7;
}
.rb-mark--cap { background: var(--red-light); }

.rb-sub {
  font-size: var(--fs-caption);
  margin: 16px 0 6px;
  color: var(--text-dim);
  font-weight: 600;
}
.rb-scroll { overflow-x: auto; }
/* Review-Fund ui-668: ohne nowrap bricht z.B. "cohort-2" mobil in der
   Spalte um, STATT dass die Tabelle die Container-Breite verlaesst und
   .rb-scroll wie vorgesehen horizontal scrollt (table-layout:auto + Default-
   Umbruch gewinnt sonst gegen width:100% aus .hexa-table). Scoped auf
   Tabellen INNERHALB von .rb-scroll (Review-Vorgabe: scoped statt global) —
   andere Admin-Tabellen (z.B. views/admin/perf.js, kein .rb-scroll-Wrapper) bleiben
   unberuehrt. Prototyp-Pendant: `.admin-table th, .admin-table td { ...
   white-space: nowrap; }`. */
.rb-scroll table th,
.rb-scroll table td {
  white-space: nowrap;
}
tr.rb-grp td {
  color: var(--text-dim);
  font-size: var(--fs-caption);
  padding-top: 10px;
  border-bottom: none;
}

/* DL-7: ≤600px — Karten einspaltig, Zuschauer-Spalte ausgeblendet, Tabellen
   scrollen horizontal statt die Seite zu überlaufen (.rb-scroll +
   die nowrap-Regel oben tragen das zusammen). */
@media (max-width: 600px) {
  .rb-grid { grid-template-columns: 1fr; }
  .rb-hide-m { display: none; }
}

/* =====================================================================
   RAUM-BALANCER · WORKER-DETAIL (GET /admin/raum-balancer/worker/:index,
   views/admin/raum-balancer-worker.js + public/admin-raum-balancer-worker.js
   — ui-684). Prototyp-Parität: `.claude/sprint/prototypes/ui-684.html`
   (`.crumb`/`.cards`/`.card`/`.legend`/`.sw`/`.chart`/`.tip`), hier unter dem
   bestehenden `rb-`-Namensraum. Nur `var(--*)` — keine neuen Farben.
   ===================================================================== */

.rb-crumb { color: var(--muted); font-size: var(--fs-caption); margin-bottom: 6px; }
.rb-crumb a { color: var(--cyan); text-decoration: none; }

/* Kopf-Karten (AK2): Prototyp-Form small/b/span (Label/Wert/Zusatztext) --
   BEWUSST kein .stat-pill (das hat keine dritte Zeile fuer den Zusatztext,
   z.B. die Raum-Namen bei der "Räume"-Karte). */
.rb-head-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 10px;
  margin-bottom: 16px;
}
.rb-head-card {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 10px 12px;
}
.rb-head-card small {
  display: block;
  color: var(--muted);
  font-size: 11px;
  letter-spacing: .06em;
  text-transform: uppercase;
}
.rb-head-card b { font-size: 18px; font-variant-numeric: tabular-nums; }
.rb-head-card span { color: var(--muted); font-size: 12px; }

/* Verlauf-Legende (Design-Lock 2-4): Farbmuster-Chips vor dem Diagramm. */
.rb-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  font-size: var(--fs-caption);
  color: var(--muted);
  margin-bottom: 8px;
  align-items: center;
}
.rb-sw { display: inline-block; width: 22px; height: 8px; border-radius: 3px; vertical-align: middle; margin-right: 6px; }
.rb-sw--res  { background: repeating-linear-gradient(135deg, var(--cyan-a55) 0 4px, transparent 4px 8px); border: 1px solid var(--cyan-a55); }
.rb-sw--mea  { background: var(--cyan); height: 3px; }
.rb-sw--soll { border-top: 2px dashed var(--muted); height: 0; }
.rb-sw--full { border-top: 2px dashed var(--red-light); height: 0; }
.rb-sw--vollz { background: var(--red-a12); border: 1px solid var(--red-a42); }

/* Diagramm (Lock 3: eigenes SVG, keine Bibliothek) + Tooltip (Design-Lock 4). */
.rb-chart-wrap { position: relative; }
.rb-chart-wrap svg { display: block; width: 100%; height: auto; }
.rb-tip {
  position: absolute;
  pointer-events: none;
  background: var(--bg-2);
  border: 1px solid var(--line-2);
  border-radius: 8px;
  padding: 8px 10px;
  font-size: 12px;
  min-width: 210px;
  display: none;
  box-shadow: var(--card-shadow);
}
.rb-tip b { color: var(--text); font-variant-numeric: tabular-nums; }
.rb-tip-row { display: flex; justify-content: space-between; gap: 10px; color: var(--muted); }

/* ui-686 (Design-Lock 2): Platzierungs-Zeile -- Hover/Fokus/Tap zeigt die
   zugehoerige Linie im Verlauf (public/admin-raum-balancer-worker.js
   #rbw-placements-Delegation), dafuer bekommt GENAU diese Zeile eine leichte
   Orange-Toenung. is-active ist JS-getrieben statt reinem CSS :hover, weil
   der Chart-Redraw synchron mitlaufen muss (Fokus/Tap haben kein
   :hover-Aequivalent). rgba() direkt (Muster .hdh-chip.is-on oben) statt
   eines neuen --orange-a12-Tokens -- einziger Konsument dieser Datei. */
.rb-plc-row { cursor: pointer; }
.rb-plc-row.is-active { background: rgba(255, 179, 71, 0.12); }
