/* ============================================================
   Galaxyweb DNS-Manager — Main App Layout
   ============================================================ */

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

/* ── Flache Laenderflaggen (Twemoji-Flaggen-Webfont) ─────────────────────
   Ersetzt die OS-abhaengigen, „gewellten" Emoji-Flaggen durch einheitliche
   flache Flaggen. unicode-range beschraenkt die Schrift exakt auf die
   Flaggen-Codepoints (Regional-Indicator-Paare + Subdivision-Tag-Flags) —
   jeder andere Text/Emoji bleibt voellig unberuehrt. Die Schrift steht
   darum gefahrlos vorne im --font-Stack: fuer Nicht-Flaggen wird sie nie
   konsultiert, fuer Flaggen schlaegt sie die OS-Emoji-Schrift.
   Nebeneffekt: Windows zeigt damit erstmals ueberhaupt Flaggen. */
@font-face {
  font-family: "Twemoji Country Flags";
  font-display: swap;
  src: url("/assets/vendor/flag-font/TwemojiCountryFlags.woff2") format("woff2");
  unicode-range: U+1F1E6-1F1FF, U+1F3F4, U+E0062-E0063, U+E0065, U+E0067,
                 U+E006C, U+E006E, U+E0073-E0074, U+E0077, U+E007F;
}

:root {
  --gw:        #0098ef;
  --gw-dark:   #0077cc;
  --gw-light:  #e8f4fd;
  /* Zeilen-Hover aller Tabellen — überall derselbe Wert wie bei DNS-Zonen, damit alle
     Tabellen gleich reagieren. Nie var(--bg): der ist im Dunkeln dunkler als die Karte. */
  --row-hover: #fafbfc;
  /* Marken-Akzent global als --accent verfügbar (Alias von --gw). Bisher war --accent nur in
     .notif-detail definiert → var(--accent) in Proxy-Modal (Wirkungs-Vorschau-Lead-Icon,
     Posture-Panel, ok-Verdikt) war unsichtbar. .notif-detail überschreibt --accent weiterhin lokal. */
  --accent:    var(--gw);
  --spark-prev:#8b5cf6;   /* Vorperiode/Vorwoche (Traffic-Spark) — Violett wie Tagesprofil/Zonen-Traffic-Modal */
  --spark-now: #ffffff;   /* „Jetzt"-Punkt (jüngster Datenpunkt) — heller Kern mit blauem Ring; klar vom gefüllten blauen Höchstpunkt unterscheidbar */
  --spark-now-tip:#7cc7f7; /* helles Linien-Ende beim Jetzt-Punkt (Stroke-Verlauf) — „hier entwickelt sich was" */
  --spark-now-pulse:#0098ef; /* Jetzt-Puls (Glow + Ripple-Ringe) — Light = Brand-Blau */
  --bg:        #f0f4f8;
  --surface:   #ffffff;
  --border:    #e4e9f0;
  /* Zeilentrenner in Tabellen — weicher als `--border`, aber in derselben
     Richtung. Bis v7.2.556 stand dort `var(--bg)`. Im Hellen ist das richtig
     (#f0f4f8 liegt zwischen Flaeche und Kontur), im Dunkeln kippt es: `--bg`
     (#0f172a) ist dunkler als die Kachel (#1e293b), waehrend `--border` heller
     ist. Dieselbe Karte hatte darum helle Trennlinien bei den Wertpaaren und
     dunkle Rillen in der Tabelle darunter.
     Ein Token, das nur in einem Thema die gewuenschte Rolle spielt, ist keins. */
  --sep:       #f0f4f8;
  --border-2:  #cdd5e0;
  --text-1:    #0d1b2a;
  --text-2:    #2d3e50;
  --text-3:    #5a6a7a;
  --text-4:    #8fa0b3;
  /* Praesenz-Ampel: Signalfarbe je Modus. Hell = --ok-Gruen (kraeftiger als das fruehere
     #10b981), dunkel ein deutlich helleres Gruen, damit Kern und Welle gegen #1e293b
     bestehen — dasselbe Prinzip wie beim Jetzt-Puls der Sparklines. */
  --pres-on:      #16a34a;
  --pres-on-glow: rgba(22,163,74,.45);
  --pres-idle:    #f59e0b;
  --ok:        #16a34a;
  --ok-bg:     #f0fdf4;
  --ok-bd:     #bbf7d0;
  --ok-text:   #14532d;
  --warn:      #d97706;
  --warn-bg:   #fffbeb;
  --warn-bd:   #fde68a;
  --warn-text: #92400e;
  --err:       #dc2626;
  --err-bg:    #fff5f5;
  --err-bd:    #fecaca;
  --err-text:  #7f1d1d;
  --sidebar-w: 56px;
  --sidebar-w-open: 236px;   /* vorher 220 px — Zähler-Pillen standen zu nah am Text */
  --topbar-h:  52px;
  --font:      "Twemoji Country Flags", system-ui, -apple-system, "Segoe UI", Helvetica, Arial, sans-serif;
  --font-mono: "Twemoji Country Flags", "SF Mono", "Fira Code", Consolas, monospace;
  --r-sm:      6px;
  --r:         8px;
  --r-lg:      12px;
  --r-xl:      16px;
  --shadow:    0 1px 4px rgba(0,0,0,.06), 0 4px 16px rgba(0,0,0,.06);
}

/* Dark-Mode: aktivierbar via [data-theme="dark"] auf <html>. Toggle setzt LocalStorage
   und Cookie, sodass das Theme bei jedem Pageload sofort greift (kein FOUC). Alle
   Farben kommen aus den Tokens — Kontrast bewahrt, Akzent-Blau bleibt unverändert. */
[data-theme="dark"] {
  --gw-light:  #0c2538;
  --row-hover: #243044;
  --spark-prev:#a78bfa;   /* Vorperiode heller im Dark-Mode (wie Tagesprofil-Legende) */
  --spark-now: #f1f5f9;   /* „Jetzt"-Punkt im Dark-Mode — heller Slate-Ton (nicht grell), mit blauem Ring */
  --spark-now-tip:#a5dbff; /* helles Linien-Ende im Dark-Mode (etwas heller, damit es leuchtet) */
  --spark-now-pulse:#5cc8ff; /* Jetzt-Puls im Dark-Mode — deutlich helleres Sky-Blau, damit Glow/Ripple auf dunklem Grund klar sichtbar sind */
  --bg:        #0f172a;
  --surface:   #1e293b;
  --border:    #2d3e50;
  --sep:       #26334a;
  --border-2:  #475569;
  --text-1:    #f1f5f9;
  --text-2:    #cbd5e1;
  --text-3:    #94a3b8;
  --text-4:    #64748b;
  --pres-on:      #4ade80;
  --pres-on-glow: rgba(74,222,128,.55);
  --pres-idle:    #fbbf24;
  --ok-bg:     #052e16;
  --ok-bd:     #14532d;
  --ok-text:   #86efac;
  --warn-bg:   #422006;
  --warn-bd:   #78350f;
  --warn-text: #fcd34d;
  --err-bg:    #450a0a;
  --err-bd:    #7f1d1d;
  --err-text:  #fca5a5;
  --shadow:    0 1px 4px rgba(0,0,0,.4), 0 4px 16px rgba(0,0,0,.3);
  color-scheme: dark;
}
[data-theme="dark"] body { color: var(--text-1); background: var(--bg); }
/* Code-Blöcke (pre / pre code) bekommen einen dunklen Kasten — inline <code>
   nicht, sonst kriegen Targets/Domain-Namen/IPs einen schwarzen Hintergrund
   und sehen aus wie pre-Blöcke. Inline <code> erbt Hintergrund vom Container
   und kriegt nur eine helle Schriftfarbe. */
[data-theme="dark"] pre,
[data-theme="dark"] pre code { background: #0b1322 !important; color: #cbd5e1 !important; border-color: #2d3e50 !important; }
[data-theme="dark"] code { color: #e2e8f0; }

/* Tabellen-Hover + Header passen mit hardcodierten Hellgrau-Werten nicht zum Dark-Mode.
   Wir überschreiben das unter [data-theme="dark"] mit dunkleren Tönen, sodass Hover
   und Spaltenkopf weiterhin als „leicht hervorgehoben" lesbar sind. Inkl. aller Tabellen
   mit hartcodiertem #e7ecf3-Header (records-table, arch-table, snp-table, snap-records, auditTable). */
[data-theme="dark"] .zone-table th,
[data-theme="dark"] .records-table thead th,
[data-theme="dark"] .arch-table thead th,
[data-theme="dark"] .snp-table thead th,
[data-theme="dark"] .snap-records thead th,
[data-theme="dark"] .find-table thead th,
[data-theme="dark"] #auditTable thead th {
  background: #18243a !important;          /* etwas heller als Surface (#1e293b → wirkt aktiv) */
  color: var(--text-3) !important;
  border-bottom-color: var(--border) !important;
}
/* (Der Hover der sortierbaren Koepfe steht einmal, weiter unten bei .sortable-th —
   diese Kopie ist am 09.09.2026 entfallen.) */
[data-theme="dark"] .zone-table td,
[data-theme="dark"] .records-table tbody td,
[data-theme="dark"] .arch-table tbody td,
[data-theme="dark"] .snp-table tbody td,
[data-theme="dark"] .snap-records tbody td {
  border-bottom-color: #1a2536;            /* dezenter Trenn-Strich, nicht weiss */
}
[data-theme="dark"] .zone-table tr:hover td,
[data-theme="dark"] .records-table tbody tr:hover td,
[data-theme="dark"] .arch-table tbody tr:hover td,
[data-theme="dark"] .snp-table tbody tr:hover td,
[data-theme="dark"] table.find-table tr.sec-clickable:hover td,
[data-theme="dark"] table.find-table tr:hover td {
  background: var(--row-hover) !important;  /* deutlicher Hover, aber nicht weiss — Wert im Token */
}
/* Hartcodierte hellgraue Trennlinien (#f5f7fa) in Inline-Styles — z.B. Audit-Log-Tabelle,
   Tenant-Details-Liste, Profile, Sessions, API-Keys-Modal — wirken im Dark-Mode wie weisse
   Streifen. Wir mappen sie via [style*="..."]-Selektor auf den dezenten Border-Ton. Trifft
   nur border-color (background-Marker im Audit-Diagramm bleiben unangetastet). */
[data-theme="dark"] [style*="#f5f7fa" i],
[data-theme="dark"] [style*="#F5F7FA" i] {
  border-color: var(--border) !important;
}
/* Gleiche Massnahme für Hover-Targets, die hartcodiert auf #fafbfc/#fafcfe setzen
   (Inline onmouseover sind bereits via var(--bg) abgedeckt — hier nur statisches CSS). */
[data-theme="dark"] [style*="#fafbfc" i],
[data-theme="dark"] [style*="#fafcfe" i] {
  border-color: var(--border) !important;
}
/* Globale Suche: die Result-Icons (Zonen, Records, Tenants, User) haben hartcodierte
   Pastell-Backgrounds (#dbeafe / #f3e8ff / #fef3c7), die im Dark-Mode wie weisse Kacheln
   wirken. Wir tauschen den Hintergrund gegen einen dezenten Tint. Die Vordergrundfarbe
   (SVG-Stroke bzw. Avatar-Initialen) kommt als --sri-fg-Custom-Property aus dem Inline-
   Style (renderSearch in base.php) — die SVGs strok'en auf currentColor, daher hellen wir
   sie im Dark-Mode pro Farbton via color-mix auf, statt dunkle Pastell-Strokes (z.B.
   Tenant-#991b1b/#6b21a8) auf dem dunklen Tint verkümmern zu lassen. */
.search-result-icon { color: var(--sri-fg, var(--text-3)); }
/* Dark-Mode-Neon (gleiche Sprache wie .rec-chip): pro Farbton ein getoenter,
   leuchtender Backdrop + heller Farbton-Stroke — statt dunkler Pastell-Strokes auf
   neutralem Grau. --sri-fg traegt die Identitaetsfarbe (zone=blau, record=violett,
   tenant=gehasht …); die SVGs stroken auf currentColor und leuchten so mit. */
[data-theme="dark"] .search-result-icon {
  /* Klar getoenter Chip (32% Farbton) + heller Glyph + dezenter Glow im selben
     Farbton — so leuchten die Icons sichtbar in ihrer Identitaetsfarbe statt als
     dunkle Kachel. Alles in srgb: color-mix(in oklch,…) wird von manchen Browsern
     still verworfen → der Glyph fiele auf die dunkle Basisfarbe zurueck (= „zu dunkel"). */
  background-color: color-mix(in srgb, var(--sri-fg, #94a3b8) 30%, transparent) !important;
  border: 1px solid color-mix(in srgb, var(--sri-fg, #94a3b8) 48%, transparent) !important;
  color: color-mix(in srgb, var(--sri-fg, #94a3b8) 45%, white) !important;
}
[data-theme="dark"] .search-result-icon svg {
  filter: drop-shadow(0 0 2px color-mix(in srgb, currentColor 55%, transparent));
}
/* User-Avatare bleiben kraeftig (gesaettigte Vollfarbe + weisse Initialen) — sie sind
   keine Pastell-Chips, der Neon-Tint wuerde die Initialen verschlucken. */
[data-theme="dark"] .search-result-icon.sri-avatar {
  background-color: var(--sri-bg) !important;
  border: none !important;
  color: #fff !important;
}
/* Inline `onmouseover="this.style.background='var(--bg)'"`-Hovers (Tenants/Users/Settings/etc.)
   sehen im Dark-Mode korrekt aus, weil var(--bg) dort dunkel ist — nichts zu tun.
   Für hartcodierte Hover-Targets in main.css (#fafbfc, #fafcfe) ergänzen wir dunkle Varianten. */
[data-theme="dark"] .opt-card:hover { background: #243044 !important; }
[data-theme="dark"] .btn-secondary { background: var(--surface); color: var(--text-2); border-color: var(--border); }
[data-theme="dark"] .btn-secondary:hover { background: #243044; color: var(--text-1); }
/* KI-Assistent-Buttons: app-weit einheitliche, distinkte Akzentfarbe (Violett),
   damit KI-Aktionen sofort als KI erkennbar sind. Setzt auf .btn auf (Layout/Padding). */
.btn-ai { background: rgba(124,58,237,.10); color: #6d28d9; border: 1px solid rgba(124,58,237,.30); }
.btn-ai:hover { background: rgba(124,58,237,.16); border-color: rgba(124,58,237,.45); color: #5b21b6; }
[data-theme="dark"] .btn-ai { background: rgba(139,92,246,.16); color: #c4b5fd; border-color: rgba(139,92,246,.40); }
[data-theme="dark"] .btn-ai:hover { background: rgba(139,92,246,.24); color: #ddd6fe; border-color: rgba(139,92,246,.55); }

/* ─── Globales KI-Modal (window.gwAi) ─────────────────────────────────────── */
.gwai-bg { position:fixed; inset:0; z-index:10050; display:flex; align-items:center; justify-content:center;
           background:rgba(15,23,42,.55); backdrop-filter:blur(3px); padding:20px; animation:gwai-fade .14s ease; }
.gwai-box { background:var(--surface); color:var(--text-1); width:min(640px,100%); max-height:86vh; display:flex; flex-direction:column;
            border:1px solid var(--border); border-radius:14px; box-shadow:0 24px 60px rgba(15,23,42,.30); overflow:hidden;
            animation:gwai-pop .16s cubic-bezier(.2,.8,.3,1); }
.gwai-head { display:flex; align-items:center; gap:10px; padding:14px 16px;
             border-bottom:1px solid var(--border);
             background:linear-gradient(90deg, rgba(124,58,237,.10), rgba(124,58,237,0)); }
[data-theme="dark"] .gwai-head { background:linear-gradient(90deg, rgba(139,92,246,.16), rgba(139,92,246,0)); }
.gwai-head__ic { display:inline-flex; width:30px; height:30px; flex:0 0 30px; align-items:center; justify-content:center;
                 border-radius:8px; background:rgba(124,58,237,.12); color:#7c3aed; }
[data-theme="dark"] .gwai-head__ic { background:rgba(139,92,246,.22); color:#c4b5fd; }
.gwai-head__t { flex:1; min-width:0; }
.gwai-head__title { font-size:14px; font-weight:650; line-height:1.2; }
.gwai-head__sub { font-size:11.5px; color:var(--text-3); margin-top:2px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.gwai-badge { font-size:9px; font-weight:700; letter-spacing:.6px; padding:2px 7px; border-radius:999px;
              background:rgba(124,58,237,.12); color:#6d28d9; }
[data-theme="dark"] .gwai-badge { background:rgba(139,92,246,.22); color:#c4b5fd; }
.gwai-x { background:none; border:none; cursor:pointer; font-size:22px; line-height:1; color:var(--text-4); padding:0 2px; }
.gwai-x:hover { color:var(--text-1); }
.gwai-body { padding:16px 18px; overflow-y:auto; }
.gwai-foot { display:flex; align-items:center; justify-content:space-between; gap:12px; padding:11px 16px;
             border-top:1px solid var(--border); background:var(--bg); }
.gwai-foot__note { font-size:10.5px; color:var(--text-4); line-height:1.4; }

/* Inhalt-Typografie (gerendertes Markdown) */
.gwai-content { font-size:13px; line-height:1.62; color:var(--text-1); }
.gwai-content p { margin:0 0 8px; }
.gwai-content p:last-child { margin-bottom:0; }
.gwai-content ul, .gwai-content ol { margin:4px 0 10px; padding-left:20px; }
.gwai-content li { margin:3px 0; }
.gwai-content strong { font-weight:650; }
/* Auch Triage-Karten + Summary (KI-Sicherheitsberater u. a.): `Werte` wie aus/website
   bekommen dort denselben violett hinterlegten Code-Look wie in .gwai-content. */
.gwai-content code, .gwai-trg code, .gwai-audit__sum code { font-family:var(--font-mono,monospace); font-size:12px; background:rgba(124,58,237,.10);
                     padding:1px 5px; border-radius:4px; }
[data-theme="dark"] .gwai-content code, [data-theme="dark"] .gwai-trg code, [data-theme="dark"] .gwai-audit__sum code { background:rgba(139,92,246,.18); }
.gwai-content .gwai-h { font-weight:650; font-size:12.5px; margin:10px 0 4px; color:var(--text-1); }
/* Fehlerkarte: Symbol links, Ueberschrift, Klartext des Diensts, darunter ein
   Satz, was jetzt hilft. Ruhige Flaeche statt Schreckfarbe; die Kontur traegt
   das Signal. Lief vor dem Fehler schon Verbrauch auf, steht er als Chip-Zeile
   darunter (.gwai-meta). */
.gwai-err { font-size:13px; color:var(--err-text); background:var(--err-bg);
            border:1px solid color-mix(in srgb, var(--err-text) 22%, var(--border));
            border-radius:10px; padding:14px 16px; animation:gwai-fade .25s ease both; }
.gwai-err__top { display:flex; align-items:flex-start; gap:12px; }
.gwai-err__ico { flex:none; width:38px; height:38px; border-radius:50%; display:grid; place-items:center;
            background:color-mix(in srgb, var(--err-text) 12%, transparent);
            color:var(--err-text); }
.gwai-err__body { min-width:0; }
.gwai-err__ttl { font-weight:650; font-size:13.5px; color:var(--err-text); margin-bottom:3px; }
.gwai-err__msg { color:var(--err-text); opacity:.92; overflow-wrap:anywhere; }
.gwai-err__hint { margin-top:7px; font-size:12px; color:var(--text-3);
            border-left:2px solid color-mix(in srgb, var(--err-text) 35%, transparent); padding-left:9px; }
.gwai-err__act { margin-top:12px; padding-left:50px; }
.gwai-err .gwai-meta { margin-top:12px; padding-top:9px; padding-left:50px;
            border-top:1px solid color-mix(in srgb, var(--err-text) 15%, var(--border)); }
@media (max-width:520px) {
  .gwai-err__act, .gwai-err .gwai-meta { padding-left:0; }
}
/* Live-Streaming: blinkender Cursor am Ende, bis der Final-Render kommt. */
.gwai-streaming::after { content:'▍'; display:inline; margin-left:1px; color:var(--accent, #8b5cf6);
            animation:gwai-caret 1s steps(2) infinite; }
@keyframes gwai-caret { 0%,50%{opacity:1} 50.01%,100%{opacity:0} }

/* Lade-Animation: violetter Ring-Spinner + pulsierende Punkte */
.gwai-loading { display:flex; flex-direction:column; align-items:center; gap:12px; padding:34px 10px 28px; }
/* Der Ring traegt die laufende Zeit in der Mitte. Die Maske wuerde ein Kind
   mitschneiden, deshalb liegt sie auf dem Ring allein und die Zahl darueber. */
.gwai-orbw { position:relative; width:52px; height:52px; display:grid; place-items:center; }
.gwai-orb { position:absolute; inset:0; border-radius:50%;
            background:conic-gradient(from 0deg, rgba(124,58,237,0), #7c3aed);
            -webkit-mask:radial-gradient(farthest-side, transparent calc(100% - 4px), #000 0);
            mask:radial-gradient(farthest-side, transparent calc(100% - 4px), #000 0);
            animation:gwai-spin .85s linear infinite; }
[data-theme="dark"] .gwai-orb { background:conic-gradient(from 0deg, rgba(139,92,246,0), #a78bfa); }
.gwai-orb__t { position:relative; font-size:11.5px; font-weight:600; color:var(--text-3);
            font-variant-numeric:tabular-nums; letter-spacing:.2px; white-space:nowrap; }
.gwai-loading__txt { font-size:13px; color:var(--text-2); }
/* Schmaler Lichtbalken unter dem Text: zeigt Bewegung, auch wenn die KI
   minutenlang denkt und kein Zeichen kommt. */
.gwai-beam { position:relative; width:180px; max-width:60%; height:2px; border-radius:2px;
            background:var(--border); overflow:hidden; }
.gwai-beam i { position:absolute; inset:0 auto 0 0; width:38%; border-radius:2px;
            background:linear-gradient(90deg, rgba(124,58,237,0), #7c3aed, rgba(124,58,237,0));
            animation:gwai-beam 1.6s ease-in-out infinite; }
[data-theme="dark"] .gwai-beam i { background:linear-gradient(90deg, rgba(167,139,250,0), #a78bfa, rgba(167,139,250,0)); }
@keyframes gwai-beam { 0% { left:-40%; } 100% { left:100%; } }
@media (prefers-reduced-motion: reduce) {
  .gwai-orb { animation-duration:2.4s; }
  .gwai-beam i { animation:none; left:0; width:100%; opacity:.5; }
}
/* Kompakter Lade-Indikator: sobald die ersten Stream-Ergebnisse erscheinen,
   schrumpft der „KI überlegt…"-Spinner zu einer kleinen Zeile oben — weniger
   prominent, aber weiter sichtbar (zeigt, dass noch geladen wird). */
.gwai-prog__head.is-compact { border-bottom:1px solid var(--border); margin-bottom:8px; }
.gwai-prog__head.is-compact .gwai-loading { flex-direction:row; align-items:center; justify-content:flex-start;
            gap:9px; padding:8px 4px 10px; }
.gwai-prog__head.is-compact .gwai-orbw { width:16px; height:16px; }
.gwai-prog__head.is-compact .gwai-orb {
            -webkit-mask:radial-gradient(farthest-side, transparent calc(100% - 2.5px), #000 0);
            mask:radial-gradient(farthest-side, transparent calc(100% - 2.5px), #000 0); }
/* Kompakt ist der Ring zu klein fuer die Zahl: die Zeit steht dann als Chip
   in der Detailzeile, die hier neben den Text rutscht. */
.gwai-prog__head.is-compact .gwai-orb__t { display:none; }
.gwai-prog__head.is-compact .gwai-beam { display:none; }
.gwai-prog__head.is-compact .gwai-meta { justify-content:flex-start; }
.gwai-prog__head.is-compact .gwai-loading__txt { font-size:11.5px; color:var(--text-4); }
/* Detailzeile zum Lauf: was die KI gerade macht, wie lange schon, wie viele
   Tokens gelesen und geschrieben sind. Waehrend des Laufs steht sie unter dem
   Spinner (--live, ohne Trennlinie), danach als ruhige Fusszeile unter der
   Antwort. Chips mit Strich-Symbol, Zahlen in Tabellenziffern (kein Zittern). */
/* Woran die KI gerade denkt: eine mitlaufende Konsole in ihren eigenen Worten
   (Kurzfassung des Modells). Dunkle Flaeche wie die JSON-Konsole (.pa-json),
   Eingabe-Zeichen je Zeile, Balken in der letzten. Sie erklaert die Wartezeit,
   ohne die Antwort zu stoeren, und verschwindet, sobald der Text kommt. */
.gwai-con { width:min(560px, 96%); border-radius:10px; overflow:hidden; background:#0f172a;
            border:1px solid #1e293b; box-shadow:0 6px 20px rgba(2,6,23,.18);
            animation:gwai-fade .3s ease both; }
.gwai-con__bar { display:flex; align-items:center; gap:5px; padding:7px 10px;
            background:linear-gradient(180deg,#162136,#111c2e); border-bottom:1px solid #1e293b; }
.gwai-con__dot { width:7px; height:7px; border-radius:50%; background:#334155; }
.gwai-con__dot:nth-child(1) { background:#475569; }
.gwai-con__ttl { margin-left:6px; font-size:10.5px; letter-spacing:.4px; text-transform:uppercase;
            color:#64748b; font-weight:600; }
.gwai-con__body { max-height:104px; overflow:auto; padding:9px 11px;
            font-family:var(--font-mono,monospace); font-size:11px; line-height:1.65; color:#94a3b8;
            text-align:left; scrollbar-width:thin; }
.gwai-con__ln { display:flex; gap:7px; animation:gwai-conln .3s ease both; }
.gwai-con__pre { color:#7c3aed; flex:none; }
[data-theme="dark"] .gwai-con__pre { color:#a78bfa; }
.gwai-con__ln--now { color:#e2e8f0; }
.gwai-con__caret { width:6px; height:12px; background:#a78bfa; display:inline-block; flex:none;
            align-self:center; margin-left:2px; animation:gwai-caret 1s steps(2) infinite; }
@keyframes gwai-conln { from { opacity:0; transform:translateY(3px); } to { opacity:1; transform:none; } }
.gwai-prog__head.is-compact .gwai-con { display:none; }
@media (prefers-reduced-motion: reduce) {
  .gwai-con__ln { animation:none; }
  .gwai-con__caret { animation:none; }
}
/* Abbrechen: bewusst zurueckhaltend (kein Alarmknopf), aber erreichbar —
   ein 90-Sekunden-Lauf soll sich stoppen lassen, bevor er Tokens verbraucht. */
.gwai-stop { margin-top:2px; background:transparent; border:1px solid var(--border);
            color:var(--text-4); font-size:11px; padding:4px 12px; border-radius:999px;
            cursor:pointer; transition:color .15s, border-color .15s, background .15s; }
.gwai-stop:hover { color:var(--err-text); border-color:color-mix(in srgb, var(--err-text) 40%, var(--border));
            background:color-mix(in srgb, var(--err-text) 7%, transparent); }
.gwai-stop:disabled { opacity:.55; cursor:default; }
.gwai-prog__head.is-compact .gwai-stop { display:none; }
.gwai-meta { display:flex; flex-wrap:wrap; align-items:center; justify-content:center; gap:6px;
            font-size:11px; color:var(--text-4); letter-spacing:.1px; }
.gwai-meta:not(.gwai-meta--live) { margin-top:12px; padding-top:8px;
            border-top:1px solid var(--border); justify-content:flex-start; }
.gwai-meta__it { display:inline-flex; align-items:center; gap:5px; white-space:nowrap;
            padding:3px 8px; border-radius:999px; background:var(--bg);
            border:1px solid var(--border); line-height:1.5; }
.gwai-meta__it svg { flex:none; opacity:.75; }
.gwai-meta__it--in { animation:gwai-chip .35s ease both; }
.gwai-meta__it--ok { color:var(--ok); border-color:color-mix(in srgb, var(--ok) 35%, var(--border)); }
.gwai-meta__it--ok svg { opacity:1; }
/* Sysadmin-Information (Kosten eines Laufs): gestrichelte Kontur als stille
   Ansage «das sieht nur der Betreiber». Benutzer zahlen ueber ihr Abo und
   bekommen den Wert gar nicht erst geschickt. */
.gwai-meta__it--admin { border-style:dashed; color:var(--text-3); }
.gwai-meta__n { font-weight:600; font-variant-numeric:tabular-nums; color:var(--text-3); }
/* Wohin die Zeit ging: eigene Zeile unter den Chips, Schritte mit Punkt getrennt.
   Ein Schritt bricht nie in sich um (Name und «1,2 s» bleiben zusammen). */
.gwai-meta__steps { flex-basis:100%; display:flex; flex-wrap:wrap; align-items:center; gap:4px 7px;
            padding:2px 2px 0; animation:gwai-chip .35s ease both; }
.gwai-meta__steps i { font-style:normal; opacity:.6; }
.gwai-meta__step { white-space:nowrap; }
.gwai-meta__step b { font-weight:600; font-variant-numeric:tabular-nums; color:var(--text-3); }
@keyframes gwai-chip { from { opacity:0; transform:translateY(4px) scale(.96); } to { opacity:1; transform:none; } }
.gwai-dots i { font-style:normal; animation:gwai-blink 1.4s infinite both; }
.gwai-dots i:nth-child(2) { animation-delay:.2s; }
.gwai-dots i:nth-child(3) { animation-delay:.4s; }
@keyframes gwai-spin { to { transform:rotate(360deg); } }
@keyframes gwai-blink { 0%,80%,100% { opacity:.2; } 40% { opacity:1; } }
@keyframes gwai-fade { from { opacity:0; } to { opacity:1; } }
@keyframes gwai-pop { from { opacity:0; transform:translateY(8px) scale(.98); } to { opacity:1; transform:none; } }

/* ─── KI-Andock-Layout (host-agnostisch) ──────────────────────────────────────
   Wird via gwAi.explain(payload,{dock:hostBox}) gesetzt: der Host (Findings-
   .sec-detail-box oder ein zd.alert-.zd-dlg) wird breiter, sein bisheriger Inhalt
   wandert in eine linke Spalte (.gwai-host-main), die KI-Ausgabe erscheint als
   rechte Spalte (.sec-ai-panel) über die volle Modal-Höhe. */
.gwai-docked { display:flex !important; flex-direction:row !important; align-items:stretch !important;
               overflow:hidden !important; width:min(1240px,96vw) !important; max-width:96vw !important; }
.gwai-docked > .gwai-host-main { display:flex; flex-direction:column; flex:1 1 0; min-width:0; min-height:0;
                                 overflow-y:auto; max-height:92vh; }
/* Sektionen (Header/Body/Footer) in der Andock-Spalte nicht stauchen — sonst
   kollabiert z. B. .sec-detail-head (hat overflow:hidden -> implizite min-height 0)
   und der Titel wird unleserlich. Stattdessen scrollt die Spalte als Ganzes. */
.gwai-docked > .gwai-host-main > * { flex-shrink:0; }
.sec-ai-panel { flex:0 0 440px; max-width:46%; display:flex; flex-direction:column; min-height:0;
                border-left:1px solid var(--border); background:var(--surface); animation:secAiSlide .22s ease-out; }
.sec-ai-panel .gwai-body { flex:1 1 auto; min-height:0; }
@keyframes secAiSlide { from { opacity:0; transform:translateX(22px); } to { opacity:1; transform:none; } }

/* KI-Vorschläge (proposes-only) — Karten im KI-Modal (window.gwAi.suggest) */
.gwai-suggest { display:flex; flex-direction:column; gap:10px; }
.gwai-sg { border:1px solid var(--border); border-radius:10px; padding:11px 13px; background:var(--bg); }
.gwai-sg__head { display:flex; align-items:center; gap:8px; }
.gwai-sg__title { font-size:13px; font-weight:650; color:var(--text-1); flex:1; min-width:0; }
.gwai-sg__hint { flex:0 0 auto; font-size:9.5px; font-weight:700; letter-spacing:.4px; text-transform:uppercase;
                 padding:2px 7px; border-radius:999px; background:var(--surface); border:1px solid var(--border); color:var(--text-3); }
.gwai-sg__why { font-size:12.5px; line-height:1.55; color:var(--text-2); margin-top:5px; }
.gwai-sg__act { display:flex; align-items:center; gap:10px; margin-top:9px; }
.gwai-sg__msg { font-size:11.5px; color:var(--ok-text); }
.gwai-sg__msg--err { color:var(--err-text); }
.gwai-sg__apply--done { opacity:.7; cursor:default; }

/* KI-Record-Check (Topic records_audit) — moderne Bereichs-Karten + Copy-Button */
.gwai-box--wide { width:min(840px,100%); }
.gwai-foot__btns { display:flex; align-items:center; gap:8px; }
.gwai-copy { display:inline-flex; align-items:center; gap:6px; }
.gwai-copy.zd-copied { color:var(--ok-text); border-color:color-mix(in srgb, var(--ok-text) 55%, transparent); }

.gwai-audit { display:flex; flex-direction:column; gap:12px; }
.gwai-audit__sum { font-size:13.5px; line-height:1.55; font-weight:550; color:var(--text-1);
                   background:linear-gradient(90deg, rgba(124,58,237,.08), rgba(124,58,237,0));
                   border:1px solid var(--border); border-left:3px solid #7c3aed; border-radius:10px; padding:11px 13px; }
[data-theme="dark"] .gwai-audit__sum { background:linear-gradient(90deg, rgba(139,92,246,.14), rgba(139,92,246,0)); border-left-color:#a78bfa; }

.gwai-aud { border:1px solid var(--border); border-radius:12px; overflow:hidden; background:var(--surface); }
.gwai-aud__hd { display:flex; align-items:center; gap:9px; padding:10px 13px; border-bottom:1px solid var(--border);
                background:color-mix(in srgb, var(--aud-accent) 9%, transparent); }
.gwai-aud__ic { display:inline-flex; width:26px; height:26px; flex:0 0 26px; align-items:center; justify-content:center;
                border-radius:7px; color:var(--aud-accent); background:color-mix(in srgb, var(--aud-accent) 16%, transparent); }
.gwai-aud__ttl { font-size:13px; font-weight:650; color:var(--text-1); flex:1; min-width:0; }
.gwai-aud__n { font-size:11px; font-weight:700; color:var(--aud-accent); min-width:22px; text-align:center;
               padding:1px 7px; border-radius:999px; background:color-mix(in srgb, var(--aud-accent) 14%, transparent); }
.gwai-aud__bd { display:flex; flex-direction:column; }
.gwai-aud__it { padding:10px 13px; border-top:1px solid color-mix(in srgb, var(--border) 60%, transparent); }
.gwai-aud__it:first-child { border-top:none; }
.gwai-aud__what { font-size:12.5px; line-height:1.55; color:var(--text-1); }
.gwai-aud__fix { display:flex; gap:8px; margin-top:7px; align-items:flex-start;
                 background:var(--bg); border:1px solid var(--border); border-radius:8px; padding:7px 9px; }
.gwai-aud__fixk { flex:0 0 auto; font-size:9.5px; font-weight:700; letter-spacing:.5px; text-transform:uppercase;
                  color:var(--ok-text); background:color-mix(in srgb, var(--ok-text) 14%, transparent);
                  border-radius:5px; padding:2px 6px; margin-top:1px; }
.gwai-aud__fixv { font-size:12px; line-height:1.5; color:var(--text-2); }
.gwai-aud__what code, .gwai-aud__fixv code { font-family:var(--font-mono,monospace); font-size:11.5px;
                  background:rgba(124,58,237,.10); padding:1px 5px; border-radius:4px; word-break:break-word; }
[data-theme="dark"] .gwai-aud__what code, [data-theme="dark"] .gwai-aud__fixv code { background:rgba(139,92,246,.18); }
.gwai-aud__what strong, .gwai-aud__fixv strong { font-weight:650; }
/* Pro-Befund-Apply-Zeile (KI-Zonen-Check) */
.gwai-aud__act { display:flex; align-items:center; gap:10px; margin-top:9px; }
.gwai-aud__msg { font-size:11.5px; color:var(--ok-text); }
.gwai-aud__msg--err { color:var(--err-text); }
.gwai-aud__it--done { opacity:.6; }

/* Bereichs-Akzentfarben (Light + Dark separat — color-mix bleibt auf beidem lesbar) */
.gwai-aud--mail   { --aud-accent:#7c3aed; }
.gwai-aud--sec    { --aud-accent:#dc2626; }
.gwai-aud--struct { --aud-accent:#2563eb; }
.gwai-aud--hyg    { --aud-accent:#0d9488; }
.gwai-aud--bp     { --aud-accent:#16a34a; }
.gwai-aud--other  { --aud-accent:#64748b; }
[data-theme="dark"] .gwai-aud--mail   { --aud-accent:#a78bfa; }
[data-theme="dark"] .gwai-aud--sec    { --aud-accent:#f87171; }
[data-theme="dark"] .gwai-aud--struct { --aud-accent:#60a5fa; }
[data-theme="dark"] .gwai-aud--hyg    { --aud-accent:#2dd4bf; }
[data-theme="dark"] .gwai-aud--bp     { --aud-accent:#4ade80; }
[data-theme="dark"] .gwai-aud--other  { --aud-accent:#94a3b8; }

/* KI-Audit-Triage (window.gwAi.auditTriage) — Severity-gefärbte Cluster-Karten
   mit Header (Icon + Severity-Pille + Titel + Event-Count), Befund + Begründung +
   Empfehlung als Label/Value-Zeilen, Drill-Link unten rechts. */
.gwai-trg { display:flex; flex-direction:column; gap:12px; }
/* Summary (gwai-audit__sum wird ohne Wrapper direkt vor .gwai-trg gerendert) braucht
   Luft zur ersten Karte — sonst klebt der violette Block direkt am Cluster. */
.gwai-audit__sum + .gwai-trg { margin-top:12px; }
.gwai-trg__c { border:1px solid var(--border); border-radius:12px; overflow:hidden; background:var(--surface);
               border-left:4px solid var(--trg-accent, #64748b); }
.gwai-trg__hd { display:flex; align-items:center; gap:9px; padding:10px 13px;
                background:color-mix(in srgb, var(--trg-accent) 8%, transparent); border-bottom:1px solid var(--border); }
.gwai-trg__ic { display:inline-flex; width:26px; height:26px; flex:0 0 26px; align-items:center; justify-content:center;
                border-radius:7px; color:var(--trg-accent); background:color-mix(in srgb, var(--trg-accent) 14%, transparent); }
.gwai-trg__sev { font-size:9.5px; font-weight:700; letter-spacing:.5px; text-transform:uppercase; padding:2px 7px; border-radius:999px;
                 color:var(--trg-accent); background:color-mix(in srgb, var(--trg-accent) 12%, transparent);
                 border:1px solid color-mix(in srgb, var(--trg-accent) 28%, transparent); }
.gwai-trg__ttl { flex:1; min-width:0; font-size:13px; font-weight:650; color:var(--text-1); }
.gwai-trg__cnt { flex:0 0 auto; font-size:10.5px; font-weight:600; color:var(--text-3);
                 background:var(--bg); border:1px solid var(--border); border-radius:999px; padding:2px 8px; }
.gwai-trg__bd { padding:10px 13px; display:flex; flex-direction:column; gap:8px; }
.gwai-trg__what { font-size:12.5px; line-height:1.55; color:var(--text-1); }
.gwai-trg__why, .gwai-trg__adv { display:flex; gap:8px; align-items:flex-start; font-size:12px; line-height:1.5;
                background:var(--bg); border:1px solid var(--border); border-radius:8px; padding:7px 9px; }
.gwai-trg__adv { background:color-mix(in srgb, var(--ok-text) 6%, var(--bg)); border-color:color-mix(in srgb, var(--ok-text) 22%, var(--border)); }
.gwai-trg__lbl { flex:0 0 auto; font-size:9.5px; font-weight:700; letter-spacing:.5px; text-transform:uppercase;
                 padding:2px 6px; border-radius:5px; color:var(--text-3); background:var(--surface); border:1px solid var(--border); }
.gwai-trg__adv .gwai-trg__lbl { color:var(--ok-text); background:color-mix(in srgb, var(--ok-text) 14%, transparent); border-color:color-mix(in srgb, var(--ok-text) 28%, transparent); }
.gwai-trg__act { padding:8px 13px 11px; display:flex; justify-content:flex-end; }
.gwai-trg__c--high { --trg-accent:#dc2626; }
.gwai-trg__c--med  { --trg-accent:#d97706; }
.gwai-trg__c--low  { --trg-accent:#0891b2; }
.gwai-trg__c--info { --trg-accent:#64748b; }
[data-theme="dark"] .gwai-trg__c--high { --trg-accent:#f87171; }
[data-theme="dark"] .gwai-trg__c--med  { --trg-accent:#fbbf24; }
[data-theme="dark"] .gwai-trg__c--low  { --trg-accent:#22d3ee; }
[data-theme="dark"] .gwai-trg__c--info { --trg-accent:#94a3b8; }

/* KI-Record-Assistent (window.gwAi.recordAssistant) — Eingabe, Rückfragen, Vorschlagskarten */
.gwai-ra { display:flex; flex-direction:column; gap:14px; }
/* Intro-Block: prominente Textarea + Beispiel-Chips + Tipp-Hint + Submit-Bar.
   Ist innerhalb einer Card-artigen Umrandung gestaltet, damit der Bereich „Hier
   beschreibt man das Vorhaben" visuell klar von Rückfragen/Vorschlag getrennt ist. */
.gwai-ra__intro { display:flex; flex-direction:column; gap:10px; padding:14px 16px;
  border:1px solid var(--border); border-radius:14px; background:var(--bg);
  background-image:linear-gradient(180deg, color-mix(in srgb, #7c3aed 5%, transparent), transparent 70%); }
[data-theme="dark"] .gwai-ra__intro {
  background-image:linear-gradient(180deg, rgba(139,92,246,.08), transparent 70%); }
.gwai-ra__input { width:100%; box-sizing:border-box; resize:none; min-height:70px; max-height:220px;
  font-size:13.5px; line-height:1.55; padding:11px 13px; border:1px solid var(--border); border-radius:10px;
  background:var(--surface); color:var(--text-1); font-family:inherit;
  transition:border-color .12s, box-shadow .12s; outline:none; }
.gwai-ra__input:focus { border-color:#7c3aed; box-shadow:0 0 0 3px rgba(124,58,237,.18); }
[data-theme="dark"] .gwai-ra__input:focus { border-color:#a78bfa; box-shadow:0 0 0 3px rgba(139,92,246,.25); }
.gwai-ra__chips { display:flex; flex-wrap:wrap; gap:6px; }
.gwai-ra__chip { font-size:11.5px; font-weight:500; color:var(--text-2);
  padding:4px 10px; border-radius:999px; border:1px solid var(--border);
  background:var(--surface); cursor:pointer; transition:border-color .12s, background .12s, color .12s;
  font-family:inherit; }
.gwai-ra__chip:hover { border-color:color-mix(in srgb, #7c3aed 50%, var(--border));
  background:color-mix(in srgb, #7c3aed 8%, var(--surface)); color:#6d28d9; }
[data-theme="dark"] .gwai-ra__chip:hover { background:rgba(139,92,246,.14); color:#c4b5fd; border-color:rgba(139,92,246,.45); }
.gwai-ra__hint { flex:1; min-width:0; font-size:11.5px; color:var(--text-4); line-height:1.5; }
.gwai-ra__bar { display:flex; justify-content:flex-end; align-items:center; gap:12px; }
.gwai-ra__out:empty { display:none; }
.gwai-ra__out { display:flex; flex-direction:column; gap:14px; }

/* Verfeinerungs-Bar — multi-turn: nach erster Vorschlagsrunde wird sie unter
   den Karten gerendert, damit der Nutzer nachjustieren kann ohne neu zu starten. */
.gwai-ra__refine { border:1px solid color-mix(in srgb, #7c3aed 25%, var(--border)); border-radius:13px;
  background:color-mix(in srgb, #7c3aed 4%, var(--surface)); padding:11px 13px; display:flex; flex-direction:column; gap:9px; }
[data-theme="dark"] .gwai-ra__refine { background:rgba(139,92,246,.06); border-color:rgba(139,92,246,.32); }
.gwai-ra__refine__hd { display:flex; flex-direction:column; gap:2px; }
.gwai-ra__refine__lbl { font-size:12.5px; font-weight:650; color:#6d28d9; }
[data-theme="dark"] .gwai-ra__refine__lbl { color:#c4b5fd; }
.gwai-ra__refine__sub { font-size:11.5px; color:var(--text-3); line-height:1.45; }
.gwai-ra__refine__row { display:flex; gap:8px; align-items:center; }
.gwai-ra__refine__in { flex:1; min-width:0; height:34px; padding:0 12px; border:1px solid var(--border);
  border-radius:9px; background:var(--surface); color:var(--text-1); font-size:13px; font-family:inherit;
  transition:border-color .12s, box-shadow .12s; outline:none; }
.gwai-ra__refine__in:focus { border-color:#7c3aed; box-shadow:0 0 0 3px rgba(124,58,237,.18); }
[data-theme="dark"] .gwai-ra__refine__in:focus { border-color:#a78bfa; box-shadow:0 0 0 3px rgba(139,92,246,.25); }
.gwai-ra__qs { display:flex; flex-direction:column; gap:11px; }
.gwai-ra__qhint { font-size:12.5px; color:var(--text-2); padding:2px 4px; }
/* Karten-Look pro Rückfrage — bessere visuelle Trennung als nur Gap. */
.gwai-ra__q { display:flex; flex-direction:column; gap:6px;
  padding:11px 13px; border:1px solid var(--border); border-radius:11px;
  background:var(--surface); transition:border-color .12s; }
.gwai-ra__q:focus-within { border-color:color-mix(in srgb, #7c3aed 45%, var(--border)); }
.gwai-ra__qlbl { font-size:12.5px; font-weight:600; color:var(--text-1); line-height:1.4; }
.gwai-ra__qin { width:100%; box-sizing:border-box; height:34px; padding:0 11px;
  border:1px solid var(--border); border-radius:8px; background:var(--bg); color:var(--text-1);
  font-size:13px; font-family:inherit; outline:none; transition:border-color .12s, box-shadow .12s; }
.gwai-ra__qin:focus { border-color:#7c3aed; box-shadow:0 0 0 3px rgba(124,58,237,.16); background:var(--surface); }
[data-theme="dark"] .gwai-ra__qin:focus { border-color:#a78bfa; box-shadow:0 0 0 3px rgba(139,92,246,.22); }
/* Frage mit Optionen: Dropdown links (passt sich dem Inhalt an, lange Werte werden
   per .zd-value-Ellipsis bei max-width gekürzt), Eingabefeld dicht rechts daneben. */
.gwai-ra__qrow { display:flex; gap:6px; align-items:center; }
.gwai-ra__qrow .gwai-ra__qzd { flex:0 1 auto; min-width:0; max-width:220px; }
.gwai-ra__qrow .gwai-ra__qin { flex:1 1 auto; width:auto; min-width:0; }
/* zd-Dropdown-Panel im KI-Modal: muss über .gwai-bg (z-index 10050) liegen. */
.zd-panel.zd-panel--gwai { z-index:10060; }
.gwai-ra__qhintsm { font-size:11px; color:var(--text-4); }

.gwai-ra__progress { display:flex; align-items:center; gap:8px; font-size:12px; font-weight:600; color:var(--ok-text);
  background:color-mix(in srgb, var(--ok-text) 10%, transparent);
  border:1px solid color-mix(in srgb, var(--ok-text) 28%, transparent); border-radius:10px; padding:9px 12px; }

/* Vorschlagskarten — modern: Akzent-Leiste links, Hover-Lift, Status-Färbung */
.gwai-ra__cards { display:flex; flex-direction:column; gap:11px; }
.gwai-ra__card { position:relative; border:1px solid var(--border); border-radius:13px; background:var(--surface);
  padding:13px 15px 13px 16px; box-shadow:0 1px 2px rgba(15,23,42,.04);
  transition:box-shadow .15s ease, border-color .15s ease; }
.gwai-ra__card::before { content:""; position:absolute; left:0; top:12px; bottom:12px; width:3px;
  border-radius:0 3px 3px 0; background:#7c3aed; opacity:.5; }
[data-theme="dark"] .gwai-ra__card::before { background:#a78bfa; }
.gwai-ra__card:hover { box-shadow:0 6px 18px rgba(15,23,42,.10);
  border-color:color-mix(in srgb, #7c3aed 35%, var(--border)); }
.gwai-ra__card--picked::before { opacity:1; }
.gwai-ra__card--done { opacity:.72; }
.gwai-ra__card--done::before { background:var(--ok-text); opacity:.9; }

.gwai-ra__chd { display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
.gwai-ra__cname { font-family:var(--font-mono,monospace); font-size:13px; font-weight:650; color:var(--text-1); word-break:break-all; }
.gwai-ra__cttl { margin-left:auto; flex:0 0 auto; font-family:var(--font-mono,monospace); font-size:10.5px; font-weight:600;
  color:var(--text-3); background:var(--bg); border:1px solid var(--border); border-radius:999px; padding:2px 9px; }
.gwai-ra__badge { display:inline-flex; align-items:center; gap:4px; font-size:10px; font-weight:700; letter-spacing:.3px; padding:2px 9px; border-radius:999px; }
.gwai-ra__badge--done { color:var(--ok-text); background:color-mix(in srgb, var(--ok-text) 14%, transparent);
  border:1px solid color-mix(in srgb, var(--ok-text) 30%, transparent); }
.gwai-ra__badge--picked { color:#6d28d9; background:rgba(124,58,237,.12); border:1px solid rgba(124,58,237,.30); }
[data-theme="dark"] .gwai-ra__badge--picked { color:#c4b5fd; background:rgba(139,92,246,.20); border-color:rgba(139,92,246,.40); }

.gwai-ra__ctitle { font-size:12.5px; font-weight:600; color:var(--text-1); margin-top:8px; }
.gwai-ra__cval { margin-top:7px; background:var(--bg); border:1px solid var(--border); border-radius:8px; padding:8px 10px; overflow-x:auto; }
.gwai-ra__cval code { font-family:var(--font-mono,monospace); font-size:11.5px; color:var(--text-1); white-space:pre-wrap; word-break:break-word; }
.gwai-ra__cwhy { font-size:12px; line-height:1.5; color:var(--text-2); margin-top:7px; }
.gwai-ra__cact { display:flex; flex-wrap:wrap; gap:8px; margin-top:11px; }
.gwai-ra__copy { display:inline-flex; align-items:center; gap:6px; }

.gwai-ra__notes { border:1px solid var(--border); border-radius:13px; background:var(--bg); padding:12px 14px; }
.gwai-ra__noteshd { font-size:11px; font-weight:700; letter-spacing:.4px; text-transform:uppercase; color:var(--text-3); margin-bottom:7px; }
.gwai-ra__notes ul { margin:0; padding-left:18px; }
.gwai-ra__notes li { font-size:12px; line-height:1.55; color:var(--text-2); margin:4px 0; }
.gwai-ra__notes code, .gwai-ra__cwhy code { font-family:var(--font-mono,monospace); font-size:11.5px; background:rgba(124,58,237,.10); padding:1px 5px; border-radius:4px; }
[data-theme="dark"] .gwai-ra__notes code, [data-theme="dark"] .gwai-ra__cwhy code { background:rgba(139,92,246,.18); }

/* KI-Tag-Vorschläge (window.gwAi.suggestTags) — Karten-Grid */
.gwai-tagsugg__lead { font-size:13px; line-height:1.55; color:var(--text-2); margin:0 0 14px; }
.gwai-tagsugg { display:grid; grid-template-columns:repeat(3, minmax(0,1fr)); gap:12px; }
@media (max-width:760px) { .gwai-tagsugg { grid-template-columns:repeat(2, minmax(0,1fr)); } }
@media (max-width:480px) { .gwai-tagsugg { grid-template-columns:1fr; } }
.gwai-tsg { display:flex; flex-direction:column; gap:10px; background:var(--surface);
  border:1px solid var(--border); border-left:3px solid var(--tsg-c,var(--border)); border-radius:13px; padding:14px;
  transition:transform .12s ease, box-shadow .12s ease, border-color .12s ease; }
.gwai-tsg:hover { box-shadow:0 6px 18px rgba(15,23,42,.10); }
/* Immer eine Zeile: bei einem langen Tag-Namen rutschte die
   Reichweiten-Pille auf eine zweite Zeile und die Karte wuchs schief. Kein `flex-wrap`
   mehr: der NAME gibt nach (kuerzt mit Auslassungszeichen, ganzer Text im Tooltip),
   die Pille bleibt ungekuerzt — sie ist kurz und traegt die Bedeutung. */
.gwai-tsg__top { display:flex; align-items:center; flex-wrap:nowrap; gap:8px; min-width:0; }
.gwai-tsg__top > .user-tag { min-width:0; max-width:100%; overflow:hidden; }
.gwai-tsg__top > .user-tag .user-tag__lbl { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; min-width:0; }
.gwai-tsg__scope { flex:none; margin-left:auto; font-size:10px; font-weight:600; letter-spacing:.2px; padding:2px 8px;
  border-radius:999px; background:var(--bg); border:1px solid var(--border); color:var(--text-3); white-space:nowrap; }
.gwai-tsg__scope--zone   { color:#1d4ed8; background:rgba(59,130,246,.10);  border-color:rgba(59,130,246,.30); }
.gwai-tsg__scope--record { color:#a16207; background:rgba(245,158,11,.12);  border-color:rgba(245,158,11,.30); }
.gwai-tsg__scope--both   { color:#6d28d9; background:rgba(124,58,237,.10);  border-color:rgba(124,58,237,.30); }
[data-theme="dark"] .gwai-tsg__scope--zone   { color:#93c5fd; background:rgba(59,130,246,.16); border-color:rgba(59,130,246,.40); }
[data-theme="dark"] .gwai-tsg__scope--record { color:#fcd34d; background:rgba(245,158,11,.16); border-color:rgba(245,158,11,.40); }
[data-theme="dark"] .gwai-tsg__scope--both   { color:#c4b5fd; background:rgba(124,58,237,.18); border-color:rgba(139,92,246,.40); }
.gwai-tsg__why { font-size:12px; line-height:1.5; color:var(--text-2); flex:1 1 auto; }
.gwai-tsg__foot { display:flex; flex-direction:column; gap:6px; margin-top:auto; }
.gwai-tsg__btn { width:100%; justify-content:center; }
.gwai-tsg__msg { font-size:11.5px; color:var(--ok-text); text-align:center; }
.gwai-tsg__msg--err { color:var(--err-text); }
.gwai-tsg--done { opacity:.65; }
/* Entwuerfe waehrend des Schreibens: blass, gestrichelt, ohne Knopf und ohne
   Anheben — sie sind noch keine Vorschlaege, der Server waehlt danach aus. */
.gwai-tsg-drafts__lead { font-size:12px; color:var(--text-4); margin:4px 0 10px; }
.gwai-tsg--draft { opacity:.72; border-style:dashed; border-left-style:solid; animation:gwai-chip .35s ease both; }
.gwai-tsg--draft:hover { transform:none; box-shadow:none; }
[data-theme="dark"] .gwai-tsg:hover { box-shadow:0 6px 18px rgba(0,0,0,.45); }
[data-theme="dark"] .gwai-tsg--draft:hover { box-shadow:none; }

/* API-Keys-Deep-Link-Highlight (Klick auf Key in Tenant-Details → /api-keys?key=…) */
@keyframes akRowFlash { 0% { background:rgba(99,102,241,.24); } 100% { background:transparent; } }
.ak-row--flash { box-shadow:inset 3px 0 0 #6366f1; }
.ak-row--flash > td { animation:akRowFlash 2.4s ease; }
[data-theme="dark"] .ak-row--flash > td { animation-name:akRowFlashDark; }
@keyframes akRowFlashDark { 0% { background:rgba(129,140,248,.28); } 100% { background:transparent; } }

[data-theme="dark"] .badge-neu { background: rgba(148,163,184,.18); color: var(--text-2); border-color: var(--border-2, var(--border)); }

/* Analyse-Tab im Zoneneditor: Score-Badge + Issue-Boxen + Status-Pills hatten alle
   hartcodierte helle Pastell-Hintergründe — gut auf weiss, völlig daneben auf dunkel.
   Wir matchen sie auf gedämpfte, dunkle Töne mit kräftigeren Vordergrundfarben. */
[data-theme="dark"] .health-score-badge.health-ok       { background: #052e16 !important; border-color: #14532d !important; }
[data-theme="dark"] .health-score-badge.health-warn     { background: #422006 !important; border-color: #78350f !important; }
[data-theme="dark"] .health-score-badge.health-critical { background: #450a0a !important; border-color: #7f1d1d !important; }
[data-theme="dark"] .hs-score { color: var(--text-1) !important; }
[data-theme="dark"] .anl-issue--error    { background: #2a1414 !important; color: #fca5a5 !important; }
[data-theme="dark"] .anl-issue--warning  { background: #2a1d0a !important; color: #fcd34d !important; }
[data-theme="dark"] .anl-issue--info     { background: #0c2538 !important; color: #93c5fd !important; }
[data-theme="dark"] .anl-issue--ok       { background: #0c2618 !important; color: #86efac !important; }
[data-theme="dark"] .anl-card__status--ok      { background: #052e16 !important; color: #86efac !important; }
[data-theme="dark"] .anl-card__status--warning { background: #422006 !important; color: #fcd34d !important; }
[data-theme="dark"] .anl-card__status--error   { background: #450a0a !important; color: #fca5a5 !important; }
[data-theme="dark"] .anl-card__status--info    { background: #0c2538 !important; color: #93c5fd !important; }
[data-theme="dark"] .anl-card__status--skipped { background: #1e293b !important; color: var(--text-3) !important; }
/* Analyse-Detail: code-Werte und „Empty"-Hinweise nicht mit weissem var(--bg)-Tint zeigen.
   Der --bg-Token wird im Dark-Mode-Override schon dunkel — sollte automatisch passen. */
[data-theme="dark"] .anl-table td { border-bottom-color: #1a2536 !important; }

/* Globale Alert-/Info-Boxen: viele Templates verwenden direkte Pastell-Hintergründe
   (#fef3c7, #dcfce7, #dbeafe, #fee2e2, #f0f9ff …). Diese sind im Dark-Mode unangenehm
   hell. Override über Attribute-Selectors fängt die häufigsten ab — gilt für inline-styles. */
[data-theme="dark"] [style*="background:#fef3c7"],
[data-theme="dark"] [style*="background: #fef3c7"] { background: #422006 !important; color: #fcd34d !important; }
[data-theme="dark"] [style*="background:#dcfce7"],
[data-theme="dark"] [style*="background: #dcfce7"] { background: #052e16 !important; color: #86efac !important; }
[data-theme="dark"] [style*="background:#dbeafe"],
[data-theme="dark"] [style*="background: #dbeafe"] { background: #0c2538 !important; color: #93c5fd !important; }
[data-theme="dark"] [style*="background:#fee2e2"],
[data-theme="dark"] [style*="background: #fee2e2"] { background: #450a0a !important; color: #fca5a5 !important; }
[data-theme="dark"] [style*="background:#f0fdf4"],
[data-theme="dark"] [style*="background: #f0fdf4"] { background: #052e16 !important; color: #86efac !important; }
[data-theme="dark"] [style*="background:#fef2f2"],
[data-theme="dark"] [style*="background: #fef2f2"] { background: #2a1414 !important; color: #fca5a5 !important; }
[data-theme="dark"] [style*="background:#fffbeb"],
[data-theme="dark"] [style*="background: #fffbeb"] { background: #2a1d0a !important; color: #fcd34d !important; }
[data-theme="dark"] [style*="background:#eff6ff"],
[data-theme="dark"] [style*="background: #eff6ff"] { background: #0c2538 !important; color: #93c5fd !important; }
[data-theme="dark"] [style*="background:#f0f9ff"],
[data-theme="dark"] [style*="background: #f0f9ff"] { background: #0c2538 !important; }
[data-theme="dark"] [style*="background:#fafbfc"],
[data-theme="dark"] [style*="background: #fafbfc"] { background: var(--bg) !important; }
[data-theme="dark"] [style*="background:#fafcfe"],
[data-theme="dark"] [style*="background: #fafcfe"] { background: var(--bg) !important; }

/* Zone-Tags (Quelle/Typ/DNSSEC/Tenant) — Pastell-Backgrounds aus zones/index.php passen
   nicht zum Dark-Mode. Wir mappen sie auf dunkle Töne mit hellerem Vordergrund für Kontrast. */
[data-theme="dark"] .tag-type-primary    { background: #0c2538 !important; color: #93c5fd !important; }
[data-theme="dark"] .tag-type-secondary  { background: #1e293b !important; color: #cbd5e1 !important; }
[data-theme="dark"] .tag-type-native     { background: #2a1535 !important; color: #d8b4fe !important; }
[data-theme="dark"] .tag-type-other      { background: #2a1414 !important; color: #fca5a5 !important; }
[data-theme="dark"] .tag-dnssec          { background: #082f37 !important; color: #67e8f9 !important; }
[data-theme="dark"] .tag-source-local    { background: #052e16 !important; color: #86efac !important; }
[data-theme="dark"] .tag-source-upstream    { background: #1e1442 !important; color: #c4b5fd !important; }
[data-theme="dark"] .tag-source-external { background: #2a1414 !important; color: #fca5a5 !important; }
[data-theme="dark"] .tag-unassigned      { background: #422006 !important; color: #fcd34d !important; }
[data-theme="dark"] .tag-unassigned:hover{ background: #54310f !important; color: #fde68a !important; }
[data-theme="dark"] .tag-tenant          { background: #1e1442 !important; color: #c4b5fd !important; }
[data-theme="dark"] .tag-sync-ok         { background: #052e16 !important; color: #86efac !important; }
[data-theme="dark"] .tag-sync-warn       { background: #422006 !important; color: #fcd34d !important; }
[data-theme="dark"] .tag-sync-err        { background: #2a1414 !important; color: #fca5a5 !important; }

/* Status-Badges (Aktiv/Inaktiv) — gleiche Behandlung */
/* Dark-Mode: identisch zu .sev-pill-Varianten — transparent-Tints in Identitätsfarbe. */
[data-theme="dark"] .badge-ok   { background: rgba(34,197,94,.18) !important;  color: #86efac !important; border: none !important; }
[data-theme="dark"] .badge-err  { background: rgba(239,68,68,.18) !important;  color: #fca5a5 !important; border: none !important; }
[data-theme="dark"] .badge-warn { background: rgba(234,179,8,.18) !important;  color: #fcd34d !important; border: none !important; }

/* ── CVE-Regel-Badges (Severity / KEV / EPSS) — dark-safe, in der Standard-Badge-Sprache
   (getönter Hintergrund + gedeckte Textfarbe + subtiler Rand; im Dark-Mode rgba-Tints). ── */
.cve-badge { display:inline-block; font-size:9.5px; font-weight:700; text-transform:uppercase; letter-spacing:.3px; border-radius:6px; padding:2px 8px; white-space:nowrap; border:1px solid transparent; line-height:1.55; }
.cve-sev-critical { background:#fee2e2; color:#b91c1c; border-color:#fecaca; }
.cve-sev-high     { background:#ffedd5; color:#c2410c; border-color:#fed7aa; }
.cve-sev-medium   { background:#fef3c7; color:#a16207; border-color:#fde68a; }
.cve-sev-low      { background:#ecfccb; color:#4d7c0f; border-color:#d9f99d; }
.cve-kev          { background:#fee2e2; color:#b91c1c; border-color:#fca5a5; }
.cve-epss         { background:color-mix(in srgb,var(--text-4) 10%,transparent); color:var(--text-2); border-color:var(--border); font-weight:600; text-transform:none; letter-spacing:0; }
[data-theme="dark"] .cve-sev-critical { background:rgba(239,68,68,.18); color:#fca5a5; border-color:rgba(239,68,68,.35); }
[data-theme="dark"] .cve-sev-high     { background:rgba(249,115,22,.18); color:#fdba74; border-color:rgba(249,115,22,.35); }
[data-theme="dark"] .cve-sev-medium   { background:rgba(234,179,8,.18);  color:#fcd34d; border-color:rgba(234,179,8,.35); }
[data-theme="dark"] .cve-sev-low      { background:rgba(132,204,22,.18); color:#bef264; border-color:rgba(132,204,22,.35); }
[data-theme="dark"] .cve-kev          { background:rgba(239,68,68,.20);  color:#fca5a5; border-color:rgba(239,68,68,.40); }
[data-theme="dark"] .cve-epss         { background:rgba(148,163,184,.15); color:var(--text-2); border-color:var(--border-2,var(--border)); }
/* Tier-Pille des proaktiven EPSS-Patches (hohe Ausnutzungswahrscheinlichkeit) — amber, klar
   unterscheidbar von der grauen EPSS-Score-Pille und der roten KEV-Pille. */
.cve-tier-epss        { background:#fef3c7; color:#a16207; border-color:#fde68a; cursor:help; }
.cve-kev              { cursor:help; }
[data-theme="dark"] .cve-tier-epss { background:rgba(234,179,8,.18); color:#fcd34d; border-color:rgba(234,179,8,.35); }
/* Wirksamkeits-Pille (Patch hat real geblockt) — gruen, damit „arbeitet" auf einen Blick sichtbar ist. */
.cve-hits             { background:#dcfce7; color:#15803d; border-color:#bbf7d0; text-transform:none; letter-spacing:0; font-weight:600; }
[data-theme="dark"] .cve-hits { background:rgba(34,197,94,.16); color:#86efac; border-color:rgba(34,197,94,.35); }
.kev-cat-row:hover { background:color-mix(in srgb,var(--text-4) 6%,transparent); }

/* ── Detail eines proaktiven Patches (KEV/EPSS) — zweispaltiges Raster im Standard-zd-Dialog ──── */
.kevd-grid { display:grid; grid-template-columns:1fr 1fr; gap:14px; text-align:left; }
@media (max-width:680px){ .kevd-grid { grid-template-columns:1fr; } }
/* Detail-Karten-Muster (wie „Warum blockiert"): Akzent-Rahmen + getönter Kopfstreifen.
   Akzent kommt per --kacc vom JS (KEV = rot, EPSS = blau). */
.kevd-sec { min-width:0; border:1px solid color-mix(in srgb,var(--kacc,#2563eb) 26%,var(--border)); border-radius:11px; overflow:hidden; background:var(--surface); }
.kevd-sec-h { display:flex; align-items:center; gap:8px; padding:9px 12px; background:color-mix(in srgb,var(--kacc,#2563eb) 8%,transparent); border-bottom:1px solid color-mix(in srgb,var(--kacc,#2563eb) 18%,var(--border)); font-size:10.5px; font-weight:700; text-transform:uppercase; letter-spacing:.5px; color:color-mix(in srgb,var(--kacc,#2563eb) 60%,var(--text-2)); }
.kevd-sec-h svg { width:14px; height:14px; flex:none; color:var(--kacc,#2563eb); }
.kevd-sec-b { padding:10px 12px 12px; }
[data-theme="dark"] .kevd-sec { background:color-mix(in srgb,#000 18%,var(--surface)); }
[data-theme="dark"] .kevd-sec-h { color:color-mix(in srgb,var(--kacc,#2563eb) 45%,var(--text-1)); }
.kevd-h { font-size:10.5px; font-weight:700; text-transform:uppercase; letter-spacing:.5px; color:var(--text-4); margin:0 0 7px; }
.kevd-kv { display:flex; gap:8px; font-size:12.5px; padding:3px 0; border-top:1px solid color-mix(in srgb,var(--text-4) 12%,transparent); }
.kevd-kv:first-of-type { border-top:0; }
.kevd-kv .k { flex:0 0 40%; color:var(--text-3); }
.kevd-kv .v { flex:1; min-width:0; color:var(--text-1); font-weight:600; word-break:break-word; }
.kevd-desc { font-size:12.5px; color:var(--text-2); line-height:1.55; margin-top:8px; }
.kevd-pat { font-family:var(--font-mono,monospace); font-size:11.5px; background:color-mix(in srgb,var(--text-4) 8%,transparent); border:1px solid var(--border); border-radius:8px; padding:8px 10px; margin-top:6px; word-break:break-all; line-height:1.5; }
.kevd-chip { display:inline-block; font-family:var(--font-mono,monospace); font-size:11px; background:color-mix(in srgb,var(--gw,#2563eb) 12%,transparent); border:1px solid color-mix(in srgb,var(--gw,#2563eb) 28%,transparent); border-radius:6px; padding:1px 7px; margin:2px 4px 2px 0; word-break:break-all; }
.kevd-host { display:flex; align-items:center; gap:8px; font-size:12px; padding:5px 0; border-top:1px solid color-mix(in srgb,var(--text-4) 12%,transparent); }
.kevd-host:first-of-type { border-top:0; }
.kevd-host .hn { flex:1; min-width:0; color:var(--text-1); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.kevd-span2 { grid-column:1 / -1; }

/* ── Per-Host KEV-Patch-Liste (Proxy-Modal, Sektion „Proaktive KEV-Patches") ──
   Kompakte Karte: Kopfzeile Name+KEV+EPSS+Status inline, darunter CVE/Beschreibung,
   Aktion (Deaktivieren/Aktivieren) rechts unten. */
.rps-kev-item { display:flex; align-items:center; gap:10px; padding:8px 10px; border:1px solid var(--border); border-radius:9px; background:var(--card,var(--bg)); margin-bottom:7px; }
.rps-kev-item.is-off { opacity:.66; }
.rps-kev-click { cursor:pointer; }
.rps-kev-click:hover { border-color:color-mix(in srgb,var(--accent,#2563eb) 45%,var(--border)); }
.rps-kev-body { flex:1 1 auto; min-width:0; }
.rps-kev-top  { display:flex; align-items:center; gap:4px; flex-wrap:nowrap; min-width:0; }
.rps-kev-name { font-weight:600; font-size:13px; color:var(--text-1); flex:1 1 auto; min-width:0; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; margin-left:2px; }
/* Kompaktere/dezentere Pillen in der Per-Host-Liste — sie nehmen sonst zu viel Platz weg. */
.rps-kev-top .cve-badge { font-size:8.5px; padding:1px 5px; border-radius:5px; letter-spacing:.2px; line-height:1.5; }
.rps-kev-cve  { font-size:11.5px; color:var(--text-4); margin-top:3px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.rps-kev-btn  { flex:0 0 auto; width:30px; height:30px; display:inline-flex; align-items:center; justify-content:center; padding:0; border:1px solid var(--border); border-radius:7px; background:transparent; color:var(--text-4); cursor:pointer; transition:color .12s, border-color .12s; }
.rps-kev-btn:hover { color:#dc2626; border-color:#fca5a5; }
.rps-kev-btn.is-off:hover { color:#15803d; border-color:#bbf7d0; }
[data-theme="dark"] .rps-kev-btn:hover { color:#fca5a5; border-color:rgba(239,68,68,.4); }
[data-theme="dark"] .rps-kev-btn.is-off:hover { color:#86efac; border-color:rgba(34,197,94,.4); }
.rps-kev-state { font-size:9px; font-weight:600; padding:1px 7px; border-radius:20px; white-space:nowrap; border:1px solid transparent; margin-left:2px; }
.rps-kev-on     { background:#dcfce7; color:#15803d; border-color:#bbf7d0; }
.rps-kev-shadow { background:#fef3c7; color:#a16207; border-color:#fde68a; }
.rps-kev-off    { background:color-mix(in srgb,var(--text-4) 12%,transparent); color:var(--text-3); border-color:var(--border); }
[data-theme="dark"] .rps-kev-on     { background:rgba(34,197,94,.18);  color:#86efac; border-color:rgba(34,197,94,.35); }
[data-theme="dark"] .rps-kev-shadow { background:rgba(234,179,8,.18);   color:#fcd34d; border-color:rgba(234,179,8,.35); }
[data-theme="dark"] .rps-kev-off    { background:rgba(148,163,184,.15); color:var(--text-3); border-color:var(--border); }

/* ── Quota-/Auslastungs-Bar (.qc-*) — systemweit ────────────────────────
   Schmaler Track + farbiger Fill, Schwellen einheitlich: ≥80% orange, ≥90% rot.
   Wird genutzt von /admin/tenants, Dashboard-Widgets (Tenant-Kapazitäten,
   Paket-Verteilung), Security-Risk-Score etc. Light + Dark automatisch durch
   var(--bg)/var(--border) — Fill-Farben sind theme-aware genug bei den
   gesättigten 22c55e/f59e0b/dc2626-Werten. */
.qc        { min-width:130px; font-family:var(--font); font-size:12.5px }
.qc-num    { color:var(--text-1); font-weight:600; line-height:1.3 }
.qc-num .qc-max { color:var(--text-4); font-weight:500 }
.qc-bar    { width:100%; height:5px; border-radius:3px; background:var(--bg); margin-top:4px; overflow:hidden; border:1px solid var(--border) }
.qc-bar-fill { height:100%; border-radius:2px; transition:width .3s }
.qc-bar-fill.ok   { background:#22c55e }
.qc-bar-fill.warn { background:#f59e0b }
.qc-bar-fill.crit { background:#dc2626 }
.qc-bar-fill.unl  { background:linear-gradient(90deg, #dbeafe, #93c5fd) }
[data-theme="dark"] .qc-bar-fill.unl { background:linear-gradient(90deg, rgba(56,189,248,.30), rgba(56,189,248,.55)) }

/* TTL-Tags: 5 Stufen (vshort/short/std/long/vlong) hatten helle Pastell-Backgrounds.
   Im Dark-Mode kräftigere Text-Farben + dezenter dunkler Hintergrund. */
[data-theme="dark"] .ttl-tag.ttl-vshort  { background: #2a1414 !important; color: #fca5a5 !important; border-color: #7f1d1d !important; }
[data-theme="dark"] .ttl-tag.ttl-short   { background: #2a1d0a !important; color: #fcd34d !important; border-color: #78350f !important; }
[data-theme="dark"] .ttl-tag.ttl-std     { background: #0c2538 !important; color: #93c5fd !important; border-color: #1e40af !important; }
[data-theme="dark"] .ttl-tag.ttl-long    { background: #082f37 !important; color: #67e8f9 !important; border-color: #155e75 !important; }
[data-theme="dark"] .ttl-tag.ttl-vlong   { background: #052e16 !important; color: #86efac !important; border-color: #14532d !important; }

/* Record-Type-Tags (.rr-A, .rr-AAAA, …) — über 30 Varianten mit hellen Pastell-Hintergründen.
   Statt jede einzeln dunkel zu mappen, nutzen wir Outline-Stil: dezenter dunkler Hintergrund,
   die ursprüngliche Type-Farbe wandert an den Rand → eindeutige Type-Identität bleibt erhalten,
   visuell konsistent zu allen anderen dunklen Pillen. */
[data-theme="dark"] .rr-chip {
  background: rgba(255, 255, 255, 0.04) !important;
  border: 1px solid currentColor !important;
  /* Fallback-Helligkeit fuer Typen ohne eigene .rr-<TYPE>-Dark-Regel (z.B. generische
     TYPE65534, oder kuenftige Typen): sonst bleibt currentColor die dunkle Light-Basis
     (#475569) → Pille auf dunklem Grund fast unsichtbar. Bekannte Typen ueberschreiben
     das via ihrer !important-Dark-Regel unten. */
  color: #cbd5e1;
}
/* Häufigste Record-Typen mit hellerer Schrift (Pastell-Originalfarben sind im Dark zu dunkel) */
[data-theme="dark"] .rr-A          { color: #93c5fd !important; }
[data-theme="dark"] .rr-AAAA       { color: #a5b4fc !important; }
[data-theme="dark"] .rr-CNAME      { color: #f0abfc !important; }
[data-theme="dark"] .rr-MX         { color: #fde047 !important; }
[data-theme="dark"] .rr-TXT        { color: #86efac !important; }
[data-theme="dark"] .rr-NS         { color: #f9a8d4 !important; }
[data-theme="dark"] .rr-PTR        { color: #5eead4 !important; }
[data-theme="dark"] .rr-SOA        { color: #fdba74 !important; }
[data-theme="dark"] .rr-SRV        { color: #67e8f9 !important; }
[data-theme="dark"] .rr-CAA        { color: #bef264 !important; }
[data-theme="dark"] .rr-SPF        { color: #fde047 !important; }
[data-theme="dark"] .rr-URI        { color: #fca5a5 !important; }
/* DNSSEC-Familie */
[data-theme="dark"] .rr-DNSKEY     { color: #c4b5fd !important; }
[data-theme="dark"] .rr-CDNSKEY    { color: #a78bfa !important; }
[data-theme="dark"] .rr-RRSIG      { color: #93c5fd !important; }
[data-theme="dark"] .rr-NSEC       { color: #d8b4fe !important; }
[data-theme="dark"] .rr-NSEC3      { color: #c084fc !important; }
[data-theme="dark"] .rr-NSEC3PARAM { color: #e9d5ff !important; }
[data-theme="dark"] .rr-DS         { color: #f9a8d4 !important; }
[data-theme="dark"] .rr-CDS        { color: #fda4af !important; }
[data-theme="dark"] .rr-DLV        { color: #fde68a !important; }
[data-theme="dark"] .rr-KEY        { color: #a5b4fc !important; }
[data-theme="dark"] .rr-TKEY       { color: #c7d2fe !important; }
[data-theme="dark"] .rr-TSIG       { color: #bef264 !important; }
[data-theme="dark"] .rr-SSHFP      { color: #cbd5e1 !important; }
[data-theme="dark"] .rr-TLSA       { color: #d2b48c !important; }
[data-theme="dark"] .rr-SMIMEA     { color: #fbb6ce !important; }
[data-theme="dark"] .rr-IPSECKEY   { color: #a5f3fc !important; }
[data-theme="dark"] .rr-HTTPS      { color: #f9a8d4 !important; }
[data-theme="dark"] .rr-SVCB       { color: #d8b4fe !important; }
[data-theme="dark"] .rr-NAPTR      { color: #67e8f9 !important; }

/* ============================================================================
   Dark-Mode Sweep — generelle Komponenten-Overrides
   ----------------------------------------------------------------------------
   Catches alle hartkodierten weiss/hellgrauen Backgrounds in der gesamten App,
   damit nichts mehr „weiss" durchschimmert. Inline-Styles werden ergänzend
   durch die [style*=…]-Selektoren oben abgedeckt.
   ============================================================================ */
[data-theme="dark"] .chip,
[data-theme="dark"] .chip::before { background: var(--bg) !important; }
[data-theme="dark"] .chip { color: var(--text-2) !important; border-color: var(--border) !important; }
[data-theme="dark"] .chip:hover { background: #243044 !important; color: var(--text-1) !important; }

/* Aktiver Zustand muss im Dark-Mode separat überschrieben werden — sonst frisst
   die obere ".chip {background:var(--bg) !important}"-Regel das is-on-Backdrop
   und alle ausgewählten Chips sehen aus wie unselektiert. Pattern wie bei
   .tag-tenant: transparenter Tint im Akzentfarbton + farbiger Border + neon-Text. */
[data-theme="dark"] .chip.is-on {
  background:   color-mix(in srgb, var(--chip-accent) 18%, transparent) !important;
  border-color: color-mix(in srgb, var(--chip-accent) 60%, transparent) !important;
  color:        color-mix(in srgb, var(--chip-accent) 35%, white)       !important;
}
[data-theme="dark"] .chip.is-on:hover {
  background:   color-mix(in srgb, var(--chip-accent) 28%, transparent) !important;
  border-color: color-mix(in srgb, var(--chip-accent) 75%, transparent) !important;
}
[data-theme="dark"] .chip.is-on::before {
  /* background-COLOR statt shorthand, sonst killt das !important das via
     .chip.is-on::before gesetzte background-image (weisses Check-SVG). */
  background-color: var(--chip-accent) !important;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'><polyline points='20 6 9 17 4 12'/></svg>") !important;
  background-size: 11px 11px !important;
  background-position: center !important;
  background-repeat: no-repeat !important;
  border-color: var(--chip-accent) !important;
}

/* Globale Inline-Overrides für #fff- und #ffffff-Backgrounds in Inline-Styles */
[data-theme="dark"] [style*="background:#fff"],
[data-theme="dark"] [style*="background: #fff"],
[data-theme="dark"] [style*="background:#ffffff"],
[data-theme="dark"] [style*="background: #ffffff"] { background: var(--surface) !important; }

/* card / .modal / .modal-overlay Overrides */
[data-theme="dark"] .modal { background: var(--surface) !important; border-color: var(--border) !important; }
[data-theme="dark"] .modal-head,
[data-theme="dark"] .modal-foot { border-color: var(--border) !important; }
[data-theme="dark"] .modal-overlay { background: rgba(0,0,0,.65) !important; }

/* Slide-Panel (Records-Editor) — weisse Bereiche dunkeln */
[data-theme="dark"] .slide-panel,
[data-theme="dark"] .slide-panel .panel-body { background: var(--bg) !important; color: var(--text-1) !important; }
[data-theme="dark"] .slide-panel .panel-foot { background: var(--surface) !important; border-color: var(--border) !important; }

/* Kacheln im Dashboard / Settings-Cards / generelle Tile-Boxen */
[data-theme="dark"] .card,
[data-theme="dark"] .settings-section,
[data-theme="dark"] .anl-card,
[data-theme="dark"] .anl-card__body,
[data-theme="dark"] .anl-card__head,
[data-theme="dark"] .analyse-header,
[data-theme="dark"] .propagation-form { background: var(--surface) !important; border-color: var(--border) !important; }

/* Auswahl-Karten (Opt-Cards für MFA, etc.) */
[data-theme="dark"] .opt-card { background: var(--surface) !important; border-color: var(--border) !important; }
[data-theme="dark"] .opt-card.is-on { background: #0c2538 !important; border-color: var(--gw) !important; }
[data-theme="dark"] .opt-card-icon { background: rgba(255,255,255,.04) !important; }

/* Inputs/Textarea/Selects — generic catch (auch mit Inline-style) */
[data-theme="dark"] input[type="text"],
[data-theme="dark"] input[type="email"],
[data-theme="dark"] input[type="password"],
[data-theme="dark"] input[type="number"],
[data-theme="dark"] input[type="search"],
[data-theme="dark"] input[type="date"],
[data-theme="dark"] input[type="datetime-local"],
[data-theme="dark"] input[type="url"],
[data-theme="dark"] textarea,
[data-theme="dark"] select { background: var(--bg) !important; color: var(--text-1) !important; border-color: var(--border-2) !important; }
[data-theme="dark"] input:focus,
[data-theme="dark"] textarea:focus,
[data-theme="dark"] select:focus { border-color: var(--gw) !important; }
/* Inputs, die in einem eigenen Wrapper sitzen (Topbar-Suche, Snapshot-Record-Suche),
   sollen den Wrapper-Hintergrund erben — sonst entsteht im Dark-Mode ein
   sichtbarer Stufen-Effekt zwischen Wrapper-Surface (im :focus-within) und
   Input-Background (durch das !important oben). */
[data-theme="dark"] .topbar-search input,
[data-theme="dark"] .snap-search input[type="text"],
[data-theme="dark"] .search-box input,
[data-theme="dark"] input.qsw-input {
  background: transparent !important;
  border-color: transparent !important;
}

/* Code-Blöcke mit hartcodiertem #f1f5f9 / hellgrau — gilt nur für <pre>-Blöcke;
   die globale Inline-<code>-Behandlung ist oben (Zeilen 69ff) definiert. */
[data-theme="dark"] pre code { background: #0b1322 !important; color: #cbd5e1 !important; border-color: #2d3e50 !important; }
[data-theme="dark"] [style*="background:#f1f5f9"],
[data-theme="dark"] [style*="background: #f1f5f9"] { background: rgba(255,255,255,.04) !important; }
[data-theme="dark"] [style*="background:#f8fafc"],
[data-theme="dark"] [style*="background: #f8fafc"] { background: var(--bg) !important; }
[data-theme="dark"] [style*="background:#f3f4f6"],
[data-theme="dark"] [style*="background: #f3f4f6"] { background: rgba(255,255,255,.05) !important; }
[data-theme="dark"] [style*="background:#fef9c3"],
[data-theme="dark"] [style*="background: #fef9c3"] { background: #2a1d0a !important; color: #fcd34d !important; }
[data-theme="dark"] [style*="background:#e7ecf3"],
[data-theme="dark"] [style*="background: #e7ecf3"] { background: #18243a !important; }
[data-theme="dark"] [style*="background:#dbe2eb"],
[data-theme="dark"] [style*="background: #dbe2eb"] { background: #243044 !important; }
[data-theme="dark"] [style*="background:#e5e7eb"],
[data-theme="dark"] [style*="background: #e5e7eb"] { background: #1e293b !important; }
[data-theme="dark"] [style*="background:#e0f2fe"],
[data-theme="dark"] [style*="background: #e0f2fe"] { background: #0c2538 !important; color: #93c5fd !important; }
[data-theme="dark"] [style*="background:#ede9fe"],
[data-theme="dark"] [style*="background: #ede9fe"] { background: #1e1442 !important; color: #c4b5fd !important; }
[data-theme="dark"] [style*="background:#f5d0fe"],
[data-theme="dark"] [style*="background: #f5d0fe"] { background: #2a1535 !important; color: #f0abfc !important; }
[data-theme="dark"] [style*="background:#fbcfe8"],
[data-theme="dark"] [style*="background: #fbcfe8"] { background: #2a1422 !important; color: #f9a8d4 !important; }
[data-theme="dark"] [style*="background:#fce7f3"],
[data-theme="dark"] [style*="background: #fce7f3"] { background: #2a1422 !important; color: #f9a8d4 !important; }
[data-theme="dark"] [style*="background:#cffafe"],
[data-theme="dark"] [style*="background: #cffafe"] { background: #082f37 !important; color: #67e8f9 !important; }
[data-theme="dark"] [style*="background:#ecfccb"],
[data-theme="dark"] [style*="background: #ecfccb"] { background: #1a2e0c !important; color: #bef264 !important; }
[data-theme="dark"] [style*="background:#fef3c7"],
[data-theme="dark"] [style*="background: #fef3c7"] { background: #422006 !important; color: #fcd34d !important; }
[data-theme="dark"] [style*="background:#fef08a"],
[data-theme="dark"] [style*="background: #fef08a"] { background: #422006 !important; color: #fde047 !important; }
[data-theme="dark"] [style*="background:#fed7aa"],
[data-theme="dark"] [style*="background: #fed7aa"] { background: #2a1a0a !important; color: #fdba74 !important; }
[data-theme="dark"] [style*="background:#fdba74"],
[data-theme="dark"] [style*="background: #fdba74"] { background: #2a1a0a !important; color: #fdba74 !important; }

/* Hover-Effekte auf Listen und „grau-blau"-Hover-Targets */
[data-theme="dark"] [style*="background:#f0f9ff"]:hover,
[data-theme="dark"] [style*="background: #f0f9ff"]:hover,
[data-theme="dark"] [style*="this.style.background='var(--bg)'"]:hover { background: #243044 !important; }

/* Gradients in Templates — generic neutralize: alle linear-gradient mit hellem Start
   werden durch Surface-Token ersetzt (greift nur in Dark-Mode). */
[data-theme="dark"] [style*="linear-gradient"][style*="#fff"],
[data-theme="dark"] [style*="linear-gradient"][style*="#fafb"],
[data-theme="dark"] [style*="linear-gradient"][style*="#fafc"] {
  background: var(--surface) !important;
}

/* Sync-Status-Bar im Zoneneditor (Synchron / Out-of-Sync / Error) */
[data-theme="dark"] .zr-sync-bar.ok          { background: #052e16 !important; color: #86efac !important; border-color: #14532d !important; }
[data-theme="dark"] .zr-sync-bar.out_of_sync { background: #422006 !important; color: #fcd34d !important; border-color: #78350f !important; }
[data-theme="dark"] .zr-sync-bar.error       { background: #450a0a !important; color: #fca5a5 !important; border-color: #7f1d1d !important; }
[data-theme="dark"] .zr-sync-bar .sync-detail,
[data-theme="dark"] .zr-sync-bar .sync-cap   { color: var(--text-3) !important; }

/* Health-Indicator-Pille (● Kritisch / ⚠ Warnung) im Zoneneditor */
[data-theme="dark"] .health-indicator.health-warn     { background: #422006 !important; color: #fcd34d !important; border-color: #78350f !important; }
[data-theme="dark"] .health-indicator.health-critical { background: #450a0a !important; color: #fca5a5 !important; border-color: #7f1d1d !important; }

/* Tab-Count-Badges (.ztab .ct) — nutzen var(--surface) was im Dark-Mode dunkel ist;
   aktiver Tab hatte hardcoded #bfdbfe als Border, „unassigned" #fef3c7. Beides anpassen. */
[data-theme="dark"] .ztab .ct          { background: var(--bg) !important; color: var(--text-3) !important; border-color: var(--border) !important; }
[data-theme="dark"] .ztab.active .ct   { background: rgba(0,152,239,.15) !important; color: #93c5fd !important; border-color: #1e40af !important; }
[data-theme="dark"] .ztab.tab-unas .ct { background: #422006 !important; color: #fcd34d !important; border-color: #78350f !important; }
/* Hover und aktiver Grund der Reiter: seit 14.09.2026 in der einen Reiter-Fassung (« Reiter: eine Fassung »). */

/* Form-Hint (`.form-hint`) ist meistens grau aber manchmal hardcoded — sicherheitshalber Token */
[data-theme="dark"] .form-hint { color: var(--text-4) !important; }

/* ========================================================================
   Dashboard-Widgets — Inline-Tiles und Pastell-Cards
   ------------------------------------------------------------------------
   Die Dashboard-Widgets (Record-Verteilung, Zone-Health, API-Usage,
   Snapshots, Archive) nutzen pro Tile inline-styles mit Pastell-bg + Border.
   Wir erweitern die Pastell-Override-Liste um alle dort verwendeten Farben. */
[data-theme="dark"] [style*="background:#eff6ff"],
[data-theme="dark"] [style*="background: #eff6ff"] { background: #0c2538 !important; }
[data-theme="dark"] [style*="background:#ecfeff"],
[data-theme="dark"] [style*="background: #ecfeff"] { background: #082f37 !important; color: #67e8f9 !important; }
[data-theme="dark"] [style*="background:#f5f3ff"],
[data-theme="dark"] [style*="background: #f5f3ff"] { background: #1e1442 !important; color: #c4b5fd !important; }
[data-theme="dark"] [style*="background:#fdf4ff"],
[data-theme="dark"] [style*="background: #fdf4ff"] { background: #2a1535 !important; color: #f0abfc !important; }
[data-theme="dark"] [style*="background:#fff7ed"],
[data-theme="dark"] [style*="background: #fff7ed"] { background: #2a1a0a !important; color: #fdba74 !important; }
[data-theme="dark"] [style*="background:#f0fdfa"],
[data-theme="dark"] [style*="background: #f0fdfa"] { background: #0c2521 !important; color: #5eead4 !important; }
[data-theme="dark"] [style*="background:#f0f8ff"],
[data-theme="dark"] [style*="background: #f0f8ff"] { background: #0c2538 !important; color: #93c5fd !important; }

/* Aktivität-7d-Balken: Hardcoded Helle für „has-data" und „empty" — im Dark-Mode dunkler */
[data-theme="dark"] [style*="background:#93c5fd"],
[data-theme="dark"] [style*="background: #93c5fd"] { background: #1e40af !important; }
[data-theme="dark"] [style*="background:#e8eef5"],
[data-theme="dark"] [style*="background: #e8eef5"] { background: #243044 !important; }

/* Borders in Inline-Styles (`border:1px solid #XXXXXX`) — die häufigsten Pastell-Borders */
[data-theme="dark"] [style*="border:1px solid #bfdbfe"],
[data-theme="dark"] [style*="border: 1px solid #bfdbfe"] { border-color: #1e40af !important; }
[data-theme="dark"] [style*="border:1px solid #a5f3fc"],
[data-theme="dark"] [style*="border: 1px solid #a5f3fc"] { border-color: #155e75 !important; }
[data-theme="dark"] [style*="border:1px solid #c4b5fd"],
[data-theme="dark"] [style*="border: 1px solid #c4b5fd"] { border-color: #5b21b6 !important; }
[data-theme="dark"] [style*="border:1px solid #fca5a5"],
[data-theme="dark"] [style*="border: 1px solid #fca5a5"] { border-color: #7f1d1d !important; }
[data-theme="dark"] [style*="border:1px solid #fcd34d"],
[data-theme="dark"] [style*="border: 1px solid #fcd34d"] { border-color: #78350f !important; }
[data-theme="dark"] [style*="border:1px solid #fde68a"],
[data-theme="dark"] [style*="border: 1px solid #fde68a"] { border-color: #78350f !important; }
[data-theme="dark"] [style*="border:1px solid #bbf7d0"],
[data-theme="dark"] [style*="border: 1px solid #bbf7d0"] { border-color: #14532d !important; }
[data-theme="dark"] [style*="border:1px solid #fecaca"],
[data-theme="dark"] [style*="border: 1px solid #fecaca"] { border-color: #7f1d1d !important; }
[data-theme="dark"] [style*="border:1px solid #fed7aa"],
[data-theme="dark"] [style*="border: 1px solid #fed7aa"] { border-color: #7c2d12 !important; }
[data-theme="dark"] [style*="border:1px solid #fdba74"],
[data-theme="dark"] [style*="border: 1px solid #fdba74"] { border-color: #7c2d12 !important; }
[data-theme="dark"] [style*="border:1px solid #f9a8d4"],
[data-theme="dark"] [style*="border: 1px solid #f9a8d4"] { border-color: #831843 !important; }
[data-theme="dark"] [style*="border:1px solid #d8b4fe"],
[data-theme="dark"] [style*="border: 1px solid #d8b4fe"] { border-color: #6b21a8 !important; }
[data-theme="dark"] [style*="border:1px solid #fbcfe8"],
[data-theme="dark"] [style*="border: 1px solid #fbcfe8"] { border-color: #9d174d !important; }

/* Pre-Delete-Archive Info-Banner (.arch-info) — hardcoded #fffbeb/#fde68a/#92400e */
[data-theme="dark"] .arch-info {
  background: #2a1d0a !important;
  border-color: #78350f !important;
  color: #fcd34d !important;
}

/* Record-Verteilung Cards (.rd-card) hatten hartcodierten #f8fafc-Background */
[data-theme="dark"] .rd-card { background: var(--bg) !important; }
[data-theme="dark"] .rd-card:hover { background: #243044 !important; }
[data-theme="dark"] .rd-card .rd-bar { background: #1a2536 !important; }

/* Widget-List-Rows (.w-row) — border-bottom-color hartcodiert #f1f5f9 */
[data-theme="dark"] .w-list .w-row { border-bottom-color: #1a2536 !important; }
[data-theme="dark"] .w-list .w-row:hover { background: #243044 !important; }

/* ============================================================================
   Dark-Mode Sweep — Phase 2: spezifische Komponenten aus dem System-Audit
   ============================================================================ */

/* Record-Type-Chips: jeder Typ behält seine Neon-Farb-Identität (per-Typ
   COLOR-Overrides oben). Wir geben einen dunklen tag-eigenen Backdrop +
   1px Border in derselben Farbe — kein Glow/Shadow. */
[data-theme="dark"] .rr-chip {
  background: color-mix(in srgb, currentColor 14%, transparent) !important;
  border: 1px solid color-mix(in srgb, currentColor 32%, transparent) !important;
  box-shadow: none !important;
  text-shadow: none !important;
}

/* tag-* Familie — Neon-Farbig (nicht glow): jede Tag-Klasse bekommt eine
   fluoreszierende neon-Farbe als Schrift, dazu einen dezenten dark-tinted
   Backdrop in derselben Farb-Identität. Kein Glow, keine Shadows.
   Neon-Palette (Tailwind-400-Ebene, höhere Saturation als Pastel-300): */
[data-theme="dark"] .tag-type-Master      { color: #38bdf8 !important; } /* sky-400 */
[data-theme="dark"] .tag-type-Slave       { color: #94a3b8 !important; } /* slate-400 */
[data-theme="dark"] .tag-type-Native      { color: #a78bfa !important; } /* violet-400 */
[data-theme="dark"] .tag-type-primary     { color: #38bdf8 !important; }
[data-theme="dark"] .tag-type-secondary   { color: #94a3b8 !important; }
[data-theme="dark"] .tag-type-native      { color: #a78bfa !important; }
[data-theme="dark"] .tag-type-other       { color: #fb7185 !important; } /* rose-400 */
[data-theme="dark"] .tag-source-local     { color: #34d399 !important; } /* emerald-400 */
[data-theme="dark"] .tag-source-upstream     { color: #a78bfa !important; }
[data-theme="dark"] .tag-source-external  { color: #fb7185 !important; }
[data-theme="dark"] .tag-status-active    { color: #34d399 !important; }
[data-theme="dark"] .tag-status-inactive  { color: #94a3b8 !important; }
[data-theme="dark"] .tag-dnssec           { color: #22d3ee !important; } /* cyan-400 */
[data-theme="dark"] .tag-approval         { color: #facc15 !important; } /* yellow-400 */
/* Tenant-Pillen sollen im Dark-Mode pro Tenant unterschiedlich gefärbt bleiben.
   --tag-color kommt inline von tenantPill() / gwTenantPill() (fg-Hex der
   Light-Mode-Palette, z.B. #9d174d). Falls die Variable nicht gesetzt ist
   (Altbestand), Fallback auf einen neutralen Violett-Ton — damit kein hartes
   Schwarz oder #9d174d auf dunklem Bg sichtbar wird. */
[data-theme="dark"] .tag-tenant,
[data-theme="dark"] .tag-tenant-link {
  color: color-mix(in srgb, var(--tag-color, #a78bfa) 60%, white) !important;
}

/* ── .gw-kpi-card — Universal KPI-Tile-Hover (Light + Dark) ────────────
   Light-Mode: dezenter Schatten, kein Hochspringen. Pure CSS — kein JS-onmouseover/-out
   das hängenbleiben könnte wenn der Cursor über ein Child wandert. */
.gw-kpi-card {
  transition: transform .12s ease, box-shadow .12s ease, border-color .12s ease;
}
a.gw-kpi-card:hover {
  box-shadow: 0 4px 10px rgba(15, 23, 42, .06);
}

/* ── Universal KPI-Card-Dark-Mode-Pattern ──────────────────────────────
   Jede Kachel/KPI-Klasse, die im Light-Mode pro-Card einen Akzentfarbton via
   inline-style emittiert, kann im Dark-Mode durch Setzen von --card-color
   automatisch das Neon-Tinted-Pattern erhalten (transparenter Backdrop +
   farbiger Border + aufgehellter Akzent-Text). Konkret betroffen:
      .stat-card     — security/index.php
      .dr-kpi        — admin/redirects.php
      .gw-kpi-card   — Hilfsklasse für künftige Kacheln
   Pages müssen pro Kachel `style="--card-color:#<hex>"` setzen.
   Falls --card-color fehlt: neutraler Slate-Fallback statt knall-bunter Pastell. */
[data-theme="dark"] .stat-card,
[data-theme="dark"] .stat-grid a.stat-card,
[data-theme="dark"] .dr-kpi,
[data-theme="dark"] .gw-kpi-card {
  background:   color-mix(in srgb, var(--card-color, #94a3b8) 14%, transparent) !important;
  border-color: color-mix(in srgb, var(--card-color, #94a3b8) 32%, transparent) !important;
  color:        color-mix(in srgb, var(--card-color, #94a3b8) 60%, white) !important;
}
/* Alle Direkt-Children mit eigenem `color:` (Label/Wert/Sub) auf denselben Tint. */
[data-theme="dark"] .stat-card > *,
[data-theme="dark"] .stat-grid a.stat-card > *,
[data-theme="dark"] .dr-kpi > *,
[data-theme="dark"] .gw-kpi-card > * {
  color: color-mix(in srgb, var(--card-color, #94a3b8) 60%, white) !important;
}
[data-theme="dark"] .stat-card:hover,
[data-theme="dark"] .stat-grid a.stat-card:hover,
[data-theme="dark"] .dr-kpi--clickable:hover,
[data-theme="dark"] .gw-kpi-card:hover {
  background:   color-mix(in srgb, var(--card-color, #94a3b8) 22%, transparent) !important;
  border-color: color-mix(in srgb, var(--card-color, #94a3b8) 55%, transparent) !important;
  box-shadow:   0 4px 14px rgba(0,0,0,.35) !important;
}
[data-theme="dark"] .dr-kpi--clickable.dr-kpi--active {
  background:   color-mix(in srgb, var(--card-color, #94a3b8) 26%, transparent) !important;
  border-color: color-mix(in srgb, var(--card-color, #94a3b8) 65%, transparent) !important;
  box-shadow:   0 0 0 2px color-mix(in srgb, var(--card-color, #94a3b8) 50%, transparent) inset, 0 4px 14px rgba(0,0,0,.4) !important;
}
[data-theme="dark"] .tag-unassigned       { color: #fb923c !important; } /* orange-400 */

/* Bulk-Treatment aller Tag-Klassen: dark-tinted Backdrop via currentColor + 1px
   Border in derselben Farbe — kein Glow/Shadow, nur saubere Neon-Farbflächen. */
[data-theme="dark"] .tag-type-Master,
[data-theme="dark"] .tag-type-Slave,
[data-theme="dark"] .tag-type-Native,
[data-theme="dark"] .tag-type-primary,
[data-theme="dark"] .tag-type-secondary,
[data-theme="dark"] .tag-type-native,
[data-theme="dark"] .tag-type-other,
[data-theme="dark"] .tag-source-local,
[data-theme="dark"] .tag-source-upstream,
[data-theme="dark"] .tag-source-external,
[data-theme="dark"] .tag-status-active,
[data-theme="dark"] .tag-status-inactive,
[data-theme="dark"] .tag-dnssec,
[data-theme="dark"] .tag-approval,
[data-theme="dark"] .tag-tenant,
[data-theme="dark"] .tag-tenant-link,
[data-theme="dark"] .tag-unassigned,
[data-theme="dark"] .pkg-tag {
  background: color-mix(in srgb, currentColor 14%, transparent) !important;
  border: 1px solid color-mix(in srgb, currentColor 32%, transparent) !important;
  box-shadow: none !important;
  text-shadow: none !important;
}

/* Hover bei interaktiven Tags — leichte Verstärkung des Backdrops, kein Glow */
[data-theme="dark"] .tag-tenant-link:hover,
[data-theme="dark"] .tag-tenant:hover,
[data-theme="dark"] .tag-unassigned:hover {
  background: color-mix(in srgb, currentColor 24%, transparent) !important;
  border-color: color-mix(in srgb, currentColor 50%, transparent) !important;
}

/* Paket-Pille hell (packagePill(), Migration 0340): Farbe des Pakets ueber --pkg-color, Hintergrund und Rand als
   Tint derselben Farbe, Schrift abgedunkelt — lesbar auch bei Gelb/Lime. Dunkelmodus: Regeln darueber und darunter. */
.pkg-tag { --pkg-color:#64748b; display:inline-flex; align-items:center; gap:5px; font-family:var(--font-mono); font-size:11px;
           font-weight:700; padding:3px 9px; border-radius:5px; letter-spacing:.2px; line-height:1.4; white-space:nowrap;
           color:color-mix(in srgb, var(--pkg-color) 70%, black);
           background:color-mix(in srgb, var(--pkg-color) 13%, white);
           border:1px solid color-mix(in srgb, var(--pkg-color) 30%, white) }
.pkg-tag > svg { flex-shrink:0 }
.pkg-tag.is-inactive { opacity:.55; text-decoration:line-through }
/* Package-Tags (admin/tenants + dashboard): --pkg-color via inline-style →
   currentColor-basierter Backdrop wie oben, plus saturatere Neon-Schrift */
[data-theme="dark"] .pkg-tag {
  color: color-mix(in srgb, var(--pkg-color, currentColor) 55%, white) !important;   /* 30 % wirkte fast weiss (17.09.2026) */
}

/* ── Benutzer-Tags (Phase 1) ───────────────────────────────────────────
   .user-tag wird vom JS-Helper tagChipHtml() emittiert. Farbe kommt per
   inline --tag-color (#rrggbb, eine der 16 Palette-Werte).

   Light-Mode: voller Hintergrund in Tag-Farbe, Text-Kontrast per --tag-fg
   (server-side via tagContrastColor() oder client-seitig per YIQ).

   Dark-Mode: transparenter Backdrop + 1px farbiger Border + neon-Schrift —
   gleiche Logik wie .tag-tenant/.snap-mode-tag, damit User-Tags visuell zur
   Familie passen statt als Fremdkörper rauszuragen. */
.user-tag {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 2px 9px;
  border-radius: 6px;
  font-size: 11.5px;
  font-weight: 600;
  line-height: 1.4;
  letter-spacing: .15px;
  background: var(--tag-color, #e2e8f0);
  color: var(--tag-fg, #0f172a);
  /* Border gegen die Theme-Border gemischt (statt transparent): sehr helle Tag-Farben
     (Weiss) behalten so eine sichtbare Kontur auf hellen Karten. */
  border: 1px solid color-mix(in srgb, var(--tag-color, #94a3b8) 30%, var(--border));
  white-space: nowrap;
}
.user-tag svg { flex-shrink: 0 }

/* Beschriftung eines Chips bricht nie um — in engen Spalten kuerzt sie mit
   Auslassungszeichen (der ganze Text steht im title). */
.user-tag__lbl { white-space:nowrap; }
[data-theme="dark"] .user-tag {
  background: color-mix(in srgb, var(--tag-color, currentColor) 14%, transparent) !important;
  border: 1px solid color-mix(in srgb, var(--tag-color, currentColor) 32%, transparent) !important;
  /* Tag-Farbe als Text — Tailwind-500-er sind im Dark-Mode hell genug, aber wir
     mischen 25% Weiss rein für extra Lesbarkeit auf sehr dunklen Page-Bgs. */
  color: color-mix(in srgb, var(--tag-color, currentColor) 75%, white) !important;
  box-shadow: none !important;
}
.user-tag:hover {
  filter: brightness(.97);
}
[data-theme="dark"] .user-tag:hover {
  background: color-mix(in srgb, var(--tag-color, currentColor) 24%, transparent) !important;
  border-color:  color-mix(in srgb, var(--tag-color, currentColor) 50%, transparent) !important;
  filter: none;
}

/* Bulk-Tag-Picker — moderner Segmented-Control (statt 3 separater Buttons).
   Wird von gwUserTags.triStateRow() emittiert. */
.tri-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  border-radius: 8px;
  border: 1px solid var(--border);
  background: var(--surface);
  transition: border-color .15s ease, background-color .15s ease;
}
.tri-row:hover { border-color: var(--text-4); }
.tri-row__chip { flex-shrink: 0; display: inline-flex; align-items: center }
.bt-tag-desc {
  flex: 1; min-width: 0;
  font-size: 11.5px; color: var(--text-3);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.bt-tag-desc:empty, .tri-row > .bt-tag-desc + .tri-seg { /* nothing */ }
.tri-row > .tri-row__chip + .tri-seg { margin-left: auto } /* Segment rechts wenn keine description */

.tri-seg {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 0;
  padding: 3px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 999px;
  flex-shrink: 0;
}
.tri-seg button.bt-st {
  position: relative;
  z-index: 1;
  width: 32px;
  height: 26px;
  border: none;
  background: transparent;
  border-radius: 999px;
  cursor: pointer;
  color: var(--text-3);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  transition: color .18s ease, transform .12s ease;
}
.tri-seg button.bt-st svg { width: 14px; height: 14px; pointer-events: none }
.tri-seg button.bt-st:hover { color: var(--text-1) }
.tri-seg button.bt-st:active { transform: scale(.92) }
.tri-seg button.bt-st.is-on { color: #fff; font-weight: 600 }
/* Animierter "Pill"-Hintergrund, der zwischen den Positionen wandert. */
.tri-seg__pill {
  position: absolute;
  top: 3px;
  height: 26px;
  width: 32px;
  border-radius: 999px;
  z-index: 0;
  transition: transform .22s cubic-bezier(.4,.0,.2,1), background-color .18s ease, box-shadow .18s ease;
  background: var(--text-3);
  opacity: 0;
  pointer-events: none;
}
.tri-seg__pill--st-1 { transform: translateX(0);    background: #dc2626; box-shadow: 0 1px 4px rgba(220,38,38,.45); opacity: 1 }
.tri-seg__pill--st0  { transform: translateX(32px); background: var(--text-3); opacity: 1 }
.tri-seg__pill--st1  { transform: translateX(64px); background: #16a34a; box-shadow: 0 1px 4px rgba(22,163,74,.45); opacity: 1 }

[data-theme="dark"] .tri-row { background: var(--surface) }
[data-theme="dark"] .tri-seg { background: rgba(0,0,0,.25); border-color: var(--border) }
[data-theme="dark"] .tri-seg button.bt-st { color: var(--text-3) }
[data-theme="dark"] .tri-seg button.bt-st:hover { color: var(--text-1) }
[data-theme="dark"] .tri-seg__pill--st0 { background: #475569 }

/* Snapshot-Modus-Tags (snap-mode-tag) in /snapshots-Tabelle und Records-Tab —
   per Tag eigene Identitätsfarbe via --mode-color, dunkler Backdrop, neon-Schrift. */
[data-theme="dark"] .snap-mode-tag {
  background: color-mix(in srgb, var(--mode-color, currentColor) 14%, transparent) !important;
  /* Border aus der bereits aufgehellten Schriftfarbe (currentColor) ableiten, nicht aus
     der dunklen --mode-color: sonst blieb z.B. T-MACHINE (#3730a3) auf dunklem Grund
     unsichtbar, waehrend AUTO (#92400e) noch durchschimmerte. Jetzt sichtbarer Rahmen
     in der Eigenfarbe fuer alle Modi. */
  color: color-mix(in srgb, var(--mode-color, currentColor) 35%, white) !important;
  border: 1px solid color-mix(in srgb, currentColor 55%, transparent) !important;
  box-shadow: none !important;
  text-shadow: none !important;
}

/* Diff-Highlight im Snapshot-Detail: gelber tint im Light-Mode, im Dark dezenter
   amber-tint mit gut lesbarer Schrift. */
[data-theme="dark"] .snap-records tr.snap-row--diff td       { background: rgba(250,204,21,.10) !important; color: var(--text-1) !important; }
[data-theme="dark"] .snap-records tr.snap-row--diff:hover td { background: rgba(250,204,21,.18) !important; }

/* Hover-States mit hardcodierten Light-Backgrounds (Records-Editor) */
/* .zr-approval-toggle-Dark-Regeln entfernt (v4.55.13) — vollstaendig in
   records.css (laedt nach main.css), die !important-Dubletten hier kaperten
   den Hover (nur .08->.12, unsichtbar). */
[data-theme="dark"] .action-btn.action-btn--danger:hover { background: rgba(220,38,38,.15) !important; border-color: var(--err) !important; color: #fca5a5 !important; }
[data-theme="dark"] .tgt-picker-btn:hover                { background: rgba(0,152,239,.10) !important; }

/* Snapshot-Row-Diff Hover (Records-Tab → Snapshot-Vergleich) */
[data-theme="dark"] .snap-row--diff:hover { background: rgba(252,211,77,.12) !important; }

/* Zone-Templates-Card Hover (admin/zone_templates.php) */
[data-theme="dark"] .ttpl-card:hover { background: rgba(255,255,255,.04) !important; border-color: var(--gw) !important; }
[data-theme="dark"] .ttpl-rm:hover { background: rgba(220,38,38,.15) !important; color: #fca5a5 !important; }

/* Action-Wahl-Cards & Compare-Cards (Template-Anwenden-Konflikte "behalten/übernehmen").
   "Behalten" ist im Light-Mode slate (#f8fafc/#475569); diese Hex-Werte haben keine
   Dark-Variante → ohne Override leuchtete die angewählte Karte weiss. Slate-Tints für
   Hover + Auswahl (.is-on) inkl. Label/Radio. Die "übernehmen"-Karte nutzt var(--gw*) und
   ist bereits dark-safe. */
[data-theme="dark"] .at-cmp__card--keep:hover { border-color:#64748b !important; background: rgba(148,163,184,.10) !important; }
[data-theme="dark"] .at-cmp__card--keep.is-on { border-color:#94a3b8 !important; background: rgba(148,163,184,.16) !important; box-shadow:0 0 0 1px #94a3b8 inset !important; }
[data-theme="dark"] .at-cmp__card--keep.is-on .at-cmp__card-lbl { color:#e2e8f0 !important; }
[data-theme="dark"] .at-cmp__card--keep.is-on .at-cmp__card-radio { border-color:#94a3b8 !important; background:#94a3b8 !important; }
/* Typ-Pille (hellindigo) und „geändert"-Meta (#92400e dunkelamber, kontaktarm auf dunkel) */
[data-theme="dark"] .at-cmp__card-meta .changed { color:#fbbf24 !important; }

/* Changelog-Items im Records-Editor */
[data-theme="dark"] .cl-item:hover { border-color: var(--border-2) !important; }

/* Settings-Section-Hover */
[data-theme="dark"] .settings-section:hover { border-color: var(--border-2) !important; }

/* Migration: SOA-Type-Chip war hardcoded grau */
[data-theme="dark"] .mw-rec-type-SOA { background: rgba(255,255,255,.06) !important; color: var(--text-3) !important; }

/* Form-Input mit Validierungs-Fehler: roter Hintergrund + roter Border */
[data-theme="dark"] .inp.is-error,
[data-theme="dark"] input.is-error,
[data-theme="dark"] textarea.is-error,
[data-theme="dark"] select.is-error { background: rgba(220,38,38,.10) !important; border-color: var(--err) !important; }

/* ── Td-Tags (admin/tenant_detail.php) — Dark-Mode-Familie ─────────────
   Im Light-Mode haben die Varianten hartcodierte Tailwind-100-er Pastell-Bgs
   mit -700 Text — auf dunklem Page-Bg sieht das fremdkörperig aus. Im Dark-Mode
   uniform auf das App-Pattern: -400 Tailwind-Text + currentColor-Backdrop (14%)
   + currentColor-Border (32%). Analog .tag-tenant / .user-tag / .snap-mode-tag. */
[data-theme="dark"] .td-tag--slate  { color: var(--text-3) !important; }
[data-theme="dark"] .td-tag--blue   { color: #60a5fa !important; } /* blue-400 */
[data-theme="dark"] .td-tag--purple { color: #a78bfa !important; } /* violet-400 */
[data-theme="dark"] .td-tag--green  { color: #34d399 !important; } /* emerald-400 */
[data-theme="dark"] .td-tag--red    { color: #fca5a5 !important; } /* red-300 */
[data-theme="dark"] .td-tag--cyan   { color: #22d3ee !important; } /* cyan-400 */
[data-theme="dark"] .td-tag--amber  { color: #fbbf24 !important; } /* amber-400 */
[data-theme="dark"] .td-tag--gray   { color: #94a3b8 !important; } /* slate-400 */
[data-theme="dark"] .td-tag--blue,
[data-theme="dark"] .td-tag--purple,
[data-theme="dark"] .td-tag--green,
[data-theme="dark"] .td-tag--red,
[data-theme="dark"] .td-tag--cyan,
[data-theme="dark"] .td-tag--amber,
[data-theme="dark"] .td-tag--gray,
[data-theme="dark"] .td-tag--slate {
  background:   color-mix(in srgb, currentColor 14%, transparent) !important;
  border-color: color-mix(in srgb, currentColor 32%, transparent) !important;
}

/* ── Zone-Templates: .zt-tag--global/tenant/restr ──────────────────────
   Light-Mode-only definiert in templates/admin/zone_templates.php — Dark-Mode
   bekommt das gleiche currentColor-Pattern wie alle anderen Tag-Familien. */
[data-theme="dark"] .zt-tag--global { color: #60a5fa !important; } /* blue-400 */
[data-theme="dark"] .zt-tag--tenant { color: #34d399 !important; } /* emerald-400 */
[data-theme="dark"] .zt-tag--restr  { color: #fbbf24 !important; } /* amber-400 */
[data-theme="dark"] .zt-tag--global,
[data-theme="dark"] .zt-tag--tenant,
[data-theme="dark"] .zt-tag--restr {
  background:   color-mix(in srgb, currentColor 14%, transparent) !important;
  border-color: color-mix(in srgb, currentColor 32%, transparent) !important;
}

/* ── Tab-Counter-Pills in /admin/domain-redirects ──────────────────────
   .dr-tab-redir .ct / .dr-tab-certs .ct — Anzahl-Pille im Tab-Header.
   Light-Mode-only definiert in redirects.php; gleiches Dark-Mode-Pattern. */
[data-theme="dark"] .dr-tab-redir .ct { color: #60a5fa !important; }
[data-theme="dark"] .dr-tab-certs .ct { color: #34d399 !important; }
[data-theme="dark"] .dr-tab-redir .ct,
[data-theme="dark"] .dr-tab-certs .ct {
  background:   color-mix(in srgb, currentColor 14%, transparent) !important;
  border-color: color-mix(in srgb, currentColor 32%, transparent) !important;
}

/* Doc-Scope-Tags (api_keys/docs.php) — inline badges */
[data-theme="dark"] .doc-scope-tag { background: rgba(255,255,255,.06) !important; color: var(--text-2) !important; }

/* zd.css: ttl-tag (Records-Editor TTL-Filter) und Dialog-Icons */
[data-theme="dark"] .ttl-tag,
[data-theme="dark"] .ttl-tag.ttl-short,
[data-theme="dark"] .ttl-tag.ttl-medium,
[data-theme="dark"] .ttl-tag.ttl-long,
[data-theme="dark"] .ttl-tag.ttl-default { background: rgba(255,255,255,.06) !important; color: var(--text-2) !important; }
[data-theme="dark"] .zd-dlg-icon.info   { background: rgba(0,152,239,.15) !important; color: #93c5fd !important; }
[data-theme="dark"] .zd-dlg-icon.warn   { background: rgba(252,211,77,.12) !important; color: #fcd34d !important; }
[data-theme="dark"] .zd-dlg-icon.danger { background: rgba(220,38,38,.15) !important; color: #fca5a5 !important; }
[data-theme="dark"] .zd-dlg-icon.ok     { background: rgba(134,239,172,.12) !important; color: #86efac !important; }

/* Propagation-Page (templates/propagation/index.php): Status-Pills, Quick-Type-Chips, Stat-Tiles, Modal */
/* .prop-type-chip ist bewusst nicht hier — die Schnellauswahl-Chips tragen ihre
   kanonischen Record-Typ-Farben (.rr-<TYPE>, currentColor) auch im Dark-Mode.
   Eine neutrale Grau-Regel hier hätte (gleiche Spezifität + !important, aber
   spätere Quellzeile) die .rr-*-Farben überschrieben → alle Chips grau. Die
   Dark-Optik der Type-Chips kommt aus dem Inline-<style> der Seite (neutraler
   Backdrop + currentColor-Rand) plus den globalen .rr-*-Farben. */
[data-theme="dark"] .prop-filter      { background: var(--bg) !important; color: var(--text-3) !important; border-color: var(--border-2) !important; }
[data-theme="dark"] .prop-filter.is-on { background: rgba(0,152,239,.18) !important; color: #93c5fd !important; border-color: var(--gw) !important; }
[data-theme="dark"] .prop-filter-count { background: rgba(255,255,255,.08) !important; color: var(--text-3) !important; }
[data-theme="dark"] .prop-filter.is-on .prop-filter-count { background: var(--gw) !important; color: #fff !important; }
[data-theme="dark"] .prop-stat        { background: var(--surface) !important; border-color: var(--border) !important; }
/* Achtung: Die Dunkel-Varianten der Ergebnisliste (.prop-row, .prop-row-head,
   .prop-status-nxdomain/-empty) sind am 09.09.2026 nach assets/css/propagation.css
   gewandert — dorthin, wo das Bauteil steht. Vorher stand die helle Fassung in der
   einen und die dunkle in der anderen Datei; wer die Liste anfasst, muss beide
   finden. Die uebrigen .prop-*-Regeln hier betreffen nur die Seite selbst. */
[data-theme="dark"] .prop-modal       { background: var(--surface) !important; }
[data-theme="dark"] .prop-modal-head  { background: var(--bg) !important; border-color: var(--border) !important; }
[data-theme="dark"] .prop-modal-close:hover { background: rgba(255,255,255,.06) !important; color: var(--text-1) !important; }
[data-theme="dark"] .prop-record-card { background: var(--bg) !important; border-color: var(--border) !important; }
[data-theme="dark"] .prop-record-val  { background: var(--surface) !important; border-color: var(--border) !important; }
[data-theme="dark"] .prop-record-meta-item { background: var(--surface) !important; border-color: var(--border) !important; }
[data-theme="dark"] .prop-copy:hover  { background: rgba(255,255,255,.06) !important; }

/* Sonstige Inline-Fallbacks für Pastels die im Audit aufgetaucht sind aber keine
   :hover-State-Targets sind. */
[data-theme="dark"] [style*="background:#ffedd5"],
[data-theme="dark"] [style*="background: #ffedd5"] { background: rgba(252,211,77,.10) !important; color: #fcd34d !important; }
[data-theme="dark"] [style*="background:#fde68a"],
[data-theme="dark"] [style*="background: #fde68a"] { background: rgba(252,211,77,.12) !important; color: #fcd34d !important; }
[data-theme="dark"] [style*="background:#fef08a"],
[data-theme="dark"] [style*="background: #fef08a"] { background: rgba(253,224,71,.12) !important; color: #fde047 !important; }
[data-theme="dark"] [style*="background:#fff5f5"],
[data-theme="dark"] [style*="background: #fff5f5"] { background: rgba(220,38,38,.10) !important; color: var(--err-text) !important; }
[data-theme="dark"] [style*="background:#dcfce7"],
[data-theme="dark"] [style*="background: #dcfce7"] { background: rgba(134,239,172,.10) !important; color: var(--ok-text) !important; }
[data-theme="dark"] [style*="background:#fef2f2"],
[data-theme="dark"] [style*="background: #fef2f2"] { background: rgba(220,38,38,.10) !important; color: var(--err-text) !important; }
[data-theme="dark"] [style*="background:#dbeafe"],
[data-theme="dark"] [style*="background: #dbeafe"] { background: rgba(0,152,239,.12) !important; color: #93c5fd !important; }
[data-theme="dark"] [style*="background:#bfdbfe"],
[data-theme="dark"] [style*="background: #bfdbfe"] { background: rgba(0,152,239,.18) !important; color: #93c5fd !important; }
[data-theme="dark"] [style*="background:#bae6fd"],
[data-theme="dark"] [style*="background: #bae6fd"] { background: rgba(0,152,239,.18) !important; color: #93c5fd !important; }
[data-theme="dark"] [style*="background:#fafbfc"],
[data-theme="dark"] [style*="background: #fafbfc"] { background: var(--bg) !important; }
[data-theme="dark"] [style*="background:#f9fafb"],
[data-theme="dark"] [style*="background: #f9fafb"] { background: var(--bg) !important; }
[data-theme="dark"] [style*="background:#f5f7fa"],
[data-theme="dark"] [style*="background: #f5f7fa"] { background: var(--bg) !important; }
[data-theme="dark"] [style*="background:#fee2e2"],
[data-theme="dark"] [style*="background: #fee2e2"] { background: rgba(220,38,38,.10) !important; color: var(--err-text) !important; }

/* Weitere Pastel-Inline-Farben aus Dashboard-Widgets / Banner */
[data-theme="dark"] [style*="background:#fffbeb"],
[data-theme="dark"] [style*="background: #fffbeb"] { background: rgba(252,211,77,.10) !important; color: #fcd34d !important; }
[data-theme="dark"] [style*="background:#f0fdf4"],
[data-theme="dark"] [style*="background: #f0fdf4"] { background: rgba(134,239,172,.08) !important; color: var(--ok-text) !important; }
[data-theme="dark"] [style*="background:#e2e8f2"],
[data-theme="dark"] [style*="background: #e2e8f2"] { background: rgba(255,255,255,.06) !important; }
[data-theme="dark"] [style*="background:#a7f3d0"],
[data-theme="dark"] [style*="background: #a7f3d0"] { background: rgba(134,239,172,.12) !important; color: var(--ok-text) !important; }
[data-theme="dark"] [style*="background:#bbf7d0"],
[data-theme="dark"] [style*="background: #bbf7d0"] { background: rgba(134,239,172,.10) !important; color: var(--ok-text) !important; }
[data-theme="dark"] [style*="background:#fde047"],
[data-theme="dark"] [style*="background: #fde047"] { background: rgba(253,224,71,.15) !important; color: #fde047 !important; }

/* Border-Inline für die soeben hinzugefügten BG-Farben */
[data-theme="dark"] [style*="border:1px solid #a7f3d0"],
[data-theme="dark"] [style*="border: 1px solid #a7f3d0"] { border-color: var(--ok-bd) !important; }
[data-theme="dark"] [style*="border:1px solid #1e3a5c"],
[data-theme="dark"] [style*="border: 1px solid #1e3a5c"] { border-color: var(--border-2) !important; }
[data-theme="dark"] [style*="border-bottom:1px solid #fcd34d"],
[data-theme="dark"] [style*="border-bottom: 1px solid #fcd34d"] { border-bottom-color: var(--warn-bd) !important; }

/* Dashboard-Widget: Tile-Backgrounds für Modal-Hero-Icons (warn/danger) */
[data-theme="dark"] .modal-hero__ic--warn   { background: rgba(252,211,77,.12) !important; color: #fcd34d !important; }
[data-theme="dark"] .modal-hero__ic--danger { background: rgba(220,38,38,.15) !important; color: #fca5a5 !important; }
[data-theme="dark"] .modal-hero__ic--brand  { background: rgba(0,152,239,.12) !important; color: #93c5fd !important; }
[data-theme="dark"] .modal-hero__ic--ok     { background: rgba(134,239,172,.12) !important; color: #86efac !important; }
[data-theme="dark"] .modal-hero__ic--info   { background: rgba(0,152,239,.12) !important; color: #93c5fd !important; }

/* Sessions-Row Hover (Dashboard) */
[data-theme="dark"] .sess-row:hover { background: rgba(255,255,255,.04) !important; }

/* Dashboard Topbar / dunkle Banner mit hartcodiertem #0d1b2a (sind schon dunkel,
   aber Border #1e3a5c und Text #fff bleiben — passt Theme-Token weisser an) */
[data-theme="dark"] [style*="color:#fff"],
[data-theme="dark"] [style*="color: #fff"] { /* nichts anpassen — weiss auf dunklem BG OK */ }

/* Zone-Tag (zone-tag) — generisch, ohne Type-Suffix bekommt man oft hellen BG.
   Achtung: `color` nicht pauschal resetten, sonst überschreibt der !important hier
   die identitätsfarbenen .tag-type-primary/.tag-status-active/… Regeln weiter oben
   (gleiche Spezifität 0-1-1, aber später im Source). Nackt-Tags ohne Modifier
   bekommen ihre graue Schrift über die :not()-Regel direkt darunter. */
[data-theme="dark"] .zone-tag { background: rgba(255,255,255,.06) !important; border: 1px solid var(--border) !important; }
[data-theme="dark"] .zone-tag:not(.tag-source-local):not(.tag-source-upstream):not(.tag-source-external):not(.tag-type-primary):not(.tag-type-secondary):not(.tag-type-native):not(.tag-type-other):not(.tag-type-Master):not(.tag-type-Slave):not(.tag-type-Native):not(.tag-status-active):not(.tag-status-inactive):not(.tag-dnssec):not(.tag-approval):not(.tag-tenant):not(.tag-tenant-link):not(.tag-unassigned):not(.tag-sync-ok):not(.tag-sync-warn):not(.tag-sync-err) { color: var(--text-2) !important; }

/* …aber Source-/Type-/Status-Modifier sollen ihre eigene Identitätsfarbe behalten.
   Höhere Spezifität (.zone-tag.tag-X = 2 Klassen) sticht den generischen Reset oben.
   Background+Border kommen aus color-mix(currentColor) — Tag wirkt damit getintet
   in der jeweiligen Identitätsfarbe (gleiche Sprache wie .user-tag/.rr-chip). */
[data-theme="dark"] .zone-tag.tag-source-local,
[data-theme="dark"] .zone-tag.tag-source-upstream,
[data-theme="dark"] .zone-tag.tag-source-external,
[data-theme="dark"] .zone-tag.tag-type-primary,
[data-theme="dark"] .zone-tag.tag-type-secondary,
[data-theme="dark"] .zone-tag.tag-type-native,
[data-theme="dark"] .zone-tag.tag-type-other,
[data-theme="dark"] .zone-tag.tag-status-active,
[data-theme="dark"] .zone-tag.tag-status-inactive,
[data-theme="dark"] .zone-tag.tag-dnssec,
[data-theme="dark"] .zone-tag.tag-approval,
[data-theme="dark"] .zone-tag.tag-tenant,
[data-theme="dark"] .zone-tag.tag-tenant-link,
[data-theme="dark"] .zone-tag.tag-unassigned,
[data-theme="dark"] .zone-tag.tag-sync-ok,
[data-theme="dark"] .zone-tag.tag-sync-warn,
[data-theme="dark"] .zone-tag.tag-sync-err {
  background: color-mix(in srgb, currentColor 14%, transparent) !important;
  border: 1px solid color-mix(in srgb, currentColor 32%, transparent) !important;
}
/* Tenant-Pille (zone-tag-Variante im Zoneneditor) braucht zusätzlich den
   per-Tenant-Hue als color — `[data-theme="dark"] .zone-tag` weiter unten
   setzt sonst color:var(--text-2) (grau) und das schlägt durch Reihenfolge
   den .tag-tenant-link color-mix. --tag-color kommt inline aus tenantPill()
   bzw. dem records.php-Render. */
[data-theme="dark"] .zone-tag.tag-tenant-link,
[data-theme="dark"] .zone-tag.tag-tenant {
  color: color-mix(in srgb, var(--tag-color, #a78bfa) 60%, white) !important;
}

/* JS-rendered actColor fallback (#e2e8f0 used as default) */
[data-theme="dark"] [style*="background:#e2e8f0"],
[data-theme="dark"] [style*="background: #e2e8f0"] { background: rgba(255,255,255,.06) !important; color: var(--text-2) !important; }
[data-theme="dark"] [style*="background:#cbd5e1"],
[data-theme="dark"] [style*="background: #cbd5e1"] { background: rgba(255,255,255,.08) !important; color: var(--text-2) !important; }

/* User-Agent-Badge in tenant_detail / api_keys (Span mit f1f5f9 + 64748b) */
[data-theme="dark"] [style*="color:#64748b"],
[data-theme="dark"] [style*="color: #64748b"] { color: var(--text-3) !important; }

/* Filter für rgba(255,255,255,.7) und .22 Inline (Approval-Toggle Code-Tag, Modal-eligibility) */
[data-theme="dark"] [style*="background:rgba(255,255,255,.7)"],
[data-theme="dark"] [style*="background: rgba(255,255,255,.7)"] { background: rgba(255,255,255,.08) !important; }

/* Zone-Health bar segments mit Hardcoded-Grau für „Ungeprüft" — bleibt stehen, Grau passt auch dunkel.
   .zh-bar braucht keinen Override weil sie Inline-styled ist mit semantischen Status-Farben. */
/* Card / Input-Hintergrund sind variabel (var(--surface)) — Inputs brauchen aber etwas
   dunkleren Hintergrund als Surface, sonst verschwimmen sie mit der Card. */
[data-theme="dark"] .inp,
[data-theme="dark"] input.inp,
[data-theme="dark"] textarea.inp,
[data-theme="dark"] select.inp {
  background: #0f172a;
  color: var(--text-1);
  border-color: var(--border-2);
}
[data-theme="dark"] .inp:focus { border-color: var(--gw); box-shadow: 0 0 0 3px rgba(0,152,239,.18); }
[data-theme="dark"] .inp::placeholder { color: var(--text-4); }

/* Mobile-Responsive: schmale Tabellen. Auf <768px werden Tabellen zu Card-Stacks
   (eine Zeile = ein Card mit Label/Value-Paaren). Erfordert in der Tabelle data-label
   pro <td> oder greift fallback per :nth-of-type → th-Inhalt mappen. */
@media (max-width: 768px) {
  .zone-table thead { display: none; }
  .zone-table, .zone-table tbody, .zone-table tr, .zone-table td { display: block; width: 100%; }
  .zone-table tr {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 8px;
    margin-bottom: 8px;
    padding: 8px 10px;
  }
  .zone-table td {
    padding: 4px 0;
    border: 0;
    display: flex;
    justify-content: space-between;
    gap: 10px;
    align-items: center;
    font-size: 13px;
  }
  .zone-table td::before {
    content: attr(data-label);
    font-size: 10.5px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .4px;
    color: var(--text-4);
    flex-shrink: 0;
  }
  .zone-table td:first-child::before { content: ''; }
  .modal { max-width: 96vw !important; max-height: 92vh !important; }
  .page-header { flex-direction: column; align-items: stretch !important; gap: 10px; }
  .page-header h1, .page-title { font-size: 18px; }
  /* Sidebar wird auf Mobile zur Slide-In-Panel: ausgeblendet bis Burger-Toggle */
  .sidebar { position: fixed; left: 0; top: 0; bottom: 0; transform: translateX(-100%); transition: transform .25s ease; z-index: 9000; box-shadow: 4px 0 20px rgba(0,0,0,.4) }
  .sidebar.is-mobile-open { transform: translateX(0) }
  /* Backdrop für offene Sidebar */
  .sidebar.is-mobile-open::after { content: ''; position: fixed; left: var(--sidebar-w-open); top: 0; right: 0; bottom: 0; background: rgba(0,0,0,.5); }
  body { padding-left: 0 !important; }
  .topbar { padding-left: 12px; padding-right: 12px; }
  .topbar-title { font-size: 14px; }
  /* Topbar-Search: auf Mobile nur Icon + Click triggert Ctrl+K-Modal */
  .topbar-search { max-width: 44px !important; padding-right: 10px !important }
  .topbar-search input { display: none }
  .topbar-search-kbd { display: none }
  /* Records-Liste & andere generische Tabellen: Card-Stack */
  .records-table thead, table.records thead { display: none }
  .records-table, table.records,
  .records-table tbody, table.records tbody,
  .records-table tr, table.records tr,
  .records-table td, table.records td { display: block; width: 100% }
  .records-table tr, table.records tr {
    background: var(--surface); border: 1px solid var(--border);
    border-radius: 8px; margin-bottom: 8px; padding: 8px 10px;
  }
  .records-table td, table.records td {
    padding: 4px 0; border: 0; display: flex; justify-content: space-between;
    gap: 10px; align-items: center; font-size: 12.5px;
  }
  .records-table td::before, table.records td::before {
    content: attr(data-label);
    font-size: 10.5px; font-weight: 700; text-transform: uppercase;
    letter-spacing: .4px; color: var(--text-4); flex-shrink: 0;
  }
  /* Security-Toolbar: Filter untereinander statt nebeneinander */
  .sec-filter-card .filter-row { flex-direction: column !important; align-items: stretch !important; gap: 8px !important }
  .sec-filter-card .filter-row > * { width: 100% !important; max-width: none !important }
  /* Tab-Bars: horizontal scrollbar statt umbruch */
  .sec-tabs, .tabs, .tab-list { overflow-x: auto; flex-wrap: nowrap !important; white-space: nowrap }
  .sec-tabs::-webkit-scrollbar, .tabs::-webkit-scrollbar { height: 0 }
  /* Mobile-Burger-Menü zum Sidebar-Toggle */
  .topbar-burger { display: inline-flex !important }
}
/* Tablets (769–1024 px): die Leiste klappt sich selbst ein — base.php setzt dort .mini (gwSbAuto), damit dieselbe
   Darstellung gilt wie beim Einklappen von Hand. Der frühere Nachbau hier (56 px, Beschriftung durchsichtig) schnitt
   seit dem Umbau der Leiste die Symbole an. */

body {
  font-family: var(--font);
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--text-1);
  background: var(--bg);
  min-height: 100vh;
}

/* ── App Shell ──────────────────────────────────────────── */
.app-shell   { display: flex; height: 100vh; overflow: hidden; }
.app-content { flex: 1; display: flex; flex-direction: column; overflow: hidden; }

/* ── Sidebar ────────────────────────────────────────────── */
.sidebar {
  /* Sidebar-Farbtokens — Light-Default = helle Nav (passt zum uebrigen Light-UI),
     dunkles Navy nur noch im Dark-Mode (Override unten). Kinder nutzen diese Tokens
     statt hartcodiertem Weiss, damit beide Modi sauber funktionieren. */
  --sidebar-bg: #ffffff;
  --sidebar-border: var(--border);
  --sidebar-fg: rgba(15,23,42,.80);
  --sidebar-fg-strong: #0f172a;
  --sidebar-fg-muted: rgba(15,23,42,.5);
  --sidebar-hover: rgba(15,23,42,.06);
  --sidebar-divider: rgba(15,23,42,.08);
  --sidebar-scroll: rgba(15,23,42,.22);
  --sidebar-scroll-hover: rgba(15,23,42,.3);
  width: var(--sidebar-w-open);   /* default: offen */
  background: var(--sidebar-bg, #0d1b2a);
  display: flex;
  flex-direction: column;
  flex-shrink: 0;
  transition: width .22s ease;
  overflow: hidden;
  position: relative;
  z-index: 100;
}
/* Trennlinie zum Inhalt erst unterhalb der Kopfleisten-Hoehe, oben neben Logo und Titel keine Linie:
   neben Logo und Seitentitel stehen Leiste und Kopfleiste als eine Flaeche. Als ::after statt border-right, weil die
   Leiste overflow:hidden hat und ein Rand sich nicht teilweise ausblenden laesst. */
/* Nicht bei .is-mobile-open: dort ist ::after der abgedunkelte Hintergrund neben der offenen Leiste. */
.sidebar:not(.is-mobile-open)::after {
  content: ""; position: absolute; right: 0; top: var(--topbar-h, 52px); bottom: 0; width: 1px;
  background: var(--sidebar-border, transparent); pointer-events: none; z-index: 20;
}
/* Dark-Mode: Sidebar an Galaxyweb-Dark-Tokens angleichen, sonst
   wirkt das cyan-tinted #0d1b2a neben dem slate-#0f172a-Body „off". */
[data-theme="dark"] .sidebar {
  --sidebar-bg: #0a1120;        /* leicht dunkler als --bg, kontrastiert sauber */
  --sidebar-border: var(--border);
  /* Dark-Mode behaelt den bisherigen Look: helle Schrift/Tints auf Navy. */
  --sidebar-fg: rgba(255,255,255,.78);
  --sidebar-fg-strong: #ffffff;
  --sidebar-fg-muted: rgba(255,255,255,.55);
  --sidebar-hover: rgba(255,255,255,.08);
  --sidebar-divider: rgba(255,255,255,.06);
  --sidebar-scroll: rgba(255,255,255,.22);
  --sidebar-scroll-hover: rgba(255,255,255,.28);
}
.sidebar.mini {
  width: var(--sidebar-w);        /* minimiert: icons only */
}
/* Schmale Fenster (< 769 px): die Leiste schwebt über dem Inhalt und ist zu, bis der Burger sie öffnet. Steht hier, nach
   der Grundregel: im Media-Block weiter oben überschrieb `.sidebar { position: relative }` das `fixed`, die Leiste wurde
   weggeschoben und liess ihren Platz leer stehen. */
@media (max-width: 768px) {
  .sidebar, .sidebar.mini { position: fixed; z-index: 9000; width: var(--sidebar-w-open); }
}

/* Logo */
.sidebar-logo {
  height: var(--topbar-h);
  display: flex;
  align-items: center;
  padding: 0 14px;
  flex-shrink: 0;
  white-space: nowrap;
  overflow: hidden;
}
.sidebar-logo-icon {
  width: 28px; height: 28px; flex-shrink: 0;
}
.sidebar-logo-text {
  margin-left: 11px;
  font-size: 13.5px; font-weight: 700;
  color: var(--sidebar-fg-strong); letter-spacing: -.3px;
  opacity: 0;
  transition: opacity .15s .05s;
}
.sidebar-logo-text span { color: var(--gw); }
.sidebar:not(.mini) .sidebar-logo-text { opacity: 1; }

/* Nav */
.sidebar-nav {
  flex: 1;
  min-height: 0;   /* Flex-Spalten-Kind muss schrumpfen duerfen, sonst waechst es
                      ueber den Sichtbereich (Inhalt unten abgeschnitten) statt zu scrollen */
  /* overflow-y:auto liess bei niedrigem Fenster die fette native System-
     Scrollbar (v.a. Firefox/Win) erscheinen → Menue wirkte „zusammengedrueckt".
     Stattdessen: schlanke, dezente Overlay-Scrollbar (siehe unten) + weicher
     Rand-Abblend-Verlauf, damit Scrollbarkeit sichtbar bleibt ohne Platz zu fressen. */
  overflow-y: auto;
  overscroll-behavior: contain;
  --nav-pad: 8px;   /* die Scroll-Hinweise gleichen genau diesen Abstand aus */
  padding: var(--nav-pad) 0;
  /* Eigene, dauerhaft reservierte Scrollbar-Spur: der Balken laeuft nie ueber
     die Menuepunkte → aktives Highlight bleibt eine durchgehende, saubere Pille
     und es gibt keinen Layout-Sprung, wenn die Scrollbar auftaucht/verschwindet. */
  scrollbar-gutter: stable both-edges;
  /* Firefox: schmale Scrollbar, im Ruhezustand unsichtbar (transparent),
     blendet erst beim Hovern ueber die Sidebar ein (siehe .sidebar:hover unten) */
  scrollbar-width: thin;
  scrollbar-color: transparent transparent;
  transition: scrollbar-color .25s ease;
}
/* Scroll-Hinweise oben/unten: erscheinen nur, wenn in die Richtung noch Menuepunkte
   ausserhalb des Sichtbereichs liegen (app.js togglet .is-scroll-top/.is-scroll-bot).
   Vorher sass der Pfeil nicht ganz am Rand. GEMESSEN: der Hinweis klebte 8 px vor
   dem Rand — sticky haelt das padding der Nav ein — und ein runder, blauer Schleier lag
   als Wolke ueber dem letzten Menuepunkt. Jetzt:
     · Versatz = --nav-pad, der Hinweis sitzt exakt am Rand; die Margins gleichen Hoehe
       und Versatz aus, die Menuepunkte ruecken keinen Pixel;
     · die Menuepunkte blenden zum Rand hin in die Sidebar-Farbe aus (::before);
     · am Rand eine feine Leuchtlinie in der Markenfarbe (::after);
     · der Pfeil sitzt als kleine leuchtende Kapsel buendig an dieser Linie. */
.sidebar-nav-hint {
  --hint-h: 34px;
  position: sticky;
  z-index: 5;
  height: var(--hint-h);
  pointer-events: none;
  opacity: 0;
  transition: opacity .25s ease;
  color: var(--gw);
}
.sidebar-nav-hint--top {
  top: calc(-1 * var(--nav-pad));
  margin-top: calc(-1 * var(--nav-pad));
  margin-bottom: calc(var(--nav-pad) - var(--hint-h));
}
.sidebar-nav-hint--bot {
  bottom: calc(-1 * var(--nav-pad));
  margin-bottom: calc(-1 * var(--nav-pad));
  margin-top: calc(var(--nav-pad) - var(--hint-h));
}
.sidebar-nav-hint::before {
  content: ""; position: absolute; inset: 0;
}
.sidebar-nav-hint--top::before { background: linear-gradient(to top, transparent, var(--sidebar-bg) 82%); }
.sidebar-nav-hint--bot::before { background: linear-gradient(to bottom, transparent, var(--sidebar-bg) 82%); }
.sidebar-nav-hint::after {
  content: ""; position: absolute; left: 10px; right: 10px; height: 1px;
  background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--gw) 80%, transparent) 50%, transparent);
  box-shadow: 0 0 8px color-mix(in srgb, var(--gw) 55%, transparent);
}
.sidebar-nav-hint--top::after { top: 0; }
.sidebar-nav-hint--bot::after { bottom: 0; }
.sidebar-nav-hint svg {
  position: absolute; left: 50%; z-index: 1;
  width: 26px; height: 14px; padding: 2px 7px; box-sizing: border-box;
  transform: translateX(-50%);
  border-radius: 999px;
  background: var(--sidebar-bg);
  border: 1px solid color-mix(in srgb, var(--gw) 60%, transparent);
  box-shadow: 0 0 10px -2px color-mix(in srgb, var(--gw) 65%, transparent);
  stroke-width: 3;
}
.sidebar-nav-hint--top svg { top: 0; }
.sidebar-nav-hint--bot svg { bottom: 0; }
.sidebar-nav.is-scroll-top .sidebar-nav-hint--top { opacity: 1; }
.sidebar-nav.is-scroll-bot .sidebar-nav-hint--bot { opacity: 1; }
/* Dezentes Pulsieren des Leuchtrands — «es geht weiter», ohne zu zappeln */
@media (prefers-reduced-motion: no-preference) {
  .sidebar-nav.is-scroll-bot .sidebar-nav-hint--bot svg,
  .sidebar-nav.is-scroll-top .sidebar-nav-hint--top svg { animation: navHintGlow 2.4s ease-in-out infinite; }
}
@keyframes navHintGlow {
  0%, 100% { box-shadow: 0 0 6px -2px color-mix(in srgb, var(--gw) 45%, transparent); }
  50%      { box-shadow: 0 0 12px 0 color-mix(in srgb, var(--gw) 75%, transparent); }
}
/* WebKit/Blink (Chrome/Safari/Edge): schwebende Overlay-Scrollbar im macOS-Stil.
   Im Ruhezustand unsichtbar, blendet beim Hovern ueber die Sidebar weich ein.
   Der 2px-transparente Rand + background-clip laesst den Thumb „schweben". */
.sidebar-nav::-webkit-scrollbar { width: 6px; }   /* vorher 10 px, schmaler wirkt ruhiger */
.sidebar-nav::-webkit-scrollbar-track { background: transparent; }
.sidebar-nav::-webkit-scrollbar-thumb {
  background-color: transparent;
  border: 1px solid transparent;
  border-radius: 6px;
  background-clip: padding-box;
  transition: background-color .25s ease;
}
/* Einblenden, sobald die Sidebar (oder die Nav selbst) gehovert wird */
.sidebar:hover .sidebar-nav::-webkit-scrollbar-thumb,
.sidebar-nav:hover::-webkit-scrollbar-thumb { background-color: var(--sidebar-scroll); }
/* „Direkt auf dem Thumb heller"-Hover (.sidebar-nav::-webkit-scrollbar-thumb:
   hover/:active) wird per JS nur in Chromium injiziert (zd.js, gwInjectWebkitScroll)
   — Firefox kennt ::-webkit-scrollbar nicht und würde den Selektor beim Parsen
   als ungültig loggen (@supports unterdrückt das nicht). */
/* Firefox-Pendant: Scrollbar-Farbe beim Hovern einblenden */
.sidebar:hover .sidebar-nav,
.sidebar-nav:hover { scrollbar-color: var(--sidebar-scroll-hover) transparent; }
/* Im Mini-Modus (nur Icons): keine reservierte Spur und keine sichtbare
   Scrollbar. Sonst frisst der Balken bei niedrigem Fenster Inhaltsbreite weg →
   die aktive Pille schrumpft und das fixe 44px-Icon wird rechts abgeschnitten.
   Volle 56px bleiben erhalten, Pille sauber zentriert. Scrollen per Rad bleibt.
   Der richtungsabhaengige Abblend-Verlauf (oben/unten) bleibt aktiv und ist hier
   das einzige Signal, dass es noch weitergeht. */
.sidebar.mini .sidebar-nav {
  scrollbar-gutter: auto;
  scrollbar-width: none;            /* Firefox */
}
.sidebar.mini .sidebar-nav::-webkit-scrollbar { width: 0; }
.nav-section-label {
  /* Gruppen als klare Unterteilung: feine Trennlinie über jeder Gruppe, mehr Luft davor, Titel 10 px statt 9 px.
     Keine Effekte. Die Linie ist der Rand des Elements; eingeklappt wird nur die Schrift unsichtbar (color), die
     Linie bleibt als Gruppentrenner stehen — opacity hätte beides ausgeblendet. */
  font-size: 10px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .9px;
  color: transparent;
  margin: 8px 12px 0;
  padding: 12px 6px 5px;
  border-top: 1px solid var(--sidebar-border);
  white-space: nowrap;
  overflow: hidden;
  transition: color .15s;
}
.sidebar:not(.mini) .nav-section-label { color: var(--sidebar-fg-muted); }
/* Eingeklappt: nur die Linie als Trenner, ohne den Leerraum der unsichtbaren Schrift. */
.sidebar.mini .nav-section-label { font-size: 0; padding: 0; margin: 8px 12px; }

.nav-item {
  display: flex;
  align-items: center;
  height: 40px;
  padding: 0;
  cursor: pointer;
  /* Default-Lesbarkeit erhöht: vorher .45 (zu blass), jetzt .78 — Icons + Label
     sind klar lesbar, ohne die aktive Auswahl optisch zu erdrücken. */
  color: var(--sidebar-fg);
  transition: color .12s, background .12s;
  position: relative;
  white-space: nowrap;
  overflow: hidden;
  margin: 1px 6px;
  border-radius: var(--r-sm);
  /* Icons centered in collapsed 56px - 12px margin each side = 32px */
  justify-content: flex-start;
}
.nav-item:hover {
  /* Beim Darüberfahren wie der aktive Eintrag, nur schwächer: Fläche leicht in Hausfarbe getönt
     (aktiv .22, hier .08), Symbol in Hausfarbe. Keine Effekte. */
  background: color-mix(in srgb, var(--gw) 8%, transparent);
  color: var(--sidebar-fg-strong);
}
.nav-item:hover .nav-item-icon { color: var(--gw); }
.nav-item-icon { transition: color .12s; }
.nav-item.active {
  background: rgba(0,152,239,.22);
  color: var(--gw);
}
.nav-item-icon {
  width: 44px; height: 40px;
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
}
.nav-item-icon svg { width: 16px; height: 16px; }
.nav-item-label {
  margin-left: 0;
  font-size: 12.5px; font-weight: 500;
  opacity: 0;
  transition: opacity .15s .05s;
  flex: 1;
  /* Lange Namen (z.B. Security-Cockpit) kuerzen statt Auge/Griff bzw. Zaehler nach rechts zu schieben (18.09.2026). */
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.sidebar:not(.mini) .nav-item-label { opacity: 1; }

.nav-badge {
  margin-left: auto; flex-shrink: 0;
  background: var(--gw);
  color: #fff;
  font-size: 9.5px; font-weight: 700;
  padding: 1px 5px;
  border-radius: 10px;
  opacity: 0;
  transition: opacity .15s .05s;
}
.nav-badge.warn { background: var(--warn); }
.sidebar:not(.mini) .nav-badge { opacity: 1; }
/* Live-Zähler (NavController::counts): rot = kaputt, orange = Warnung, neutral = Hinweis.
   Eingeklappt ein Punkt oben rechts am Symbol statt der Zahl. */
.nav-badge { margin-right: 10px; min-width: 18px; text-align: center; font-variant-numeric: tabular-nums; line-height: 15px; }
.nav-badge.is-err   { background: #dc2626; color: #fff; }
.nav-badge.is-warn  { background: #f59e0b; color: #1f2937; }
/* Problem-Zaehler mit Ziel (19.09.2026): Klick auf die Zahl oeffnet genau diese Eintraege. Beim Ueberfahren ein Ring,
   damit man sieht, dass die Zahl ein eigenes Ziel hat. */
.nav-badge.is-link { cursor: pointer; }
.nav-badge.is-link:hover { box-shadow: 0 0 0 2px var(--sidebar-bg), 0 0 0 3.5px var(--gw); }
.nav-badge.is-muted { background: color-mix(in srgb, var(--sidebar-fg) 12%, transparent); color: var(--sidebar-fg-muted); }
/* Blau = läuft gerade (z.B. Auftrag beim Registrar), kein Problem */
.nav-badge.is-info  { background: var(--gw); color: #fff; }
/* «Live» statt Zahl (Propagation fragt auf Knopfdruck live bei öffentlichen Resolvern), ruhig, ohne Animation. */
.nav-badge.is-live  { background: color-mix(in srgb, #16a34a 14%, transparent); color: #15803d; text-transform: uppercase; letter-spacing: .4px; }
[data-theme="dark"] .nav-badge.is-live { color: #4ade80; }
/* Trend-Pfeil in der Pille: grau, erst ab 10 % Änderung; die Prozente stehen im Tooltip. */
.nav-trend { font-size: 9px; margin-right: 2px; opacity: .75; }
.sidebar.mini .nav-badge.is-live { display: none; }
.sidebar.mini .nav-badge { opacity: 1; position: absolute; top: 9px; left: 26px; min-width: 0; width: 7px; height: 7px; padding: 0; margin: 0; font-size: 0; border-radius: 50%; }
.sidebar.mini .nav-badge.is-muted { display: none; }
/* Marke «Neu» (18.09.2026): Hausblau, vor dem Zaehler; eingeklappt ein blauer Punkt am Symbol. */
.nav-new { flex: none; margin-right: 6px; padding: 1px 6px; border-radius: 10px; font-size: 9.5px; font-weight: 700; line-height: 15px;
  letter-spacing: .2px; color: var(--gw); background: color-mix(in srgb, var(--gw) 14%, transparent); white-space: nowrap; }
.nav-new[hidden] { display: none; }
/* «Neu»-Punkt (19.09.2026): Eintrag mit einem Kapitel in der aktuellen Ausgabe von «Was ist neu», bis er einmal geoeffnet
   wird. Ruhiger als die Marke «Neu»: nur ein Punkt in Hausblau vor dem Zaehler; eingeklappt an derselben Stelle wie dort. */
.nav-fresh { flex: none; width: 7px; height: 7px; margin-right: 7px; border-radius: 50%; background: var(--gw); }
.sidebar.mini .nav-fresh { position: absolute; top: 9px; left: 26px; margin: 0; box-shadow: 0 0 0 2px var(--sidebar-bg); }
@media (min-width: 769px) and (max-width: 1024px) {
  .sidebar:not(.mini) .nav-fresh { position: absolute; top: 9px; left: 26px; margin: 0; box-shadow: 0 0 0 2px var(--sidebar-bg); }
}
.sidebar.mini .nav-new:not([hidden]) { position: absolute; top: 9px; left: 26px; width: 7px; height: 7px; padding: 0; margin: 0;
  font-size: 0; border-radius: 50%; background: var(--gw); box-shadow: 0 0 0 2px var(--sidebar-bg); }
@media (min-width: 769px) and (max-width: 1024px) {
  .sidebar:not(.mini) .nav-new:not([hidden]) { position: absolute; top: 9px; left: 26px; width: 7px; height: 7px; padding: 0; margin: 0;
    font-size: 0; border-radius: 50%; background: var(--gw); box-shadow: 0 0 0 2px var(--sidebar-bg); }
}
/* Aktiver Eintrag: schmale Akzentleiste links; Titel der Gruppe, in der man ist, in Hausfarbe. */
.nav-item.active::before { content: ''; position: absolute; left: 0; top: 9px; bottom: 9px; width: 3px; border-radius: 3px; background: var(--gw); }
.sidebar:not(.mini) .nav-section-label.is-current { color: var(--gw); }
/* Einklappbare Gruppen: Überschrift als Schalter mit Pfeil. Zustand im Cookie gw_nav_collapsed,
   der Server rendert zugeklappte Einträge gleich mit .is-grp-hidden (kein Aufblitzen). Eingeklappte Leiste und
   Tablet-Breite zeigen immer alle Einträge — dort gibt es keine Überschrift zum Anklicken. */
.nav-section-label[data-nav-group-key] { display: flex; align-items: center; gap: 6px; cursor: pointer; user-select: none; }
.sidebar:not(.mini) .nav-section-label[data-nav-group-key]:hover { color: var(--sidebar-fg); }
.nav-section-label[data-nav-group-key]:focus-visible { outline: 2px solid var(--gw); outline-offset: 2px; border-radius: 4px; }
.nav-section-chev { width: 10px; height: 10px; margin-left: auto; flex-shrink: 0; transition: transform .15s; }
.nav-section-label.is-collapsed .nav-section-chev { transform: rotate(-90deg); }
.nav-section-dot { width: 6px; height: 6px; border-radius: 50%; flex-shrink: 0; }
.nav-section-dot.is-err  { background: #dc2626; }
.nav-section-dot.is-warn { background: #f59e0b; }
.nav-item.is-grp-hidden { display: none; }
.sidebar.mini .nav-item.is-grp-hidden { display: flex; }
.sidebar.mini .nav-section-chev, .sidebar.mini .nav-section-dot { display: none; }

/* Tooltip when collapsed */
.nav-item[title]:not(:hover)::after { display: none; }

/* Sidebar footer */
.sidebar-footer {
  padding: 10px 6px;
  border-top: 1px solid var(--sidebar-divider);
  flex-shrink: 0;
}
.sidebar-user {
  display: flex;
  align-items: center;
  height: 40px;
  padding: 0 8px;
  border-radius: var(--r-sm);
  cursor: pointer;
  transition: background .12s;
  overflow: hidden;
  white-space: nowrap;
}
.sidebar-user:hover { background: var(--sidebar-hover); }
.sidebar-avatar {
  width: 28px; height: 28px; border-radius: 8px;
  background: var(--gw); flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  font-size: 11px; font-weight: 700; color: #fff;
}
/* Topbar-rechts: alle Icon-Controls einheitlich & kompakt (randlos, 30×30, 16px-Icon) —
   Theme/Benachrichtigung/Hilfe/Info + Abmelden gleich; Avatar gleiche Box, gefüllt. */
.topbar-right .topbar-notif,
.topbar-right .sidebar-avatar { width: 30px; height: 30px; }
.topbar-right .sidebar-avatar { border-radius: var(--r); font-size: 11px; }
.topbar-right .btn-icon { width: 30px; height: 30px; border: none; background: transparent; color: var(--text-3); border-radius: var(--r); }
.topbar-right .btn-icon:hover { background: var(--bg); border-color: transparent; color: var(--text-1); }
.topbar-right .topbar-notif svg,
.topbar-right .topbar-theme svg,
.topbar-right .btn-icon svg { width: 16px; height: 16px; }
.sidebar-user-info {
  margin-left: 10px;
  opacity: 0;
  transition: opacity .15s .05s;
}
.sidebar:not(.mini) .sidebar-user-info,
.sidebar:not(.mini) .sidebar-user-info { opacity: 1; }
.sidebar-user-name { font-size: 12px; color: var(--sidebar-fg); font-weight: 500; }
/* Gruppentitel bleiben beim Scrollen der Leiste oben stehen, bis der naechste sie ueberdeckt.
   Gleicher Versatz wie die Scroll-Hinweise (Inhaltskante der .sidebar-nav), unter ihnen (z 5), deckender Hintergrund
   auch seitlich (Titel hat 12 px Rand). Nicht in der schmalen Leiste und nicht im Bearbeiten-Modus. */
@media (min-width: 1025px) {
  .sidebar:not(.mini):not(.is-editing) .nav-section-label {
    position: sticky; top: calc(-1 * var(--nav-pad, 0px)); z-index: 4;
    background: var(--sidebar-bg); box-shadow: -12px 0 0 var(--sidebar-bg), 12px 0 0 var(--sidebar-bg);
  }
}
@media (max-width: 768px) {
  .sidebar.is-mobile-open:not(.is-editing) .nav-section-label {
    position: sticky; top: calc(-1 * var(--nav-pad, 0px)); z-index: 4;
    background: var(--sidebar-bg); box-shadow: -12px 0 0 var(--sidebar-bg), 12px 0 0 var(--sidebar-bg);
  }
}
/* Leiste anpassen: Eintraege ausblenden und innerhalb ihrer Gruppe verschieben. Ausgeblendete sind
   im Normalbetrieb weg (Server markiert .is-user-hidden), im Bearbeiten-Modus gedaempft sichtbar mit Auge und Griff. */
.nav-item.is-user-hidden, .nav-section-label.is-user-hidden { display: none; }
.sidebar.is-editing .nav-item.is-user-hidden, .sidebar.is-editing .nav-item.is-grp-hidden { display: flex; }
.sidebar.is-editing .nav-section-label.is-user-hidden { display: flex; }
.sidebar.is-editing .nav-item.is-user-hidden > .nav-item-icon, .sidebar.is-editing .nav-item.is-user-hidden > .nav-item-label { opacity: .4; }
.sidebar.is-editing .nav-item { cursor: default; }
.sidebar.is-editing .nav-item .nav-badge, .sidebar.is-editing .nav-item .nav-new { display: none; }
.sidebar.is-editing .nav-section-chev { visibility: hidden; }
.nav-edit { display: none; align-items: center; gap: 2px; margin-left: auto; margin-right: 6px; flex-shrink: 0; }
.sidebar.is-editing .nav-edit { display: flex; }
.nav-edit button { width: 26px; height: 26px; display: flex; align-items: center; justify-content: center; border: none; border-radius: 6px;
  background: none; color: var(--sidebar-fg-muted); cursor: pointer; padding: 0; }
.nav-edit button:hover { background: var(--sidebar-hover); color: var(--sidebar-fg); }
.nav-edit button:focus-visible { outline: 2px solid var(--gw); outline-offset: -2px; }
.nav-edit svg { width: 15px; height: 15px; }
.nav-edit .nav-edit-drag { cursor: grab; }
.nav-item.is-dragging { opacity: .5; }
.nav-item.is-drop-before { box-shadow: inset 0 2px 0 var(--gw); }
.nav-item.is-drop-after { box-shadow: inset 0 -2px 0 var(--gw); }
/* Im Bearbeiten-Modus klebt der Kasten buendig am oberen Rand; der Hinweis nach oben laege sonst ueber ihm (18.09.2026). */
.sidebar.is-editing .sidebar-nav-hint--top { visibility: hidden; }
.nav-edit-bar { position: sticky; top: calc(-1 * var(--nav-pad, 0px)); z-index: 6; margin: 0 6px 8px; padding: 10px; border-radius: 10px;
  background: color-mix(in srgb, var(--gw) 9%, var(--sidebar-bg)); border: 1px solid color-mix(in srgb, var(--gw) 30%, transparent); }
.nav-edit-bar__t { font-size: 12.5px; font-weight: 650; color: var(--sidebar-fg); }
.nav-edit-bar__h { margin: 3px 0 8px; font-size: 11px; line-height: 1.45; color: var(--sidebar-fg-muted); }
.nav-edit-bar__b { display: flex; gap: 6px; }
.nav-edit-bar__b button { flex: 1; height: 28px; border-radius: 7px; font: inherit; font-size: 12px; font-weight: 600; cursor: pointer; }
.nav-edit-bar__reset { border: 1px solid var(--sidebar-divider); background: none; color: var(--sidebar-fg); }
.nav-edit-bar__reset:hover { background: var(--sidebar-hover); }
.nav-edit-bar__done { border: none; background: var(--gw); color: #fff; }
.nav-edit-bar__done:hover { background: var(--gw-dark); }
/* Kontext-Kopf unter dem Logo: als wer und fuer welchen Mandanten man gerade arbeitet.
   Gleiche Form wie der Benutzer in der Fusszeile: ohne Rahmen,
   40 px, Kachel 28 px, Name oben, Rolle klein darunter, Trennlinie zur Navigation. Gefiltert = Hausblau. */
.sb-ctx { position: relative; flex-shrink: 0; padding: 4px 6px 8px; border-bottom: 1px solid var(--sidebar-divider); }
.sb-ctx__btn { display: flex; align-items: center; gap: 10px; width: 100%; height: 40px; box-sizing: border-box; padding: 0 8px; border: none;
  border-radius: var(--r-sm); background: none; font: inherit; color: inherit; text-align: left; overflow: hidden; white-space: nowrap; cursor: default; }
button.sb-ctx__btn { cursor: pointer; transition: background .12s; }
button.sb-ctx__btn:hover, .sb-ctx__btn[aria-expanded="true"] { background: var(--sidebar-hover); }
button.sb-ctx__btn:focus-visible { outline: 2px solid var(--gw); outline-offset: -2px; }
.sb-ctx__ic { position: relative; width: 28px; height: 28px; flex: none; border-radius: 8px; display: flex; align-items: center; justify-content: center;
  color: var(--sidebar-fg); background: color-mix(in srgb, var(--sidebar-fg) 10%, transparent); }
.sb-ctx__ic svg { width: 15px; height: 15px; }
.sb-ctx__av { position: relative; width: 28px; height: 28px; flex: none; border-radius: 8px; display: flex; align-items: center; justify-content: center;
  font-size: 11px; font-weight: 700; color: #fff; background: var(--av, var(--gw)); }
.sb-ctx__txt { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.sb-ctx__name { font-size: 12px; font-weight: 500; color: var(--sidebar-fg); overflow: hidden; text-overflow: ellipsis; }
.sb-ctx__role { font-size: 10px; color: var(--sidebar-fg-muted); overflow: hidden; text-overflow: ellipsis; }
.sb-ctx__chev { width: 14px; height: 14px; flex: none; margin-left: 6px; color: var(--sidebar-fg-muted); }
.sb-ctx.is-scoped .sb-ctx__btn { background: color-mix(in srgb, var(--gw) 9%, transparent); }
.sb-ctx.is-scoped button.sb-ctx__btn:hover { background: color-mix(in srgb, var(--gw) 14%, transparent); }
.sb-ctx.is-scoped .sb-ctx__name { color: var(--gw); font-weight: 600; }
.sb-ctx__clr { position: absolute; top: 50%; right: 34px; margin-top: -13px; width: 22px; height: 22px; display: flex; align-items: center; justify-content: center;
  border-radius: 6px; color: var(--gw); text-decoration: none; }
.sb-ctx__clr:hover { background: color-mix(in srgb, var(--gw) 16%, transparent); }
.sb-ctx__clr svg { width: 12px; height: 12px; }
.sb-ctx.is-scoped .sb-ctx__txt { padding-right: 24px; }
/* Gemerkt, aber diese Seite hat keinen Mandanten-Filter: ruhiger, Name bleibt sichtbar, Zeile darunter sagt «Hier alle». */
.sb-ctx.is-soft .sb-ctx__btn { background: none; }
.sb-ctx.is-soft button.sb-ctx__btn:hover { background: var(--sidebar-hover); }
.sb-ctx.is-soft .sb-ctx__name { color: var(--sidebar-fg); }
.sidebar.mini .sb-ctx__btn { justify-content: center; padding: 0; }
.sidebar.mini .sb-ctx__txt, .sidebar.mini .sb-ctx__chev, .sidebar.mini .sb-ctx__clr { display: none; }
.sidebar.mini .sb-ctx.is-scoped .sb-ctx__av::after { content: ''; position: absolute; top: -2px; right: -2px; width: 7px; height: 7px; border-radius: 50%;
  background: var(--gw); box-shadow: 0 0 0 2px var(--sidebar-bg); }
@media (min-width: 769px) and (max-width: 1024px) {
  .sidebar:not(.mini) .sb-ctx__txt, .sidebar:not(.mini) .sb-ctx__chev, .sidebar:not(.mini) .sb-ctx__clr { display: none; }
  .sidebar:not(.mini) .sb-ctx__btn { justify-content: center; padding: 0; }
}
/* Waehler: gleiche Formsprache wie das Benutzermenue (.gw-um) — Karte, Zeilen mit Kachel, kein Slug. */
.sb-ctxpop { position: fixed; z-index: 1200; width: 272px; box-sizing: border-box; padding: 6px; background: var(--surface); border: 1px solid var(--border);
  border-radius: 12px; box-shadow: 0 16px 40px rgba(15, 23, 42, .18), 0 2px 6px rgba(15, 23, 42, .08); }
.sb-ctxpop[hidden] { display: none; }
[data-theme="dark"] .sb-ctxpop { box-shadow: 0 16px 40px rgba(0, 0, 0, .45), 0 0 0 1px rgba(255, 255, 255, .02); }
.sb-ctxpop__search { width: 100%; box-sizing: border-box; height: 32px; margin-bottom: 2px; padding: 0 10px; border: 1px solid var(--border); border-radius: 8px;
  background: var(--surface); color: var(--text-1); font: inherit; font-size: 13px; outline: none; }
[data-theme="dark"] .sb-ctxpop__search { background: var(--bg); }
.sb-ctxpop__search:focus { border-color: var(--gw); box-shadow: 0 0 0 3px var(--gw-light); }
.sb-ctxpop__hint { margin: 6px 8px 4px; font-size: 11.5px; line-height: 1.45; color: var(--text-4); }
.sb-ctxpop__list { max-height: 320px; overflow-y: auto; }
.sb-ctxpop__it { display: flex; align-items: center; gap: 10px; padding: 6px 8px; border-radius: 8px; font-size: 13px; color: var(--text-2); text-decoration: none; }
/* Achtung: hidden allein wirkt nicht, weil die Zeile display:flex setzt — ohne diese Regel filterte die Suche unsichtbar. */
.sb-ctxpop__it[hidden], .sb-ctxpop__none[hidden] { display: none; }
.sb-ctxpop__it:hover, .sb-ctxpop__it.is-kb { background: var(--row-hover, var(--bg)); color: var(--text-1); }
.sb-ctxpop__it.is-on { color: var(--gw); font-weight: 600; }
.sb-ctxpop__ic, .sb-ctxpop__av { width: 26px; height: 26px; font-size: 10.5px; }
.sb-ctxpop__ic { color: var(--text-3); background: color-mix(in srgb, var(--text-3) 12%, transparent); }
.sb-ctxpop__ic svg { width: 14px; height: 14px; }
.sb-ctxpop__nm { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Siegel «Zugriffspruefung bestanden» direkt hinter dem Namen, «inaktiv» bleibt rechts; ohne Tooltip */
.sb-ctxpop__it .us-ar-ok { flex: none; margin-left: -6px; cursor: inherit; }
.sb-ctxpop__off { flex: none; margin-left: auto; padding: 1px 7px; border-radius: 999px; font-size: 10.5px; font-weight: 600; color: var(--text-3); background: color-mix(in srgb, var(--text-3) 12%, transparent); }
.sb-ctxpop__it.is-off .sb-ctxpop__av { opacity: .55; }
.sb-ctxpop__all { margin-bottom: 4px; }
.sb-ctxpop__all::after { content: ''; }
.sb-ctxpop__none { padding: 10px 8px; font-size: 12.5px; color: var(--text-4); }

.sidebar-user-role { font-size: 10px; color: var(--sidebar-fg-muted); }
/* Benutzer-Menue (18.09.2026): die Fusszeile ist ein Knopf, der das Menue oeffnet. */
button.sidebar-user { width: 100%; border: none; background: none; font: inherit; color: inherit; text-align: left; }
button.sidebar-user:focus-visible { outline: 2px solid var(--gw); outline-offset: -2px; }
.sidebar-user[aria-expanded="true"] { background: var(--sidebar-hover); }
.sidebar-user-info { display: flex; flex-direction: column; min-width: 0; flex: 1; overflow: hidden; }
.sidebar-user-name, .sidebar-user-role { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sidebar-user-chev { width: 14px; height: 14px; flex: none; margin-left: 6px; color: var(--sidebar-fg-muted); }
.sidebar.mini .sidebar-user-chev { display: none; }
.gw-um { position: fixed; z-index: 1200; box-sizing: border-box; padding: 6px;
  background: var(--surface); border: 1px solid var(--border); border-radius: 12px;
  box-shadow: 0 16px 40px rgba(15, 23, 42, .18), 0 2px 6px rgba(15, 23, 42, .08); }
.gw-um[hidden] { display: none; }
.gw-um__head { display: flex; align-items: center; gap: 10px; padding: 8px 8px 10px; margin-bottom: 4px; border-bottom: 1px solid var(--border); }
.gw-um__head .sidebar-avatar { width: 32px; height: 32px; }
.gw-um__who { display: flex; flex-direction: column; min-width: 0; }
.gw-um__name { font-size: 13px; font-weight: 650; color: var(--text-1); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gw-um__sub { font-size: 11.5px; color: var(--text-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gw-um__item { display: flex; align-items: center; gap: 10px; width: 100%; box-sizing: border-box; padding: 7px 8px;
  border: none; border-radius: 8px; background: none; font: inherit; font-size: 13px; color: var(--text-2);
  text-align: left; text-decoration: none; cursor: pointer; }
.gw-um__item svg { width: 15px; height: 15px; flex: none; color: var(--text-3); }
.gw-um__item > span { flex: 1; min-width: 0; }
.gw-um__item:hover, .gw-um__item:focus-visible { background: var(--row-hover, var(--bg)); color: var(--text-1); outline: none; }
.gw-um__item:hover svg, .gw-um__item:focus-visible svg { color: var(--gw); }
.gw-um__item--out:hover, .gw-um__item--out:focus-visible { color: var(--err); }
.gw-um__item--out:hover svg, .gw-um__item--out:focus-visible svg { color: var(--err); }
/* Status-Punkt (nur Sysadmin): am Avatar unten rechts und im Menue neben System-Status, Farbe aus /api/nav/counts. */
.sidebar-avatar { position: relative; }
.gw-stdot { width: 8px; height: 8px; border-radius: 50%; background: var(--text-4); flex-shrink: 0; }
.gw-stdot[hidden] { display: none; }
.gw-stdot.is-ok   { background: var(--ok); }
.gw-stdot.is-warn { background: #f59e0b; }
.gw-stdot.is-err  { background: #dc2626; }
.sidebar-avatar .gw-stdot { position: absolute; right: -3px; bottom: -3px; box-shadow: 0 0 0 2px var(--sidebar-bg); }
.gw-um__item .gw-stdot { flex: 0 0 8px; height: 8px; margin: 0 2px 0 auto; }
/* Punkt am Fragezeichen der Kopfleiste: nur wenn der Status eingeschraenkt oder gestoert ist. «in Ordnung» und
   «keine frische Messung» (grau) zeigt schon der Avatar; oben soll nichts dauerhaft leuchten. */
#gwHelpBtn .gw-stdot { position: absolute; top: 4px; right: 4px; box-shadow: 0 0 0 2px var(--surface); }
#gwHelpBtn .gw-stdot.is-ok, #gwHelpBtn .gw-stdot.is-muted { display: none; }
.gw-um__kbd { font-family: var(--font-mono); font-size: 10.5px; color: var(--text-4); padding: 1px 6px; border: 1px solid var(--border); border-radius: 5px; white-space: nowrap; }
.gw-um__sep { height: 1px; background: var(--border); margin: 5px 2px; }
.gw-um__row { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 4px 8px; }
.gw-um__lbl { font-size: 12.5px; color: var(--text-3); }
.gw-um__seg { display: inline-flex; padding: 2px; border-radius: 8px; background: var(--bg); border: 1px solid var(--border); }
.gw-um__seg button { display: inline-flex; align-items: center; gap: 5px; padding: 4px 9px; border: none; border-radius: 6px;
  background: none; font: inherit; font-size: 12px; color: var(--text-3); cursor: pointer; }
.gw-um__seg button svg { width: 13px; height: 13px; }
.gw-um__seg button[aria-pressed="true"] { background: var(--surface); color: var(--text-1); box-shadow: 0 1px 2px rgba(15, 23, 42, .12); }
.gw-um__seg button:focus-visible { outline: 2px solid var(--gw); outline-offset: 1px; }
[data-theme="dark"] .gw-um { box-shadow: 0 16px 40px rgba(0, 0, 0, .45), 0 0 0 1px rgba(255, 255, 255, .02); }
/* Eingeklappte Leiste: Karte beim Ueberfahren (18.09.2026) — Gruppenname + Eintraege mit Zaehler, gleiche Formsprache wie .gw-um. */
.gw-nfly { position: fixed; z-index: 1150; min-width: 216px; max-width: 280px; padding: 6px; box-sizing: border-box;
  background: var(--surface); border: 1px solid var(--border); border-radius: 12px;
  box-shadow: 0 16px 40px rgba(15, 23, 42, .18), 0 2px 6px rgba(15, 23, 42, .08); animation: gwNflyIn .12s ease-out; }
@keyframes gwNflyIn { from { opacity: 0; transform: translateX(-4px); } to { opacity: 1; transform: none; } }
/* Ruhige Uebergaenge: beim Wechsel zwischen Symbolen gleitet die offene Karte samt Spitze zum
   neuen Symbol (.is-glide) und der Inhalt blendet weich ueber; beim Schliessen blendet sie kurz aus (.is-leaving). */
@property --nfly-y { syntax: '<length>'; inherits: false; initial-value: 22px; }
.gw-nfly.is-glide { transition: top .16s cubic-bezier(.2, .7, .2, 1), --nfly-y .16s cubic-bezier(.2, .7, .2, 1); }
.gw-nfly.is-glide > * { animation: gwNflySwap .14s ease-out; }
@keyframes gwNflySwap { from { opacity: .3; } to { opacity: 1; } }
.gw-nfly.is-leaving { opacity: 0; transform: translateX(-3px); transition: opacity .12s ease-in, transform .12s ease-in; pointer-events: none; }
@media (prefers-reduced-motion: reduce) { .gw-nfly, .gw-nfly.is-glide, .gw-nfly.is-glide > *, .gw-nfly.is-leaving { animation: none; transition: none; } }
.gw-nfly[hidden] { display: none; }
.gw-nfly__h { padding: 6px 8px 5px; font-size: 10.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--text-4); }
.gw-nfly__row { display: flex; align-items: center; gap: 10px; padding: 7px 8px; border-radius: 8px; cursor: pointer;
  font-size: 13px; color: var(--text-2); white-space: nowrap; }
.gw-nfly__row svg { width: 16px; height: 16px; flex: none; color: var(--text-3); }
.gw-nfly__lbl { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.gw-nfly__row:hover, .gw-nfly__row.is-hover { background: var(--row-hover, var(--bg)); color: var(--text-1); }
.gw-nfly__row:hover svg, .gw-nfly__row.is-hover svg { color: var(--gw); }
.gw-nfly__row.is-active { color: var(--gw); font-weight: 600; }
.gw-nfly__row.is-active svg { color: var(--gw); }
.gw-nfly__ct, .gw-nfly__new { flex: none; padding: 1px 6px; border-radius: 10px; font-size: 9.5px; font-weight: 700; line-height: 15px;
  font-variant-numeric: tabular-nums; min-width: 18px; text-align: center; box-sizing: border-box; }
.gw-nfly__ct { color: var(--text-3); background: color-mix(in srgb, var(--text-3) 14%, transparent); }
.gw-nfly__ct.is-err { background: #dc2626; color: #fff; }
.gw-nfly__ct.is-warn { background: #f59e0b; color: #1f2937; }
.gw-nfly__ct.is-info { background: var(--gw); color: #fff; }
.gw-nfly__ct.is-live { background: color-mix(in srgb, #16a34a 14%, transparent); color: #15803d; text-transform: uppercase; letter-spacing: .4px; }
[data-theme="dark"] .gw-nfly__ct.is-live { color: #4ade80; }
.gw-nfly__ct .nav-trend { font-size: 9px; margin-right: 2px; opacity: .75; }
.gw-nfly__new { color: var(--gw); background: color-mix(in srgb, var(--gw) 14%, transparent); }
.gw-nfly { min-width: 232px; padding: 6px; }
/* Spitze zur Leiste: zeigt auf das ueberfahrene Symbol (--nfly-y aus dem Skript). */
.gw-nfly::before { content: ''; position: absolute; left: -6px; top: var(--nfly-y, 22px); width: 10px; height: 10px; margin-top: -5px;
  background: var(--surface); border-left: 1px solid var(--border); border-bottom: 1px solid var(--border); transform: rotate(45deg); border-radius: 0 0 0 2px; }
/* Kopf = der Eintrag selbst (anklickbar): Symbol-Kachel, Kategorie klein ueber dem Namen, Zaehler rechts. */
.gw-nfly__head { position: relative; display: flex; align-items: center; gap: 10px; padding: 7px 8px; border-radius: 9px; cursor: pointer; }
.gw-nfly__head:hover { background: var(--row-hover, var(--bg)); }
.gw-nfly__ic { width: 30px; height: 30px; flex: none; border-radius: 8px; display: flex; align-items: center; justify-content: center;
  color: var(--text-2); background: color-mix(in srgb, var(--text-3) 11%, transparent); }
.gw-nfly__ic svg { width: 16px; height: 16px; color: inherit !important; }
.gw-nfly__head:hover .gw-nfly__ic, .gw-nfly__head.is-active .gw-nfly__ic { color: var(--gw); background: color-mix(in srgb, var(--gw) 12%, transparent); }
.gw-nfly__ht { flex: 1; min-width: 0; display: flex; flex-direction: column; line-height: 1.25; }
.gw-nfly__cat { font-size: 10px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--text-4); }
.gw-nfly__title { font-size: 13.5px; font-weight: 650; color: var(--text-1); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.gw-nfly__head.is-active .gw-nfly__title { color: var(--gw); }
/* Direktlinks: eingerueckt unter dem Namen, mit feiner Fuehrungslinie; Pfeil erscheint beim Ueberfahren. */
.gw-nfly__subs { position: relative; margin: 2px 0 2px; padding: 2px 0 0 0; }
.gw-nfly__subs::before { content: ''; position: absolute; left: 22px; top: 4px; bottom: 6px; width: 1px; background: var(--border); }
.gw-nfly__sub { position: relative; display: flex; align-items: center; gap: 8px; margin-left: 30px; padding: 6px 8px 6px 10px; border-radius: 7px;
  font-size: 12.5px; color: var(--text-2); text-decoration: none; white-space: nowrap; }
.gw-nfly__sub > span { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
/* Zahl am Direktlink (18.10.2026) bleibt so breit wie ihr Inhalt, der Name nimmt den Rest */
.gw-nfly__sub > .gw-nfly__ct { flex: none; }
/* Symbol je Direktlink (02.10.2026, navSubIcon()): gleiche Strich-Sprache wie die Leiste, eine Spalte links vom Namen,
   gedaempft; beim Ueberfahren und auf der offenen Unterseite in Hausblau. Die Karte darf dafuer bis 352 px breit
   werden (vorher 280): so passt auch der laengste Name «DS beim Parent offen» in allen sechs Sprachen ganz hinein. */
.gw-nfly__si { width: 14px; height: 14px; flex: none; color: var(--text-3); transition: color .12s; }
.gw-nfly__sub:hover .gw-nfly__si, .gw-nfly__sub:focus-visible .gw-nfly__si, .gw-nfly__sub.is-here .gw-nfly__si { color: var(--gw); }
.gw-nfly.has-subs { max-width: 352px; }
.gw-nfly__go { width: 12px; height: 12px; flex: none; opacity: 0; transform: translateX(-3px); transition: opacity .12s, transform .12s; color: var(--gw); }
.gw-nfly__sub:hover, .gw-nfly__sub:focus-visible { background: var(--row-hover, var(--bg)); color: var(--text-1); outline: none; }
.gw-nfly__sub:hover .gw-nfly__go, .gw-nfly__sub:focus-visible .gw-nfly__go { opacity: 1; transform: none; }
.gw-nfly__sub.is-here { color: var(--gw); font-weight: 600; }
.gw-nfly__sub.is-here::before { content: ''; position: absolute; left: -9px; top: 50%; width: 5px; height: 5px; margin-top: -2.5px; border-radius: 50%; background: var(--gw); }
.gw-nfly.has-subs .gw-nfly__head { margin-bottom: 2px; }
.gw-nfly:not(.has-subs) { min-width: 0; }
.gw-nfly:not(.has-subs) .gw-nfly__head { padding-right: 12px; }
@media (prefers-reduced-motion: reduce) { .gw-nfly__go, .gw-nfly__si { transition: none; } }
[data-theme="dark"] .gw-nfly { box-shadow: 0 16px 40px rgba(0, 0, 0, .45), 0 0 0 1px rgba(255, 255, 255, .02); }
/* «Was ist neu»: modernere Darstellung mit ausfuehrlicherem Text.
   Zwei Bereiche: links Kapitel-Leiste, rechts je Neuerung eine Vorschau aus Haus-Bausteinen und der ausfuehrliche Text.
   Haus-Stil: Hausblau, Haus-Radien, gleicher Hintergrund wie die uebrigen Fenster, keine Leucht-/Glas-Effekte. */
.gw-wn { position: fixed; inset: 0; z-index: 9990; display: flex; align-items: center; justify-content: center; padding: 16px;
  background: rgba(15, 23, 42, .55); backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px); }
.gw-wn[hidden] { display: none; }
.gw-wn__dlg { position: relative; width: 960px; max-width: 100%; height: min(700px, calc(100vh - 32px)); display: grid;
  grid-template-columns: 276px minmax(0, 1fr); background: var(--surface); border-radius: 16px; overflow: hidden;
  box-shadow: 0 32px 80px rgba(0, 0, 0, .28), 0 0 0 1px rgba(0, 0, 0, .04); animation: gwWnIn .22s cubic-bezier(.2, .8, .2, 1); }
@keyframes gwWnIn { from { opacity: 0; transform: translateY(10px) scale(.985); } to { opacity: 1; transform: none; } }
.gw-wn.is-closing { animation: gwWnFade .16s ease forwards; }
@keyframes gwWnFade { to { opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .gw-wn__dlg, .gw-wn.is-closing, .gw-wn__pane { animation: none !important; } }
.gw-wn__x { position: absolute; top: 14px; right: 14px; z-index: 2; width: 32px; height: 32px; display: flex; align-items: center; justify-content: center;
  border: none; border-radius: 8px; background: none; color: var(--text-4); cursor: pointer; }
.gw-wn__x:hover { background: var(--bg); color: var(--text-1); }
.gw-wn__x:focus-visible { outline: 2px solid var(--gw); outline-offset: 1px; }
.gw-wn__x svg { width: 18px; height: 18px; }
/* Kapitel-Leiste */
.gw-wn__rail { display: flex; flex-direction: column; min-height: 0; border-right: 1px solid var(--border);
  background: color-mix(in srgb, var(--bg) 60%, var(--surface)); }
.gw-wn__rhead { padding: 24px 22px 16px; }
.gw-wn__top { display: flex; align-items: center; gap: 10px; margin-bottom: 14px; }
.gw-wn__badge { width: 36px; height: 36px; border-radius: 10px; flex: none; display: flex; align-items: center; justify-content: center;
  color: var(--gw); background: color-mix(in srgb, var(--gw) 12%, transparent); }
.gw-wn__badge svg { width: 18px; height: 18px; }
.gw-wn__eyebrow { display: inline-flex; align-items: center; padding: 3px 10px; border-radius: 999px; font-size: 11px; font-weight: 650;
  letter-spacing: .3px; color: var(--gw); background: color-mix(in srgb, var(--gw) 10%, transparent); }
.gw-wn__title { margin: 0; font-size: 21px; font-weight: 700; letter-spacing: -.015em; color: var(--text-1); line-height: 1.25; }
.gw-wn__intro { margin: 6px 0 0; font-size: 12.5px; line-height: 1.55; color: var(--text-3); }
.gw-wn__tabs { list-style: none; margin: 0; padding: 4px 12px 12px; overflow-y: auto; flex: 1; min-height: 0; }
.gw-wn__tab { position: relative; display: grid; grid-template-columns: 28px minmax(0, 1fr) auto; align-items: center; gap: 10px; width: 100%;
  padding: 6px 10px; margin-bottom: 1px; border: none; border-radius: 10px; background: none; font: inherit; text-align: left; cursor: pointer; color: var(--text-2); }
.gw-wn__tab:hover { background: var(--row-hover, var(--bg)); color: var(--text-1); }
.gw-wn__tab:focus-visible { outline: 2px solid var(--gw); outline-offset: -2px; }
.gw-wn__tab.is-on { background: var(--surface); color: var(--text-1); box-shadow: 0 1px 2px rgba(15, 23, 42, .06), 0 0 0 1px var(--border); }
.gw-wn__tab.is-on::before { content: ''; position: absolute; left: 0; top: 10px; bottom: 10px; width: 3px; border-radius: 3px; background: var(--gw); }
.gw-wn__tic { width: 28px; height: 28px; border-radius: 8px; display: flex; align-items: center; justify-content: center;
  color: var(--text-3); background: color-mix(in srgb, var(--text-3) 10%, transparent); }
.gw-wn__tab.is-on .gw-wn__tic { color: var(--gw); background: color-mix(in srgb, var(--gw) 12%, transparent); }
.gw-wn__tic svg { width: 16px; height: 16px; }
.gw-wn__tt { font-size: 13.5px; font-weight: 600; line-height: 1.3; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gw-wn__tn { font-size: 10.5px; font-weight: 700; color: var(--text-4); font-variant-numeric: tabular-nums; }
.gw-wn__tab.is-seen .gw-wn__tn { color: var(--gw); }
.gw-wn__rfoot { padding: 12px 22px 16px; font-size: 11.5px; line-height: 1.45; color: var(--text-4); border-top: 1px solid var(--border); }
/* Ausgaben-Wechsel: die Ausgabe im Kopf ist ein Knopf, die Liste klappt als kleines Menü darunter auf (18.10.2026) */
.gw-wn__rel { position: relative; }
.gw-wn__rel > summary { list-style: none; cursor: pointer; gap: 5px; }
.gw-wn__rel > summary::-webkit-details-marker { display: none; }
.gw-wn__rel > summary svg { width: 11px; height: 11px; transition: transform .15s; }
.gw-wn__rel[open] > summary svg { transform: rotate(180deg); }
.gw-wn__rel > summary:focus-visible { outline: 2px solid var(--gw); outline-offset: 2px; }
.gw-wn__relmenu { position: absolute; top: calc(100% + 6px); left: 0; z-index: 5; display: flex; flex-direction: column; gap: 2px; min-width: 170px; padding: 6px;
  border: 1px solid var(--border); border-radius: 10px; background: var(--surface); box-shadow: 0 10px 28px rgba(15, 23, 42, .14); }
[data-theme="dark"] .gw-wn__relmenu { box-shadow: 0 10px 28px rgba(0, 0, 0, .4); }
.gw-wn__relmenu .gw-wn__hi { justify-content: space-between; border-color: transparent; border-radius: 7px; padding: 5px 9px; }
.gw-wn__hi { display: inline-flex; align-items: center; gap: 5px; padding: 2px 9px; border-radius: 999px; border: 1px solid var(--border); font-size: 11.5px; font-weight: 600; color: var(--text-2); text-decoration: none; background: var(--surface); }
.gw-wn__hi:hover { color: var(--gw); border-color: color-mix(in srgb, var(--gw) 40%, var(--border)); }
.gw-wn__hi.is-on { color: var(--gw); background: color-mix(in srgb, var(--gw) 10%, transparent); border-color: transparent; }
.gw-wn__cur { font-size: 10px; font-weight: 600; color: var(--text-4); }
/* Inhalt */
.gw-wn__main { display: flex; flex-direction: column; min-width: 0; min-height: 0; }
.gw-wn__panes { flex: 1; min-height: 0; overflow-y: auto; }
.gw-wn__pane { animation: gwWnPane .18s ease-out; }
.gw-wn__pane[hidden] { display: none; }
@keyframes gwWnPane { from { opacity: 0; transform: translateX(6px); } to { opacity: 1; transform: none; } }
.gw-wn__stage { height: 196px; display: flex; align-items: center; justify-content: center; padding: 20px 28px; box-sizing: border-box;
  background: var(--bg); border-bottom: 1px solid var(--border); overflow: hidden; }
.gw-wn__body { padding: 22px 30px 24px; }
.gw-wn__ph { margin: 0; font-size: 20px; font-weight: 700; letter-spacing: -.01em; color: var(--text-1); line-height: 1.3; padding-right: 30px; }
.gw-wn__pl { margin: 8px 0 0; font-size: 14.5px; line-height: 1.55; color: var(--text-2); font-weight: 500; }
.gw-wn__h4 { margin: 20px 0 6px; font-size: 10.5px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase; color: var(--text-4); }
.gw-wn__p { margin: 0; font-size: 13.5px; line-height: 1.7; color: var(--text-2); }
.gw-wn__steps { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.gw-wn__steps li { display: grid; grid-template-columns: 24px minmax(0, 1fr); gap: 10px; align-items: start; font-size: 13.5px; line-height: 1.6; color: var(--text-2); }
.gw-wn__num { width: 24px; height: 24px; border-radius: 7px; display: flex; align-items: center; justify-content: center; margin-top: 0;
  font-size: 11.5px; font-weight: 700; color: var(--gw); background: color-mix(in srgb, var(--gw) 12%, transparent); font-variant-numeric: tabular-nums; }
.gw-wn__cta { display: inline-flex; align-items: center; gap: 6px; margin-top: 18px; padding: 0; border: none; background: none; font: inherit;
  font-size: 13px; font-weight: 600; color: var(--gw); text-decoration: none; cursor: pointer; }
.gw-wn__cta svg { width: 14px; height: 14px; transition: transform .15s; }
.gw-wn__cta:hover svg { transform: translateX(2px); }
.gw-wn__cta:focus-visible { outline: 2px solid var(--gw); outline-offset: 2px; border-radius: 4px; }
.gw-wn__kbd { font-family: var(--font-mono); font-size: 11px; padding: 1px 6px; border: 1px solid var(--border); border-bottom-width: 2px;
  border-radius: 5px; color: var(--text-2); background: var(--bg); white-space: nowrap; }
.gw-wn__foot { flex: none; display: flex; align-items: center; gap: 14px; padding: 14px 24px; border-top: 1px solid var(--border); }
.gw-wn__prog { display: flex; gap: 4px; flex: 1; max-width: 220px; }
.gw-wn__seg { flex: 1; height: 4px; border-radius: 2px; background: color-mix(in srgb, var(--text-3) 18%, transparent); }
.gw-wn__seg.is-done { background: color-mix(in srgb, var(--gw) 45%, transparent); }
.gw-wn__seg.is-on { background: var(--gw); }
.gw-wn__count { font-size: 12px; color: var(--text-4); font-variant-numeric: tabular-nums; white-space: nowrap; }
.gw-wn__btns { margin-left: auto; display: flex; gap: 8px; }
.gw-wn__btns .btn { min-width: 96px; justify-content: center; }
.gw-wn__btns .btn[hidden] { display: none; }
[data-theme="dark"] .gw-wn__dlg { box-shadow: 0 32px 80px rgba(0, 0, 0, .55), 0 0 0 1px rgba(255, 255, 255, .04); }
[data-theme="dark"] .gw-wn__tab.is-on { background: var(--bg); }
/* Vorschau-Karten: kleine Nachbildungen echter Bausteine (Leiste, Menue, Suche, Kacheln) */
.gw-wm { width: 100%; max-width: 380px; background: var(--surface); border: 1px solid var(--border); border-radius: 12px; padding: 8px;
  box-shadow: 0 10px 28px rgba(15, 23, 42, .10), 0 1px 3px rgba(15, 23, 42, .06); font-size: 12.5px; color: var(--text-2); }
[data-theme="dark"] .gw-wm { box-shadow: 0 10px 28px rgba(0, 0, 0, .35); }
.gw-wm__h { padding: 4px 8px 6px; font-size: 10px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--text-4); }
.gw-wm__row { display: flex; align-items: center; gap: 10px; padding: 7px 8px; border-radius: 8px; white-space: nowrap; }
.gw-wm__row svg { width: 15px; height: 15px; flex: none; color: var(--text-3); }
.gw-wm__row.is-on { background: color-mix(in srgb, var(--gw) 10%, transparent); color: var(--gw); font-weight: 600; }
.gw-wm__row.is-on svg { color: var(--gw); }
.gw-wm__lbl { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.gw-wm__pill { flex: none; padding: 1px 6px; min-width: 18px; box-sizing: border-box; text-align: center; border-radius: 10px; font-size: 9.5px; font-weight: 700; line-height: 15px;
  color: var(--text-3); background: color-mix(in srgb, var(--text-3) 14%, transparent); font-variant-numeric: tabular-nums; }
.gw-wm__pill.is-err { background: #dc2626; color: #fff; }
.gw-wm__pill.is-warn { background: #f59e0b; color: #1f2937; }
.gw-wm__pill.is-new { color: var(--gw); background: color-mix(in srgb, var(--gw) 14%, transparent); }
.gw-wm__pill.is-ok { color: #15803d; background: color-mix(in srgb, #16a34a 14%, transparent); }
[data-theme="dark"] .gw-wm__pill.is-ok { color: #4ade80; }
.gw-wm__dot { width: 8px; height: 8px; border-radius: 50%; flex: none; background: #16a34a; }
.gw-wm__dot.is-warn { background: #f59e0b; }
.gw-wm__mono { font-family: var(--font-mono); font-size: 11.5px; }
.gw-wm__sub { color: var(--text-4); font-size: 11.5px; }
.gw-wm__search { display: flex; align-items: center; gap: 8px; margin: 2px 2px 6px; padding: 0 10px; height: 34px; border: 1px solid var(--gw);
  border-radius: 8px; box-shadow: 0 0 0 3px var(--gw-light); color: var(--text-1); }
.gw-wm__search svg { width: 15px; height: 15px; color: var(--text-3); flex: none; }
.gw-wm__search span { flex: 1; }
.gw-wm__caret { display: inline-block; width: 1px; height: 14px; margin-left: 1px; vertical-align: -2px; background: var(--gw); }
.gw-wm__tag { flex: none; min-width: 34px; padding: 1px 6px; box-sizing: border-box; text-align: center; border-radius: 5px; font-family: var(--font-mono);
  font-size: 10.5px; font-weight: 700; color: var(--gw); background: color-mix(in srgb, var(--gw) 10%, transparent); }
.gw-wm__grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
.gw-wm__kpi { padding: 10px 11px; border: 1px solid var(--border); border-radius: 10px; background: var(--surface); }
.gw-wm__kl { font-size: 10.5px; color: var(--text-4); font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.gw-wm__kv { margin-top: 3px; font-size: 18px; font-weight: 700; color: var(--text-1); font-variant-numeric: tabular-nums; letter-spacing: -.01em; }
.gw-wm__bar { height: 8px; border-radius: 4px; background: color-mix(in srgb, var(--text-3) 14%, transparent); overflow: hidden; margin: 2px 0 8px; }
.gw-wm__bar > span { display: block; height: 100%; border-radius: 4px; background: var(--gw); }
.gw-wm__kpi.is-wait .gw-wm__kv { height: 18px; margin-top: 6px; width: 70%; border-radius: 5px; background: color-mix(in srgb, var(--text-3) 12%, transparent); }
.gw-wm__kpi.is-wait .gw-wm__kl { width: 55%; height: 9px; border-radius: 4px; background: color-mix(in srgb, var(--text-3) 12%, transparent); }
.gw-wm .gw-um__seg { margin-left: auto; }
.gw-wm__dot.is-bad { background: #dc2626; }
.gw-wm__bars { display: flex; align-items: flex-end; gap: 5px; height: 70px; padding: 4px 4px 0; border-bottom: 1px solid var(--border); }
.gw-wm__barv { flex: 1; min-height: 6px; border-radius: 3px 3px 0 0; background: color-mix(in srgb, var(--gw) 45%, transparent); }
.gw-wm__barv.is-dim { background: color-mix(in srgb, var(--text-3) 22%, transparent); }
.gw-wm__barv.is-on { background: var(--gw); box-shadow: 0 0 0 2px var(--surface), 0 0 0 4px color-mix(in srgb, var(--gw) 35%, transparent); }
.gw-wm__diff { width: 16px; flex: none; text-align: center; font-weight: 700; font-family: var(--font-mono); }
.gw-wm__diff.is-add { color: #16a34a; } .gw-wm__diff.is-del { color: #dc2626; }
.gw-wm__bulk { display: flex; align-items: center; gap: 6px; padding: 6px 8px 8px; margin-bottom: 4px; border-bottom: 1px solid var(--border); }
.gw-wm__btn { padding: 2px 8px; border: 1px solid var(--border); border-radius: 6px; font-size: 11px; font-weight: 600; color: var(--text-2); white-space: nowrap; }
.gw-wm__cb { width: 14px; height: 14px; flex: none; border: 1.5px solid var(--border-2, var(--border)); border-radius: 4px; display: flex; align-items: center; justify-content: center; box-sizing: border-box; }
.gw-wm__cb.is-on { background: var(--gw); border-color: var(--gw); color: #fff; }
.gw-wm__cb svg { width: 10px !important; height: 10px !important; color: #fff !important; }
.gw-wm__line { display: block; height: 8px; border-radius: 4px; background: color-mix(in srgb, var(--text-3) 18%, transparent); }
.gw-wm__fmt { display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 12px 6px; border: 1px solid var(--border); border-radius: 10px; font-size: 12px; font-weight: 700; color: var(--text-1); }
.gw-wm__fmt svg { width: 20px; height: 20px; color: var(--gw); }
.gw-wm__thead { display: flex; gap: 10px; margin: 8px 2px 0; padding: 8px 10px; border-radius: 6px; background: color-mix(in srgb, var(--text-3) 10%, transparent); }
.gw-wm__thead span { display: block; height: 7px; border-radius: 4px; background: color-mix(in srgb, var(--text-3) 28%, transparent); }
.gw-wm__empty { display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 14px 0 6px; }
.gw-wm__empty svg { width: 22px; height: 22px; color: var(--text-4); }
.gw-wm__search .gw-wm__clr { flex: none; }
.gw-wm__clr { display: inline-flex; width: 18px; height: 18px; align-items: center; justify-content: center; border-radius: 50%; background: color-mix(in srgb, var(--text-3) 16%, transparent); }
.gw-wm__clr svg { width: 10px !important; height: 10px !important; }
.gw-wm__pill svg { width: 10px; height: 10px; vertical-align: -1px; }
/* Bildschirm-Ausschnitte in den Anleitungen (GuideShot, 22.09.2026): jeder Ausschnitt eine Karte mit Hausrand, alle im
   selben Massstab, mehrere nebeneinander, Fusszeile «wo in der App». Das Zeichen oben rechts ist immer sichtbar
   (Klickbares im Ruhezustand erkennbar, 21.09.) und öffnet die Shadowbox (guide-shots.js). Keine Leuchteffekte. */
.gd-shots { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 14px; margin: 4px 0 18px; }
.gd-shot { margin: 0; max-width: 100%; border: 1px solid var(--border); border-radius: 12px; background: var(--surface);
  overflow: hidden; cursor: zoom-in; transition: border-color .15s; }
.gd-shot:hover, .gd-shot:focus-visible { border-color: var(--gw); }
.gd-shot:focus-visible { outline: 2px solid var(--gw); outline-offset: 2px; }
.gd-shot__frame { position: relative; overflow: hidden; }
.gd-shot__img { display: block; max-width: none; height: auto; }
.gd-shot__img--dark { display: none; }
[data-theme="dark"] .gd-shot__img--light { display: none; }
[data-theme="dark"] .gd-shot__img--dark { display: block; }
.gd-shot__zoom { position: absolute; top: 8px; right: 8px; display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; border-radius: 7px; border: 1px solid var(--border); background: var(--surface); color: var(--text-3);
  transition: color .15s, border-color .15s; }
.gd-shot__zoom svg { width: 13px; height: 13px; }
.gd-shot:hover .gd-shot__zoom, .gd-shot:focus-visible .gd-shot__zoom { color: var(--gw); border-color: var(--gw); }
.gd-shot__cap { display: block; padding: 7px 12px; border-top: 1px solid var(--border); font-size: 11.5px; font-weight: 500; line-height: 1.4;
  color: var(--text-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; background: color-mix(in srgb, var(--text-1) 3%, var(--surface)); }
.gd-shot__cap .gd-shot__sep { margin: 0 5px; }
.gd-shot__sep { color: var(--text-4); font-weight: 400; }
/* Vorschaubild-Spalte rechts neben einer Schrittliste (GuideShot::column): die Bilder stehen rechts
   und beeinflussen weder Höhe noch Abstand der einzelnen Punkte. Raster aus Liste und fester Spalte: die Schritte behalten Höhe und Abstand, die Bilder eines
   Abschnitts stehen eng untereinander. Unter 720px Breite folgen sie unter der Liste. */
/* ── Anleitungs-Schritte ───────────────────────────────────────────────────────────────────────────────────────
   eine Darstellung für jede Handlungsfolge in jeder Anleitung — die aus «Erste Schritte»: Nummernkreis, Verbindungs-
   linie, optional Titel (.qs-step__title) und Text (.qs-step__body). Bis 25.09.2026 standen rund 140 Listen als rohes <ol> oder mit selbst erfundenen Klassen (wr-steps, zp-steps …). Die Regeln
   hängen am <li> selbst, damit auch Listen aus Sprachtexten (<li> im Wert) gleich aussehen. Test:
   GuideStepsUseOneStyleTest verbietet jedes andere <ol> in templates/guides. */
/* Schritte stehen immer in einer Kachel wie der übrige Text, damit die Anleitung einheitlich wirkt: in einer .qs-card ohne eigene Kachel,
   allein stehend (Erste Schritte) bekommt die Liste selbst die Kachelform. */
ol.qs-steps { list-style: none; counter-reset: qs-step; margin: 0 0 14px; padding: 18px 18px 6px;
  background: var(--surface); border: 1px solid var(--border); border-radius: 10px; }
.qs-card ol.qs-steps, .qs-step__body ol.qs-steps, .gp-tab ol.qs-steps {
  margin: 12px 0 6px; padding: 0; background: none; border: 0; border-radius: 0; }
ol.qs-steps > li { position: relative; padding: 0 0 18px 42px; counter-increment: qs-step;
  font-size: 13.5px; line-height: 1.65; color: var(--text-2); }
ol.qs-steps > li:last-child { padding-bottom: 12px; }
.qs-card ol.qs-steps > li:last-child { padding-bottom: 4px; }
/* Schrittmarke: abgerundetes Quadrat (Haus-Radius), zart getönt, dunkelblaue Ziffer — bewusst anders als die gefüllte
   runde Kapitelnummer (.qs-section__num), klarer Kontrast hell wie dunkel. Kein Schatten, kein Leuchten (Hausregel). */
ol.qs-steps > li::before { content: counter(qs-step); position: absolute; left: 0; top: 0;
  width: 26px; height: 26px; border-radius: 7px; box-sizing: border-box;
  background: color-mix(in srgb, var(--gw) 12%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--gw) 40%, var(--surface));
  color: color-mix(in srgb, var(--gw) 72%, #0b1f33);
  font-weight: 700; font-size: 12.5px; font-variant-numeric: tabular-nums;
  display: flex; align-items: center; justify-content: center; }
[data-theme="dark"] ol.qs-steps > li::before { background: color-mix(in srgb, var(--gw) 18%, var(--surface));
  border-color: color-mix(in srgb, var(--gw) 45%, var(--surface)); color: color-mix(in srgb, var(--gw) 55%, #fff); }
ol.qs-steps > li:not(:last-child)::after { content: ''; position: absolute; left: 12px; top: 31px; bottom: 5px;
  width: 2px; border-radius: 1px; background: var(--border); }
ol.qs-steps > li > strong:first-child { color: var(--text-1); }
.qs-step__title { display: block; font-size: 14px; font-weight: 700; color: var(--text-1); margin: 2px 0 4px; line-height: 1.4; }
.qs-step__body { font-size: 13.5px; color: var(--text-2); line-height: 1.65; }
.qs-step__body p { margin: 0 0 8px; }
.qs-step__body p:last-child { margin-bottom: 0; }
.qs-step__body code, ol.qs-steps > li code { font-family: var(--font-mono); font-size: 12px; padding: 1px 6px;
  background: var(--bg); border: 1px solid var(--border); border-radius: 4px; }
ol.qs-steps ul, ol.qs-steps ol:not(.qs-steps) { margin: 6px 0 0; }

:has(> .gd-shot-cols) { container-type: inline-size; }
.gd-shot-cols { display: grid; grid-template-columns: minmax(0, 1fr) 296px; column-gap: 28px; align-items: start; }
/* Das Panel: Karte wie die übrigen, links der Akzentstrich des aktiven Menüpunkts (.nav-item.active::before), Kopf mit
   Symbol-Kachel wie .qs-next-icon. Bleibt beim Lesen des Abschnitts unter der Kopfleiste stehen. Keine Leuchteffekte. */
.gd-shot-stack { position: sticky; top: calc(var(--topbar-h, 52px) + 16px); display: flex; flex-direction: column; gap: 12px;
  padding: 14px; border: 1px solid var(--border); border-radius: 14px; background: var(--surface); box-shadow: var(--shadow);
  /* Abstand nach unten: ist die Spalte höher als der Text daneben, klebte sie an der nächsten Karte. */
  margin-bottom: 18px; }
.gd-shot-stack::before { content: ''; position: absolute; left: -1px; top: 18px; width: 3px; height: 20px; border-radius: 0 3px 3px 0; background: var(--gw); }
.gd-shot-stack__head { display: flex; align-items: center; gap: 9px; font-size: 12.5px; font-weight: 700; color: var(--text-1); }
.gd-shot-stack__icon { display: inline-flex; align-items: center; justify-content: center; width: 26px; height: 26px; border-radius: 8px;
  background: var(--gw-light); color: var(--gw); flex-shrink: 0; }
.gd-shot-stack__icon svg { width: 14px; height: 14px; }
.gd-shot--thumb { width: 100%; border-radius: 10px; }
/* Kein Zoom ins Bild mehr: die Karte hebt sich leicht,
   das Bild dunkelt dezent ab und in der Mitte erscheint der Lupen-Knopf (Milchglas). */
.gd-shot--thumb { transition: transform .22s ease, box-shadow .22s ease, border-color .15s; }
.gd-shot--thumb:hover, .gd-shot--thumb:focus-visible { box-shadow: 0 12px 26px -12px rgba(15, 23, 42, .4); }
.gd-shot--thumb .gd-shot__frame::after { content: ''; position: absolute; inset: 0; background: rgba(15, 23, 42, 0); transition: background-color .22s ease;
  pointer-events: none; }
.gd-shot--thumb:hover .gd-shot__frame::after, .gd-shot--thumb:focus-visible .gd-shot__frame::after { background: rgba(15, 23, 42, .16); }
.gd-shot--thumb .gd-shot__zoom { z-index: 1; top: 50%; right: auto; left: 50%; width: 38px; height: 38px; border-radius: 50%;
  border-color: color-mix(in srgb, var(--border) 60%, transparent); background: color-mix(in srgb, var(--surface) 78%, transparent);
  backdrop-filter: blur(8px) saturate(1.4); color: var(--gw); box-shadow: 0 6px 16px -6px rgba(15, 23, 42, .4);
  opacity: 0; transform: translate(-50%, -50%) scale(.85); transition: opacity .22s ease, transform .22s ease; }
.gd-shot--thumb .gd-shot__zoom svg { width: 16px; height: 16px; }
.gd-shot--thumb:hover .gd-shot__zoom, .gd-shot--thumb:focus-visible .gd-shot__zoom { opacity: 1; transform: translate(-50%, -50%) scale(1); }
@media (prefers-reduced-motion: reduce) { .gd-shot--thumb, .gd-shot--thumb .gd-shot__zoom { transition: none; } .gd-shot--thumb:hover { transform: none; } }
.gd-shot--thumb .gd-shot__cap { display: flex; flex-direction: column; gap: 3px; white-space: normal; padding: 8px 11px 9px; }
/* Bildunterschrift in der Spalte: oben Schritt + was das Bild zeigt, darunter der Weg dorthin (03.10.2026). */
.gd-shot__title { display: flex; align-items: center; min-width: 0; }
.gd-shot__what { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 12px; font-weight: 600; color: var(--text-1); }
.gd-shot__path { display: flex; flex-wrap: wrap; align-items: center; row-gap: 1px; font-size: 10.5px; font-weight: 500; color: var(--text-4); }
.gd-shot__path .gd-shot__sep { margin: 0 4px; }
.gd-shot__sep { user-select: none; }
.gd-lb__cap .gd-shot__title { display: inline-flex; margin-right: 10px; }
.gd-lb__cap .gd-shot__what { color: inherit; font-size: inherit; }
.gd-lb__cap .gd-shot__path { display: inline-flex; color: #94a3b8; font-size: inherit; }
.gd-shot__step { margin-right: 8px; padding: 1px 8px; border-radius: 999px; background: var(--gw-light); color: var(--gw);
  font-size: 10.5px; font-weight: 700; line-height: 1.6; white-space: nowrap; }
.gd-lb__cap .gd-shot__step { font-size: 11.5px; }
/* Bildwechsler ab 2 Bildern (GuideShot::column):
   oben die Vorschauleiste aller Bilder, darunter die Bühne mit dem aktiven Bild; die nächsten zwei liegen gestaffelt
   darunter wie ein Kartenstapel. Pfeile als Milchglas-Knöpfe auf dem Bild, Zähler im Kopf. Keine Leuchteffekte,
   nur Hausblau. Ohne Skript (kein .is-deck) und im Druck: Leiste/Pfeile weg, alle Bilder untereinander. */
.gd-deck__strip, .gd-deck__ctl { display: none; }
.gd-shot-stack--deck.is-deck .gd-deck__ctl { display: inline-flex; align-items: center; gap: 2px; margin-left: auto; }
.gd-deck__count { min-width: 34px; text-align: center; font: 600 11px/1 var(--font-mono); color: var(--text-3); font-variant-numeric: tabular-nums; }
.gd-shot-stack--deck.is-deck .gd-deck__strip { display: flex; flex-direction: column; gap: 3px; }
.gd-deck__tab { display: flex; align-items: center; gap: 8px; min-width: 0; padding: 3px 8px 3px 3px; border: 1px solid transparent;
  border-radius: 8px; background: var(--surface); color: var(--text-2); font: 500 11.5px/1.3 var(--font, inherit); text-align: left;
  cursor: pointer; transition: border-color .2s ease, background-color .2s ease, color .2s ease; }
.gd-deck__num { flex-shrink: 0; min-width: 22px; padding: 2px 5px; border-radius: 5px; background: var(--bg); color: var(--text-3);
  font: 700 10.5px/1.3 var(--font-mono); text-align: center; transition: background-color .2s ease, color .2s ease; }
.gd-deck__lbl { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gd-deck__tab:hover { background: color-mix(in srgb, var(--text-1) 4%, var(--surface)); color: var(--text-1); }
.gd-deck__tab.is-on { border-color: var(--gw); background: var(--gw-light); color: var(--gw); font-weight: 600; }
.gd-deck__tab.is-on .gd-deck__num { background: var(--gw); color: #fff; }
.gd-deck__tab:focus-visible, .gd-deck__arrow:focus-visible { outline: 2px solid var(--gw); outline-offset: 2px; }
.gd-deck__stage { position: relative; }
.gd-shot-stack--deck.is-deck .gd-deck__pile { position: relative; isolation: isolate; margin-bottom: 18px; }
.gd-shot-stack--deck.is-deck .gd-deck__item { border-radius: 10px; transform-origin: 50% 100%;
  transition: transform .42s cubic-bezier(.2, .8, .2, 1), opacity .32s ease, box-shadow .32s ease; }
.gd-shot-stack--deck.is-deck .gd-deck__item.is-on { position: relative; z-index: 3; box-shadow: 0 10px 28px -8px rgba(15, 23, 42, .28); }
.gd-shot-stack--deck.is-deck .gd-deck__item:not(.is-on) { position: absolute; inset: 0; overflow: hidden; pointer-events: none; opacity: 0;
  transform: translateY(26px) scale(.82); }
.gd-shot-stack--deck.is-deck .gd-deck__item.is-n1 { z-index: 2; opacity: .9; pointer-events: auto; cursor: pointer; transform: translateY(9px) scale(.94); }
.gd-shot-stack--deck.is-deck .gd-deck__item.is-n2 { z-index: 1; opacity: .7; pointer-events: auto; cursor: pointer; transform: translateY(18px) scale(.88); }
/* Das gerade verlassene Bild gleitet nach links aus der Bühne. */
.gd-shot-stack--deck.is-deck .gd-deck__item.is-out { z-index: 4; opacity: 0; transform: translateX(-24px) scale(.97); }
/* Dahinterliegende Karten zeigen nur ihre leere Kante, keine angeschnittenen Bildteile. */
.gd-shot-stack--deck.is-deck .gd-deck__item:not(.is-on) { background: var(--surface); border: 1px solid var(--border); }
.gd-deck__item:not(.is-on) > * { visibility: hidden; }
.gd-deck__item:not(.is-on) .gd-shot { transform: none !important; box-shadow: none !important; }
.gd-deck__arrow { display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px; padding: 0; border: 0;
  border-radius: 6px; background: none; color: var(--text-3); cursor: pointer; transition: color .15s, background-color .15s; }
.gd-deck__arrow svg { width: 15px; height: 15px; }
.gd-deck__arrow:hover { color: var(--gw); background: var(--gw-light); }
[data-theme="dark"] .gd-shot-stack--deck.is-deck .gd-deck__item.is-on { box-shadow: 0 10px 28px -8px rgba(0, 0, 0, .7); }
@media (prefers-reduced-motion: reduce) { .gd-shot-stack--deck.is-deck .gd-deck__item, .gd-deck__tab, .gd-deck__arrow { transition: none; } }
/* Quellenzeile unter fremden Bildern (Hersteller-Dokus, Wikimedia Commons; 03.10.2026) */
.gd-shot-credited { display: flex; flex-direction: column; gap: 5px; }
.gd-shot__credit { margin: 0 2px; font-size: 11px; line-height: 1.4; color: var(--text-4); }
.gd-shot-credited .gd-shot__credit a { color: inherit; text-decoration: underline; text-decoration-color: var(--border); }
.gd-shot-credited .gd-shot__credit a:hover { color: var(--gw); }
@container (max-width: 720px) {
  .gd-shot-cols { display: block; }
  .gd-shot-stack { position: static; flex-flow: row wrap; margin: 4px 0 12px; }
  .gd-shot-stack__head { flex-basis: 100%; }
  .gd-shot-stack .gd-shot--thumb { width: 272px; max-width: 100%; }
  .gd-shot-stack .gd-shot-credited { width: 272px; max-width: 100%; }
  /* Bildwechsler unter dem Text (schmale Seite, Hilfe-Lasche): quer statt schmaler Turm — links die Bildliste, rechts
     das Bild (in der Lasche blieb rechts sonst alles leer). */
  .gd-shot-stack--deck.is-deck { display: grid; grid-template-columns: minmax(150px, 230px) minmax(0, 1fr);
    grid-template-areas: "head head" "strip stage"; gap: 12px 18px; align-items: start; }
  .gd-shot-stack--deck.is-deck .gd-shot-stack__head { grid-area: head; }
  .gd-shot-stack--deck.is-deck .gd-deck__strip { grid-area: strip; }
  .gd-shot-stack--deck.is-deck .gd-deck__stage { grid-area: stage; max-width: 560px; }
  .gd-shot-stack--deck .gd-shot--thumb, .gd-shot-stack--deck .gd-shot-credited { width: 100%; }
}
@container (max-width: 460px) {
  .gd-shot-stack--deck.is-deck { grid-template-columns: minmax(0, 1fr); grid-template-areas: "head" "strip" "stage"; }
}
/* Hinweis-Kästen (qs-tip/-warn/-info/-rec): nur die fette Überschrift am Anfang steht auf eigener Zeile. Die Regel
   «.qs-info strong { display:block }» in 25 Anleitungen traf jedes fette Wort im Text — «Und, oder» zerfiel in
   Einzelzeilen. Höhere Spezifität als die Vorlagen-Regeln, damit sie überall gilt. */
:is(.qs-tip, .qs-warn, .qs-info, .qs-rec) > :not(svg) strong { display: inline; margin-bottom: 0; }
:is(.qs-tip, .qs-warn, .qs-info, .qs-rec) > :not(svg) > strong:first-child { display: block; margin-bottom: 2px; }
/* Beispiel je Funktion in den Reiter-Anleitungen (guide.wafcat.<fn>.bsp), wie bisher auf den WAF-Seiten (.wc-bsp).
   Eine Klasse fuer alle Reiter, damit die Beispiele nach der Umleitung der WAF-Seiten ueberall gleich aussehen. */
/* «Begriffe in dieser Anleitung» am Ende jeder Anleitung (Core\GuideTerms, 26.09.2026): wie das Begriffsnetz im
   Glossar — Hausblau, Umlaufbahn, geschwungene Linien, kein Leuchten. Serverseitig gezeichnet (auch in der Hilfe-Lasche). */
/* «Begriffe in dieser Anleitung» — gleich gestaltet wie das Begriffsnetz im Glossar: Hintergrund
   wie der Visualizer (weiche Farbflecken), Punktraster, Umlaufbahn, Mitte als gefüllte Pille mit Doppelring, durchgezogene
   gebogene Linien, Begriffe mit Bereichssymbol und Verbindungszahl, volle Breite. Kein Leuchten. */
.gd-terms { margin: 34px 0 10px; padding: 14px 16px 12px; border: 1px solid var(--border); border-radius: 14px; overflow: hidden;
  background:
    radial-gradient(circle at 12% -10%, rgba(236,72,153,.09), transparent 46%),
    radial-gradient(circle at 92% 110%, rgba(34,211,238,.11), transparent 52%),
    radial-gradient(circle at 50% 45%, rgba(139,92,246,.05), transparent 65%),
    var(--surface) }
[data-theme="dark"] .gd-terms { border-color: rgba(34,211,238,.10);
  background:
    radial-gradient(circle at 14% -8%, rgba(236,72,153,.20), transparent 48%),
    radial-gradient(circle at 92% 108%, rgba(34,211,238,.22), transparent 52%),
    radial-gradient(circle at 50% 45%, rgba(139,92,246,.10), transparent 65%),
    repeating-linear-gradient(0deg, rgba(34,211,238,.030) 0 1px, transparent 1px 4px),
    linear-gradient(180deg, #04060c 0%, #0a0e1a 100%) }
.gd-terms__head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 12px }
.gd-terms__ttl { font-size: 10px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase; color: var(--gw) }
.gd-terms__sub { font-size: 12.5px; color: var(--text-3) }
.gd-terms__svg { display: block; width: 100%; height: auto; margin: 6px 0 4px }
.gd-terms__svg .dot { fill: color-mix(in srgb, var(--text-4) 30%, transparent) }
[data-theme="dark"] .gd-terms__svg .dot { fill: rgba(34,211,238,.16) }
.gd-terms__svg .orbit { fill: none; stroke: color-mix(in srgb, var(--gw) 35%, transparent); stroke-dasharray: 2 6 }
.gd-terms__svg .e1 { fill: none; stroke: color-mix(in srgb, var(--gw) 55%, transparent); stroke-width: 1.6 }
.gd-terms__svg g.n rect { fill: var(--surface); stroke: color-mix(in srgb, var(--gw) 55%, var(--border)); stroke-width: 1.5 }
.gd-terms__svg g.n text { fill: var(--text-1); font-size: 12.5px; font-weight: 600 }
.gd-terms__svg g.n .ico { color: var(--gw) }
.gd-terms__svg g.n .badge circle { fill: var(--surface); stroke: var(--border); stroke-width: 1 }
.gd-terms__svg g.n .badge text { font-size: 9.5px; font-weight: 700; fill: var(--text-3) }
.gd-terms__svg a:hover g.n rect, .gd-terms__svg a:focus-visible g.n rect { stroke: var(--gw); fill: color-mix(in srgb, var(--gw) 8%, var(--surface)) }
.gd-terms__svg g.n0 .body { fill: var(--gw); stroke: var(--gw); stroke-width: 1.5 }
.gd-terms__svg g.n0 .halo { fill: none; stroke: color-mix(in srgb, var(--gw) 45%, transparent); stroke-width: 1.5; stroke-dasharray: 4 3 }
.gd-terms__svg g.n0 .ico { color: #fff }
.gd-terms__svg g.n0 text { fill: #fff; font-size: 14px; font-weight: 750 }
.gd-terms__svg text { dominant-baseline: central; text-anchor: middle; pointer-events: none; font-family: inherit }
.gh-reader__doc .gd-terms { margin-top: 24px }
.gd-bsp { margin-top: 11px; border-left: 3px solid var(--text-4); border-radius: 0 8px 8px 0;
          background: color-mix(in srgb, var(--text-4) 7%, transparent); padding: 9px 12px; break-inside: avoid; }
.gd-bsp__t { font-size: 11px; font-weight: 700; color: var(--text-3); margin-bottom: 3px; text-transform: uppercase; letter-spacing: .05em; }
.gd-bsp__p { font-size: 12.5px; line-height: 1.65; color: var(--text-2); }
.gd-bsp__p strong { color: var(--text-1); }
.gd-bsp__p code { font-family: var(--font-mono); font-size: 11.5px; background: var(--bg-2); border: 1px solid var(--border); border-radius: 5px; padding: 1px 5px; word-break: break-all; }
/* Shadowbox */
.gd-lb { position: fixed; inset: 0; z-index: 10050; display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 12px; padding: 56px 72px 28px; background: rgba(8, 12, 20, .9); backdrop-filter: blur(6px); opacity: 0; transition: opacity .15s; }
.gd-lb.is-open { opacity: 1; }
.gd-lb:focus { outline: none; }
.gd-lb__frame { position: relative; overflow: hidden; border-radius: 12px; border: 1px solid rgba(255, 255, 255, .14);
  background: var(--surface); box-shadow: 0 24px 64px rgba(0, 0, 0, .45); cursor: zoom-out; }
.gd-lb__frame .gd-shot__img { display: block !important; }
/* Leiste der Gruppe unten in der Shadowbox: Klein-Vorschau aller Bilder der Spalte. */
.gd-lb__strip { display: flex; gap: 8px; max-width: min(100%, 900px); overflow-x: auto; padding: 4px 2px; scrollbar-width: thin; }
.gd-lb__thumb { flex: 0 0 auto; width: 84px; height: 58px; padding: 0; border: 1px solid rgba(255, 255, 255, .16); border-radius: 8px; overflow: hidden;
  background: #0f172a; cursor: pointer; opacity: .55; transition: opacity .2s ease, border-color .2s ease, transform .2s ease; }
.gd-lb__thumb img { display: block; width: 100%; height: 100%; object-fit: cover; object-position: 50% 0; }
.gd-lb__thumb:hover { opacity: .9; }
.gd-lb__thumb.is-on { opacity: 1; border-color: var(--gw); box-shadow: inset 0 0 0 1px var(--gw); }
.gd-lb__thumb:focus-visible { outline: 2px solid var(--gw); outline-offset: 2px; }
.gd-lb__cap { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 6px; font-size: 13px; font-weight: 600; color: #e5e7eb; }
.gd-lb__cap .gd-shot__sep { color: #94a3b8; }
.gd-lb__count { margin-left: 10px; font-weight: 500; color: #94a3b8; font-variant-numeric: tabular-nums; }
.gd-lb__btn { position: absolute; display: inline-flex; align-items: center; justify-content: center; width: 40px; height: 40px;
  border-radius: 10px; border: 1px solid rgba(255, 255, 255, .18); background: rgba(255, 255, 255, .08); color: #fff; cursor: pointer; }
.gd-lb__btn:hover { background: rgba(255, 255, 255, .16); }
.gd-lb__btn:focus-visible { outline: 2px solid var(--gw); outline-offset: 2px; }

/* ── Schemazeichnungen der Anleitungen (Core/GuideDiagram, 22.09.2026) ──────────────────────────
   Reines Inline-SVG; jede Farbe kommt aus den Haus-Variablen, darum braucht Dunkel keine eigene Fassung.
   Hausblau markiert nur das eigene System und seine Schritte — dort passiert, was der Text erklärt.
   Unter 640 px schrumpft die Schrift nicht weiter, die Figur scrollt dann quer. */
.gdd { --gdd-band: color-mix(in srgb, var(--text-4) 9%, var(--surface));
  margin: 6px 0 18px; padding: 18px 18px 12px; border: 1px solid var(--border); border-radius: 12px; background: var(--surface); }
.gdd__scroll { overflow-x: auto; }
.gdd__svg { display: block; width: 100%; min-width: 640px; height: auto; font-family: var(--font); }
.gdd__cap { margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--sep); font-size: 12.5px; line-height: 1.55; color: var(--text-3); }
.gdd-phase { fill: var(--gdd-band); stroke: none; }
.gdd-phase__lbl { font-size: 10.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; fill: var(--text-4); paint-order: stroke; stroke: var(--gdd-band); stroke-width: 4px; stroke-linejoin: round; }
.gdd-life { stroke: var(--border-2); stroke-width: 1.2; stroke-dasharray: 3 5; }
.gdd-life.is-own { stroke: var(--gw); stroke-opacity: .45; }
.gdd-actor rect { fill: var(--surface); stroke: var(--border-2); stroke-width: 1.2; }
.gdd-actor.is-own rect { fill: var(--gw-light); stroke: var(--gw); stroke-width: 1.6; }
.gdd-actor__t { font-size: 13.5px; font-weight: 700; fill: var(--text-1); text-anchor: middle; }
.gdd-actor__s { font-size: 11px; font-family: var(--font-mono); fill: var(--text-3); text-anchor: middle; }
.gdd-msg line { stroke: var(--text-3); stroke-width: 1.6; }
.gdd-msg polygon, .gdd-msg circle { fill: var(--text-3); }
.gdd-msg.is-reply line { stroke-dasharray: 5 4; }
.gdd-msg.is-own line { stroke: var(--gw); }
.gdd-msg.is-own polygon, .gdd-msg.is-own circle { fill: var(--gw); }
.gdd-msg__n { font-size: 11px; font-weight: 700; fill: var(--surface); text-anchor: middle; font-variant-numeric: tabular-nums; }
.gdd-msg.is-own .gdd-msg__n { fill: #fff; }
.gdd-msg__t { font-size: 12.5px; font-weight: 600; fill: var(--text-2); text-anchor: middle; paint-order: stroke; stroke: var(--gdd-band); stroke-width: 4px; stroke-linejoin: round; }
.gdd-msg.is-own .gdd-msg__t { fill: var(--text-1); }
.gdd-edge { fill: none; stroke: var(--border-2); stroke-width: 1.4; }
.gdd-edge.is-own { stroke: var(--gw); stroke-width: 1.6; }
.gdd-q rect { fill: var(--gdd-band); stroke: var(--border-2); stroke-width: 1.2; }
.gdd-q__t { font-size: 13px; font-weight: 600; fill: var(--text-1); text-anchor: middle; }
.gdd-fix__t { font-size: 12.5px; font-weight: 600; fill: var(--text-2); text-anchor: middle; }
.gdd-yn { font-size: 11.5px; font-weight: 700; fill: var(--text-3); text-anchor: middle; }
.gdd-yn--start { text-anchor: start; }
.gdd-top { font-size: 12.5px; font-weight: 600; fill: var(--text-3); text-anchor: middle; }
.gdd-stage rect { fill: var(--surface); stroke: var(--gw); stroke-opacity: .45; stroke-width: 1.1; }
.gdd-stage__n { font-size: 11px; font-weight: 700; fill: var(--gw); text-anchor: middle; font-variant-numeric: tabular-nums; }
.gdd-stage__t { font-size: 12.5px; font-weight: 600; fill: var(--text-1); text-anchor: middle; }
.gdd-actor.is-bad rect { stroke-dasharray: 5 4; }
.gdd-msg.is-bad line { stroke-dasharray: 5 4; }
.gdd-stop { fill: var(--surface); stroke: var(--text-3); stroke-width: 1.6; }
.gdd-stop__x { stroke: var(--text-2); stroke-width: 1.8; stroke-linecap: round; fill: none; }
.gdd-axis { stroke: var(--border-2); stroke-width: 2; }
.gdd-axis__tip { fill: var(--border-2); }
.gdd-gap { fill: var(--gdd-band); stroke: var(--border-2); stroke-width: 1; stroke-dasharray: 3 3; }
.gdd-gap__t { font-size: 11.5px; font-weight: 600; fill: var(--text-3); text-anchor: middle; }
.gdd-tick circle { fill: var(--text-3); }
.gdd-tick.is-own circle { fill: var(--gw); }
.gdd-tick__n { font-size: 10.5px; font-weight: 700; fill: var(--surface); text-anchor: middle; }
.gdd-tick.is-own .gdd-tick__n { fill: #fff; }
.gdd-when { font-size: 12px; font-weight: 600; fill: var(--text-3); text-anchor: middle; font-family: var(--font-mono); }
.gdd-tl__s { font-size: 12px; font-weight: 500; fill: var(--text-3); text-anchor: middle; }
.gdd-edge__t { font-size: 11.5px; font-weight: 600; fill: var(--text-3); text-anchor: middle; paint-order: stroke; stroke: var(--surface); stroke-width: 4px; stroke-linejoin: round; }
.gdd-lvl { font-size: 11px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; fill: var(--text-3); }
.gdd-own { fill: none; stroke: var(--gw); stroke-width: 1.4; stroke-dasharray: 6 5; stroke-opacity: .7; }
.gdd-own__t { font-size: 11px; font-weight: 700; fill: var(--gw); text-anchor: end; letter-spacing: .03em; }
.gdd-edge__dot { fill: var(--border-2); }
.gdd-edge__dot.is-own { fill: var(--gw); }
.gdd-edge__t--start { text-anchor: start; }
.gdd-tn__big { font-size: 28px; font-weight: 800; }
.gdd-tn__s { font-size: 11.5px; font-weight: 500; fill: var(--text-3); text-anchor: middle; }
.gdd-tn.is-own .gdd-tn__s { fill: var(--gw); }
.gdd-dq rect { fill: var(--surface); stroke: var(--border-2); stroke-width: 1.2; }
.gdd-dfix rect { fill: var(--gdd-band); stroke: var(--border-2); stroke-width: 1.2; stroke-dasharray: 0; }
.gdd-dkick { font-size: 10.5px; font-weight: 700; letter-spacing: .07em; fill: var(--gw); }
.gdd-dq__t { font-size: 13.5px; font-weight: 700; fill: var(--text-1); }
.gdd-dfix .gdd-dq__t, text.gdd-dq__t { font-weight: 700; }
.gdd-dq__s { font-size: 12px; font-weight: 500; fill: var(--text-3); }
.gdd-dwhere { font-size: 11.5px; font-weight: 600; fill: var(--gw); }
.gdd-dtool g { fill: none; stroke: var(--gw); stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }
.gdd-dpill rect { fill: var(--surface); stroke: var(--border-2); stroke-width: 1.2; }
.gdd-dpill text { font-size: 11px; font-weight: 700; fill: var(--text-2); text-anchor: middle; }
.gdd-dpill.is-go rect { fill: var(--gw-light); stroke: var(--gw); stroke-opacity: .5; }
.gdd-dpill.is-go text { fill: var(--gw); }
.gdd-dnum { font-size: 12px; }
.gdd-dterm.is-own rect { stroke-width: 1.6; }
.gdd-pl__t { font-size: 13.5px; font-weight: 700; fill: var(--text-1); }
.gdd-pl__s { font-size: 11.5px; font-weight: 500; fill: var(--text-3); }
.gdd-pl__st { font-size: 12.5px; font-weight: 600; fill: var(--text-1); }
.gdd-pl__row { fill: var(--surface); stroke: color-mix(in srgb, var(--gw) 35%, transparent); stroke-width: 1; }
.gdd-pl__rail { stroke: var(--gw); stroke-opacity: .35; stroke-width: 2; }
.gdd-pl__dot { fill: var(--gw); }
.gdd-pl__n { font-size: 10.5px; font-weight: 700; fill: #fff; text-anchor: middle; font-variant-numeric: tabular-nums; }
.gdd-ico > circle { fill: var(--gdd-band); stroke: none; }
.gdd-ico g { fill: none; stroke: var(--text-2); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.gdd-ico g circle { fill: none; }
.gdd-ico.is-own > circle { fill: var(--surface); }
.gdd-ico.is-own g { stroke: var(--gw); }
.gdd-pl.is-bad .gdd-ico g { stroke: var(--text-3); }
.gd-lb__btn svg { width: 18px; height: 18px; }
.gd-lb__close { top: 12px; right: 12px; }
.gd-lb__prev { left: 16px; top: 50%; margin-top: -20px; }
.gd-lb__next { right: 16px; top: 50%; margin-top: -20px; }
@media (max-width: 760px) { .gd-lb { padding: 56px 12px 20px; } .gd-lb__prev, .gd-lb__next { top: auto; bottom: 14px; margin: 0; } }
@media (max-width: 760px) {
  .gw-wn { padding: 8px; }
  .gw-wn__dlg { grid-template-columns: 1fr; grid-template-rows: auto minmax(0, 1fr); height: calc(100vh - 16px); }
  .gw-wn__rail { border-right: none; border-bottom: 1px solid var(--border); }
  .gw-wn__rhead { padding: 18px 20px 12px; }
  .gw-wn__intro, .gw-wn__tabs, .gw-wn__rfoot { display: none; }
  .gw-wn__stage { height: 176px; padding: 16px; }
  .gw-wn__body { padding: 18px 20px 20px; }
  .gw-wn__foot { padding: 12px 16px; }
  .gw-wn__prog { display: none; }
}
[data-theme="dark"] .gw-um__seg button[aria-pressed="true"] { background: var(--surface-2, var(--border)); }

/* DNS status dot */
.sidebar-dns-status {
  display: flex; align-items: center; gap: 7px;
  padding: 6px 14px;
  opacity: 0;
  transition: opacity .15s .05s;
  white-space: nowrap;
}
.sidebar:not(.mini) .sidebar-dns-status,
.sidebar:not(.mini) .sidebar-dns-status { opacity: 1; }
.dns-dot { width: 6px; height: 6px; border-radius: 50%; }
.dns-dot.online  { background: var(--ok); box-shadow: 0 0 0 2px rgba(22,163,74,.2); }
.dns-dot.offline { background: var(--err); }
.sidebar-dns-status span { font-size: 11px; color: var(--sidebar-fg-muted); }

/* ── Topbar ─────────────────────────────────────────────── */
.topbar {
  height: var(--topbar-h);
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  display: flex;
  align-items: center;
  /* links 8 px: der Einklapp-Knopf sitzt nah an der seitlichen Navigation, mobil gilt weiter 12 px (Media-Regel oben) */
  padding: 0 20px 0 8px;
  gap: 12px;
  flex-shrink: 0;
}
.topbar-title { font-size: 15px; font-weight: 700; color: var(--text-1); }
/* Brotkrumen mit Zonen-Auswahl (19.09.2026): «Zonen › example.ch ▾». Die Zone ist ein Knopf, sieht aber
   aus wie der Titel; erst beim Ueberfahren wird er als Knopf sichtbar. */
/* Zonenname nie mit «…» kürzen: die Brotkrumen schrumpfen nicht, Platz gibt die Suche
   daneben ab (.topbar-search-wrap) — bei 1440 px stand vorher «example.c…». */
.tb-crumbs { display: flex; align-items: center; gap: 4px; min-width: 0; flex-shrink: 0; }
.tb-crumb { color: var(--text-3); font-weight: 600; text-decoration: none; padding: 3px 6px; border-radius: var(--r); white-space: nowrap; }
a.tb-crumb:hover { color: var(--text-1); background: var(--bg); text-decoration: none; }
.tb-crumb-sep { color: var(--text-4); font-weight: 400; }
.tb-crumb--zone { display: inline-flex; align-items: center; gap: 5px; min-width: 0; border: 0; background: transparent;
  font: inherit; font-weight: 700; color: var(--text-1); cursor: pointer; }
.tb-crumb--zone:hover, .tb-crumb--zone[aria-expanded="true"] { background: var(--bg); }
.tb-crumb--zone:focus-visible { outline: 2px solid var(--gw); outline-offset: 1px; }
.tb-crumb__txt { white-space: nowrap; }
.tb-crumb--cur { display: inline-flex; min-width: 0; color: var(--text-1); font-weight: 700; }
.tb-crumb--zone svg { width: 14px; height: 14px; flex: none; color: var(--text-3); }
.gw-zsw { width: 320px; }
.gw-zsw__search { display: flex; align-items: center; gap: 8px; margin: 2px 2px 6px; padding: 0 10px; height: 34px;
  border: 1px solid var(--border); border-radius: 8px; background: var(--bg); }
.gw-zsw__search:focus-within { border-color: var(--gw); box-shadow: 0 0 0 3px var(--gw-light); }
.gw-zsw__search svg { width: 14px; height: 14px; flex: none; color: var(--text-3); }
.gw-zsw__search input { flex: 1; min-width: 0; border: 0; outline: none; background: transparent; color: var(--text-1); font: inherit; font-size: 13px; }
.gw-zsw__list { max-height: min(60vh, 420px); overflow-y: auto; }
.gw-zsw__item { justify-content: space-between; }
.gw-zsw__name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gw-zsw__item .gw-zsw__star { width: 12px; height: 12px; margin-right: 6px; vertical-align: -1px; color: inherit; }
.gw-zsw__item > .gw-zsw__sub { flex: none; max-width: 45%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--text-4); font-size: 11.5px; }
.gw-zsw__item[aria-current="page"] { color: var(--gw); font-weight: 600; background: var(--gw-light); }
.gw-zsw__item.is-inactive .gw-zsw__name { color: var(--text-4); }
.gw-zsw__empty, .gw-zsw__more { padding: 10px 8px; color: var(--text-4); font-size: 12px; }
.gw-zsw__more { border-top: 1px solid var(--border); margin-top: 4px; padding-bottom: 4px; }

/* Search */
/* Die Suche ist das, was in der Kopfzeile nachgibt (flex-shrink 20 gegen 1 der Aktionen): Zonenname und
   Seiten-Aktionen behalten ihre Breite. Bis 1440 px darf sie bis aufs Lupen-Symbol schrumpfen, der Hinweis
   «Ctrl F» fällt dort weg (das Kürzel öffnet die Suche weiterhin). */
.topbar-search-wrap { position: relative; flex: 1 20 220px; min-width: 170px; max-width: 330px; margin: 0 14px; }
@media (max-width: 1440px) { .topbar-search-wrap { min-width: 44px; margin: 0 8px; } .topbar-search-kbd { display: none; } .topbar-actions:not(:has(.tba-filters)) { flex-shrink: 0; } }
.topbar-search {
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--bg);
  border: 1.5px solid var(--border);
  border-radius: 8px;
  padding: 0 12px;
  height: 34px;
  width: 100%;
  cursor: text;
  transition: border-color .15s, box-shadow .15s;
}
.topbar-search:focus-within {
  border-color: var(--gw);
  box-shadow: 0 0 0 3px rgba(0,152,239,.1);
  background: var(--surface);
}
.topbar-search svg { color: var(--text-4); width: 14px; height: 14px; flex-shrink: 0; }

/* ── Klebende Kopfzeile — die Regel steht einmal ───────────────────────────────
   v7.3.69 hat sie fuer die Records-Tabelle gebaut, v7.3.70 auf einen angemeldeten
   Zustand eingegrenzt (sie hing an einer Klasse, die fuenf Tabellen tragen). Seit dem
   09.09. gilt sie auch auf «DNS-Zonen» und «DNS-Records» — also steht die Entscheidung
   jetzt hier, statt ein drittes Mal abgeschrieben zu werden.

   Achtung: die Falle (drei Anlaeufe in v7.3.69): jeder Vorfahre mit `overflow` ausser
   `visible` ist ein Scrollport, und `position:sticky` haengt sich an den naechsten.
   `.card` traegt `overflow:hidden` (wegen der runden Ecken) — darin klebt eine
   Kopfzeile an einem Behaelter, der gar nicht scrollt, also sichtbar an nichts.
   Der Rahmen gibt seinen Scrollport darum auf, aber nur wenn die Tabelle ohnehin
   ohne Querscrollen hineinpasst; sonst waere der Querscroll weg.
   `top` kommt aus --gw-stickbar-h (app.js misst die Unterkante einer angedockten
   Leiste); ohne Leiste klebt sie oben, was ohne Leiste genau richtig ist. */
/* Achtung: Die Klasse steht doppelt: der Rahmen ist mal `.card` (overflow:hidden, wegen
   der runden Ecken), mal `.records-table-wrap` (overflow-x:auto). Beide sind
   einklassig — mit nur einer Klasse entschiede die Reihenfolge der Dateien, wer
   gewinnt, und das ist keine Entscheidung, sondern ein Zufall. */
.gw-stickhead-wrap.gw-stickhead-wrap { overflow: visible }
.gw-head-sticks thead th { position: sticky; top: var(--gw-stickbar-h, 0px); z-index: 3 }
/* Kopf-Doppel (app.js gwKopfDoppel): wenn die Tabelle quer scrollt, kann der Kopf nicht
   sticky kleben — eine Kopie steht fest unter der Leiste und laeuft quer mit (Zone-Health,
   14.09.2026). Unter der Leiste (z-index 20), ueber den Zeilen; Schatten wie die angedockte
   Leiste. Kein `display` hier, damit `hidden` sie wirklich versteckt. */
.gw-kopfdoppel { position: fixed; z-index: 19; overflow: hidden; box-shadow: 0 6px 18px rgba(0,0,0,.10), 0 1px 0 var(--border) }
[data-theme="dark"] .gw-kopfdoppel { box-shadow: 0 6px 20px rgba(0,0,0,.45), 0 1px 0 var(--border) }
.gw-kopfdoppel > table { margin: 0 }
/* Feste erste Spalte (data-gw-stickcol): scrollt eine breite Tabelle quer, bleibt die Spalte,
   die die Zeile benennt, links stehen (z.B. die Spalte «Zone» in Zone-Health). Die Zellen brauchen einen deckenden Grund,
   sonst laufen die anderen Spalten sichtbar darunter durch; der Hover gilt auch hier. Die
   Kopie des Kopfes (gwKopfDoppel) schiebt ihre erste Zelle in app.js gegen den Querscroll.
   Nur ab Tablet-Breite — darunter ist die Tabelle ein Kartenstapel. */
@media (min-width: 769px) {
  table[data-gw-stickcol] > thead > tr > th:first-child,
  table[data-gw-stickcol] > tbody > tr > td:first-child { position: sticky; left: 0; z-index: 2; box-shadow: inset -1px 0 0 var(--border) }
  table[data-gw-stickcol] > tbody > tr > td:first-child { background: var(--surface) }
  table[data-gw-stickcol] > tbody > tr:hover > td:first-child { background: var(--row-hover) }
  table[data-gw-stickcol].gw-head-sticks > thead > tr > th:first-child { z-index: 4 }
  /* data-gw-stickcol="N" (2–5): die ersten N Spalten bleiben stehen. Erst für die Benutzerverwaltung (zwei,
     23.09.2026 — vorne die Auswahl-Checkbox, die Zeile benennt erst «Benutzer»), am 01.10.2026 für
     DNS-Zonen bis und mit «Zone» (5) und DNS-Records bis und mit «Zone» (2). Der Abstand links der Spalte k ist
     die Summe der Breiten davor, gemessen in app.js (--gw-sc1 … --gw-sc4, nur bei geändertem Wert gesetzt).
     Die Trennlinie steht an der letzten festen Spalte. */
  table[data-gw-stickcol="2"] > thead > tr > th:nth-child(-n+2),
  table[data-gw-stickcol="2"] > tbody > tr > td:nth-child(-n+2) { position: sticky; z-index: 2; box-shadow: none }
  table[data-gw-stickcol="2"] > tbody > tr > td:nth-child(-n+2) { background: var(--surface) }
  table[data-gw-stickcol="2"] > tbody > tr:hover > td:nth-child(-n+2) { background: var(--row-hover) }
  table[data-gw-stickcol="2"].gw-head-sticks > thead > tr > th:nth-child(-n+2) { z-index: 4 }
  table[data-gw-stickcol="2"] > thead > tr > th:nth-child(2),
  table[data-gw-stickcol="2"] > tbody > tr > td:nth-child(2) { box-shadow: inset -1px 0 0 var(--border) }
  table[data-gw-stickcol="2"] > thead > tr > th:nth-child(2), table[data-gw-stickcol="2"] > tbody > tr > td:nth-child(2) { left: var(--gw-sc1, 0px) }
  table[data-gw-stickcol="3"] > thead > tr > th:nth-child(-n+3),
  table[data-gw-stickcol="3"] > tbody > tr > td:nth-child(-n+3) { position: sticky; z-index: 2; box-shadow: none }
  table[data-gw-stickcol="3"] > tbody > tr > td:nth-child(-n+3) { background: var(--surface) }
  table[data-gw-stickcol="3"] > tbody > tr:hover > td:nth-child(-n+3) { background: var(--row-hover) }
  table[data-gw-stickcol="3"].gw-head-sticks > thead > tr > th:nth-child(-n+3) { z-index: 4 }
  table[data-gw-stickcol="3"] > thead > tr > th:nth-child(3),
  table[data-gw-stickcol="3"] > tbody > tr > td:nth-child(3) { box-shadow: inset -1px 0 0 var(--border) }
  table[data-gw-stickcol="3"] > thead > tr > th:nth-child(2), table[data-gw-stickcol="3"] > tbody > tr > td:nth-child(2) { left: var(--gw-sc1, 0px) }
  table[data-gw-stickcol="3"] > thead > tr > th:nth-child(3), table[data-gw-stickcol="3"] > tbody > tr > td:nth-child(3) { left: var(--gw-sc2, 0px) }
  table[data-gw-stickcol="4"] > thead > tr > th:nth-child(-n+4),
  table[data-gw-stickcol="4"] > tbody > tr > td:nth-child(-n+4) { position: sticky; z-index: 2; box-shadow: none }
  table[data-gw-stickcol="4"] > tbody > tr > td:nth-child(-n+4) { background: var(--surface) }
  table[data-gw-stickcol="4"] > tbody > tr:hover > td:nth-child(-n+4) { background: var(--row-hover) }
  table[data-gw-stickcol="4"].gw-head-sticks > thead > tr > th:nth-child(-n+4) { z-index: 4 }
  table[data-gw-stickcol="4"] > thead > tr > th:nth-child(4),
  table[data-gw-stickcol="4"] > tbody > tr > td:nth-child(4) { box-shadow: inset -1px 0 0 var(--border) }
  table[data-gw-stickcol="4"] > thead > tr > th:nth-child(2), table[data-gw-stickcol="4"] > tbody > tr > td:nth-child(2) { left: var(--gw-sc1, 0px) }
  table[data-gw-stickcol="4"] > thead > tr > th:nth-child(3), table[data-gw-stickcol="4"] > tbody > tr > td:nth-child(3) { left: var(--gw-sc2, 0px) }
  table[data-gw-stickcol="4"] > thead > tr > th:nth-child(4), table[data-gw-stickcol="4"] > tbody > tr > td:nth-child(4) { left: var(--gw-sc3, 0px) }
  table[data-gw-stickcol="5"] > thead > tr > th:nth-child(-n+5),
  table[data-gw-stickcol="5"] > tbody > tr > td:nth-child(-n+5) { position: sticky; z-index: 2; box-shadow: none }
  table[data-gw-stickcol="5"] > tbody > tr > td:nth-child(-n+5) { background: var(--surface) }
  table[data-gw-stickcol="5"] > tbody > tr:hover > td:nth-child(-n+5) { background: var(--row-hover) }
  table[data-gw-stickcol="5"].gw-head-sticks > thead > tr > th:nth-child(-n+5) { z-index: 4 }
  table[data-gw-stickcol="5"] > thead > tr > th:nth-child(5),
  table[data-gw-stickcol="5"] > tbody > tr > td:nth-child(5) { box-shadow: inset -1px 0 0 var(--border) }
  table[data-gw-stickcol="5"] > thead > tr > th:nth-child(2), table[data-gw-stickcol="5"] > tbody > tr > td:nth-child(2) { left: var(--gw-sc1, 0px) }
  table[data-gw-stickcol="5"] > thead > tr > th:nth-child(3), table[data-gw-stickcol="5"] > tbody > tr > td:nth-child(3) { left: var(--gw-sc2, 0px) }
  table[data-gw-stickcol="5"] > thead > tr > th:nth-child(4), table[data-gw-stickcol="5"] > tbody > tr > td:nth-child(4) { left: var(--gw-sc3, 0px) }
  table[data-gw-stickcol="5"] > thead > tr > th:nth-child(5), table[data-gw-stickcol="5"] > tbody > tr > td:nth-child(5) { left: var(--gw-sc4, 0px) }
}

/* ── Der Grund einer Suchleiste — einmal ───────────────────────────────────────
   Suchleisten haben denselben Grund wie die Suche in der Kopfleiste, im Dunkeln also
   dunkel und nicht hellgrau (auch im Zoneneditor bei den Snapshots).
   Gemessen: im Dunkeln ist `--surface` (#1e293b) heller als der Seitengrund
   (#0f172a). Vier Suchleisten standen auf `--surface` und leuchteten als graues
   Band aus der Seite: .aut-search (Automatisierung), die Snapshot-Record-Suche im
   Zoneneditor, .ptm-search (Proxy-Verkehr) und .snapv-search (Snapshot-Ansicht).
   Die Eingabefelder waren nie das Problem — `[data-theme="dark"] input[type=…]`
   oben zieht sie ohnehin auf `--bg`. Es war jedes Mal der Rahmen darum.
   Dieselbe Rezeptur wie .search-box im Zoneneditor: hell die Karte, dunkel der
   Seitengrund. Wer eine neue Suchleiste baut, nimmt diese Klasse statt eine
   fuenfte Kopie der Entscheidung. `suchleiste_grund_test.cjs` haelt es fest. */
.gw-searchbar { background: var(--surface); }
[data-theme="dark"] .gw-searchbar { background: var(--bg); }
.topbar-search input {
  border: none; background: transparent;
  font-size: 13px; color: var(--text-1);
  font-family: var(--font); outline: none;
  flex: 1; min-width: 0;
}
.topbar-search input::placeholder { color: var(--text-4); }
.topbar-search-kbd {
  font-size: 10px; color: var(--text-4);
  background: var(--surface); border: 1px solid var(--border-2);
  border-radius: 4px; padding: 1px 5px;
  font-family: var(--font-mono);
  flex-shrink: 0;
}

/* Toolbar-Suchfeld (DNS-/Proxy-Analytics, rechts oben): identische Optik wie die
   globale Topbar-Suche (.topbar-search) — Wrapper var(--bg) statt var(--surface),
   Fokus-Glow, dark-safe. Ersetzt die frueheren Inline-Styles, die var(--surface)
   nutzten und im Dark-Mode einen Stufen-Effekt gegen das native <select> ergaben
   („grau/dunkelgrau gemischt"). Das eingebettete <select> (Such-Dimension) erbt den
   Wrapper-Grund; sein Popup folgt dem globalen color-scheme (dark). */
.gw-toolbar-search {
  display: flex; align-items: center; gap: 6px;
  background: var(--bg);
  border: 1.5px solid var(--border);
  border-radius: 8px;
  padding: 0 6px 0 11px;
  height: 36px;
  cursor: text;
  transition: border-color .15s, box-shadow .15s;
}
.gw-toolbar-search:focus-within {
  border-color: var(--gw);
  box-shadow: 0 0 0 3px rgba(0,152,239,.1);
  background: var(--surface);
}
.gw-toolbar-search > svg { color: var(--text-4); width: 14px; height: 14px; flex: none; }
.gw-toolbar-search input {
  border: none; background: transparent; outline: none;
  color: var(--text-1); font-size: 12.5px; font-family: var(--font);
  width: 150px; height: 100%; min-width: 0;
}
.gw-toolbar-search input::placeholder { color: var(--text-4); }
.gw-toolbar-search select {
  border: none; border-left: 1px solid var(--border);
  background: transparent; outline: none;
  color: var(--text-2); font-size: 11.5px; font-family: var(--font);
  padding: 0 2px 0 8px; height: 22px; cursor: pointer;
}
/* Input + Select erben im Dark-Mode denselben transparenten Grund wie die Topbar-
   Suche → kein sichtbarer Stufen-Effekt zwischen Wrapper und Feldern. */
[data-theme="dark"] .gw-toolbar-search input,
[data-theme="dark"] .gw-toolbar-search select {
  background: transparent !important;
}

/* Seiten-Aktionen in der Kopfzeile. Leer (Seite ohne eigene Knöpfe) schiebt das `auto` trotzdem
   alles Folgende nach rechts — die Glocke sitzt also unverändert am Rand. */
/* Achtung: Glocke, Hilfe und Profil bleiben immer ganz rechts. Darum gibt
   diese Leiste als Erste nach: sie darf schrumpfen (min-width 0) und schneidet notfalls ab,
   während .topbar-right auf `flex: none` steht und nie weicht. */
.topbar-actions { margin-left: auto; display: flex; align-items: center; gap: 8px; min-width: 0; }
/* ── Filterleiste einer Seite in der Kopfzeile (Analytik) ──────────────────────────────────
   eine Leiste statt fünf Kästen: Rahmen und Rundung gehören der Hülle, die Felder darin sind
   flach und durch feine Linien getrennt. Jedes Bedienelement ist gleich
   hoch und sitzt auf derselben Mittellinie — vorher trugen zd-Trigger (36 px, eigener Rahmen),
   Suchfeld und Segment-Schalter je eigene Masse, und die Leiste wirkte zusammengedrückt.

   Achtung: Die Spezifität muss `.zd.active .zd-trigger` (0,3,0) schlagen, sonst kommt der Rahmen des
   aktiven Auswahlfelds zurück. */
.tba-filters {
  display: flex; align-items: stretch; gap: 0; min-width: 0; flex-wrap: nowrap;
  height: 34px; padding: 0;
  background: var(--bg); border: 1px solid var(--border); border-radius: 10px;
  overflow: hidden;            /* die inneren Ecken laufen sauber in die Rundung */
}
/* Achtung: `:not(script)`: die Regel setzt `display:flex` — ohne die Ausnahme wird ein Inline-Skript
   im Block (die Mandanten-Sicht bringt eines mit) sichtbar und sein Quelltext steht als Text
   in der Leiste. Dasselbe gilt für <template> und <style>. */
.tba-filters > *:not(script):not(style):not(template) { flex: none; display: flex; align-items: center; height: 100%; }
.tba-filters > script, .tba-filters > style, .tba-filters > template { display: none !important; }
.tba-filters > *:not(script):not(style):not(template) + *:not(script):not(style):not(template) { border-left: 1px solid var(--border); }

/* Symbol-Filter in der Leiste (Anleitungen): ein Feld je Kategorie, durch
   die Haarlinie der Leiste getrennt. Nur Hausblau als aktiver Zustand — die bunten Akzentfarben
   der Kategorien bleiben den Abschnitts-Ueberschriften; eine Regenbogenreihe in der Kopfzeile
   wuerde unruhig wirken. */
.tba-filters .gw-catfil {
  height: 100%; padding: 0 9px; border: 0; background: transparent; color: var(--text-3);
  display: flex; align-items: center; cursor: pointer; transition: background .12s, color .12s;
}
.tba-filters .gw-catfil:hover { background: var(--surface); color: var(--text-1); }
.tba-filters .gw-catfil.is-on { background: color-mix(in srgb, var(--gw) 12%, transparent); color: var(--gw); }
.tba-filters .gw-catfil svg { width: 15px; height: 15px; }

/* Alles, was darin bedient wird: gleiche Höhe, kein eigener Rahmen, kein eigener Grund. */
.tba-filters :is(.gw-toolbar-search, .zd, .ana-range, .ana-auto, .ana-tenant) {
  height: 100%; border: 0 !important; background: transparent !important;
  box-shadow: none !important; border-radius: 0 !important; padding: 0 !important; gap: 0;
}
.tba-filters .gw-toolbar-search { padding: 0 10px !important; gap: 7px; }
.tba-filters .gw-toolbar-search > svg { color: var(--text-4); flex: none; }
.tba-filters .gw-toolbar-search input {
  height: 100%; border: 0; background: transparent; font-size: 12.5px; color: var(--text-1);
  padding: 0; width: 150px; min-width: 0;
}
.tba-filters .gw-toolbar-search select {
  height: 22px; border: 0; background: transparent; color: var(--text-3);
  font-size: 12px; font-family: var(--font); cursor: pointer; padding: 0 2px;
}

/* Auswahlfelder: der Trigger füllt seinen Abschnitt, ohne Rahmen und ohne Akzentstrich. */
.tba-filters .zd .zd-trigger,
.tba-filters .zd.active .zd-trigger,
.tba-filters .zd.open .zd-trigger {
  height: 100% !important; min-height: 0 !important;
  border: 0 !important; background: transparent !important; box-shadow: none !important;
  border-radius: 0 !important; padding: 0 12px !important;
  font-size: 12.5px !important; font-weight: 600 !important; color: var(--text-1) !important;
}
.tba-filters .zd .zd-trigger:hover { background: var(--surface) !important; }
.tba-filters .zd.open .zd-trigger { background: var(--surface) !important; color: var(--gw) !important; }
.tba-filters .zd-chev { opacity: .5; }

/* Segment-Schalter (Zeitraum, Auto-Aktualisierung): Pillen auf der Leiste, kein Kasten. */
.tba-filters :is(.ana-range, .ana-auto) { padding: 0 6px !important; gap: 2px; }
.tba-filters .ana-auto > svg { width: 13px; height: 13px; color: var(--text-4); margin-right: 4px; flex: none; }
.tba-filters .ana-range-btn {
  height: 24px; padding: 0 9px; font-size: 11.5px; font-weight: 600; line-height: 1;
  border: 0; background: transparent; color: var(--text-3); border-radius: 7px;
  cursor: pointer; transition: background .12s, color .12s;
}
.tba-filters .ana-range-btn:hover { background: var(--surface); color: var(--text-1); }
.tba-filters .ana-range-btn.is-active {
  background: var(--surface); color: var(--gw); box-shadow: 0 1px 2px rgba(15,23,42,.08);
}
[data-theme="dark"] .tba-filters .ana-range-btn.is-active { box-shadow: 0 1px 2px rgba(0,0,0,.4); }

/* Schmales Fenster: die Leiste bleibt erreichbar (sie ist die Bedienung der Seite) und wird
   seitlich scrollbar, statt zu verschwinden. */
@media (max-width: 1280px) { .tba-filters { max-width: 38vw; overflow-x: auto; scrollbar-width: none; } }
.tba-filters::-webkit-scrollbar { display: none; }
/* Die Nebenaktionen stehen als eine Werkzeuggruppe da — sechs einzeln gerahmte Knöpfe machten
   die Leiste unruhig. Der Rahmen liegt jetzt um die Gruppe, die Knöpfe
   darin sind reine Symbole wie Glocke und Hell/Dunkel rechts daneben. Ihre Beschriftung steht im
   Titel; sichtbar bleibt sie nur bei der primären Aktion. */
/* Derselbe Grund wie die Dropdowns daneben: die Gruppe hatte var(--bg) und stach
   dadurch als grauer Block heraus (z.B. Time-Machine neben den anderen Knöpfen).
   Erkennbar ist sie weiterhin an ihrem Rahmen. */
.tba-group {
  display: flex; align-items: center; gap: 2px;
  background: var(--surface); border: 1px solid var(--border); border-radius: 9px; padding: 2px;
}
/* Eine Erscheinung fuer alles in der Gruppe, egal welche Zusatzklassen ein Knopf
   von seiner Seite mitbringt: die Zonen-Liste uebergibt blosse `.btn`, der
   Zoneneditor `.btn.btn-secondary`. Dessen eigener Hover faerbt Text und Rahmen
   blau, waehrend der Gruppen-Hover nur die Flaeche wechselt — dadurch sah dasselbe
   Bedienelement je nach Seite anders aus. Es soll überall gleich wirken. */
.tba-group .btn,
.tba-group .btn.btn-secondary,
.tba-group .btn.btn-ghost,
.tba-group .btn.btn-warning {
  height: 26px; min-width: 28px; padding: 0 6px; border: 0; background: transparent;
  color: var(--text-3); border-radius: 7px; box-shadow: none;
}
.tba-group .btn:hover,
.tba-group .btn.btn-secondary:hover,
.tba-group .btn.btn-ghost:hover,
.tba-group .btn.btn-warning:hover {
  background: var(--bg); color: var(--text-1); border-color: transparent; box-shadow: none;
}
.tba-group .btn:focus-visible { outline: 2px solid var(--gw); outline-offset: -2px; }
/* Die Dropdowns in der Kopfzeile («Erstellen», «Werkzeuge») haben nur den
   allgemeinen zd-Hover: Rahmen- und Textfarbe, keine Flaeche. Neben den Knoepfen der
   Gruppe, die ihre Flaeche wechseln, wirkten sie tot. In der
   Kopfzeile reagieren sie jetzt gleich. */
.topbar-actions .zd-trigger:hover { background: var(--bg); border-color: var(--border); color: var(--text-1); }
.topbar-actions .zd.open .zd-trigger { background: var(--bg); border-color: var(--gw); color: var(--text-1); }
/* Eine Gruppe, deren Knoepfe alle versteckt sind, zeigt sonst ihre leere Huelle — ein grauer
   Fleck neben den echten Werkzeugen (20.09.2026 im Rig gesehen, Dashboard im Bearbeiten-Modus). */
.tba-group:not(:has(> *:not([hidden]))) { display: none; }
/* Beschriftung in der Gruppe unsichtbar — auch bei Knöpfen aus dem Bestand, deren Text ohne
   eigenes <span> direkt im Knopf steht: font-size 0 am Knopf, das Symbol behält seine Grösse.
   Was der Knopf tut, steht im title (und damit im Tooltip). */
/* gap: 0 — sonst hält der Knopf den Abstand zum (unsichtbaren) Text frei und das Symbol sitzt
   sichtbar links statt mittig (z.B. einzelner Knopf auf DNS-Records). */
.tba-group .btn { font-size: 0; gap: 0; }
.tba-group .btn .tba-txt { display: none; }
/* Knopf ohne Symbol: der Text ist sein Inhalt und bleibt darum stehen. */
.tba-group .btn.tba-keep-text { font-size: 12.5px; padding: 0 9px; gap: 6px; }
/* KI-Aktionen behalten ihr Violett — dieselbe Linie wie .btn-ai überall sonst.
   In der Gruppe färbt sie nur das Symbol, die Hülle bleibt ruhig. */
/* Gruppe mit Beschriftung: «Reports» und daneben die Symbole der einzelnen Berichte.
   Die Beschriftung ist Teil der Hülle, nicht der Knöpfe. */
/* Die Bearbeiten-Leiste des Dashboards hält nur dann Platz, wenn sie etwas zeigt: im Ruhezustand
   ist ihr Hinweissatz display:none, und ein Abstand darunter wäre ein Streifen ohne Inhalt. */
#dash-toolbar:has(> *:not(span):not([style*="display:none"])),
#dash-toolbar:has(> #dash-edit-hint:not([style*="display:none"])) { margin-bottom: 14px; }
/* Die Knöpfe des Bearbeiten-Modus in der Kopfzeile: eine Reihe, gleiche Höhe wie die Werkzeuge
   daneben. Sie stehen ausserhalb der Werkzeuggruppe und behalten darum ihre Beschriftung. */
.dash-tba { display: flex; align-items: center; gap: 8px; }
.dash-tba .btn { height: 30px; padding: 0 11px; font-size: 12.5px; white-space: nowrap; }
.dash-tba > div { display: flex; align-items: center; }

.tba-group__lbl {
  font-size: 10.5px; font-weight: 700; letter-spacing: .4px; text-transform: uppercase;
  color: var(--text-4); padding: 0 6px 0 4px; white-space: nowrap;
}
/* In der vollständigen Ansicht trägt jeder Knopf seine Beschriftung — dann braucht die Gruppe
   keinen eigenen Namen mehr. */
.topbar-actions.is-full .tba-group__lbl { display: none; }

.tba-group .btn-ai { color: #6d28d9; background: rgba(124,58,237,.10); }
.tba-group .btn-ai:hover { color: #5b21b6; background: rgba(124,58,237,.18); }
[data-theme="dark"] .tba-group .btn-ai { color: #c4b5fd; background: rgba(139,92,246,.16); }
[data-theme="dark"] .tba-group .btn-ai:hover { color: #ddd6fe; background: rgba(139,92,246,.26); }

/* «Vollständig» statt «kompakt» (Einstellung in Mein Profil, je Benutzer): die Werkzeuggruppe
   löst sich auf, jeder Knopf steht wieder für sich und trägt seine Beschriftung — wie vor dem
   20.09.2026, nur eben in der Kopfzeile statt im Seitenkopf. */
.topbar-actions.is-full .tba-group { background: transparent; border: 0; padding: 0; gap: 6px; }
.topbar-actions.is-full .tba-group .btn {
  height: 30px; min-width: 0; padding: 0 10px; font-size: 12.5px;
  border: 1px solid var(--border); background: var(--surface); color: var(--text-2); border-radius: var(--r);
}
.topbar-actions.is-full .tba-group .btn:hover { background: var(--bg); color: var(--text-1); }
.topbar-actions.is-full .tba-group .btn .tba-txt { display: inline; }
/* Vollständige Ansicht: auch die Auswahlfelder stehen als einzelne Knöpfe mit Beschriftung da. */
.topbar-actions.is-full .tba-group .zd { height: 30px; }
.topbar-actions.is-full .tba-group .zd .zd-trigger {
  height: 30px !important; padding: 0 11px !important; font-size: 12.5px !important; gap: 6px !important;
  border: 1px solid var(--border) !important; background: var(--surface) !important;
  border-radius: var(--r) !important; color: var(--text-2) !important;
}
.topbar-actions.is-full .tba-group .zd .zd-trigger:hover { border-color: var(--gw) !important; color: var(--text-1) !important; }
.topbar-actions.is-full .tba-group .zd[data-key="zr-ai"] .zd-trigger { border-color: rgba(124,58,237,.30) !important; }
.topbar-actions.is-full .tba-group .btn { gap: 6px; }
.topbar-actions.is-full .tba-group .btn-ai {
  color: #6d28d9; background: rgba(124,58,237,.10); border-color: rgba(124,58,237,.30);
}
.topbar-actions.is-full .tba-group .btn-ai:hover { color: #5b21b6; background: rgba(124,58,237,.18); }
[data-theme="dark"] .topbar-actions.is-full .tba-group .btn-ai {
  color: #c4b5fd; background: rgba(139,92,246,.16); border-color: rgba(139,92,246,.40);
}
.topbar-actions.is-full .tba-group .btn svg { width: 14px; height: 14px; }
@media (max-width: 1400px) { .topbar-actions.is-full .tba-group .btn { font-size: 0; padding: 0 8px; } }
/* Achtung: Die Geometrie gehört dem Baustein, nicht dem einzelnen Knopf: viele Symbole tragen aus
   ihrer alten Umgebung ein `style="margin-right:6px"` mit. In der Gruppe sitzt das Symbol
   mittig — sonst steht es sichtbar links (z.B. DNS-Analytics). */
.tba-group .btn svg { width: 15px; height: 15px; margin: 0 !important; vertical-align: middle !important; }

/* Auswahlfelder in der Gruppe (Zoneneditor: Erstellen, Werkzeuge, KI) sehen aus wie die Knöpfe
   daneben — dieselbe Höhe, kein eigener Rahmen, nur das Symbol. Der Pfeil bleibt: ein Eintrag
   mit Untermenü muss als solcher erkennbar sein. */
.tba-group #zr-toolbar { display: contents; }
.tba-group .zd { height: 26px; display: flex; align-items: center; }
/* Der Zoneneditor bringt im Inline-Stil «#zr-toolbar .zd { height: 30px }» mit — die Kennung schlug die Regel oben, die
   Werkzeug-Gruppe wurde 36 statt 32 px hoch und stand höher als «Reports» und «Doku». */
.tba-group #zr-toolbar .zd { height: 26px; }
.topbar-actions.is-full .tba-group #zr-toolbar .zd { height: 30px; }
.tba-group .zd .zd-trigger,
.tba-group .zd.active .zd-trigger,
.tba-group .zd.open .zd-trigger {
  height: 26px !important; min-height: 0 !important; padding: 0 6px !important;
  border: 0 !important; background: transparent !important; box-shadow: none !important;
  border-radius: 7px !important; color: var(--text-3) !important; font-size: 0 !important; gap: 0 !important;
}
.tba-group .zd .zd-trigger:hover { background: var(--surface) !important; color: var(--text-1) !important; box-shadow: var(--sh-1) !important; }
/* Ein Hover fuer alles in den Kopfzeilen-Gruppen (Reports, Doku, Werkzeuge), hell und dunkel: Symbol in Hausblau auf
   leicht blauer Flaeche, gleich wie bei Reports und Doku. Vorher faerbte nur «[data-theme=dark] .btn-secondary:hover»
   die Knoepfe blau; die Auswahlfelder (+, Werkzeuge) sind keine .btn und wurden nur heller, im hellen Modus wechselte
   gar nur die Flaeche. Auch die Ruheflaeche ist ueberall dieselbe (dunkel gab .btn-secondary einen Grauschleier).
   KI behaelt ihr Violett. .topbar-actions vorne: schlaegt die !important-Regeln des dunklen Modus (weiter unten). */
.topbar-actions .tba-group .btn.btn-secondary:not(.btn-ai),
.topbar-actions .tba-group #zr-toolbar .btn.btn-secondary:not(.btn-ai) { background: transparent !important; }
.topbar-actions .tba-group .btn:not(.btn-ai):hover,
.topbar-actions .tba-group #zr-toolbar .btn:not(.btn-ai):hover,
.topbar-actions .tba-group .zd:not([data-key="zr-ai"]) .zd-trigger:hover,
.topbar-actions .tba-group .zd.open:not([data-key="zr-ai"]) .zd-trigger {
  color: var(--gw) !important; background: color-mix(in srgb, var(--gw) 9%, transparent) !important; box-shadow: none !important;
}
.topbar-actions .tba-group .zd[data-key="zr-ai"] .zd-trigger:hover,
.topbar-actions .tba-group .zd.open[data-key="zr-ai"] .zd-trigger { background: rgba(124,58,237,.18) !important; box-shadow: none !important; }
[data-theme="dark"] .topbar-actions .tba-group .zd[data-key="zr-ai"] .zd-trigger:hover,
[data-theme="dark"] .topbar-actions .tba-group .zd.open[data-key="zr-ai"] .zd-trigger { background: rgba(139,92,246,.28) !important; }
.tba-group .zd .zd-trigger .zd-trigger-icon { width: 15px !important; height: 15px !important; margin: 0 !important; opacity: 1; }
.tba-group .zd .zd-chev { width: 9px !important; height: 9px !important; opacity: .5; margin-left: 2px !important; }
.tba-group .zd[data-key="zr-ai"] .zd-trigger { color: #6d28d9 !important; background: rgba(124,58,237,.10) !important; }
[data-theme="dark"] .tba-group .zd[data-key="zr-ai"] .zd-trigger { color: #c4b5fd !important; background: rgba(139,92,246,.16) !important; }
.topbar-actions > .btn { height: 30px; padding: 0 12px; font-size: 12.5px; white-space: nowrap; }
.topbar-actions > .btn svg { width: 14px; height: 14px; }
/* Trennstrich zur rechten Gruppe: Seiten-Aktionen und Konto-Bereich sind zweierlei. */
.topbar-actions::after {
  content: ''; width: 1px; height: 20px; background: var(--border); margin-left: 2px;
}
/* Eng wird es zuerst bei der Beschriftung der primären Aktion, dann fällt die ganze Leiste weg —
   unter 1024 px ist die Kopfzeile ohnehin auf Suche und Symbole zusammengezogen. */
@media (max-width: 1280px) { .topbar-actions > .btn .tba-txt { display: none; } .topbar-actions > .btn { padding: 0 9px; } }
@media (max-width: 1024px) { .topbar-actions { display: none; } }
/* Auffangnetz fuer genau diese Regel: faellt die Leiste weg, holt der
   «⋮»-Knopf dieselben Bedienelemente als Liste zurueck — sonst waere «Neue Zone» auf einem Tablet
   gar nicht erreichbar. Der Knopf zeigt sich nur dort, wo die Leiste faellt. */
.gw-tbam-btn { display: none; }
@media (max-width: 1024px) { .gw-tbam-btn:not([hidden]) { display: flex; } }
/* `hidden` verliert gegen eine Klasse, die display setzt (Hausregel): ohne diese beiden Regeln
   blieb das Blatt sichtbar, obwohl das Skript es laengst auf hidden gestellt hatte — genau der
   Befund vom 20.09.2026: das Menue blieb stehen. */
.gw-tbam[hidden] { display: none !important; }
.topbar-notif[hidden], .gw-tbam-btn[hidden] { display: none !important; }
.gw-tbam {
  position: fixed; z-index: 1200; min-width: 230px; max-width: min(320px, calc(100vw - 16px));
  max-height: min(70vh, 560px); overflow: auto; padding: 6px;
  background: var(--surface); border: 1px solid var(--border); border-radius: 12px; box-shadow: var(--sh-3, 0 10px 30px rgba(0,0,0,.14));
  display: flex; flex-direction: column; gap: 2px;
}
/* Im Blatt traegt jedes Bedienelement wieder seine Beschriftung: die Gruppe ist hier nur ein
   Behaelter, kein Platzsparer. */
.gw-tbam .tba-group, .gw-tbam .tba-filters {
  display: flex; flex-direction: column; align-items: stretch; gap: 2px;
  height: auto; background: transparent; border: 0; border-radius: 0; padding: 0; overflow: visible;
}
.gw-tbam .tba-group__lbl { padding: 8px 8px 3px; }
.gw-tbam .tba-filters > * + * { border-left: 0; border-top: 1px solid var(--border); }
.gw-tbam :is(.btn, .gw-catfil) {
  width: 100%; justify-content: flex-start; gap: 9px; height: 36px; min-width: 0; padding: 0 10px;
  font-size: 13px; border-radius: 8px; border: 0; background: transparent; color: var(--text-1); box-shadow: none;
}
.gw-tbam :is(.btn, .gw-catfil):hover { background: var(--bg); }
.gw-tbam .btn .tba-txt { display: inline; }
.gw-tbam .btn-primary { background: var(--gw); color: #fff; }
.gw-tbam .btn-primary:hover { background: var(--gw-dark, var(--gw)); color: #fff; }
.gw-tbam :is(.btn, .gw-catfil) svg { width: 15px; height: 15px; flex: none; }
.gw-tbam .zd { width: 100%; }
/* Gruppe «Doku»: im Zoneneditor und in den Systemeinstellungen stehen die Anleitungen aller
   Reiter im Markup, sichtbar nur die des aktiven (data-doku-tab, help_drawer.js). `hidden` verliert gegen .btn
   (display:inline-flex) — darum hier ausdrücklich, auch im «⋮»-Blatt, das die Leiste klont. */
.tba-doku > [hidden], .gw-tbam .tba-doku > [hidden] { display: none !important; }
/* Enger wird die Kopfzeile in dieser Reihenfolge kompakter (die Namen «Reports» und «Doku»
   bleiben bis 1280 px stehen): erst fällt die dritte, dann die zweite automatische Anleitung (alle
   stehen weiter in der Hilfe-Lasche und im «⋮»-Blatt unter 1024 px), dann rücken die Gruppen enger zusammen, erst
   unter 1280 px fallen die Namen. Gemessen im Zoneneditor, auf API-Keys, Threat-Feed (Admin) und dem Dashboard. */
@media (max-width: 1680px) { .topbar-actions .tba-doku > [data-doku-rank="2"] { display: none; } }
@media (max-width: 1440px) { .topbar-actions .tba-doku > [data-doku-rank="1"] { display: none; } }
@media (max-width: 1366px) {
  .topbar-actions { gap: 5px; }
  .topbar-actions .tba-group { gap: 0; }
  .topbar-actions .tba-group .btn { min-width: 26px; padding: 0 5px; }
  .topbar-actions .tba-group__lbl { padding: 0 4px 0 3px; letter-spacing: .2px; }
  /* Auswahlknöpfe der Werkzeuggruppe ohne Pfeil (ihr Menü öffnet weiter per Klick), Kopfzeile enger. */
  .topbar-actions .tba-group .zd-chev { display: none; }
  .topbar { gap: 8px; }
  .topbar-actions { gap: 4px; }
  .topbar-actions .tba-group { padding: 2px 1px; }
  .topbar-search-wrap { margin: 0 4px; }
}
@media (max-width: 1279px) { .topbar-actions .tba-group__lbl { display: none; } }

/* Kleiner Link «Anleitung» in Reiter-Einleitungen und Fenstern (gwGuideLink, Proxy-Fenster): ein Aussehen. */
.gw-guide-link {
  display: inline-flex; align-items: center; gap: 5px; white-space: nowrap; vertical-align: baseline;
  font-size: 12px; font-weight: 600; color: var(--gw); text-decoration: none;
}
.gw-guide-link:hover { text-decoration: underline; }
.gw-guide-link[hidden] { display: none; }
.gw-guide-link svg { width: 13px; height: 13px; flex: none; }
/* Im Fensterkopf rechts vor dem Schliessen, auf Höhe der Titelzeile (über dem getönten ::before der Kopfzeile). */
.zd-dlg-head > .gw-guide-link { position: relative; align-self: flex-start; margin-top: 8px; }
/* In Assistenten, die als Bestätigungsfenster gebaut sind (zd.confirm): rechts unter dem Inhalt. */

.topbar-right { margin-left: 8px; display: flex; align-items: center; gap: 8px; flex: none; }

/* Notif bell */
.topbar-notif {
  position: relative; cursor: pointer;
  width: 34px; height: 34px;
  display: flex; align-items: center; justify-content: center;
  border-radius: var(--r); transition: background .12s;
  color: var(--text-3);
}
.topbar-notif:hover { background: var(--bg); }
.topbar-notif svg { width: 16px; height: 16px; }
/* Hilfe-Knopf ist ein <button> (Menue), sieht aber aus wie die Glocke. */
button.topbar-notif { border: 0; background: transparent; padding: 0; font: inherit; }
button.topbar-notif:hover, button.topbar-notif[aria-expanded="true"] { background: var(--bg); color: var(--text-1); }
button.topbar-notif:focus-visible { outline: 2px solid var(--gw); outline-offset: 1px; }
/* Hilfe-Menue: Form von .gw-um, unter dem Knopf rechtsbuendig. */
.gw-hm { width: 240px; }
.notif-badge {
  /* Counter-Badge — zeigt Anzahl ungelesener Notifications. Wird per JS
     mit Text gefüllt (max "99+"). Position rechts oben auf der Bell. */
  min-width: 16px; height: 16px; padding: 0 4px;
  border-radius: 8px;
  background: var(--err);
  border: 2px solid var(--surface);
  color: #fff;
  font-size: 10px; font-weight: 700; letter-spacing: -.2px;
  position: absolute; top: 2px; right: 2px;
  display: flex; align-items: center; justify-content: center;
  line-height: 1;
}

/* ══ Benachrichtigungen: Glocke, Karten, Seite, Toasts ════════════════════════════════════════════
   Neu gestaltet 02.10.2026 (vorher standen «Erledigt» und «×» untereinander, «Öffnen» ohne feste Stelle). Eine Karte (window._notifCardHtml in base.php) fuer
   Glocke und Seite: festes Raster Symbol | Inhalt, Titel und Text je höchstens zwei Zeilen, Fusszeile mit
   Zeit · Art · «2×» links und den Aktionen rechts — «Öffnen» immer ganz rechts, «Erledigt» links daneben,
   «×» oben rechts beim Zeigen/Fokus (Touch: immer). Ungelesen = Akzentleiste links in Hausblau. Glas mit Rückfall auf die
   volle Fläche, feine Haarlinien, weiche Höhe — kein Leuchten (Hausregel), nur Strich-Symbole. */
.notif-panel, .notif-page, .notif-toast-stack {
  --nt-hair:    color-mix(in srgb, var(--text-1) 9%, transparent);
  --nt-hover:   color-mix(in srgb, var(--text-1) 4%, transparent);
  --nt-unread:  color-mix(in srgb, var(--gw) 6%, transparent);
  --nt-glass:   color-mix(in srgb, var(--surface) 90%, transparent);
  --nt-solid:   var(--surface);
  --nt-shadow:  0 1px 2px rgba(15,23,42,.06), 0 12px 32px -8px rgba(15,23,42,.18), 0 32px 64px -24px rgba(15,23,42,.22);
  --nt-info:    var(--gw);
  --nt-success: var(--ok);
  --nt-warn:    var(--warn);
  --nt-danger:  var(--err);
}
[data-theme="dark"] .notif-panel, [data-theme="dark"] .notif-page, [data-theme="dark"] .notif-toast-stack {
  --nt-hair:    color-mix(in srgb, var(--text-1) 10%, transparent);
  --nt-hover:   color-mix(in srgb, var(--text-1) 5%, transparent);
  --nt-unread:  color-mix(in srgb, var(--gw) 9%, transparent);
  --nt-glass:   color-mix(in srgb, var(--surface) 88%, transparent);
  --nt-shadow:  0 1px 2px rgba(0,0,0,.35), 0 16px 40px -8px rgba(0,0,0,.55), 0 40px 80px -24px rgba(0,0,0,.6);
}
.notif-sr { position: absolute !important; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }

/* ── Panel (Glocke) ─────────────────────────────────────────────────── */
.notif-panel {
  position: absolute; top: 56px; right: 16px;
  width: 448px; max-width: calc(100vw - 32px); max-height: min(78vh, 760px);
  background: var(--nt-solid);
  border: 1px solid var(--nt-hair); border-radius: 16px;
  box-shadow: var(--nt-shadow);
  z-index: 9999;
  display: flex; flex-direction: column; overflow: hidden;
  font-size: 13px;
  /* Öffnen: gleitet 6 px herab und blendet ein; .is-open setzt das JS einen Tick nach display:flex. */
  transform: translateY(-6px) scale(.99); transform-origin: top right;
  opacity: 0; pointer-events: none;
  transition: transform .18s cubic-bezier(.16,1,.3,1), opacity .14s ease-out;
}
/* Volle Fläche statt Glas: der klebende Tageskopf muss deckend sein, und auf einer halb durchsichtigen Glocke
   stand er als hellerer Streifen da. Ein Hauch Hausblau oben gibt der Fläche Tiefe (kein Leuchten). */
.notif-panel { background: linear-gradient(180deg, color-mix(in srgb, var(--gw) 4%, var(--nt-solid)) 0, var(--nt-solid) 88px); }
.notif-panel.is-open { transform: none; opacity: 1; pointer-events: auto; }
.notif-panel__head {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 14px 16px 10px; flex-shrink: 0;
}
.notif-panel__title { font-weight: 700; color: var(--text-1); font-size: 15px; letter-spacing: -.01em; }
.notif-panel__titlewrap { display: inline-flex; align-items: center; gap: 8px; min-width: 0; }
.notif-panel__count {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 20px; height: 20px; padding: 0 7px; border-radius: 999px;
  background: var(--gw); color: #fff; font-size: 11px; font-weight: 700; font-variant-numeric: tabular-nums;
}
.notif-panel__count[hidden] { display: none; }
.notif-panel__mark {
  display: inline-flex; align-items: center; gap: 6px;
  background: none; border: 0; color: var(--gw); font: inherit; font-size: 12px; font-weight: 600;
  cursor: pointer; padding: 5px 8px; border-radius: 7px; transition: background .12s;
}
.notif-panel__mark svg { width: 14px; height: 14px; }
.notif-panel__mark:hover { background: color-mix(in srgb, var(--gw) 10%, transparent); }
.notif-panel__mark:focus-visible { outline: 2px solid var(--gw); outline-offset: 1px; }
/* Filter = Haus-Pillen (filterChip, .rec-chip); fixe Zone, darf nicht schrumpfen. */
.notif-panel__filters {
  display: flex; gap: 6px; padding: 0 16px 12px;
  border-bottom: 1px solid var(--nt-hair);
  overflow-x: auto; scrollbar-width: none; flex-shrink: 0;
}
.notif-panel__filters::-webkit-scrollbar { display: none; }
.notif-panel__filters .rec-chip { flex-shrink: 0; white-space: nowrap; }
.notif-panel__body { overflow-y: auto; flex: 1; min-height: 72px; padding: 0 6px 6px; overscroll-behavior: contain; scrollbar-width: thin; }
.notif-panel__foot {
  display: flex; align-items: center; justify-content: flex-end;
  padding: 8px 12px; border-top: 1px solid var(--nt-hair); flex-shrink: 0;
}
.notif-panel__foot a {
  display: inline-flex; align-items: center; gap: 6px;
  color: var(--gw); text-decoration: none; font-weight: 600; font-size: 12.5px;
  padding: 6px 10px; border-radius: 8px; transition: background .12s;
}
.notif-panel__foot a svg { width: 14px; height: 14px; transition: transform .15s; }
.notif-panel__foot a:hover { background: color-mix(in srgb, var(--gw) 10%, transparent); }
.notif-panel__foot a:hover svg { transform: translateX(2px); }

/* ── Tagesgruppe (Heute / Gestern / Diese Woche …) — klebt beim Scrollen oben ──
   Vorher scrollte /notifications unruhig: auf der Seite klebte der Kopf 20 px unter
   der Oberkante des Scroll-Behälters (.app-main zählt in Chromium seinen Innenabstand auf top:0 drauf), die
   Karten liefen durch die Lücke darüber sichtbar weiter. Jetzt: deckende Fläche, über den Karten, und der
   Haftpunkt kommt auf der Seite von der andockenden Werkzeugleiste (--gw-stickbar-h, app.js misst ihn je
   Browser). In der Glocke ist der Scroll-Behälter der Panel-Körper ohne Innenabstand oben — dort top:0. */
.notif-group {
  position: sticky; top: 0; z-index: 3;
  display: flex; align-items: center; gap: 10px;
  margin: 0 -6px; padding: 12px 20px 7px;
  font-size: 10.5px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase;
  color: var(--text-3);
  background: var(--nt-solid);
}
.notif-group::after { content: ''; flex: 1; height: 1px; background: var(--nt-hair); }

/* ── Karte ───────────────────────────────────────────────────────────── */
.notif-card {
  position: relative;
  display: grid; grid-template-columns: 32px minmax(0, 1fr); column-gap: 12px;
  padding: 12px 12px 10px 14px; border-radius: 12px;
  cursor: pointer; transition: background .14s;
}
.notif-card.has-pick { grid-template-columns: 18px 32px minmax(0, 1fr); }
/* Haarlinie zwischen zwei Karten — verschwindet neben der Karte unter dem Zeiger. */
.notif-card + .notif-card::before {
  content: ''; position: absolute; top: 0; left: 58px; right: 14px; height: 1px;
  background: var(--nt-hair); transition: opacity .14s;
}
.notif-card.has-pick + .notif-card::before, .notif-card + .notif-card.has-pick::before { left: 88px; }
.notif-card:hover::before, .notif-card:hover + .notif-card::before,
.notif-card.is-unread::before, .notif-card.is-unread + .notif-card::before { opacity: 0; }
.notif-card:hover { background: var(--nt-hover); }
.notif-card.is-unread { background: var(--nt-unread); }
.notif-card.is-unread:hover { background: color-mix(in srgb, var(--gw) 12%, transparent); }
.notif-card + .notif-card.is-unread, .notif-card.is-unread + .notif-card { margin-top: 2px; }
/* Ungelesen: Akzentleiste links (statt Punkt). */
.notif-card.is-unread::after {
  content: ''; position: absolute; left: 0; top: 12px; bottom: 12px; width: 3px;
  border-radius: 0 3px 3px 0; background: var(--gw);
}
/* Ungelesen zusätzlich am Symbol: ein Punkt in Hausblau an der Ecke (mit Ring in der Kartenfarbe, kein Leuchten). */
.notif-card.is-unread .notif-card__icon::after {
  content: ''; position: absolute; top: -3px; right: -3px; width: 9px; height: 9px; border-radius: 50%;
  background: var(--gw); border: 2px solid color-mix(in srgb, var(--gw) 6%, var(--nt-solid));
}
.notif-card.is-grp-member { margin-left: 22px; }
/* Stufe = Symbol-Kachel mit feinem Verlauf in der Stufenfarbe (nur die vier Stufen). */
.notif-card__icon {
  --c: var(--nt-info);
  position: relative;
  width: 32px; height: 32px; border-radius: 10px;
  display: flex; align-items: center; justify-content: center;
  color: var(--c);
  background: linear-gradient(145deg, color-mix(in srgb, var(--c) 17%, transparent), color-mix(in srgb, var(--c) 6%, transparent));
  border: 1px solid color-mix(in srgb, var(--c) 26%, transparent);
}
.notif-card__icon svg { width: 17px; height: 17px; }
.notif-card.sev-success .notif-card__icon { --c: var(--nt-success); }
.notif-card.sev-warn    .notif-card__icon { --c: var(--nt-warn); }
.notif-card.sev-danger  .notif-card__icon { --c: var(--nt-danger); }
.notif-card__main { min-width: 0; }
.notif-card__title {
  padding-right: 26px;                                  /* Platz fuer «×» oben rechts */
  font-weight: 550; color: var(--text-2); font-size: 13px; line-height: 1.38;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
  overflow-wrap: anywhere;
}
.notif-card.is-unread .notif-card__title { font-weight: 650; color: var(--text-1); }
.notif-card__text {
  margin-top: 3px; color: var(--text-3); font-size: 12.25px; line-height: 1.45;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
  overflow-wrap: anywhere;
}
.notif-card .notif-pills { margin-top: 5px; }
/* Reicht der Platz nicht für Zeit · Art · «2×» und die Knöpfe, rutschen die Knöpfe in eine eigene Zeile —
   weiterhin rechtsbündig, «Öffnen» bleibt ganz rechts unten. Die Art wird so nie mit «…» gekürzt. */
.notif-card__foot {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 6px 10px;
  margin-top: 8px; min-height: 24px;
}
.notif-card__meta {
  display: flex; align-items: center; gap: 6px; min-width: 0; flex: 0 1 auto;
  color: var(--text-4); font-size: 11.5px; white-space: nowrap; overflow: hidden;
}
.notif-card__meta time { flex: 0 0 auto; font-variant-numeric: tabular-nums; }
.notif-card__cat { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.notif-card__cat::before { content: '·'; margin-right: 6px; color: var(--text-4); }
.notif-card__count {
  flex: 0 0 auto; font: inherit; font-size: 10.5px; font-weight: 700; line-height: 1;
  padding: 3px 7px; border-radius: 999px; cursor: pointer;
  color: var(--text-3); background: color-mix(in srgb, var(--text-1) 7%, transparent);
  border: 1px solid transparent; transition: color .12s, border-color .12s, background .12s;
}
.notif-card__count:hover, .notif-card__count.is-open { color: var(--gw); border-color: color-mix(in srgb, var(--gw) 45%, transparent); background: transparent; }
.notif-card__actions { display: flex; align-items: center; gap: 6px; flex: 0 0 auto; margin-left: auto; }
.notif-card__actions .btn-xs { height: 26px; padding: 0 10px; border-radius: 8px; border-width: 1px; gap: 5px; }
.notif-card__actions .btn-xs svg { width: 12px; height: 12px; }
/* «Öffnen» ist der Hauptweg: leise in Hausblau getönt; «Erledigt» bleibt neutral daneben. */
.notif-card__actions .notif-card__go {
  color: var(--gw); background: color-mix(in srgb, var(--gw) 8%, transparent);
  border-color: color-mix(in srgb, var(--gw) 30%, transparent);
}
.notif-card__actions .notif-card__go:hover { background: color-mix(in srgb, var(--gw) 14%, transparent); border-color: color-mix(in srgb, var(--gw) 50%, transparent); }
/* Dunkel: [data-theme="dark"] .btn-secondary setzt Fläche, Rahmen und Farbe mit !important (Zeile ~5716) — darum hier auch. */
[data-theme="dark"] .notif-card__actions .notif-card__go { color: color-mix(in srgb, var(--gw) 72%, var(--text-1)) !important; background: color-mix(in srgb, var(--gw) 12%, var(--surface)) !important; border-color: color-mix(in srgb, var(--gw) 38%, var(--border)) !important; }
[data-theme="dark"] .notif-card__actions .notif-card__go:hover { color: color-mix(in srgb, var(--gw) 55%, var(--text-1)) !important; background: color-mix(in srgb, var(--gw) 20%, var(--surface)) !important; border-color: color-mix(in srgb, var(--gw) 55%, var(--border)) !important; }
.notif-card__go svg { transition: transform .15s; }
.notif-card__go:hover svg { transform: translateX(2px); }
.notif-card__ack:hover { color: var(--ok); border-color: color-mix(in srgb, var(--ok) 55%, transparent); }
/* «×»: oben rechts, erscheint beim Zeigen/Fokus; ohne Zeiger (Touch) immer sichtbar. */
.notif-card__dismiss {
  position: absolute; top: 8px; right: 8px;
  width: 24px; height: 24px; padding: 0; border: 0; border-radius: 7px;
  display: flex; align-items: center; justify-content: center;
  background: transparent; color: var(--text-4); cursor: pointer;
  opacity: 0; transition: opacity .12s, background .12s, color .12s;
}
.notif-card__dismiss svg { width: 14px; height: 14px; }
.notif-card:hover .notif-card__dismiss, .notif-card:focus-within .notif-card__dismiss, .notif-card__dismiss:focus-visible { opacity: 1; }
.notif-card__dismiss:hover { background: color-mix(in srgb, var(--err) 12%, transparent); color: var(--err); }
.notif-card__dismiss:focus-visible, .notif-card__count:focus-visible { outline: 2px solid var(--gw); outline-offset: 1px; }
@media (hover: none) and (pointer: coarse) { .notif-card__dismiss { opacity: 1; } }

/* Angaben aus metadata (Host: …, Zone: …) — leise Pillen. Auch im Detail-Fenster (.notif-detail__facts). */
.notif-pills { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 4px; }
.notif-pill {
  display: inline-flex; align-items: baseline; gap: 4px;
  padding: 2px 8px; border-radius: 6px;
  background: color-mix(in srgb, var(--text-1) 5%, transparent); border: 1px solid var(--nt-hair, var(--border));
  font-size: 11px; color: var(--text-2);
  max-width: 100%; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.notif-pill__k { color: var(--text-4); font-weight: 600; font-size: 10.5px; }
.notif-pill__v { color: var(--text-1); font-weight: 500; }
/* Art-Pille im Detail-Fenster. */
.notif-evt-badge {
  flex: 0 0 auto; display: inline-block; padding: 1px 7px; border-radius: 5px;
  background: color-mix(in srgb, var(--gw) 12%, var(--surface));
  color: color-mix(in srgb, var(--gw) 70%, var(--text-1));
  font-size: 11px; font-weight: 600; white-space: nowrap;
}
.notif-evt-badge.sev-warn   { background: color-mix(in srgb, var(--warn) 14%, var(--surface)); color: color-mix(in srgb, var(--warn) 75%, var(--text-1)); }
.notif-evt-badge.sev-danger { background: color-mix(in srgb, var(--err) 14%, var(--surface)); color: color-mix(in srgb, var(--err) 75%, var(--text-1)); }
.notif-evt-badge.sev-success{ background: color-mix(in srgb, var(--ok) 14%, var(--surface)); color: color-mix(in srgb, var(--ok) 70%, var(--text-1)); }

/* ── Leer- und Ladezustand ───────────────────────────────────────────── */
.notif-empty { padding: 40px 24px 36px; text-align: center; }
.notif-empty__ic {
  width: 52px; height: 52px; margin: 0 auto 12px; border-radius: 16px;
  display: flex; align-items: center; justify-content: center;
  color: var(--gw); background: color-mix(in srgb, var(--gw) 9%, transparent);
  border: 1px solid color-mix(in srgb, var(--gw) 20%, transparent);
}
.notif-empty__ic svg { width: 26px; height: 26px; }
/* Zwei feine Ringe um das Symbol — Strich, kein Leuchten. */
.notif-empty__ic { position: relative; margin-bottom: 18px; }
.notif-empty__ic::before, .notif-empty__ic::after {
  content: ''; position: absolute; border-radius: 22px; pointer-events: none;
  border: 1px solid color-mix(in srgb, var(--gw) 14%, transparent);
}
.notif-empty__ic::before { inset: -9px; }
.notif-empty__ic::after  { inset: -18px; border-radius: 28px; border-color: color-mix(in srgb, var(--gw) 7%, transparent); }
.notif-empty__t { color: var(--text-1); font-weight: 650; font-size: 13.5px; }
.notif-empty__h { color: var(--text-4); font-size: 12px; margin-top: 4px; line-height: 1.45; }
.notif-empty.is-error .notif-empty__t { color: var(--err); }
.notif-skeleton {
  display: grid; grid-template-columns: 32px 1fr; gap: 12px;
  padding: 14px 12px 12px 14px;
}
.notif-skeleton + .notif-skeleton { border-top: 1px solid var(--nt-hair, var(--border)); }
.notif-skeleton__icon, .notif-skeleton__line {
  background: linear-gradient(90deg,
    color-mix(in srgb, var(--text-1) 6%, transparent) 0%,
    color-mix(in srgb, var(--text-1) 12%, transparent) 50%,
    color-mix(in srgb, var(--text-1) 6%, transparent) 100%);
  background-size: 200% 100%;
  animation: notif-shimmer 1.4s linear infinite;
  border-radius: 6px;
}
.notif-skeleton__icon { width: 32px; height: 32px; border-radius: 10px; }
.notif-skeleton__lines { display: flex; flex-direction: column; gap: 7px; padding-top: 2px; }
.notif-skeleton__line { height: 10px; }
.notif-skeleton__line.is-long   { width: 92%; }
.notif-skeleton__line.is-medium { width: 70%; }
.notif-skeleton__line.is-short  { width: 54%; }
.notif-skeleton__line.is-tiny   { width: 28%; height: 8px; margin-top: 4px; }
@keyframes notif-shimmer {
  0%   { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

/* Glocke wackelt kurz, wenn neue ungelesene Meldungen kommen (Klasse is-pulsing, ~700 ms). */
@keyframes notif-bell-pulse {
  0%   { transform: scale(1)    rotate(0); }
  20%  { transform: scale(1.18) rotate(-12deg); }
  40%  { transform: scale(1.18) rotate(12deg); }
  60%  { transform: scale(1.18) rotate(-8deg); }
  80%  { transform: scale(1.05) rotate(4deg); }
  100% { transform: scale(1)    rotate(0); }
}
.topbar-notif.is-pulsing svg {
  animation: notif-bell-pulse .7s ease-in-out;
  transform-origin: 50% 4px;
  color: var(--gw);
}

/* ── Toast bei neuen Meldungen ───────────────────────────────────────── */
/* bottom: 80px lässt Platz für die Status-Pillen (.zd-toast-stack bei bottom:20px). */
.notif-toast-stack {
  position: fixed; bottom: 80px; right: 20px;
  display: flex; flex-direction: column-reverse; gap: 10px;
  z-index: 99999; pointer-events: none;
  max-width: 380px;
}
.notif-toast {
  position: relative;
  display: grid; grid-template-columns: 32px 1fr 22px; gap: 12px; align-items: start;
  background: var(--nt-solid); border: 1px solid var(--nt-hair);
  border-radius: 14px; padding: 12px 12px 12px 14px;
  box-shadow: var(--nt-shadow);
  pointer-events: auto; cursor: pointer;
  transform: translateX(400px); opacity: 0;
  transition: transform .28s cubic-bezier(.16,1,.3,1), opacity .2s;
}
@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .notif-toast { background: var(--nt-glass); -webkit-backdrop-filter: blur(22px) saturate(1.6); backdrop-filter: blur(22px) saturate(1.6); }
}
.notif-toast.is-visible { transform: translateX(0); opacity: 1; }
.notif-toast.is-leaving { transform: translateX(400px); opacity: 0; }
.notif-toast__icon {
  --c: var(--nt-info);
  width: 32px; height: 32px; border-radius: 10px;
  display: flex; align-items: center; justify-content: center;
  color: var(--c); background: color-mix(in srgb, var(--c) 11%, transparent);
  border: 1px solid color-mix(in srgb, var(--c) 22%, transparent);
}
.notif-toast__icon svg { width: 17px; height: 17px; }
.notif-toast__icon.sev-success { --c: var(--nt-success); }
.notif-toast__icon.sev-warn    { --c: var(--nt-warn); }
.notif-toast__icon.sev-danger  { --c: var(--nt-danger); }
.notif-toast__body { min-width: 0; }
.notif-toast__title {
  font-weight: 650; color: var(--text-1); font-size: 13px; line-height: 1.38;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.notif-toast__sub {
  color: var(--text-3); font-size: 12px; margin-top: 2px; line-height: 1.45;
  overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
}
.notif-toast__close {
  width: 22px; height: 22px; border-radius: 6px; border: 0; padding: 0;
  background: none; color: var(--text-4); font-size: 16px; line-height: 1; cursor: pointer;
}
.notif-toast__close:hover { color: var(--text-1); background: var(--nt-hover); }

@media (prefers-reduced-motion: reduce) {
  .notif-panel, .notif-toast, .notif-card, .notif-card::before, .notif-card__dismiss,
  .notif-card__go svg, .notif-panel__foot a svg { transition: none; }
  .notif-skeleton__icon, .notif-skeleton__line, .topbar-notif.is-pulsing svg { animation: none; }
  .notif-panel { transform: none; }
}

/* ── /notifications — Vollbild-Inbox: dieselbe Karte, hier als einzelne Kacheln ──
   Werkzeugleiste (Auswahl, Filter, «Alle als gelesen») dockt oben an (.gw-stickbar, Haftpunkt von app.js),
   die Tageskoepfe kleben direkt darunter (--gw-stickbar-h) auf deckendem Seitengrund. */
.notif-page { max-width: 920px; margin: 0 auto; }
.notif-page__head {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 14px; gap: 12px; flex-wrap: wrap;
}
.notif-page__title { font-size: 22px; font-weight: 700; color: var(--text-1); letter-spacing: -.015em; }
.notif-page__filters {
  display: flex; align-items: center; gap: 8px; padding: 9px 10px 9px 14px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 14px; margin-bottom: 4px; flex-wrap: wrap;
}
.notif-page__filters .notif-page__mark { margin-left: auto; }
/* Suche in der Leiste: nimmt den Platz zwischen Chips und «Alle als gelesen» */
.notif-page__filters .notif-page__search { flex: 1 1 220px; max-width: 360px; min-width: 180px; }
.notif-page__mark svg { width: 14px; height: 14px; }
.notif-page__list { display: flex; flex-direction: column; gap: 8px; }
.notif-page__list .notif-group {
  top: var(--gw-stickbar-h, 0px);
  margin: 0; padding: 14px 2px 6px; background: var(--bg);
}
.notif-page__list .notif-card {
  padding: 14px 14px 12px 18px; border-radius: 14px;
  background: linear-gradient(180deg, var(--surface) 0, color-mix(in srgb, var(--gw) 2%, var(--surface)) 100%);
  border: 1px solid var(--border);
  box-shadow: 0 1px 2px rgba(15,23,42,.04);
  transition: border-color .15s, background .15s;
}
.notif-page__list .notif-card + .notif-card::before { display: none; }
.notif-page__list .notif-card + .notif-card.is-unread, .notif-page__list .notif-card.is-unread + .notif-card { margin-top: 0; }
.notif-page__list .notif-card:hover { border-color: color-mix(in srgb, var(--gw) 38%, var(--border)); }
.notif-page__list .notif-card.is-unread {
  background: linear-gradient(180deg, color-mix(in srgb, var(--gw) 7%, var(--surface)) 0, var(--surface) 100%);
  border-color: color-mix(in srgb, var(--gw) 26%, var(--border));
}
.notif-page__list .notif-card.is-unread:hover { border-color: color-mix(in srgb, var(--gw) 48%, var(--border)); }
.notif-page__list .notif-card.is-unread::after { top: 14px; bottom: 14px; }
.notif-page__list .notif-card .notif-card__icon::after { border-color: color-mix(in srgb, var(--gw) 6%, var(--surface)); }
.notif-page__list .notif-card__title { font-size: 13.5px; }
[data-theme="dark"] .notif-page__list .notif-card { box-shadow: none; }
.notif-page__list > .notif-skeleton, .notif-page__list > .notif-empty {
  background: var(--surface); border: 1px solid var(--border); border-radius: 14px;
}
.notif-page__list > .notif-skeleton + .notif-skeleton { border-top: 1px solid var(--border); }
.notif-page__list > .notif-empty { padding: 56px 24px 52px; }

/* Einblenden beim ersten Laden (Glocke öffnen, Seite laden): kurz von unten, gestaffelt. Die Klasse .notif-anim
   setzt das JS nur für diesen einen Durchgang — Lesen/Erledigen/Filtern zeichnet ohne Bewegung neu. */
@keyframes notif-in { from { opacity: 0; transform: translateY(6px); } }
.notif-anim > .notif-card, .notif-anim > .notif-group { animation: notif-in .34s cubic-bezier(.16,1,.3,1) backwards; }
.notif-anim > :nth-child(2) { animation-delay: .02s; } .notif-anim > :nth-child(3) { animation-delay: .04s; }
.notif-anim > :nth-child(4) { animation-delay: .06s; } .notif-anim > :nth-child(5) { animation-delay: .08s; }
.notif-anim > :nth-child(6) { animation-delay: .10s; } .notif-anim > :nth-child(7) { animation-delay: .12s; }
.notif-anim > :nth-child(n+8) { animation-delay: .14s; }
@media (prefers-reduced-motion: reduce) {
  .notif-anim > .notif-card, .notif-anim > .notif-group { animation: none; }
  .notif-page__list .notif-card { transition: none; }
}

/* ── /notifications — Mehrfachauswahl + Export (14.09.2026) ──────────────────
   Checkbox als eigene erste Spalte (.has-pick); Export-Zeile = .snapx (Snapshot-Details);
   Sammel-Leiste = .gw-bulkbar. */
.notif-pick { display: flex; align-items: center; justify-content: center; height: 32px; margin: 0; cursor: pointer; }
.notif-pick input, .notif-selall input { width: 15px; height: 15px; margin: 0; cursor: pointer; accent-color: var(--gw); }
.notif-page__head-actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.notif-page__chips { display: flex; gap: 8px; flex-wrap: wrap; }
.notif-selall {
  display: inline-flex; align-items: center; gap: 7px; white-space: nowrap; cursor: pointer;
  font-size: 12px; font-weight: 600; color: var(--text-2);
  padding-right: 12px; border-right: 1px solid var(--border);
}
/* Sammel-Leisten von Snapshots und Mitteilungen: gemeinsamer Baustein .gw-bulkbar (19.09.2026). Uebrig bleibt der
   Text-Knopf «Alle N Nachrichten auswaehlen» der Mitteilungen. */
.snp-bulk-bar__link {
  background:none;border:0;padding:0;color:inherit;font:inherit;font-weight:600;
  text-decoration:underline;text-underline-offset:2px;cursor:pointer;white-space:nowrap;
}

/* ── Notification-Detail-Modal — zusammenhängender Flow statt Box-Sections ──
   Ersetzt die bisherigen 5–6 .zd-dlg-section-Karten durch eine vertikale
   Hierarchie: Lead-Text → Fact-Pills → Kontext-Karte (Accent-Line) → Meta-
   Footer. Akzentfarbe wird über `.is-<sev>` aus CSS-Variablen gezogen. */
.notif-detail {
  display: flex; flex-direction: column; gap: 16px;
  /* Severity-Akzent für Kontext-Karte. Wird von .is-<sev> überschrieben. */
  --accent: #2563eb;
}
.notif-detail.is-info    { --accent: #2563eb; }
.notif-detail.is-success { --accent: #16a34a; }
.notif-detail.is-warn    { --accent: #d97706; }
.notif-detail.is-danger  { --accent: #dc2626; }

.notif-detail__lead {
  font-size: 14.5px; line-height: 1.6; color: var(--text-1);
  white-space: pre-wrap; word-wrap: break-word;
}
/* Mehrzeilige Bodies (Sammel-Notifications, eine Zeile je Befund) als gegliederte
   Liste: Trennlinien + Bullet in der Severity-Farbe (--accent vom .notif-detail). */
.notif-detail__list {
  margin: 0; padding: 0; list-style: none;
  font-size: 13px; line-height: 1.5; color: var(--text-1);
}
.notif-detail__list li { padding: 7px 0 7px 15px; position: relative; word-wrap: break-word; }
.notif-detail__list li + li { border-top: 1px solid var(--border); }
.notif-detail__list li::before {
  content: ''; position: absolute; left: 0; top: 13px; width: 6px; height: 6px;
  border-radius: 99px; background: var(--accent, var(--gw, #0098ef));
}

/* Gegliederte Sammel-Mitteilung: Überschrift (Host/Zone) trägt den Punkt, die
   Angaben darunter gehören sichtbar dazu. Vorher stand der Hostname als
   gleichrangiger Aufzählungspunkt neben seinen eigenen Messwerten und die
   Zuordnung war zu erraten. */
.notif-detail__head { display: block; font-weight: 700; }
/* Hiess bis 06.08.2026 ebenfalls .notif-detail__sub — genau wie die Unterzeile im
   MODAL-KOPF weiter unten. Zwei Bauteile, ein Klassenname: die spaeter definierte
   Kopf-Regel (display:inline-flex; gap:8px) gewann und legte die Angaben dieser
   Liste NEBENeinander statt untereinander. Im Ergebnis stand «vorher: … jetzt: …»
   und «gemessen: …» auf einer Zeile, getrennt nur durch eine Luecke — als waere es
   ein Satz. Eigener Name, weil der Fehler sonst beim naechsten
   Anfassen der Kopfzeile stillschweigend zurueckkommt. */
.notif-detail__sublist {
  margin: 4px 0 0; padding: 0 0 0 1px; list-style: none;
  border-left: 2px solid var(--border);
}
.notif-detail__sublist li {
  padding: 3px 0 3px 10px; border-top: 0 !important;
  color: var(--text-2); font-size: 12.5px;
}
/* Der Punkt gehört zur Überschrift, nicht zu jeder Angabe darunter. */
.notif-detail__sublist li::before { display: none; }

.notif-detail__facts {
  display: flex; flex-wrap: wrap; gap: 6px;
}
.notif-detail__facts .notif-pill {
  font-size: 12px; padding: 4px 10px;
  background: var(--surface); border-color: var(--border-2);
  /* Lange Metadaten-Werte (z.B. die Beförderungs-Begründung „why") vollständig
     zeigen: im Detail-Modal umbrechen statt ellipsieren — die kompakten Pills im
     Glocken-Dropdown bleiben einzeilig (Platz), das Modal ist der Ort der
     Vollständigkeit. */
  white-space: normal; overflow: visible; text-overflow: clip;
  overflow-wrap: anywhere;
}

.notif-detail__context {
  /* Akzentkarte für Warum/Was-tun — getöntes Background mit linker Linie,
     visuell wirkt es wie ein einziges Element statt zwei Boxen. */
  background: color-mix(in srgb, var(--accent) 7%, var(--surface));
  border-left: 3px solid var(--accent);
  border-radius: 0 10px 10px 0;
  padding: 13px 16px;
  display: flex; flex-direction: column; gap: 12px;
}
[data-theme="dark"] .notif-detail__context {
  background: color-mix(in srgb, var(--accent) 14%, rgba(255,255,255,.02));
}
.notif-detail__context-block {
  display: grid; grid-template-columns: 18px 1fr; gap: 10px;
  align-items: start;
}
.notif-detail__context-block svg {
  width: 14px; height: 14px; margin-top: 2px;
  color: var(--accent); flex-shrink: 0;
}
.notif-detail__context-h {
  font-size: 11px; font-weight: 700;
  color: var(--text-3); text-transform: uppercase;
  letter-spacing: .04em; margin-bottom: 4px;
}
.notif-detail__context-t {
  font-size: 13px; line-height: 1.55; color: var(--text-1);
}

.notif-detail__meta {
  font-size: 11.5px; color: var(--text-4);
  border-top: 1px solid var(--border); padding-top: 11px;
  display: flex; flex-wrap: wrap;
  gap: 4px 0;
}
.notif-detail__meta > span {
  display: inline-flex; align-items: baseline; gap: 4px;
  padding-right: 14px;
}
.notif-detail__meta > span + span {
  border-left: 1px solid var(--border);
  padding-left: 14px;
}
.notif-detail__meta b {
  color: var(--text-3); font-weight: 600;
}
.notif-detail__meta code {
  background: var(--bg); padding: 1px 5px; border-radius: 3px;
  font-size: 10.5px; color: var(--text-2);
  border: 1px solid var(--border);
}

/* Subtitle im Modal-Header — Severity-Pill + Event-Badge + Zeit, inline. */
.notif-detail__sub {
  display: inline-flex; flex-wrap: wrap; align-items: center;
  gap: 8px; margin-top: 5px;
}
.notif-detail__sub-time {
  color: var(--text-4); font-size: 12px;
}

/* "✓ Bestätigt"-Badge im Sub-Header — erscheint sobald acknowledged_at gesetzt
   ist (entweder beim Öffnen einer bereits bestätigten Notification oder nach
   Klick auf „Erledigt" im Modal selbst). Grünes Pill, immer gleiche Farbe
   unabhängig von der Severity, weil der State semantisch „Erledigt" ist. */
.notif-ack-badge {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 2px 8px 2px 6px;
  border-radius: 999px;
  background: color-mix(in srgb, #16a34a 14%, var(--surface));
  color: color-mix(in srgb, #16a34a 75%, var(--text-1));
  font-size: 11px; font-weight: 700;
  letter-spacing: .02em;
}
.notif-ack-badge svg { width: 12px; height: 12px; }
[data-theme="dark"] .notif-ack-badge {
  background: rgba(134,239,172,.14);
  color: #86efac;
}

/* Highlight-Flash — wird nach erfolgreichem Ack auf Meta-Footer und
   Bestätigt-Badge gelegt, damit der State-Change visuell registriert wird. */
@keyframes notif-detail-flash {
  0%   { background-color: color-mix(in srgb, #16a34a 26%, transparent); }
  100% { background-color: transparent; }
}
@keyframes notif-ack-badge-pop {
  0%   { transform: scale(.7); opacity: 0; }
  60%  { transform: scale(1.12); opacity: 1; }
  100% { transform: scale(1); }
}
.notif-detail__meta.is-flashing {
  animation: notif-detail-flash 1.2s ease-out;
  border-radius: 6px;
}
.notif-ack-badge.is-flashing {
  animation: notif-ack-badge-pop .5s cubic-bezier(.16,1,.3,1);
}

/* Topbar buttons */
.btn-icon {
  width: 34px; height: 34px;
  border-radius: var(--r); border: 1px solid var(--border-2);
  background: var(--surface); cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  color: var(--text-3); transition: all .12s;
}
.btn-icon:hover { border-color: var(--gw); color: var(--gw); }
.btn-icon svg { width: 15px; height: 15px; }

/* Global search results dropdown */
.search-dropdown {
  /* Die Auswahlliste ist eckig und sitzt direkt am Suchfeld. Rechts war sie nie
     eckig — die Scrollleiste schnitt die Ecken ab.
     Und der Abstand kam von `top: calc(var(--topbar-h) - 4px)`: gemessen an der
     52 px hohen Kopfleiste, das Suchfeld ist aber 34 px hoch ⇒ 14 px Luft. Jetzt
     haengt die Liste am Suchfeld selbst (der Elternteil ist genau so hoch). */
  position: absolute; top: calc(100% + 4px);
  /* Vom 380px-Suchbox-Parent entkoppeln: fixe Breite, links bündig, nach
     rechts erweitert. max-width fängt schmale Viewports ab. */
  left: 0; right: auto;
  width: 640px;
  max-width: calc(100vw - 40px);
  background: var(--surface);
  border: 1.5px solid var(--border);
  border-radius: 0;
  box-shadow: 0 8px 32px rgba(0,0,0,.12);
  z-index: 200;
  overflow: hidden;
  display: none;
}
.search-dropdown.open { display: block; }
.search-dropdown { max-height: 70vh; overflow-y: auto; scrollbar-width: thin }
/* Beim Blättern mit der Pfeiltaste soll die gewählte Zeile sichtbar bleiben. Die Tastenhinweise kleben
   unten (.sr-foot, sticky) — scrollIntoView({block:'nearest'}) schob die Zeile genau an die
   Unterkante, also hinter die Fusszeile. scroll-padding haelt deren Hoehe frei (oben den
   Lauf-Balken). */
.search-dropdown { scroll-padding-block: 4px 40px; }
.search-dropdown::-webkit-scrollbar { width: 8px }
.search-dropdown::-webkit-scrollbar-thumb { background: var(--border); border-radius: 4px }
/* ── Die Suche antwortet sichtbar (13.09.2026) ──────────────────────────────────
   Vorher stand zwischen Tastendruck und Antwort nichts: 220 ms Pause, dann die
   Anfrage, dann schlagartig die ganze Liste neu. Jetzt:
     .is-loading  — ein schmaler Lauf-Balken oben, die alten Treffer bleiben
                    gedimmt stehen, statt zu verschwinden (kein Springen)
     .sr-neu      — nur Treffer, die vorher nicht da waren, blenden ein; was
                    bleibt, bleibt ruhig (gw-fade-in, gestaffelt ueber --sr-i)
     .sr-hit      — der Suchbegriff im Treffer
   Beim ersten Oeffnen stehen gw-skel-Zeilen in der Form der Treffer. */
.search-dropdown::before {
  content: ""; display: block; position: sticky; top: 0; z-index: 2;
  height: 2px; margin-bottom: -2px;
  background: linear-gradient(90deg, transparent, var(--gw), transparent) no-repeat;
  background-size: 40% 100%; background-position: -40% 0;
  opacity: 0; transition: opacity .15s;
}
.search-dropdown.is-loading::before { opacity: 1; animation: sr-lade 1s ease-in-out infinite; }
@keyframes sr-lade { from { background-position: -40% 0; } to { background-position: 140% 0; } }
.search-dropdown .search-result-item { transition: background .1s, opacity .15s; }
.search-dropdown.is-loading .search-result-item { opacity: .55; }
/* Platzhalter in der Kopf-Suche: exakt das Raster eines Treffers (4 px Polster + 28 px Zeile),
   sonst schrumpft der Kasten beim Umschalten sichtbar zusammen — die Vorschau stand rund 45 px
   hoeher als das Ergebnis. */
.search-dropdown > .gw-skel-box { padding: 4px 14px; }
.search-dropdown .gw-skel--row  { height: 28px; border-radius: 6px; }
.search-dropdown .gw-skel--row + .gw-skel--row { margin-top: 8px; }
.search-dropdown .sr-neu { animation: gw-fade-in .18s ease-out both; animation-delay: calc(var(--sr-i, 0) * 14ms); }
/* Signalfarbe Bernstein statt Markenblau, damit Treffer im Dunkelmodus deutlich hervortreten.
   Blau verschwand im Dunkeln im blauen Seitengrund; Bernstein steht neben den blauen,
   violetten und gruenen Treffer-Symbolen klar fuer sich. */
.sr-hit {
  background: #fef3c7; color: #92400e; font-weight: 600;
  border-radius: 2px; padding: 0 1px;
  box-shadow: inset 0 -1px 0 #f59e0b;
}
[data-theme="dark"] .sr-hit {
  background: color-mix(in srgb, #f59e0b 22%, transparent); color: #fcd34d;
  box-shadow: inset 0 -1px 0 color-mix(in srgb, #f59e0b 70%, transparent);
}
@media (prefers-reduced-motion: reduce) {
  .search-dropdown.is-loading::before { animation: none; background-size: 100% 100%; background-position: 0 0; }
  .search-dropdown .sr-neu { animation: none; }
}
.search-group-label {
  font-size: 10.5px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .8px;
  color: var(--text-3);
  padding: 7px 14px;
  background: var(--bg);
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  display: flex !important;
  align-items: center;
  gap: 8px;
}
.search-group-label:first-child { border-top: none }
.search-group-label .group-dot {
  display: inline-block; width: 8px; height: 8px; border-radius: 50%;
  flex-shrink: 0;
}
.search-result-item {
  display: flex; align-items: center; gap: 9px;
  padding: 4px 14px; cursor: pointer;
  transition: background .1s;
  min-height: 28px;
}
.search-result-item:hover { background: var(--bg); }
.search-result-icon {
  width: 22px; height: 22px; border-radius: 5px;
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
}
.search-result-icon svg { width: 12px; height: 12px; }
.search-result-title { font-size: 12.5px; font-weight: 500; color: var(--text-1); line-height: 1.3; overflow: hidden; text-overflow: ellipsis }
.search-result-sub   { font-size: 10.5px; color: var(--text-4); line-height: 1.25; overflow: hidden; text-overflow: ellipsis }
.search-result-content { min-width: 0; flex: 1 }
/* Marke an einem Settings-Treffer ohne eigenes Feld: die Einstellung existiert, wird aber
   nur vom Hintergrund-Dienst gelesen — der Klick kann darum nichts hervorheben. Dezent
   (Tint statt Vollton), damit sie den Treffer kennzeichnet und nicht als Warnung liest. */
.search-result-flag {
  margin-left: 6px; padding: 0 5px; border-radius: 999px; vertical-align: 1px;
  font-size: 9.5px; font-weight: 600; letter-spacing: .02em; white-space: nowrap;
  color: var(--text-3); background: color-mix(in srgb, var(--text-4) 16%, transparent);
}
.search-result-kbd   { margin-left: auto; font-size: 10px; color: var(--text-4); font-family: var(--font-mono); }
/* ── Tastatur-Auswahl, Schnellaktionen, Tastenhinweise (13.09.2026) ─────────────
   Die aktive Zeile traegt einen
   Lichtbalken in der Markenfarbe (--gw) statt nur einen grauen Grund, damit sie neben
   dem Hover-Grund eindeutig bleibt. Zeiger und Tastatur setzen dieselbe Klasse. */
.search-dropdown .search-result-item.is-active,
.search-dropdown .sr-ai-foot.is-active {
  background: color-mix(in srgb, var(--gw) 9%, var(--surface));
  box-shadow: inset 2px 0 0 var(--gw);
}
[data-theme="dark"] .search-dropdown .search-result-item.is-active,
[data-theme="dark"] .search-dropdown .sr-ai-foot.is-active {
  background: color-mix(in srgb, var(--gw) 17%, var(--surface));
  box-shadow: inset 2px 0 0 var(--gw), inset 0 0 18px -8px color-mix(in srgb, var(--gw) 55%, transparent);
}
.sr-acts {
  display: flex; gap: 2px; margin-left: auto; flex-shrink: 0;
  opacity: 0; visibility: hidden; transition: opacity .12s, visibility .12s;
}
.search-result-item:hover .sr-acts,
.search-result-item.is-active .sr-acts { opacity: 1; visibility: visible; }
.sr-act {
  width: 22px; height: 22px; padding: 0; border: 1px solid transparent; border-radius: 5px;
  display: inline-flex; align-items: center; justify-content: center;
  background: transparent; color: var(--text-3); cursor: pointer;
  transition: background .1s, color .1s, border-color .1s;
}
.sr-act svg { width: 13px; height: 13px; }
.sr-act:hover { color: var(--gw); border-color: color-mix(in srgb, var(--gw) 35%, transparent); background: var(--surface); }
.sr-foot {
  position: sticky; bottom: 0; z-index: 2;
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  padding: 6px 14px; border-top: 1px solid var(--border);
  background: color-mix(in srgb, var(--bg) 86%, transparent);
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  font-size: 11px; color: var(--text-4);
}
.sr-foot kbd {
  font-family: var(--font-mono); font-size: 10px; padding: 1px 5px; margin-right: 2px;
  border: 1px solid var(--border); background: var(--surface); border-radius: 3px; color: var(--text-3);
}
/* Ohne Zeiger (Touch): Aktionen immer sichtbar; Tastenhinweise ohne Tastatur sinnlos. */
@media (hover: none) {
  .sr-acts { opacity: 1; visibility: visible; }
  .sr-foot { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .sr-acts, .sr-act { transition: none; }
}
/* Tag-Pillen im Search-Dropdown + Ctrl+K nutzen die kanonische .user-tag-Klasse
   (siehe oben), bekommen aber Full-Pill-Border-Radius — passt visuell zu den
   pill-förmigen qsw-row-meta-Slots, und bei kleinen Pillen wirken 999px viel
   „runder" als die 6px-Default.
   Ausserdem kompakter als der Default: in einer Result-Row neben Titel-Text
   sollen die Pillen sich unterordnen, nicht dominieren — also kleinere Schrift,
   Padding und Icon. !important nötig, weil chipHtml() font-size inline setzt.
   Dasselbe Set gilt auch in den Multi-Select-Zonen-Pickern (uza im
   User-Modal, vza im Vanity-NS-Apply-Modal) — sonst wären die User-Tags
   dort visuell grösser als die Meta-Tags (Primary, 10 Rec, …). */
.search-dropdown .user-tag,
.qsw-row .user-tag,
.uza-row .user-tag,
.vza-row .user-tag {
  border-radius: 999px !important;
  font-size: 10px !important;
  padding: 1px 7px !important;
  gap: 4px;
  letter-spacing: .1px;
}
.search-dropdown .user-tag svg,
.qsw-row .user-tag svg,
.uza-row .user-tag svg,
.vza-row .user-tag svg {
  width: 9px !important;
  height: 9px !important;
}

/* ── Main content area ──────────────────────────────────── */
.app-main {
  flex: 1;
  overflow-y: auto;
  padding: 20px 24px;
}

/* ── Andockende Filter-/Suchleiste ───────────────────────────
   Muster aus dem Zoneneditor, seit v7.0.63 seitenuebergreifend: die Leiste mit Suche und
   Filtern bleibt beim Scrollen unter der Kopfleiste stehen, statt wegzuscrollen — bei langen
   Listen musste man sonst hochscrollen, nur um die Suche zu erreichen.

   Zwei Klassen im Markup:
     .gw-stick-sentinel  1px hoher Waechter direkt ueber der Leiste (meldet das Andocken)
     .gw-stickbar        die Leiste selbst; zusaetzlich .is-attached, wenn sie unmittelbar
                         unter der Reiterleiste sitzt (dann wachsen beide zu einem Feld
                         zusammen: oben keine Rundung, kein Rahmen, kein Abstand dazwischen).
   Ob .is-attached gilt, entscheidet das TEMPLATE — nicht ein Positions-Selektor: ein
   unsichtbares <script> zwischen Reiter und Leiste genuegt, und :first-child trifft nie mehr.

   Den Haftpunkt setzt app.js: Firefox rechnet den oberen Innenabstand des Scroll-Behaelters
   auf ihn drauf, andere Browser nicht. */
.gw-stickbar { position: sticky; top: 0; z-index: 20 }
/* Angedockt ist die Leiste eine Kante über die ganze Breite: keine Rundung, weder oben noch
   unten — sonst stehen über dem angedockten Tabellenkopf zwei runde Ecken. */
.gw-stickbar.is-stuck { border-radius: 0; box-shadow: 0 6px 18px rgba(0,0,0,.10), 0 1px 0 var(--border) }
[data-theme="dark"] .gw-stickbar.is-stuck { box-shadow: 0 6px 20px rgba(0,0,0,.45), 0 1px 0 var(--border) }
.gw-stickbar.is-attached { border-top-left-radius: 0; border-top-right-radius: 0; border-top: 0 }
.gw-stick-sentinel { height: 1px; margin: 0; padding: 0 }
/* Der Waechter waere zwischen Reiterleiste und angesetzter Karte als Haarlinie sichtbar. */
.gw-stick-sentinel:has(+ .gw-stickbar.is-attached) { margin-bottom: -1px }
/* Reiterleiste direkt darueber laesst ihren Abstand weg. Das sagt das TEMPLATE per Klasse,
   nicht ein Nachbar-Selektor: die Seiten nutzen unterschiedliche Leisten (.tab-bar im
   Zoneneditor, .ztab-bar sonst), verschiedene Panel-Container oder gar keine, und zwischen
   Leiste und Karte steht mal ein <style>, mal ein <script>. Die Klasse doppelt notiert, damit
   sie die margin-Regel der jeweiligen Leiste sicher ueberschreibt (zd.css laedt spaeter). */
.gw-tabs-attached.gw-tabs-attached { margin-bottom: 0 }
/* Ausnahme Zoneneditor: dort steht erst im Reiter fest, ob die Leiste oben sitzt (darueber
   koennen Domain-Weiterleitungen liegen) — die Reiterleiste ist da laengst gerendert. Hier
   traegt der Nachbar-Selektor, weil die Struktur auf dieser einen Seite bekannt ist. */
.tab-bar:has(+ .tab-panel.active .gw-stickbar.is-attached) { margin-bottom: 0 }

/* ── Page header ────────────────────────────────────────── */
.page-header {
  display: flex; align-items: center; gap: 12px;
  margin-bottom: 20px;
  /* flex-wrap: sonst laufen Titel + Action-Buttons bei knapper Breite (schmale
     Laptops / OS-Display-Scaling) rechts aus dem overflow:hidden-Content raus und
     werden abgeschnitten. Mit wrap fallen die Buttons auf eine zweite Zeile. */
  flex-wrap: wrap;
}
.page-title { font-size: 18px; font-weight: 700; color: var(--text-1); letter-spacing: -.3px; display: flex; align-items: center; gap: 9px; }
.page-title > svg { flex-shrink: 0; color: var(--gw); }
.page-subtitle { font-size: 13px; color: var(--text-3); margin-top: 2px; }
.page-actions { margin-left: auto; display: flex; gap: 8px; flex-wrap: wrap; }

/* Breadcrumbs */
.breadcrumbs { display: flex; align-items: center; gap: 6px; font-size: 12.5px; color: var(--text-4); margin-bottom: 16px; }
.breadcrumbs a { color: var(--text-3); text-decoration: none; }
.breadcrumbs a:hover { color: var(--gw); }
.breadcrumbs .sep { color: var(--border-2); }

/* ── Stat cards ─────────────────────────────────────────── */
.stat-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; margin-bottom: 20px; }
.stat-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: 16px 18px;
}
.stat-card-value { font-size: 24px; font-weight: 700; color: var(--text-1); letter-spacing: -.5px; line-height: 1; }
.stat-card-label { font-size: 12px; color: var(--text-3); margin-top: 4px; }
.stat-card-delta { font-size: 11.5px; margin-top: 6px; font-weight: 500; }
.delta-ok   { color: var(--ok); }
.delta-warn { color: var(--warn); }
.delta-err  { color: var(--err); }
.delta-neu  { color: var(--text-4); }

/* ── Cards ──────────────────────────────────────────────── */
.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  overflow: hidden;
}
.card-head {
  padding: 12px 16px;
  border-bottom: 1px solid var(--border);
  /* flex-start statt center: bei zweizeiligem Kopf (Titel + Untertitel im
     flex:1-Block) blieb ein rechtsstehender Action-Button (z.B. „Add") sonst
     gegen beide Zeilen zentriert und sass tiefer als der inline im Titel
     stehende „Anleitung"-Button → beide jetzt auf Titelzeilen-Höhe. Einzeilige
     Köpfe sind unverändert; Köpfe mit eigenem inline align-items behalten ihres. */
  display: flex; align-items: flex-start; gap: 8px;
}
.card-title {
  font-size: 13px; font-weight: 600; color: var(--text-1); flex: 1;
  display: inline-flex; align-items: center; gap: 9px;
}
.card-title-icon { color: var(--gw); flex-shrink: 0; opacity: .85; }
.card-link  { font-size: 12px; color: var(--gw); text-decoration: none; cursor: pointer; }
.card-link:hover { text-decoration: underline; }
.card-body  { padding: 0; }

/* ── Detail-Fenster: geteilte Grundzuege (ptm-*) ───────────────────────────
   Achtung: Diese zwei Regeln standen in proxy_ja4ml.css. Sie gehoeren aber drei Renderern:
   proxy_traffic_modal.js (Zonen-Editor + Proxy-Analytik), proxy_ja4ml.js und
   proxy_settings_modal.js (Pool-Detail). Die drei Seiten teilen als einzige Stilvorlage
   main.css — in proxy_ja4ml.css fehlte `.ptm-copyval` darum im Zonen-Editor, und die
   Kopier-Symbole standen dort dauerhaft auf voller Deckkraft statt erst beim Schweben.
   Gefunden vom Riegel `tests/js/shared_modal_styles_travel_test.cjs` (30.08.2026), nicht
   von Auge — genau dafuer gibt es ihn. */
.ptm-reqdet { text-align:left }
.ptm-copyval { margin-left:6px; vertical-align:middle; opacity:.5; transition:opacity .12s ease }
.ptm-bd-row:hover .ptm-copyval, .ptm-copyval:hover, .ptm-copyval:focus-visible, .ptm-copyval.copied { opacity:1 }

/* ── Zone table ─────────────────────────────────────────── */
.zone-table { width: 100%; border-collapse: collapse; }
.zone-table th {
  text-align: left; font-size: 11px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .5px;
  color: var(--text-3); padding: 8px 16px;
  border-bottom: 1px solid var(--border);
  background: #e7ecf3;
  white-space: nowrap;     /* keine Umbrüche im Spaltenkopf */
}
/* Einheitlicher Header-Hintergrund auch für inline-gestylte Tabellen
   (Audit-Log, Snapshots-Übersicht, Records-Listing usw.). */
#auditTable thead th,
.snp-table thead th { background: #e7ecf3 !important; }
.zone-table td {
  padding: 10px 16px;
  border-bottom: 1px solid #f5f7fa;
  font-size: 13px;
  color: var(--text-2);
}
.zone-table tr:last-child td { border-bottom: none; }
/* Auswahl-Spalte (Mehrfachauswahl) — eine Breite fuer jede Liste: Benutzer, Mandanten, … (20.09.2026). */
/* Auch in der mitlaufenden Kopf-Kopie (ohne #userTable): dort schlug `.zone-table th` mit seinem Innenabstand die
   einfache Klasse, die Auswahl-Spalte wurde 2 px breiter und schob den ganzen Kopf daneben (23.09.2026). */
.us-selcol, .zone-table .us-selcol { width: 38px; padding-left: 14px; padding-right: 0; }
.us-selcol input { width: 16px; height: 16px; accent-color: var(--gw); cursor: pointer; vertical-align: middle; }
.us-selcol input:disabled { cursor: not-allowed; opacity: .35; }

/* ── Sammel-Fenster: Betroffene und Eingabefelder ────────────────────────────────────────────────
   Standen bis 20.09.2026 nur in admin/users.php — in der Mandanten-Liste blieben dieselben Klassen
   darum ohne Stil. Eine Quelle fuer jede Liste. */
.us-bulk-f { display: flex; flex-direction: column; gap: 6px; margin-top: 12px; }
.us-bulk-f label { font-size: 12px; font-weight: 600; color: var(--text-2); }
.us-bulk-f select, .us-bulk-f input { height: 36px; padding: 0 10px; border: 1px solid var(--border); border-radius: 8px; background: var(--surface); color: var(--text-1); font-family: var(--font); font-size: 13px; }
.us-bulk-f select:focus, .us-bulk-f input:focus { outline: none; border-color: var(--gw); box-shadow: 0 0 0 3px var(--gw-light); }
.us-bulk-names { margin: 10px 0 0; padding-left: 18px; font-size: 12.5px; color: var(--text-2); }
.us-bulk-note { margin-top: 8px; font-size: 12px; color: var(--text-4); }
/* Betroffene je Zeile: Kennzeichen + Name + Zweitzeile (E-Mail bzw. Slug), scrollt ab ~6 Eintraegen. */
.us-bl { list-style: none; margin: 14px 0 0; padding: 4px; border: 1px solid var(--border); border-radius: 12px; background: var(--bg); max-height: 300px; overflow-y: auto; text-align: left; }
.us-bl li { display: flex; align-items: center; gap: 11px; padding: 8px 10px; border-radius: 9px; background: var(--surface); }
.us-bl li + li { margin-top: 4px; }
.us-bl__av { width: 30px; height: 30px; border-radius: 9px; display: flex; align-items: center; justify-content: center; flex-shrink: 0; font-size: 11px; font-weight: 700; color: #fff; letter-spacing: .2px; }
.us-bl__t { display: flex; flex-direction: column; min-width: 0; line-height: 1.3; }
.us-bl__n { font-size: 13px; font-weight: 600; color: var(--text-1); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.us-bl__e { font-family: var(--font-mono); font-size: 11.5px; color: var(--text-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* ── Abzeichen «Zugriffspruefung bestanden» ──────────────────────────────────────────────────────
   Gezacktes Siegel hinter dem Namen — Benutzerliste, Benutzer-Detail, Mandantenliste und
   Mandanten-Detail. --lg fuer Kopfzeilen. */
.us-ar-ok { display: inline-block; width: 14px; height: 14px; margin-left: 5px; vertical-align: -2px; line-height: 0; cursor: help; }
.us-ar-ok--lg { width: 17px; height: 17px; margin-left: 7px; }
.us-ar-ok__seal { fill: #16a34a; stroke: var(--surface); stroke-width: 2.6; paint-order: stroke; }
.us-ar-ok__check { fill: none; stroke: #fff; stroke-width: 3; stroke-linecap: round; stroke-linejoin: round; }
[data-theme="dark"] .us-ar-ok__seal { fill: #22c55e; }
/* Letzte Zeile jeder Tabelle ohne Trennlinie — sonst steht eine Linie vor dem Kartenrand, unter der nichts
   mehr kommt (z.B. Tenant-Pakete, Propagation). Das !important ist noetig, weil mehrere
   Renderer die Linie inline am <tr> mitgeben; eine Fusszeile (tfoot) bleibt unberuehrt. */
table tbody > tr:last-child { border-bottom: 0 !important; }
table tbody > tr:last-child > td { border-bottom: 0; }
.zone-table tr:hover td { background: var(--row-hover); }

/* ── Sortable column headers ─────────────────────────────────────────────
   Single source of truth für klickbare Spaltenheader. Einheitliches Hover-Feedback
   (etwas dunkleres Grau) und Sortier-Pfeil per CSS — wird sowohl von server-seitig
   sortierten Listen (Tenants, Users) als auch vom client-seitig sortierenden
   wireSortableTable() in app.js genutzt.

   ── Hintergrund (09.09.2026) ─────────────────────────────────────────────
   Im Zoneneditor leuchten die Spaltenköpfe Typ, Name, TTL beim Darüberfahren auf,
   bei DNS-Zonen, DNS-Records usw. passierte das nicht.
   Gemessen: dieselbe Idee stand dreimal da, und die drei Fassungen waren im
   Dunkeln nicht gleich —
     * `.sortable-th`                       → color-mix(--text-1 14%, transparent)
     * `.records-table thead th.sortable`   → #243044 (deckend, Zoneneditor)
     * `.snap-records thead th.snap-th`     → gar keine Dunkel-Fassung
   Die globale Records-Tabelle (/records) trug überhaupt keine der drei Klassen:
   nacktes <th> mit einem <a> darin, also weder Hand noch Aufleuchten.
   Jetzt trägt ein Regelblock alle vier Stellen. Ändert jemand den Ton, ändert er
   ihn überall. → SortableHeadersShareOneHoverTest */
.sortable-th,
.records-table thead th.sortable,
.snap-records thead th.snap-th { cursor: pointer; user-select: none; transition: background-color .12s; }
.sortable-th:hover,
.records-table thead th.sortable:hover,
.snap-records thead th.snap-th:hover { background: #dbe2eb !important; }
/* Der dunkle Ton ist gemessen, nicht gewaehlt: die bisherige `.sortable-th`-Fassung
   (color-mix(--text-1 14%, transparent)) war die einzige, die man beim Darauffahren
   wirklich sah — nur eben durchsichtig, und unter einer klebenden Kopfzeile scheinen
   dann die Zeilen durch (DNS-Zonen und DNS-Records kleben seit v7.3.76). Also
   derselbe Ton, aber ausgerechnet ueber dem Kopf-Grund #18243a und damit deckend:
   0.14 * #e2e8f0 + 0.86 * #18243a = #343f54. Die alte #243044 des Zoneneditors war
   um zwei Drittel schwaecher — sie fiel kaum auf. */
[data-theme="dark"] .sortable-th:hover,
[data-theme="dark"] .records-table thead th.sortable:hover,
[data-theme="dark"] .snap-records thead th.snap-th:hover { background: #343f54 !important; }
/* ── Der Sortier-Pfeil ──────────────────────────────────────────────────────
   Die Zustandsklasse darf an jedem Vorfahren haengen, nicht nur am `<th>`:
   sortiert der Server (die globale Records-Tabelle haengt sie an den <a>, weil
   der Kopf selbst aus dem Template kommt), sortiert der Browser (dann traegt sie
   das `<th>`). Vor v7.3.87 verlangten diese Regeln woertlich `.sortable-th` als
   Vorfahr — und genau darum malte `/records` sich seinen Pfeil mit vier
   Inline-Stilen selbst: ▲▼ in 9 px, aktiv ▲ oder ▼ in --text-1. Dieselbe Optik,
   zweite Fassung, die beim naechsten Ton-Wechsel stehenbleibt. */
.sortable-th__arrow { display: inline-block; margin-left: 4px; font-size: 9px; color: var(--text-4); opacity: .4; line-height: 1; vertical-align: middle; }
.is-sorted-asc  .sortable-th__arrow,
.is-sorted-desc .sortable-th__arrow { opacity: 1; color: var(--text-1); }
.sortable-th__arrow::before        { content: '▲▼'; letter-spacing: -1px; }
.is-sorted-asc  .sortable-th__arrow::before { content: '▲'; letter-spacing: 0; }
.is-sorted-desc .sortable-th__arrow::before { content: '▼'; letter-spacing: 0; }
/* Server-side variant: wenn der Header ein <a> mit Pfeil-Anker enthält, gleiche Optik.
   Den Abstand macht hier `gap` — der Pfeil bringt fuer den <th>-Fall sein eigenes
   `margin-left` mit, das waere im Anker doppelt. */
.sortable-th a { color: inherit; text-decoration: none; display: inline-flex; align-items: center; gap: 4px; }
.sortable-th a > .sortable-th__arrow { margin-left: 0; }
.zone-name-cell { font-weight: 500; color: var(--text-1); font-family: var(--font-mono); font-size: 12.5px; }
.zone-dot { width: 7px; height: 7px; border-radius: 50%; display: inline-block; }

/* ── Badges / Status ────────────────────────────────────── */
/* hidden-Attribut wirkt nur ueber die UA-Vorgabe display:none — eine eigene display-Regel schlaegt sie. */
.badge[hidden] { display:none; }
.badge {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 11px; font-weight: 600;
  padding: 2px 8px; border-radius: 5px;
}
/* Severity-Varianten der .badge — visuell und dark-mode-mässig identisch zur
   .sev-pill (Pill-Form + UPPERCASE). Damit sehen Status-Badges auf Audit-Log,
   Tenant-/User-Detail-Aktivitäten, Cron-Manager etc. überall gleich aus. */
.badge-ok, .badge-warn, .badge-err, .badge-neu, .badge-ai {
  border-radius: 999px;
  text-transform: uppercase;
  font-weight: 700;
  letter-spacing: .3px;
}
.badge-ok   { background: #dcfce7; color: #166534; }
.badge-warn { background: #fef3c7; color: #92400e; }
.badge-err  { background: #fee2e2; color: #991b1b; }
.badge-neu  { background: var(--bg); color: var(--text-3); border: 1px solid var(--border); }
/* KI-Aktions-Badge — gleiche violette Linie wie .btn-ai / .gwai-head / .qsw-orb /
   .sr-orb, damit man im Audit-Log auf einen Blick sieht: das war eine KI-Aktion. */
.badge-ai  { background: rgba(124,58,237,.12); color: #6d28d9; border: 1px solid rgba(124,58,237,.30); }
[data-theme="dark"] .badge-ai { background: rgba(139,92,246,.22); color: #c4b5fd; border-color: rgba(139,92,246,.40); }

/* Severity-Pille — systemweit einheitlich für Status-/Severity-Anzeigen
   (Zone-Health, Security-Findings, Cron-Manager etc.). Pill-Form,
   UPPERCASE, identische Dark-Mode-Tints — gleiche Sprache überall. */
.sev-pill {
  display: inline-flex; align-items: center;
  padding: 2px 8px; border-radius: 999px;
  font-size: 11px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .3px;
}
.sev-pill.success  { background: #dcfce7; color: #166534 }
.sev-pill.info     { background: #dbeafe; color: #1e40af }
.sev-pill.warning  { background: #fef3c7; color: #92400e }
.sev-pill.critical { background: #fee2e2; color: #991b1b }
.sev-pill.neutral  { background: var(--bg); color: var(--text-3); border: 1px solid var(--border) }
/* Dark-Mode: transparent-Tints in Identitätsfarbe. */
[data-theme="dark"] .sev-pill.success  { background: rgba(34,197,94,.18);  color: #86efac }
[data-theme="dark"] .sev-pill.info     { background: rgba(56,189,248,.18); color: #7dd3fc }
[data-theme="dark"] .sev-pill.warning  { background: rgba(234,179,8,.18);  color: #fcd34d }
[data-theme="dark"] .sev-pill.critical { background: rgba(239,68,68,.18);  color: #fca5a5 }
[data-theme="dark"] .sev-pill.neutral  { background: rgba(255,255,255,.06); color: var(--text-3); border-color: var(--border) }

/* Tenant-Pille — Layout zentral, Farbe kommt deterministisch pro Tenant
   via tenantPill() (PHP) bzw. window.gwTenantPill() (JS) als inline-style. */
.tag-tenant {
  display: inline-flex; align-items: center;
  height: 22px; padding: 0 9px; border-radius: 6px;
  font-size: 11px; font-weight: 600; letter-spacing: .2px; line-height: 1;
  max-width: 220px; min-width: 0; overflow: hidden; white-space: nowrap;
  vertical-align: middle;
}
/* Inner-Label: hier greift text-overflow:ellipsis — geht nicht auf der
   inline-flex-Box selbst, weil Ellipsis eine Block-Formatting-Box braucht. */
.tag-tenant > .tag-tenant__lbl {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Auto-Layout-Tabellen drücken die Tenant-Spalte sonst auf die natürliche
   Breite der Pille — bei 220px Pillen wirkt das aber gequetscht, weil
   anderen Spalten mehr Platz zugeteilt wird. Mindestbreite garantiert, dass
   die Pille nicht visuell vom Cell beschnitten wird. Kein direkt-Child-
   Combinator, weil manche Templates die Pille in <a> oder <div> wrappen. */
td:has(.tag-tenant) { min-width: 240px }

/* System-Tag — für Sysadmin-/Systemkonten ohne Tenant-Bindung (z.B. in Audit-
   Log, Benutzer-Liste). Bewusst neutraler Look mit gestricheltem Border,
   damit er optisch nicht mit Tenant-Pillen konkurriert. */
.tag-system {
  display: inline-flex; align-items: center;
  height: 22px; padding: 0 9px; border-radius: 6px;
  font-size: 11px; font-weight: 600; letter-spacing: .2px; line-height: 1;
  background: var(--bg); color: var(--text-3);
  border: 1px dashed var(--border);
}
[data-theme="dark"] .tag-system { background: rgba(255,255,255,.04); color: var(--text-3); border-color: var(--border) }

/* ── Detail-Hero (Profilseiten-Look) ──────────────────────────────────────
   Wiederverwendbar für Tenant-Detail, Benutzer-Detail, später ggf. weitere.
   Akzentfarbe pro Subjekt via --dh-tone (Hex) inline gesetzt. Mesh-Gradient
   aus zwei Radial-Gradients + Diagonalverlauf, Avatar mit Inset-Highlight
   und farbigem Drop-Shadow. */
.detail-card-with-hero { overflow: hidden }
.detail-hero {
  position: relative;
  padding: 32px 20px 22px;
  text-align: center;
  border-bottom: 1px solid var(--border);
  background:
    radial-gradient(ellipse 70% 50% at 25% 0%, color-mix(in srgb, var(--dh-tone) 28%, transparent), transparent 60%),
    radial-gradient(ellipse 60% 60% at 80% 100%, color-mix(in srgb, var(--dh-tone) 18%, transparent), transparent 65%),
    linear-gradient(135deg, color-mix(in srgb, var(--dh-tone) 10%, var(--surface)) 0%, var(--surface) 75%);
}
[data-theme="dark"] .detail-hero {
  background:
    radial-gradient(ellipse 70% 50% at 25% 0%, color-mix(in srgb, var(--dh-tone) 40%, transparent), transparent 60%),
    radial-gradient(ellipse 60% 60% at 80% 100%, color-mix(in srgb, var(--dh-tone) 26%, transparent), transparent 65%),
    linear-gradient(135deg, color-mix(in srgb, var(--dh-tone) 18%, var(--surface)) 0%, var(--surface) 75%);
}
.detail-hero__avatar {
  margin: 0 auto 14px;
  width: 68px; height: 68px; border-radius: 18px;
  display: flex; align-items: center; justify-content: center;
  font-size: 26px; font-weight: 700; color: #fff;
  background: linear-gradient(135deg, var(--dh-tone) 0%, color-mix(in srgb, var(--dh-tone) 70%, #000) 100%);
  box-shadow:
    0 8px 24px -8px color-mix(in srgb, var(--dh-tone) 60%, transparent),
    0 2px 6px rgba(0,0,0,.08),
    inset 0 1px 0 rgba(255,255,255,.25);
}
[data-theme="dark"] .detail-hero__avatar {
  box-shadow:
    0 10px 26px -8px color-mix(in srgb, var(--dh-tone) 70%, transparent),
    0 2px 6px rgba(0,0,0,.4),
    inset 0 1px 0 rgba(255,255,255,.18);
}
/* Praesenz-Ampel — ein Muster fuer Benutzer-/Tenant-Verwaltung und die Detailseiten.
   An der Avatar-/Badge-Ecke: gruen (weicher Schimmer) = gerade aktiv, amber = angemeldet
   aber inaktiv, hohl+verblassend = nicht angemeldet. Ring in --surface ⇒ Hell/Dunkel sauber.
   --hero: groessere Variante fuer die 68px-Avatare im Detail-Kopfbereich. */
.pres-wrap { position: relative; flex-shrink: 0; line-height: 0 }
.pres-dot { position: absolute; right: 0; bottom: 0; width: 8px; height: 8px; border-radius: 50%; border: 1.5px solid var(--surface); box-sizing: content-box }
/* «Jemand ist da» muss man finden, ohne es zu suchen. Traegt wird die Aussage vom Kern:
   kraeftige Signalfarbe je Modus und ein weicher Schein — der fruehere 7px-Punkt in
   #10b981 ging in beiden Modi unter (hell zu blass gegen Weiss, dunkel zu matt gegen
   #1e293b, Befund 12.08.2026).

   Ausdruecklich kein harter Farbring um den Punkt: als 2.5px-Ring gesetzt wirkte er grob
   und liess den Punkt wie umrandet statt wie leuchtend aussehen. Der Schein bleibt weich
   und ohne Kante. Die Welle laeuft eng am Kern (bis 1.75-fach) statt weit auszulaufen —
   sie soll den Blick holen, nicht die Zeile dominieren.

   Bewegung nur bei «aktiv»: liefe sie auch bei untaetig/offline, flimmerte eine Liste mit
   vierzehn Tenants durchgehend und die Aussage waere wieder keine. */
.pres-dot--on   { width: 9px; height: 9px; background: var(--pres-on); box-shadow: 0 0 6px 1px var(--pres-on-glow) }
.pres-dot--on::after {
  content: ""; position: absolute; inset: -2px; border-radius: 50%;
  border: 1.5px solid var(--pres-on); pointer-events: none;
  animation: pres-ripple 2.2s cubic-bezier(.25,.6,.35,1) infinite;
}
@keyframes pres-ripple {
  0%   { transform: scale(.92); opacity: .7 }
  70%  { transform: scale(1.75); opacity: 0 }
  100% { opacity: 0 }
}
/* Wer Bewegung abbestellt hat, bekommt den Ring als ruhigen Zweitkreis — die Aussage
   bleibt, nur die Animation faellt weg. */
@media (prefers-reduced-motion: reduce) {
  .pres-dot--on::after { animation: none; opacity: .45 }
}
.pres-dot--idle { background: var(--pres-idle) }
.pres-dot--off  { background: var(--surface); box-shadow: inset 0 0 0 1.5px var(--text-4); opacity: .65 }
.pres-dot--hero { width: 13px; height: 13px; right: 1px; bottom: 1px; border-width: 2.5px }
.pres-dot--hero.pres-dot--on { width: 14px; height: 14px; box-shadow: 0 0 9px 1.5px var(--pres-on-glow) }
.pres-dot--hero.pres-dot--on::after { inset: -3px; border-width: 2px }

.detail-hero__name { font-size: 19px; font-weight: 700; color: var(--text-1); letter-spacing: -.2px; line-height: 1.2 }
.detail-hero__sub  { font-size: 13px; color: var(--text-3); margin-top: 4px }
.detail-hero__slug { font-size: 12px; color: var(--text-3); font-family: var(--font-mono); margin-top: 4px; opacity: .85 }
.detail-hero__status { margin-top: 14px; display: flex; flex-wrap: wrap; gap: 6px; justify-content: center }
.detail-hero__badge {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 4px 12px 4px 10px; border-radius: 999px;
  font-size: 11.5px; font-weight: 600; letter-spacing: .2px;
  border: 1px solid transparent;
}
.detail-hero__badge.is-ok   { background: rgba(22,163,74,.12); color: #166534; border-color: rgba(22,163,74,.28) }
.detail-hero__badge.is-err  { background: rgba(220,38,38,.12); color: #991b1b; border-color: rgba(220,38,38,.28) }
.detail-hero__badge.is-warn { background: rgba(217,119,6,.14); color: #854d0e; border-color: rgba(217,119,6,.32) }
[data-theme="dark"] .detail-hero__badge.is-ok   { background: rgba(34,197,94,.18); color: #86efac; border-color: rgba(34,197,94,.36) }
[data-theme="dark"] .detail-hero__badge.is-err  { background: rgba(239,68,68,.18); color: #fca5a5; border-color: rgba(239,68,68,.36) }
[data-theme="dark"] .detail-hero__badge.is-warn { background: rgba(234,179,8,.18); color: #fcd34d; border-color: rgba(234,179,8,.36) }
.detail-hero__dot {
  width: 7px; height: 7px; border-radius: 50%; background: currentColor;
  box-shadow: 0 0 0 2px color-mix(in srgb, currentColor 18%, transparent);
}
.detail-hero__badge.is-ok .detail-hero__dot { animation: detail-hero-pulse 2.4s ease-out infinite }
@keyframes detail-hero-pulse {
  0%   { box-shadow: 0 0 0 0   color-mix(in srgb, currentColor 45%, transparent) }
  70%  { box-shadow: 0 0 0 6px color-mix(in srgb, currentColor 0%,  transparent) }
  100% { box-shadow: 0 0 0 0   color-mix(in srgb, currentColor 0%,  transparent) }
}

/* Explizite Tenant-Spalte für find-table — Inline-`min-width` an <th> reicht
   in Auto-Layout nicht zuverlässig, weil der Browser die Spalte rechnerisch
   verteilt. `width` ist autoritativer und propagiert sicher zur Column-Width. */
.find-table th.col-tenant,
.find-table td.col-tenant { width: 240px; min-width: 240px }
.zone-table th.col-tenant,
.zone-table td.col-tenant { width: 240px; min-width: 240px }

/* ── Health bar ─────────────────────────────────────────── */
.health-bar-wrap { height: 5px; background: var(--bg); border-radius: 3px; overflow: hidden; flex: 1; }
.health-bar-fill { height: 100%; border-radius: 3px; transition: width .3s; }

/* ── Buttons ────────────────────────────────────────────── */
/* `.btn` setzt display — damit verliert das `hidden`-Attribut (Hausregel, 20.09.2026 im Rig
   nachgestellt: ein Knopf mit `hidden` stand sichtbar in der Kopfzeile). Das trifft jeden Knopf,
   den ein Skript ueber `hidden` schaltet: «Layout bearbeiten», «Speichern», «Abbrechen» im
   Dashboard standen darum immer da. Eine Regel fuer alle, statt an jeder Stelle eine eigene. */
.btn[hidden] { display: none !important; }

.btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: 6px; height: 36px; padding: 0 16px;
  border-radius: var(--r);
  /* Einheitliche 1.5px-Border-Basis (transparent) — sichert identische Höhe
     zwischen Primary (kein sichtbarer Rand) und Secondary (sichtbarer Rand). */
  border: 1.5px solid transparent;
  font-size: 13px; font-weight: 600; line-height: 1;
  font-family: var(--font); cursor: pointer;
  text-decoration: none; transition: all .12s;
  white-space: nowrap;
  vertical-align: middle;
}
.btn:disabled { opacity: .45; cursor: not-allowed; }
/* Live-Aufrufe beim Registrar: überall, wo live über die API gelesen wird, bleibt die Seite flüssig. Der Knopf wartet sichtbar (Ring + Text, Breite bleibt, window.gwBusy); Inhalte zeigen
   die Platzhalter des Hauses (.gw-skel, weiter unten). Ohne Bewegung bei prefers-reduced-motion. */
.btn.is-busy { opacity: 1; cursor: progress; }
.btn.is-busy svg { display: none; }
.btn.is-busy::before { content: ''; width: 12px; height: 12px; flex: none; border-radius: 50%; border: 2px solid currentColor;
  border-right-color: transparent; animation: gw-busy-spin .7s linear infinite; }
@keyframes gw-busy-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .btn.is-busy::before { animation: none; } }
.btn svg { width: 14px; height: 14px; flex-shrink: 0; }

.btn-primary   { background: var(--gw);  color: #fff; border-color: var(--gw); }
.btn-primary:hover { background: var(--gw-dark); border-color: var(--gw-dark); }

.btn-secondary {
  background: var(--surface); color: var(--text-2);
  border-color: var(--border-2);
}
.btn-secondary:hover { border-color: var(--gw); color: var(--gw); }

/* Ghost = niedrigste Emphase, aber muss als Button lesbar sein: sichtbarer
   Hairline-Rand + lesbarer Text, Füllung erst beim Hover. (Vorher randlos +
   --text-3 → verschwand weiss-auf-weiss / dunkel-auf-dunkel.) */
.btn-ghost { background: none; color: var(--text-2); border: 1.5px solid var(--border-2); }
.btn-ghost:hover { background: var(--bg); color: var(--text-1); border-color: var(--gw); }

.btn-danger { background: var(--err-bg); color: var(--err); border: 1px solid var(--err-bd); }
.btn-danger:hover { background: var(--err); color: #fff; }
/* Gegenstueck zu .btn-danger in Gruen — fuer Paare, bei denen die eine Wahl so schwer
   wiegt wie die andere: «Zugriff bestaetigen» gegen «Zugriff verweigern» (21.09.2026). */
.btn-ok { background: var(--ok-bg); color: var(--ok); border: 1px solid var(--ok-bd); }
.btn-ok:hover { background: var(--ok); color: #fff; }
/* Aktivieren/Deaktivieren/Willkommens-Mail teilen die gleiche Hover-Logik wie
   .btn-secondary (Bearbeiten/MFA): beim Hover färben sich Rahmen + Icon in der
   Akzentfarbe, keine Hintergrund-Füllung (einheitlich über User- +
   Tenant-Verwaltung). Semantische Farbe (grün=Aktivieren/Welcome, amber=Deaktiv.)
   sitzt im Icon + Rand; dark-safe über --ok-* / --warn-*-Tokens. */
.btn-activate   { background: var(--surface); color: var(--ok);   border: 1.5px solid var(--ok-bd); }
.btn-activate:hover   { background: var(--surface); border-color: var(--ok);   color: var(--ok); }
.btn-deactivate { background: var(--surface); color: var(--warn); border: 1.5px solid var(--warn-bd); }
.btn-deactivate:hover { background: var(--surface); border-color: var(--warn); color: var(--warn); }
.btn-welcome    { background: var(--surface); color: var(--ok);   border: 1.5px solid var(--ok-bd); }
.btn-welcome:hover    { background: var(--surface); border-color: var(--ok);   color: var(--ok); }


/* Tastatur-Fokus: dezenter markenfarbener Ring statt des kantigen UA-Default-
   Outlines. Der Default-Outline wirkte am autofokussierten OK-Button der Detail-
   Modals (zd.alert fokussiert ihn beim Öffnen) wie ein Fremdrahmen und erschien
   nur „manchmal" — naemlich bei Tastatur-Modalitaet. Mit :focus-visible zeigen
   Maus-Klicks (Modal per Klick geoeffnet) keinen Ring → der Button bleibt
   schlicht blau; echte Tastatur-Navigation behaelt einen sauberen a11y-Ring. */
.btn:focus-visible { outline: none; box-shadow: 0 0 0 3px color-mix(in srgb, var(--gw, #0098ef) 30%, transparent); }
.btn-danger:focus-visible { box-shadow: 0 0 0 3px color-mix(in srgb, var(--err, #dc2626) 30%, transparent); }

.btn-sm { height: 30px; padding: 0 12px; font-size: 12px; }
.btn-xs { height: 24px; padding: 0 9px; font-size: 11px; gap: 4px; border-radius: 6px; }
.btn-xs svg { width: 11px; height: 11px; }
.btn-lg { height: 42px; padding: 0 20px; font-size: 14px; }
.btn-warning { background: var(--warn, #f59e0b); color: #fff; }
.btn-warning:hover { background: #b45309; }

/* ── Alerts ─────────────────────────────────────────────── */
.alert {
  display: flex; align-items: flex-start; gap: 10px;
  border-radius: var(--r); padding: 12px 14px;
  font-size: 13.5px; line-height: 1.5;
  margin-bottom: 16px; border: 1px solid;
}
.alert-icon {
  flex-shrink: 0; width: 20px; height: 20px;
  border-radius: 50%; display: flex; align-items: center;
  justify-content: center; margin-top: 1px;
}
.alert-icon svg { width: 11px; height: 11px; stroke: #fff; }
.alert-body { flex: 1; }
.alert-title { font-weight: 600; margin-bottom: 2px; }
.alert-error   { background: var(--err-bg);  border-color: var(--err-bd);  color: #991b1b; }
.alert-error   .alert-icon { background: var(--err); }
.alert-success { background: var(--ok-bg);   border-color: var(--ok-bd);   color: #14532d; }
.alert-success .alert-icon { background: var(--ok); }
.alert-warning { background: var(--warn-bg); border-color: var(--warn-bd); color: #78350f; }
.alert-warning .alert-icon { background: var(--warn); }
.alert-info    { background: var(--gw-light);border-color: #bfdbfe;        color: #1e3a5f; }
.alert-info    .alert-icon { background: var(--gw); }

/* Dark-Mode: Schrift muss hell sein (die expliziten dunklen colors oben werden
   sonst unlesbar auf dunklem Backdrop). Backdrop wechselt auf transparent-Tint. */
[data-theme="dark"] .alert-error   { background: rgba(239,68,68,.12)   !important; border-color: rgba(239,68,68,.40)   !important; color: #fca5a5 !important; }
[data-theme="dark"] .alert-success { background: rgba(34,197,94,.12)   !important; border-color: rgba(34,197,94,.40)   !important; color: #86efac !important; }
[data-theme="dark"] .alert-warning { background: rgba(234,179,8,.12)   !important; border-color: rgba(234,179,8,.40)   !important; color: #fcd34d !important; }
[data-theme="dark"] .alert-info    { background: rgba(56,189,248,.12)  !important; border-color: rgba(56,189,248,.40)  !important; color: #93c5fd !important; }

/* ── Forms ──────────────────────────────────────────────── */
.form-group  { margin-bottom: 16px; }
.form-label  { display: block; font-size: 12px; font-weight: 600; color: var(--text-2); margin-bottom: 5px; }
.form-hint   { font-size: 11.5px; color: var(--text-4); margin-top: 4px; }
.inp {
  width: 100%; height: 38px;
  border: 1.5px solid var(--border-2);
  border-radius: var(--r); padding: 0 12px;
  font-size: 13px; color: var(--text-1);
  background: var(--surface); font-family: var(--font);
  outline: none; transition: border-color .15s, box-shadow .15s;
}
.inp:focus { border-color: var(--gw); box-shadow: 0 0 0 3px rgba(0,152,239,.1); }
.inp::placeholder { color: var(--text-4); }
/* Validierungs-Fehler: hellroter Background + roter Border, bis der Wert wieder gültig ist */
.inp.is-error { border-color:#fca5a5; background:#fff5f5 }
.inp.is-error:focus { border-color:#dc2626; box-shadow:0 0 0 3px rgba(220,38,38,.12) }
select.inp { cursor: pointer; }
textarea.inp { height: auto; padding: 10px 12px; resize: vertical; }

/* ── Toast notifications ────────────────────────────────── */
.toast-container {
  position: fixed; bottom: 20px; right: 20px;
  display: flex; flex-direction: column; gap: 8px;
  /* Vor den Fenstern (zd-dlg-backdrop 10000 … 10060): Meldungen aus einem offenen Fenster lagen sonst dahinter (18.10.2026) */
  z-index: 10100;
}
.toast {
  display: flex; align-items: center; gap: 10px;
  background: var(--text-1); color: #fff;
  border-radius: var(--r-lg); padding: 12px 16px;
  font-size: 13.5px; font-weight: 500;
  box-shadow: 0 4px 20px rgba(0,0,0,.2);
  animation: toast-in .2s ease;
  max-width: 320px;
}
/* Dark-Mode-Fix: die Basis nutzt background:var(--text-1) — im Dark-Mode hell,
   damit weisse Schrift auf hellem Grund unlesbar (z.B. der Toast „Sitzung
   verlängert" unten rechts). Untypisierte/info-Toasts daher
   im Dark-Mode auf einen stabilen dunklen Grund. Steht vor den Typ-Farben:
   ok/err/warn haben dieselbe Spezifität und gewinnen per Quell-Reihenfolge,
   behalten also ihre Signalfarbe. */
[data-theme="dark"] .toast { background: #334155; }
/* Beide Namens-Schemata abdecken: ok/err/warn (base.php-showToast + CSS) und
   success/error/warning/info (app.js-showToast, u. a. session-guard.js). Ohne
   die success/…-Aliasse fielen diese Toasts auf die kaputte Basis zurück. */
.toast.toast-ok,   .toast.toast-success { background: var(--ok); }
.toast.toast-err,  .toast.toast-error   { background: var(--err); }
.toast.toast-warn, .toast.toast-warning { background: var(--warn); }
.toast.toast-info  { background: var(--gw, #0098ef); }
@keyframes toast-in { from { opacity:0; transform: translateY(8px); } to { opacity:1; transform: none; } }

/* ── Split-Pill (Label/Wert, zweifarbig) ──────────────────────────────────
   Zweifarbige Pille: links Label (dunklerer Tint der Identitätsfarbe), rechts
   Wert (hellerer Tint). Farbe per `--gw-tone` als R,G,B-Tripel inline gesetzt.
   Erste Anwendung: Risk-Score-Komponenten in der „alle bewerteten Zonen"-
   Tabelle (Alias `.rs-comp-tag`). Auch verwendet für Tag-Vorkommnisse auf
   /tenant/tags. Optional als <a> rendern → bleibt klickbar mit Hover-Brightness. */
.gw-split-pill, .rs-comp-tag {
  display: inline-flex; align-items: stretch;
  margin: 0 6px 4px 0; border-radius: 5px; overflow: hidden;
  font-size: 11px; font-weight: 600; line-height: 1;
  text-decoration: none; cursor: pointer;
  transition: filter .12s;
}
.gw-split-pill:hover, .rs-comp-tag:hover { filter: brightness(1.08) }
.gw-split-pill__lbl, .gw-split-pill__val,
.rs-comp-tag__lbl,   .rs-comp-tag__val {
  padding: 4px 7px;
  display: inline-flex; align-items: center;
}
.gw-split-pill__lbl { color: rgb(var(--gw-tone)); background: rgba(var(--gw-tone), .22) }
.gw-split-pill__val { color: rgb(var(--gw-tone)); background: rgba(var(--gw-tone), .12); font-variant-numeric: tabular-nums }
.rs-comp-tag__lbl   { color: rgb(var(--rs-tone)); background: rgba(var(--rs-tone), .22) }
.rs-comp-tag__val   { color: rgb(var(--rs-tone)); background: rgba(var(--rs-tone), .12); font-variant-numeric: tabular-nums }
[data-theme="dark"] .gw-split-pill__lbl { background: rgba(var(--gw-tone), .26) }
[data-theme="dark"] .gw-split-pill__val { background: rgba(var(--gw-tone), .14) }
[data-theme="dark"] .rs-comp-tag__lbl   { background: rgba(var(--rs-tone), .26) }
[data-theme="dark"] .rs-comp-tag__val   { background: rgba(var(--rs-tone), .14) }
/* Dark-Mode: der Text ist sonst die rohe Ton-Farbe (--gw-tone/--rs-tone) — bei dunklen
   Service-/Komponenten-Farben (z.B. dunkelblau/bordeaux) ergab das dunkel-auf-dunkel und war
   kaum erkennbar. Ton mit Weiss aufhellen → Farbton bleibt, Kontrast auf dem dunklen Grund passt. */
[data-theme="dark"] .gw-split-pill__lbl,
[data-theme="dark"] .gw-split-pill__val { color: color-mix(in srgb, rgb(var(--gw-tone)) 55%, white) }
/* Tag-Pillen (--tag-Variante, nur Tags-Seite): Label-Haelfte in der echten Tag-Farbe wie die
   .user-tag-Chips im Zoneneditor (Light solid + Kontrast-Schrift); Dark behaelt den Neon-Tint
   — dort rendert auch der Zoneneditor transparent/neon (Paritaet statt Doppel-Optik). */
.gw-split-pill--tag { border: 1px solid color-mix(in srgb, rgb(var(--gw-tone)) 25%, var(--border)) }
.gw-split-pill--tag .gw-split-pill__lbl { background: rgb(var(--gw-tone)); color: var(--gw-fg, #ffffff) }
[data-theme="dark"] .gw-split-pill--tag .gw-split-pill__lbl { background: rgba(var(--gw-tone), .26); color: color-mix(in srgb, rgb(var(--gw-tone)) 55%, white) }
[data-theme="dark"] .rs-comp-tag__lbl,
[data-theme="dark"] .rs-comp-tag__val   { color: color-mix(in srgb, rgb(var(--rs-tone)) 55%, white) }

/* ── Reiter: eine Fassung fuer das ganze Haus (14.09.2026) ───────────────────
   Im Dunkelmodus war der aktive Reiter bei DNS-Zonen blau, im Zoneneditor grau; dasselbe
   bei Tenant-Details und Security & Risk. Das soll einheitlich sein.
   Gemessen (getComputedStyle, dunkel, aktiver Reiter) standen sechs Fassungen da:
     DNS-Zonen    .ztab       (zd.css)            rgba(0,152,239,.10)  blau
     Zoneneditor  .tab-bar .tab  (hier)           rgb(30,41,59)        grau (--surface)
     Einstellungen .tab-btn   (hier)              rgb(30,41,59)        grau
     Tenant       .tdtab-btn  (in der Seite)      kein Grund, 13.5px/600
     Security     .sec-tab    (security.css)      volle blaue Pille, 6px Rundung
     Migration    .mig-tab    (in der Seite)      nur Unterstrich, keine Lasche
   Die Vorgaenger-Regel vom 08.09. («zwei Klassennamen, eine Regel») hatte zwei der
   sechs zusammengelegt — die uebrigen vier lebten weiter, weil jede Seite ihren
   eigenen Namen erfand. Darum jetzt umgekehrt: jeder Reiter traegt die Klasse
   `.ztab`, jede Leiste `.ztab-bar`. Die alten Namen bleiben nur als Haken fuer
   Skripte (`.tab[data-tab]`, `.tdtab-btn`) und Seiten-Abstaende. Aktive Farbe = die
   von DNS-Zonen, Hover = die Fassung vom 08.09. (Begruendung direkt darunter). */
.ztab-bar,
.tab-bar {
  display: flex; flex-wrap: wrap; align-items: stretch; gap: 4px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 20px; padding: 0; position: relative;
}
.ztab-bar { margin-bottom: 14px; }
/* Hausvariante «Leiste links» (18.10.2026, System › Einstellungen: 20 Reiter gruppiert wie die App-Leiste). Senkrecht,
   ohne Lasche und Linie; der aktive Reiter hat einen hellblauen Grund und rechts einen blauen Strich. Das Seitengitter
   (Spalten) legt die Seite selbst fest. */
.ztab-bar--side { flex-direction: column; flex-wrap: nowrap; gap: 1px; border-bottom: 0; margin-bottom: 0; overflow-x: visible; }
.ztab-bar--side .ztab { justify-content: flex-start; width: 100%; margin: 0; padding: 7px 12px; border-radius: 8px 0 0 8px;
  border-right: 2px solid transparent; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ztab-bar--side .ztab::before, .ztab-bar--side .ztab::after { display: none; }
.ztab-bar--side .ztab.active { background: color-mix(in srgb, var(--gw) 10%, transparent); color: var(--text-1); border-right-color: var(--gw); }
.ztab-bar--side .ztab:not(.active):hover { background: color-mix(in srgb, var(--text-1) 6%, transparent); color: var(--text-1); }
.ztab {
  position: relative; display: inline-flex; align-items: center; gap: 8px;
  padding: 9px 14px; margin: 0 0 -1px 0; box-sizing: border-box; height: auto;
  border: none; border-radius: 8px 8px 0 0; background: transparent;
  font-family: var(--font); font-size: 13px; font-weight: 500; font-style: normal; line-height: 1;
  color: var(--text-3); text-decoration: none; cursor: pointer; outline: none;
  transition: color .15s, background .15s;
}
.ztab:focus-visible { outline: 2px solid var(--gw); outline-offset: -2px; }
/* Ein <a class="ztab"> (Security, Migration, Weiterleitungen) bekaeme sonst die Linkfarbe. */
a.ztab:link, a.ztab:visited { color: var(--text-3); text-decoration: none; }
.ztab::after {
  content: ''; position: absolute; left: 10px; right: 10px; bottom: 0;
  height: 2px; background: transparent; border-radius: 2px 2px 0 0;
  transition: background .15s;
}
/* Zeilenumbruch der Reiterleiste: je nach Breite bricht die Leiste um, die Linie darunter muss trotzdem
   jede Reihe abschliessen.
   Die Trennlinie ist der `border-bottom` der Leiste — bricht sie um (Security 24 Reiter,
   Zoneneditor 16), steht die Linie nur unter der untersten Reihe, die oberen Reiter haengen
   frei und ihre aktive Lasche endet im Nichts. DNS-Zonen hat vier Reiter und bricht nie um,
   darum sah man es dort nie.
   Jetzt zeichnet jeder Reiter die Linie selbst, ab seiner linken Kante bis weit nach rechts;
   die Leiste schneidet am eigenen Rand ab (`overflow-x: clip` macht, anders als hidden,
   keinen Scrollbereich auf und laesst die 1 px, die der Reiter nach unten ueberhaengt,
   stehen). So hat jede Reihe ihre durchgehende Linie. Die spaeteren Reiter liegen darueber:
   der aktive deckt sie mit seinem Grund ab wie bisher die Leistenlinie.
   Nur ab 769 px: darunter scrollen die Leisten quer in einer Reihe (Mobil-Regel oben), eine
   100vw-Linie wuerde dort nur leere Scrollbreite erzeugen. */
@media (min-width: 769px) {
  .ztab-bar, .tab-bar { overflow-x: clip; }
  .ztab::before {
    content: ''; position: absolute; left: 0; bottom: 0; width: 100vw; height: 1px;
    background: var(--border); pointer-events: none;
  }
}
/* Hover auf einem Reiter brach links und rechts die Optik. Zwei Ursachen, beide in diesen
   vier Zeilen:

   1. `background: var(--bg)` — das ist der SEITEN-Hintergrund (#f0f4f8 hell,
      #0f172a dunkel). Die Reiterleiste sitzt aber auf einer `--surface`-Karte
      (#ffffff / #1e293b). Im Hellmodus ist --bg darum ein leichtes Anheben, im
      Dunkelmodus ist er dunkler als der Grund: der Reiter bekam beim Ueberfahren
      ein dunkles Rechteck mit harten senkrechten Kanten — genau die «gebrochenen»
      Kanten links und rechts. Ein Ton, der auf zwei Untergruenden in
      entgegengesetzte Richtungen wirkt, taugt nicht als Hover.
      Jetzt ein Anheben aus der Textfarbe: hell auf dunkel, dunkel auf hell.

   2. Die Marke stand 1 px neben der Trennlinie. Der Reiter haengt per
      `margin-bottom:-1px` eine Pixelzeile tiefer als die Leiste; `bottom: 0`
      liegt damit unter deren `border-bottom`. Ergebnis: zwei fast parallele
      Linien in zwei Farben, und weil `::after` links/rechts 10 px einrueckt,
      endete die obere abrupt — ein heller Stummel. Auf der Linie
      statt daneben, und in einem Ton, der sich der Trennlinie unterordnet
      statt mit der aktiven Marke zu konkurrieren.
      (Die aktive Marke bleibt bei `bottom: 0`: dort deckt der eigene
      `--surface`-Grund die Trennlinie ab, Reiter und Inhalt verschmelzen — das
      ist gewollt und sieht richtig aus.) */
.ztab:hover,
a.ztab:hover {
  color: var(--text-1); text-decoration: none;
  /* Achtung: Die Fuellung laesst die unterste Pixelzeile frei. Der Reiter haengt per
     `margin-bottom:-1px` genau eine Zeile tiefer als die Leiste; eine volle
     Flaeche deckt damit deren `border-bottom` auf der Breite des Reiters ab —
     die Linie bricht ab und setzt daneben wieder an, und genau diese zwei
     senkrechten Kanten waren sichtbar. Mit `calc(100% - 1px)`
     laeuft die Linie durch und die Fuellung sitzt sauber darauf. */
  background: linear-gradient(
      color-mix(in srgb, var(--text-1) 8%, transparent),
      color-mix(in srgb, var(--text-1) 8%, transparent)
    ) top / 100% calc(100% - 1px) no-repeat;
}
.ztab:hover::after {
  bottom: 1px;
  background: color-mix(in srgb, var(--text-4) 55%, transparent);
}
.ztab.active:hover::after { bottom: 0; }
/* `a.ztab:link/:visited/:hover` sind spezifischer als `.ztab.active` — ohne die drei hier
   bekaeme ein aktiver LINK-Reiter die graue Linkfarbe bzw. beim Darauffahren den Hover-Grund. */
.ztab.active,
a.ztab.active:link,
a.ztab.active:visited,
a.ztab.active:hover {
  color: var(--gw); background: var(--surface); font-weight: 700;
  box-shadow: 0 1px 3px rgba(15,23,42,.08), 0 -1px 0 var(--border) inset;
}
/* Dunkel: der aktive Reiter leuchtet im Markenton (so stand es auf DNS-Zonen) statt im
   --surface-Grau. !important wie bisher: es schlaegt auch die Bernstein-Lasche «nicht zugewiesen». */
[data-theme="dark"] .ztab.active { background: rgba(0,152,239,.10) !important; }
.ztab.active::after { background: var(--gw); height: 3px; }
/* ── Karteikarten-Reiter ──────────────────────────────────────────────────────────────────────────
   Waagrechte Leisten: jeder Reiter ist eine Karteikarte mit feinem Rand und runden oberen Ecken; die aktive ist eine
   offene Karte mit blauer Oberkante (Variante 1, 19.10.2026). Die Reihe steht bündig links und bleibt eine Zeile: was nicht
   passt, kommt unter «Mehr ▾» (tabs_more.js setzt .gw-tabs-one/.gw-tab-off). Ohne Leuchten, ohne Hochspringen.
   Unter 769 px gilt weiter das Querscrollen. Die senkrechte Leiste (.ztab-bar--side) bleibt, wie sie ist. */
@media (min-width: 769px) {
  .ztab-bar:not(.ztab-bar--side), .tab-bar:not(.ztab-bar--side) { gap: 3px; padding-left: 0; }
  .ztab-bar.gw-tabs-one, .tab-bar.gw-tabs-one { flex-wrap: nowrap; min-width: 0; max-width: 100%; }
  :is(.ztab-bar, .tab-bar):not(.ztab-bar--side) .ztab {
    flex: none; white-space: nowrap; padding: 9px 12px 10px;
    border: 1px solid var(--border); border-bottom: 0; border-radius: 10px 10px 0 0;
    background: color-mix(in srgb, var(--surface) 45%, transparent);
  }
  :is(.ztab-bar, .tab-bar):not(.ztab-bar--side) .ztab:not(.active):hover {
    background: color-mix(in srgb, var(--text-1) 6%, color-mix(in srgb, var(--surface) 45%, transparent));
  }
  :is(.ztab-bar, .tab-bar):not(.ztab-bar--side) .ztab:not(.active):hover::after { background: transparent; }
  :is(.ztab-bar, .tab-bar):not(.ztab-bar--side) .ztab.active,
  :is(.ztab-bar, .tab-bar):not(.ztab-bar--side) a.ztab.active:link,
  :is(.ztab-bar, .tab-bar):not(.ztab-bar--side) a.ztab.active:visited {
    /* Offene Karte mit blauer Oberkante: Grund wie der Inhalt, unten offen (die
       Trennlinie läuft unter ihr nicht durch), oben eine feine blaue Kante; kein blauer Grund, keine Linie unten */
    background: var(--surface) !important; border-color: var(--border);
    color: var(--text-1); font-weight: 650; box-shadow: inset 0 2px 0 var(--gw);   /* folgt den runden Ecken */
  }
  :is(.ztab-bar, .tab-bar):not(.ztab-bar--side) .ztab.active > svg { color: var(--gw); }
  :is(.ztab-bar, .tab-bar):not(.ztab-bar--side) .ztab.active::before { display: none; }
  :is(.ztab-bar, .tab-bar):not(.ztab-bar--side) .ztab.active::after { display: none; }
  .gw-tab-off { display: none !important; }
  /* «Mehr» direkt hinter der letzten Karteikarte, nicht am rechten Rand, wo man ihn leicht übersieht */
  :is(.ztab-bar, .tab-bar) .ztab.gw-tabs-more { gap: 6px; font-weight: 600; color: var(--text-2); }
  :is(.ztab-bar, .tab-bar) .ztab.gw-tabs-more[aria-expanded="true"] { color: var(--text-1); }
}
/* «Mehr» versteckt sich über [hidden] — .ztab setzt display, darum ausdrücklich (sonst stand «Mehr (1)» ohne Inhalt da;
   Hausregel: hidden braucht einen display-Riegel) */
.ztab.gw-tabs-more[hidden] { display: none !important; }
/* Menü «Mehr» (tabs_more.js) — Stil der zd-Auswahllisten */
.gw-tabs-menu { position: fixed; z-index: 2000; min-width: 220px; max-height: 70vh; overflow: auto; padding: 6px; display: flex; flex-direction: column; gap: 2px;
  background: var(--surface); border: 1px solid var(--border); border-radius: 12px; box-shadow: 0 12px 30px rgba(15, 23, 42, .16); }
[data-theme="dark"] .gw-tabs-menu { border-color: var(--border-2, var(--border)); box-shadow: 0 12px 30px rgba(0, 0, 0, .45); }
.gw-tabs-menu__it { display: flex; align-items: center; gap: 9px; width: 100%; padding: 8px 10px; border: 0; border-radius: 8px; background: transparent;
  font: inherit; font-size: 13px; font-weight: 500; color: var(--text-2); text-align: left; cursor: pointer; white-space: nowrap; }
.gw-tabs-menu__it svg { width: 15px; height: 15px; flex: none; color: var(--text-3); }
.gw-tabs-menu__it .tab-count { margin-left: auto; }
.gw-tabs-menu__it:hover, .gw-tabs-menu__it:focus-visible { background: color-mix(in srgb, var(--text-1) 6%, transparent); color: var(--text-1); outline: none; }
/* ── Senkrechte Reiter-Navigation: .ztab-v (14.09.2026) ─────────────────────────────
   Reiter in Fenstern angeglichen. Proxy-Einstellungen (.rps-tab in
   .rps-layout) und Record-Seitenpanel (.ptab) sind senkrechte Navigationen; sie hatten eigene
   Werte (Hover Markenton 6 %, aktiv 11 %, 600). Jetzt dieselben Zustaende wie .ztab: Hover aus
   der Textfarbe, aktiv Markenfarbe 700, hell Karten-Grund, dunkel Markenton .10 — die 3-px-Marke
   steht links statt unten. .ztab selbst passt hier nicht: seine Linie je Reihe (100vw) und der
   Unterstrich liefen quer ueber den Inhalt. Groesse wie bisher (Spalte 164 px). */
.ztab-v {
  position: relative; display: inline-flex; align-items: center; gap: 6px; width: 100%;
  justify-content: flex-start; text-align: left; white-space: nowrap; box-sizing: border-box;
  padding: 7px 9px; margin: 0; border: 0; border-radius: 8px; background: transparent;
  font-family: var(--font); font-size: 12.5px; font-weight: 500; line-height: 1.2;
  color: var(--text-3); cursor: pointer; transition: color .15s, background .15s;
}
.ztab-v:focus-visible { outline: 2px solid var(--gw); outline-offset: -2px; }
.ztab-v:hover { color: var(--text-1); background: color-mix(in srgb, var(--text-1) 8%, transparent); }
/* Aktiv wie in der linken Navigation: getoente Flaeche und ein kurzer,
   abgerundeter Strich links — nicht der durchgehende Balken mit Karten-Schatten von vorher. */
.ztab-v.active, .ztab-v.is-active {
  color: var(--gw); font-weight: 700;
  background: color-mix(in srgb, var(--gw) 14%, transparent);
  box-shadow: none;
}
.ztab-v.active::before, .ztab-v.is-active::before {
  content: ''; position: absolute; left: 0; top: 7px; bottom: 7px;
  width: 3px; border-radius: 3px; background: var(--gw);
}
[data-theme="dark"] .ztab-v.active, [data-theme="dark"] .ztab-v.is-active { background: rgba(0,152,239,.20); }
.ztab-v > svg { width: 14px; height: 14px; flex-shrink: 0; opacity: .55; transition: opacity .12s; }
.ztab-v:hover > svg { opacity: .85; }
.ztab-v.active > svg, .ztab-v.is-active > svg { opacity: 1; }
.tab-count {
  font-size: 11px; font-weight: 700;
  padding: 2px 8px; border-radius: 10px;
  background: var(--surface); color: var(--text-3);
  min-width: 24px; text-align: center; letter-spacing: .2px;
  border: 1px solid var(--border);
}
.tab-btn.active .tab-count,
.tab-bar .tab.active .tab-count { background: var(--gw-light); color: var(--gw); border-color: #bfdbfe; }
/* Zwei Namen fuer dieselbe Sache, historisch gewachsen: `.warn` auf den einen
   Seiten, `.tab-count-warn` im Zoneneditor. Beide hier, damit kein Ort seine
   eigene Fassung braucht. */
.tab-count.warn,
.tab-count.tab-count-warn { background: #fef3c7; color: #92400e; border-color: #fde68a; }
/* Reiter «Domain»: beim Registrar läuft ein Auftrag (blau, wie laufend/in Arbeit) */
.tab-bar .tab .tab-count.tab-count-job, .tab-count.tab-count-job,
[data-theme="dark"] .tab-bar .tab .tab-count.tab-count-job, [data-theme="dark"] .tab-bar .tab.active .tab-count.tab-count-job {
  background: color-mix(in srgb, var(--gw) 16%, transparent) !important; color: var(--gw) !important; border-color: color-mix(in srgb, var(--gw) 35%, transparent) !important; }
/* Reiter-Icon folgt dem Zustand des Reiters — gehoert zur gemeinsamen Sprache. Direktes Kind,
   damit ein Icon IN einer Marke nicht mitgedimmt wird; gilt fuer .ztab-ico, .tab-ico und Icons ohne Klasse. */
.ztab > svg { color: currentColor; opacity: .55; flex-shrink: 0; transition: opacity .12s; }
.ztab:hover > svg { opacity: .85; }
.ztab.active > svg { opacity: 1; }

/* Marken der Reiter: weicher Ton statt vollgesaettigtem Blau, im Dunkelmodus
   getoent statt grell. Stand bis 08.09.2026 nur in records.css und galt darum nur
   im Zoneneditor — dieselbe Marke sah auf den Einstellungs-Reitern anders aus. */
.tab-btn .tab-count,
.tab-bar .tab .tab-count { background: #dbeafe; color: #1d4ed8; font-weight: 700; }
.tab-btn.active .tab-count,
.tab-bar .tab.active .tab-count { background: var(--gw-light); color: var(--gw); }
.tab-btn .tab-count.warn, .tab-btn .tab-count.tab-count-warn,
.tab-bar .tab .tab-count.tab-count-warn { background: #fef3c7; color: #92400e; }
[data-theme="dark"] .tab-btn .tab-count,
[data-theme="dark"] .tab-bar .tab .tab-count {
  background: rgba(59,130,246,.16) !important;
  color: #93c5fd !important;
  border-color: rgba(147,197,253,.28) !important;
}
[data-theme="dark"] .tab-btn.active .tab-count,
[data-theme="dark"] .tab-bar .tab.active .tab-count {
  background: rgba(0,152,239,.20) !important;
  color: #5ec5fb !important;
  border-color: rgba(94,197,251,.40) !important;
}
[data-theme="dark"] .tab-btn .tab-count.warn,
[data-theme="dark"] .tab-btn .tab-count.tab-count-warn,
[data-theme="dark"] .tab-bar .tab .tab-count.tab-count-warn {
  background: rgba(245,158,11,.16) !important;
  color: #fbbf24 !important;
  border-color: rgba(251,191,36,.30) !important;
}
/* Inline-«on»-Pillen (DNSSEC/DMARC/TLS-RPT) tragen ihre Farbe im style-Attribut —
   ueber den Attribut-Selektor abgefangen, damit sie im Dunkelmodus nicht knallen. */
[data-theme="dark"] .tab-btn .tab-count[style*="#dcfce7"],
[data-theme="dark"] .tab-btn .tab-count[style*="#166534"],
[data-theme="dark"] .tab-bar .tab .tab-count[style*="#dcfce7"],
[data-theme="dark"] .tab-bar .tab .tab-count[style*="#166534"] {
  background: rgba(34,197,94,.18) !important;
  color: #86efac !important;
  border-color: rgba(34,197,94,.35) !important;
}

/* ── Namens-Zelle: ein Name plus Etiketten ───────────────────────────────────
   Befund 08.09.2026 (/records): in der Spalte «Zone» stand nur noch
   «Produktiv · Shared-Services · Infrastruct…» — der Zonenname war weg. Nicht
   abgeschnitten, sondern gemessen 0.0 px breit.

   Der Grund steckte in der Flex-Verteilung: der Name war `flex:0 1 auto`, also
   schrumpfbar, die Etiketten `flex:none`, also starr. In einem `nowrap`-Container
   mit `overflow:hidden` gibt darum ausschliesslich der Name nach — bis auf null —,
   waehrend die starren Etiketten ihre volle Breite behalten und am Rand hart
   abgeschnitten werden. Das Wichtigste der Spalte verschwindet, das Beiwerk bleibt.

   Die Regel dreht das um: der NAME ist das Subjekt der Spalte und bekommt den
   Platz zuerst; die Etiketten geben nach. Und der Name kuerzt mit Auslassungs-
   zeichen, statt zu verschwinden — «galaxy…» sagt mehr als nichts.

   Achtung: eine Regel fuer alle Stellen (globale Records: Zone und Name · Zoneneditor:
     Name). Dieselbe Zelle dreimal von Hand zu setzen war der Weg, auf dem der
     Fehler ueberhaupt entstanden ist. */
.gw-namecell {
  display: flex; flex-wrap: nowrap; gap: 4px 6px; align-items: center;
  min-width: 0; overflow: hidden;
}
.gw-namecell__name {
  /* `min-width` ist der eigentliche Riegel: der Name darf kuerzen, aber nie unter
     eine lesbare Restlaenge fallen. Ohne ihn endet er wieder bei 0 px. */
  flex: 0 1 auto; min-width: 7ch;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Achtung: Die Reihenfolge des Nachgebens steckt in der Schrumpf-Zahl, nicht in einer
   Breitenangabe: `flex-shrink:100` gegen die 1 des Namens. Bei Platzmangel geben
   damit die Etiketten hundertmal so stark nach — der Name kuerzt erst, wenn sie
   nichts mehr hergeben. Mit gleicher Schrumpf-Zahl kuerzen beide gleichmaessig,
   und dann steht «galaxydns…» neben «Produ…» — beides halb. */
.gw-namecell__tags {
  display: flex; flex-wrap: nowrap; gap: 4px 6px; align-items: center;
  flex: 0 100 auto; min-width: 0; overflow: hidden;
}
/* Wird es eng, kuerzen die Etiketten selbst mit Auslassungszeichen. Ein am
   Zellenrand hart abgeschnittenes Etikett («Shared-Se» ohne Ende, oder nur «S»)
   liest sich wie ein Fehler; «Shared-Se…» liest sich wie eine Kuerzung. */
.gw-namecell__tags .user-tag { flex: 0 1 auto; min-width: 0 }
/* Eingeklappt, weil der Platz nicht reicht — gesetzt von gwNamecellFit in app.js.
   Achtung: `!important` ist hier kein Faulheitsgriff: die Etiketten und der Zaehler sind
     `display:inline-flex`, und eine display-Regel aus der Klasse selbst schlaegt
     sonst das Ausblenden. Genau daran hing am 08.09.2026 die Reiterleiste, deren
     Menue immer offen stand (`display:flex` schlug `[hidden]`). */
.gw-namecell .gw-fold { display: none !important }
.gw-namecell__tags .user-tag > .ut-lbl {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Das Etikett, nach dem gerade gefiltert wird, traegt einen Ring — damit man
   sieht, warum diese Zeile dasteht, und nicht nur dass sie dasteht. */
.gw-namecell__tags .user-tag.is-filtered {
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--tag-color, #64748b) 45%, transparent);
}
/* «+2» fuer die Etiketten, die nicht mehr gezeigt werden: klein, nie schrumpfend,
   die vollstaendige Liste steht im title. */
.gw-namecell__more {
  flex: none; font-size: 10px; line-height: 1.4; padding: 1px 6px;
  border-radius: 999px; border: 1px solid var(--border);
  background: var(--bg); color: var(--text-4); white-space: nowrap; cursor: help;
  transition: color .12s, border-color .12s;
}
.gw-namecell__more:hover,
.gw-namecell__more:focus-visible { color: var(--text-2); border-color: var(--text-4); outline: none }

/* Das Popover dazu haengt am <body> (die Zelle schneidet ab) und zeigt die
   Etiketten so, wie sie in der Zeile aussehen — mit Farbe und Symbol, eines je
   Zeile. Ein einzeiliges `title="A · B · C"` war die Notloesung davor. */
.gw-tagpop {
  /* Über Dialogen (.zd-dlg-backdrop 10000): «+N» gibt es auch im Zonen-Picker des Benutzer-Modals. */
  position: absolute; z-index: 10050;
  display: flex; flex-direction: column; align-items: flex-start; gap: 5px;
  max-width: 320px; padding: 8px;
  background: var(--surface); border: 1px solid var(--border); border-radius: 10px;
  box-shadow: 0 10px 28px rgba(15,23,42,.16), 0 2px 6px rgba(15,23,42,.07);
}
[data-theme="dark"] .gw-tagpop { box-shadow: 0 12px 32px rgba(0,0,0,.5), 0 2px 8px rgba(0,0,0,.35) }
.gw-tagpop .user-tag { font-size: 11px; padding: 2px 8px; line-height: 1.5; max-width: 100%; }

/* ── Modal ──────────────────────────────────────────────────────────────────
   Hintergrund-Overlay-Werte sind absichtlich identisch mit .zd-dlg-backdrop
   (zd.css), damit alle Modals (Mail-Setup, Wildcard, Delegation, Klonen,
   Health-Check, zd.confirm-Dialoge) denselben Look haben.
   z-index 10000 = gleiche Ebene wie zd-Dialoge; zd-Dropdowns liegen via 10001
   wieder darüber. */
/* Legacy-Modal — gleicher visueller Stil wie .zd-dlg (siehe zd.css).
   Bestehende showModal()/Custom-Modals nutzen weiterhin .modal-overlay/.modal,
   bekommen aber automatisch den moderneren Look (mehr Schatten, grösserer
   Border-Radius, intensiverer Backdrop). */
.modal-overlay {
  position: fixed; inset: 0;
  background: rgba(15,23,42,.72);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  display: flex; align-items: center; justify-content: center;
  z-index: 10000; padding: 24px;
  animation: zdFadeIn .15s ease-out;
}
.modal {
  background: var(--surface);
  border-radius: 14px;
  border: 1px solid var(--border);
  box-shadow: 0 32px 80px rgba(0,0,0,.28), 0 0 0 1px rgba(0,0,0,.04);
  width: 100%; max-width: 520px;
  max-height: 92vh; overflow-y: auto;
  animation: zdDlgIn .18s ease-out;
}
[data-theme="dark"] .modal { box-shadow: 0 32px 80px rgba(0,0,0,.6), 0 0 0 1px rgba(255,255,255,.06); }
.modal-head, .modal-header {
  padding: 22px 24px 16px;
  border-bottom: 1px solid var(--border);
  display: flex; align-items: center; gap: 12px;
}
.modal-title { font-size: 17px; font-weight: 700; color: var(--text-1); flex: 1; line-height: 1.3; }
.modal-close { background: none; border: none; cursor: pointer; color: var(--text-4); padding: 4px; border-radius: var(--r-sm); }
.modal-close:hover { color: var(--text-1); background: var(--bg); }
.modal-body { padding: 20px 24px; font-size: 13.5px; line-height: 1.6; color: var(--text-2); }
.modal-body strong { color: var(--text-1); }
.modal-foot {
  padding: 13px 24px;
  border-top: 1px solid var(--border);
  display: flex; justify-content: flex-end; gap: 8px;
  background: var(--bg);
}
[data-theme="dark"] .modal-foot { background: rgba(255,255,255,.02); }

/* ── Slide panel ────────────────────────────────────────── */
/* Dasselbe fuer das Seitenfenster: `hidden` muss auch hier wirken. */
.slide-panel[hidden] { display: none !important; }
.slide-panel {
  position: fixed; top: 0; right: 0; bottom: 0;
  width: 440px; background: var(--surface);
  border-left: 1px solid var(--border);
  box-shadow: -8px 0 32px rgba(0,0,0,.1);
  z-index: 400;
  transform: translateX(100%);
  transition: transform .22s ease;
  display: flex; flex-direction: column;
}
.slide-panel.open { transform: none; }
.slide-overlay {
  position: fixed; inset: 0;
  background: rgba(13,27,42,.3);
  z-index: 399; display: none;
}
.slide-overlay.open { display: block; }
.slide-head {
  padding: 16px 20px; border-bottom: 1px solid var(--border);
  display: flex; align-items: center; gap: 10px; flex-shrink: 0;
}
.slide-title { font-size: 15px; font-weight: 700; color: var(--text-1); flex: 1; }
.slide-body  { flex: 1; overflow-y: auto; padding: 16px 20px; }

/* ── Utilities ──────────────────────────────────────────── */
.flex         { display: flex; }
.flex-1       { flex: 1; }
.items-center { align-items: center; }
.gap-8        { gap: 8px; }
.gap-12       { gap: 12px; }
.mt-4         { margin-top: 4px; }
.mt-8         { margin-top: 8px; }
.mt-16        { margin-top: 16px; }
.mb-16        { margin-bottom: 16px; }
.text-sm      { font-size: 12px; }
.text-muted   { color: var(--text-3); }
.text-ok      { color: var(--ok); }
.text-warn    { color: var(--warn); }
.text-err     { color: var(--err); }
.text-mono    { font-family: var(--font-mono); }
.grid-2       { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.grid-3       { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 12px; }
.grid-4       { display: grid; grid-template-columns: repeat(4,1fr); gap: 12px; }

/* ── Hover-Utilities (CSP-Nonce-Migration: Ersatz für Inline-
   onmouseover/onmouseout="this.style.…"). Nur anwenden, wenn das Element
   die jeweilige Eigenschaft nicht inline gesetzt hat (inline gewinnt sonst
   gegen :hover). Für inline gesetzte border-color → -bd-Variante mit !important. */
.gwh-bg:hover       { background: var(--bg); }
.gwh-bg-light:hover { background: var(--gw-light); }
/* Als Tabellen-ZEILE gilt der Haus-Hover (Tags: Liste war var(--bg) = im Dunkeln dunkel, die
   Verwaltung var(--gw-light) — zwei Toene auf einer Seite, 14.09.2026). */
tr.gwh-bg:hover, tr.gwh-bg-light:hover { background: var(--row-hover); }
/* Deaktivierte Zeile = dieselbe Optik wie ein deaktivierter Record im Zoneneditor (records.css, .records-table
   tr.row-inactive): gedämpft und schräg gestreift. Für Benutzer- (#userTable) und Mandantenverwaltung (#tenantTable):
   deaktivierte Konten und Tenants sehen aus wie ein deaktivierter Record. */
#userTable tbody tr[data-row-inactive] td, #tenantTable tbody tr[data-row-inactive] td { opacity:.6; background:repeating-linear-gradient(45deg, var(--bg) 0 8px, transparent 8px 16px) }
#userTable tbody tr[data-row-inactive]:hover td, #tenantTable tbody tr[data-row-inactive]:hover td { background:repeating-linear-gradient(45deg, var(--border) 0 8px, var(--bg) 8px 16px) }
/* Achtung: Die beiden festen Spalten (data-gw-stickcol="2") brauchen einen deckenden Grund: mit opacity .6 und Streifen
   über «transparent» lief beim Querscroll die Benutzername-Spalte sichtbar darunter durch. Dort also Streifen über --surface bzw. --row-hover, und gedämpft wird nur der
   Inhalt der Zelle, nicht die Zelle selbst. Die Streifenfarbe ist dabei schon mit 60 % gemischt — genau der Ton, der
   in den übrigen Zellen durch opacity .6 über dem Zeilengrund entsteht; ungemischt wirkte die feste Spalte dunkler. */
@media (min-width: 769px) {
  #userTable > tbody > tr[data-row-inactive] > td:nth-child(-n+2), #tenantTable > tbody > tr[data-row-inactive] > td:nth-child(-n+2) {
    opacity:1; background:repeating-linear-gradient(45deg, color-mix(in srgb, var(--bg) 60%, var(--surface)) 0 8px, var(--surface) 8px 16px) }
  #userTable > tbody > tr[data-row-inactive]:hover > td:nth-child(-n+2), #tenantTable > tbody > tr[data-row-inactive]:hover > td:nth-child(-n+2) {
    background:repeating-linear-gradient(45deg, color-mix(in srgb, var(--border) 60%, var(--row-hover)) 0 8px, color-mix(in srgb, var(--bg) 60%, var(--row-hover)) 8px 16px) }
  #userTable > tbody > tr[data-row-inactive] > td:nth-child(-n+2) > *, #tenantTable > tbody > tr[data-row-inactive] > td:nth-child(-n+2) > * { opacity:.6 }
}
.gwh-bd:hover       { border-color: var(--gw) !important; }
.gwh-c-gw:hover     { color: var(--gw) !important; }

/* ── .rec-chip — Filter-Chip: ein Baustein fuer jede Filter-Pille im Haus (14.09.2026) ─────────────
   Filter-Pillen sehen überall gleich aus (vorher z.B. in den Snapshot-Details anders als im Zoneneditor). Vorbild: Typ-Filter unter der Suche im Zoneneditor — die Regeln standen
   dort in records.css und sind hierher gezogen, weil Snapshots-Seite, Mandanten-Ansicht, Migration,
   Sicherheit und Proxy records.css nicht laden. Markup nur ueber window.gwFilterChip (filter_chip.js)
   bzw. filterChip() (PHP). Zwei Arten:
     neutral (Alle, Kategorie, Status): Grund --surface; aktiv voller Markenton
     Typ (.rec-chip--typed + .rr-<TYPE>): Farbe aus .rr-<TYPE> (hell/dunkel), Grund und Rand aus currentColor
   Zustand: .active-all (einziger Aktiv-Zustand). Kein Leuchten, keine Bewegung. */
.rec-chip { font-size:12px; font-weight:700; padding:4px 10px; border-radius:6px; border:1px solid; line-height:1.4; cursor:pointer; font-family:var(--font); }
a.rec-chip { display:inline-block; text-decoration:none; }
.rec-chip span { opacity:.7; font-weight:400; margin-left:2px }
.rec-chip:disabled { cursor:default }
.rec-chip.is-empty { opacity:.45; cursor:default }
/* Farbpunkt vorne im Chip (Option «dot» in gwFilterChip/filterChip): Legende der Time-Machine-Schiene, Farbe aus
   snapshot_view.css .snapv-kc.is-* (dieselbe Tabelle wie Punkte und Art-Pillen). */
.rec-chip__dot { display:inline-block; width:8px; height:8px; border-radius:50%; background:currentColor; margin-right:6px; vertical-align:0 }
.rec-chip.active-all .rec-chip__dot { box-shadow:0 0 0 1.5px var(--surface,#fff) }
/* Zeile der Filter-Chips (mit Beschriftung «Typ»): steht hier und nicht in records.css, weil auch
   Seiten ohne records.css sie nutzen — auf /records klebte sie ohne Abstand an der Tabelle.
   Die Variante innerhalb der Filterkarte (.gw-stickbar > …) bleibt in records.css. */
.rec-typechips { display:flex; gap:6px; flex-wrap:wrap; margin-bottom:14px; align-items:center }
.rec-typechips .lbl { font-size:11.5px; color:var(--text-4); font-weight:600; text-transform:uppercase; letter-spacing:.4px; margin-right:4px }
/* ── .gw-bulkbar — Mehrfachauswahl: eine schwebende Leiste fuer jede Liste (19.09.2026) ─────────────────────────
   Ueberall gleich: schwebt unten mittig ueber dem Inhalt (neben der Seitenleiste, auch eingeklappt). Kontrast: hell reicht
   die weisse Flaeche mit Schatten; dunkel waere die Tabellenfarbe zu schwach → hellere, erhoehte Flaeche + blauer Rand.
   Sichtbar = display:flex; ausblenden per hidden (Regel unten) oder inline style="display:none" (gewinnt immer).
   Achtung: Blendet eine Seite per Klasse aus (.x{display:none} .x.on{display:flex}), muss ihre Regel nach main.css kommen
   bzw. spezifischer sein — beim Umstellen je Seite pruefen. Inhalt: .gw-bulkbar__n
   (Zaehler, schiebt die Knoepfe nach rechts), danach normale .btn-sm. Unten bekommt die Seite Platz, damit die
   Leiste die letzten Zeilen nicht verdeckt. */
.gw-bulkbar {
  position: fixed; z-index: 900; bottom: 18px;
  left: calc(var(--sidebar-w-open) + 24px); right: 24px;
  margin: 0 auto; width: fit-content; max-width: calc(100vw - var(--sidebar-w-open) - 48px);
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 10px 12px 10px 16px; font-size: 13px;
  background: var(--surface); border: 1px solid var(--border); border-radius: 12px;
  box-shadow: 0 12px 32px rgba(15,23,42,.18), 0 2px 6px rgba(15,23,42,.08);
}
body.sidebar-mini .gw-bulkbar { left: calc(var(--sidebar-w) + 24px); max-width: calc(100vw - var(--sidebar-w) - 48px); }
@media (max-width: 900px) { .gw-bulkbar, body.sidebar-mini .gw-bulkbar { left: 12px; right: 12px; max-width: none; } }
.gw-bulkbar[hidden] { display: none !important; }
.gw-bulkbar__n { font-weight: 700; color: var(--text-1); margin-right: auto; white-space: nowrap; padding-right: 8px; }
.gw-bulkbar .btn { white-space: nowrap; display: inline-flex; align-items: center; gap: 6px; }
/* Symbol je Aktion (gwBulkIcon) — gleiche Groesse und Ausrichtung in jeder Leiste. */
.gw-bulkbar .btn > svg { width: 13px; height: 13px; flex-shrink: 0; }
[data-theme="dark"] .gw-bulkbar {
  background: #2a3950; border-color: color-mix(in srgb, var(--gw, #0098ef) 55%, transparent);
  box-shadow: 0 14px 40px rgba(0,0,0,.6), 0 0 0 1px color-mix(in srgb, var(--gw, #0098ef) 25%, transparent);
}
[data-theme="dark"] .gw-bulkbar .btn-secondary { background: #34465f; border-color: #4a5f7d; color: var(--text-1); }
[data-theme="dark"] .gw-bulkbar .btn-secondary:hover { background: #3d5270; }
/* app.js haengt jede .gw-bulkbar an <body> (ein clip-path/transform eines Elternteils — z.B. .gw-stickhead-wrap der
   Zonen-Karte — wuerde sie sonst abschneiden); der Platz unten richtet sich darum nach body.
   Nur solange eine Leiste sichtbar ist (ausgeblendet per [hidden] oder style display:none): vorher hielt jede Seite
   mit einer Leiste 84 px leer — im Zoneneditor fehlte das dem Visualizer unten. */
body:has(> .gw-bulkbar:not([hidden]):not([style*="display:none"]):not([style*="display: none"])) .app-main { padding-bottom: 84px; }
/* Variante in Fenstern (z.B. Proxy-Traffic): eine fixierte Leiste laege hinter der Abdunkelung des Fensters, app.js
   haengt --inline darum nicht an <body>. Sie steht im Platz .gw-bulkbar-host zwischen Scrollbereich und Fensterfuss
   (unten fest wie bei DNS-Zonen, unabhaengig von der Scrollposition immer sichtbar) — vorher klebte sie im
   Scrollbereich am Listenende und war beim Scrollen weg. Der Platz ist 0 hoch, die Leiste schwebt über dem unteren Rand
   der Liste: das Fenster aendert seine Hoehe nicht; der
   Scrollbereich bekommt unten Luft, damit die letzten Zeilen nicht verdeckt bleiben. */
.gw-bulkbar-host { position: relative; height: 0; }
.gw-bulkbar.gw-bulkbar--inline { position: absolute; bottom: 12px; left: 50%; right: auto; transform: translateX(-50%); margin: 0;
  width: max-content; max-width: calc(100% - 40px); }
.zd-dlg:has(> .gw-bulkbar-host:not(:empty)) > .zd-dlg-body { padding-bottom: 76px; }

/* ── .gw-bulkbar.gw-dock — Sammel-Leiste als Dock, einheitlich auf allen
   Seiten mit Mehrfachaktionen. Symbol über Wort, Aktionen in Gruppen nach Absicht (.gw-bulkbar__grp:
   Status | Bearbeiten | Teilen | Entfernen), Gruppen durch eine feine Linie getrennt, Löschen und Aufheben immer zuletzt.
   Nur Hausblau, kein Leuchten. Knöpfe bleiben .btn (Handler, data-act, disabled unverändert) — nur ihre Form ändert sich. */
.gw-bulkbar.gw-dock { gap: 4px; padding: 8px; border-radius: 20px; border-color: var(--border); align-items: stretch;
  box-shadow: 0 1px 2px rgba(15,23,42,.06), 0 14px 36px -12px rgba(15,23,42,.32); }
.gw-bulkbar.gw-dock .gw-bulkbar__n { display: flex; align-items: center; gap: 0; white-space: pre; margin: 0 4px 0 0; padding: 4px 16px 4px 6px;
  border-right: 1px solid var(--border); font-size: 13px; font-variant-numeric: tabular-nums; }
.gw-bulkbar.gw-dock .gw-bulkbar__n::before { content: ""; flex: none; width: 34px; height: 34px; border-radius: 11px; margin-right: 10px;
  background: #0098ef url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 34 34'%3E%3Cpath d='M11 17.5l4 4 8-9' fill='none' stroke='%23fff' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / 34px 34px no-repeat; }
.gw-bulkbar.gw-dock .gw-bulkbar__grp { display: flex; align-items: stretch; gap: 2px; padding: 0 4px; position: relative; }
.gw-bulkbar.gw-dock .gw-bulkbar__grp + .gw-bulkbar__grp::before { content: ""; position: absolute; left: -2px; top: 8px; bottom: 8px; width: 1px; background: var(--border); }
.gw-bulkbar.gw-dock .btn { display: grid; justify-items: center; align-content: center; gap: 4px; min-width: 70px; height: auto; padding: 7px 8px 6px;
  border: 0; border-radius: 12px; background: transparent; box-shadow: none; color: var(--text-2); font-size: 11.5px; font-weight: 600; line-height: 1.2; }
.gw-bulkbar.gw-dock .btn > svg { width: 19px; height: 19px; margin: 0; vertical-align: 0; }
.gw-bulkbar.gw-dock .btn:hover:not(:disabled) { background: color-mix(in srgb, var(--gw, #0098ef) 10%, transparent); color: var(--gw, #0098ef); }
.gw-bulkbar.gw-dock .btn:focus-visible { outline: 2px solid var(--gw, #0098ef); outline-offset: -2px; }
.gw-bulkbar.gw-dock .btn:disabled { opacity: .38; cursor: not-allowed; }
.gw-bulkbar.gw-dock .btn-primary { color: var(--gw, #0098ef); }
.gw-bulkbar.gw-dock .btn-danger { color: var(--err); }
.gw-bulkbar.gw-dock .btn-ok { color: var(--ok); }
.gw-bulkbar.gw-dock .btn-ok:hover:not(:disabled) { background: color-mix(in srgb, var(--ok) 11%, transparent); color: var(--ok); }
.gw-bulkbar.gw-dock .btn-deactivate { color: var(--warn); }
.gw-bulkbar.gw-dock .btn-deactivate:hover:not(:disabled) { background: color-mix(in srgb, var(--warn) 11%, transparent); color: var(--warn); }
.gw-bulkbar.gw-dock .snp-bulk-bar__link { align-self: center; }
.gw-bulkbar.gw-dock .btn-danger:hover:not(:disabled) { background: color-mix(in srgb, var(--err) 11%, transparent); color: var(--err); }
[data-theme="dark"] .gw-bulkbar.gw-dock { background: var(--surface); border-color: var(--border); box-shadow: 0 1px 2px rgba(0,0,0,.4), 0 16px 40px -12px rgba(0,0,0,.75); }
/* Dunkel: [data-theme="dark"] .btn-primary/-secondary/-danger setzen Fläche, Rahmen und Farbe mit !important (main.css ~5852) —
   im Dock darum ebenfalls, die höhere Spezifität entscheidet. */
[data-theme="dark"] .gw-bulkbar.gw-dock .btn { background: transparent !important; border-color: transparent !important; color: var(--text-2) !important; }
[data-theme="dark"] .gw-bulkbar.gw-dock .btn:hover:not(:disabled) { background: color-mix(in srgb, var(--gw, #0098ef) 16%, transparent) !important; color: #7cc8f5 !important; }
[data-theme="dark"] .gw-bulkbar.gw-dock .btn-primary { color: #7cc8f5 !important; }
[data-theme="dark"] .gw-bulkbar.gw-dock .btn-danger { color: #f87171 !important; }
[data-theme="dark"] .gw-bulkbar.gw-dock .btn-ok { color: #4ade80 !important; }
[data-theme="dark"] .gw-bulkbar.gw-dock .btn-ok:hover:not(:disabled) { background: color-mix(in srgb, #4ade80 14%, transparent) !important; color: #4ade80 !important; }
[data-theme="dark"] .gw-bulkbar.gw-dock .btn-deactivate { color: #fbbf24 !important; }
[data-theme="dark"] .gw-bulkbar.gw-dock .btn-deactivate:hover:not(:disabled) { background: color-mix(in srgb, #fbbf24 14%, transparent) !important; color: #fbbf24 !important; }
[data-theme="dark"] .gw-bulkbar.gw-dock .btn-danger:hover:not(:disabled) { background: color-mix(in srgb, #f87171 14%, transparent) !important; color: #f87171 !important; }
@media (prefers-reduced-motion: no-preference) { .gw-bulkbar.gw-dock .btn { transition: background .12s, color .12s; } }
body:has(> .gw-bulkbar.gw-dock:not([hidden]):not([style*="display:none"]):not([style*="display: none"])) .app-main { padding-bottom: 104px; }

/* ── .gw-nohits — «Keine Treffer»: ein Baustein fuer jede Suche/jeden Filter ohne Ergebnis (14.09.2026) ──
   JS window.gwNoHits()/gwNoHitsRow() (nohits.js), PHP gwNoHits() (_helpers_impl.php). Nur fuer «Daten da,
   Suche/Filter trifft nichts» — der Leerzustand «noch gar nichts vorhanden» bleibt je Seite. */
.gw-nohits { display:flex; flex-direction:column; align-items:center; text-align:center; gap:6px; padding:40px 20px; color:var(--text-3) }
.gw-nohits__ic { color:var(--text-4); line-height:0; margin-bottom:4px }
.gw-nohits__ic svg { width:40px; height:40px; display:block }
.gw-nohits__title { font-size:14px; font-weight:600; color:var(--text-2); max-width:560px; overflow-wrap:anywhere }
.gw-nohits__hint { font-size:12.5px; color:var(--text-4); max-width:460px }
.gw-nohits__reset { margin-top:8px }
/* ── .gw-ro-hint — Read-only-Zone: ein Hinweis fuer Snapshots im Zoneneditor und Time-Machine (15.09.2026) ──
   In einer Read-only-Zone laesst sich nichts wiederherstellen; der Hinweis ist derselbe wie im Zoneneditor bei
   Snapshots. Vorher Inline-Stil in records.php und eine graue, abgeschnittene
   Fusszeile in der Time-Machine. Text: js.snap.ro-title / js.snap.ro-body. */
.gw-ro-hint { background:var(--gw-light); border:1px solid var(--gw); border-radius:8px; padding:10px 13px; display:flex; gap:10px; align-items:center; margin-bottom:12px }
.gw-ro-hint > svg { flex-shrink:0; width:18px; height:18px; color:var(--gw) }
.gw-ro-hint__text { font-size:12.5px; color:var(--text-1); line-height:1.55 }
.gw-ro-hint[hidden] { display:none }
.gw-nohits--compact { padding:20px 14px }
.gw-nohits--compact .gw-nohits__ic svg { width:28px; height:28px }
tr.gw-nohits-row > td { padding:0; background:var(--surface) }
.rec-chip:not(.rec-chip--typed) { background:var(--surface); color:var(--text-2); border-color:var(--border) }
.rec-chip.active-all:not(.rec-chip--typed) { background:var(--gw); color:#fff; border-color:var(--gw) }
/* Typ-Chips spiegeln exakt die Record-Typ-Pille der Liste (.rr-chip): Farbe aus .rr-<TYPE>, Grund und
   Rand aus currentColor. :where() haelt den Fallback bei Spezifitaet 0, damit .rr-<TYPE> gewinnt. */
:where(.rec-chip--typed) { color: var(--rec-color, #64748b) }
.rec-chip--typed {
  background: color-mix(in srgb, currentColor 14%, transparent);
  border-color: color-mix(in srgb, currentColor 30%, transparent);
}
.rec-chip--typed:not(:disabled):hover { background: color-mix(in srgb, currentColor 22%, transparent); }
/* Aktiver Typ-Filter: kraeftigerer Tint + voller Rand (Innenlinie ohne Unschaerfe) — kein solider Block,
   color nicht setzen → bleibt die theme-aware .rr-<TYPE>-Farbe. */
.rec-chip--typed.active-all {
  background: color-mix(in srgb, currentColor 24%, transparent);
  border-color: currentColor;
  box-shadow: inset 0 0 0 1px currentColor;
}
[data-theme="dark"] .rec-chip--typed { background: rgba(255,255,255,.04); border-color: currentColor; }
[data-theme="dark"] .rec-chip--typed:not(:disabled):hover { background: rgba(255,255,255,.09); }
[data-theme="dark"] .rec-chip--typed.active-all {
  background: color-mix(in srgb, currentColor 22%, transparent);
  border-color: currentColor;
  box-shadow: inset 0 0 0 1px currentColor;
}

/* ── .rr-chip — Record-Typen-Pille (zentral, damit Zoneneditor, globale
   Records-Liste, Snapshots, Archive etc. Identisch aussehen). Ein Algorithmus:
   Backdrop + Border aus currentColor (color-mix), die .rr-*-Regeln setzen nur
   die color. Dark-Mode hellt die color je Typ auf. Früher lag das nur in
   records.css (nur Zoneneditor) → globale Liste driftete. */
.rr-chip {
  display:inline-block; font-family:var(--font-mono); font-size:11px;
  font-weight:700; padding:2px 8px; border-radius:5px; line-height:1.4;
  color:#475569;
  background: color-mix(in srgb, currentColor 14%, transparent);
  border: 1px solid color-mix(in srgb, currentColor 30%, transparent);
}
/* Klickbare Typ-/TTL-Filter-Pillen — einheitlicher Hover (Zoneneditor: data-rtype/.ttl-tag-Spans
   mit JS-Handler; globale /records: als <a data-act="gwStop"> gewrappt). Gleicher Effekt ueberall. */
.records-table .rr-chip[data-rtype]:hover,
a.rr-chip[data-act="gwStop"]:hover,
.records-table .td-ttl .ttl-tag[data-ttl]:hover,
a[data-act="gwStop"] > .ttl-tag[data-ttl]:hover {
  filter: brightness(1.06);
  outline: 1px solid color-mix(in srgb, currentColor 30%, transparent);
  outline-offset: 1px;
}
/* Semantische Pillen-Farben fuer Nicht-Record-Pillen (Redirect TLS/Status/Code etc.):
   Light-Ton + hellerer Dark-Ton (analog der Record-Typ-Pillen .rr-A…), sonst verblassen
   inline-Hex-Pillen im Dark-Mode. currentColor speist Tint (bg/border) und Text. */
/* Kopf-Felder im Record-Inhalt (MX-Prioritaet, SRV-Prioritaet/Gewichtung/Port,
   CAA-Flag/Tag). Gleiche Bauform wie die Typ-Pille; die Prioritaet ist wie die
   TTL-Pille abgestuft, weil bei MX die kleinste Zahl gewinnt — das sieht man einer
   nackten Zahl nicht an. Farbe kommt aus currentColor, darum genuegt `color`. */
.rec-cpills { display:inline-flex; gap:4px; margin-right:6px; vertical-align:baseline }
.rec-cpills > .rr-chip { white-space:nowrap }
/* Ausgeblendet, weil die Zeile zu schmal ist (records.js recFitPills). !important: .rr-chip setzt display. */
.rec-cpills > .is-cut { display:none !important }
.rec-cpills__more { cursor:help }
/* SOA: die Zahlen stehen im Wert hinten, die Pillen darum hinter den beiden Namen. */
.rec-cpills--after { margin:0 0 0 6px }
.prio-tag { letter-spacing:.2px }
.rr-chip.prio-p1 { color:#1d4ed8 }
.rr-chip.prio-p2 { color:#0e7490 }
.rr-chip.prio-p3 { color:#b45309 }
.rr-chip.prio-p4 { color:#64748b }
[data-theme="dark"] .rr-chip.prio-p1 { color:#93c5fd }
[data-theme="dark"] .rr-chip.prio-p2 { color:#67e8f9 }
[data-theme="dark"] .rr-chip.prio-p3 { color:#fcd34d }
[data-theme="dark"] .rr-chip.prio-p4 { color:#cbd5e1 }
.rr-chip.rrc-ok    { color:#16a34a }
.rr-chip.rrc-warn  { color:#b45309 }
.rr-chip.rrc-warn2 { color:#ea580c }
.rr-chip.rrc-err   { color:#dc2626 }
.rr-chip.rrc-info  { color:#1d4ed8 }
.rr-chip.rrc-mute  { color:#64748b }
[data-theme="dark"] .rr-chip.rrc-ok    { color:#4ade80 !important }
[data-theme="dark"] .rr-chip.rrc-warn  { color:#fbbf24 !important }
[data-theme="dark"] .rr-chip.rrc-warn2 { color:#fb923c !important }
[data-theme="dark"] .rr-chip.rrc-err   { color:#f87171 !important }
[data-theme="dark"] .rr-chip.rrc-info  { color:#93c5fd !important }
[data-theme="dark"] .rr-chip.rrc-mute  { color:#cbd5e1 !important }
.rr-A          { color:#1d4ed8 }
.rr-AAAA       { color:#3730a3 }
.rr-CNAME      { color:#7e22ce }
.rr-MX         { color:#854d0e }
.rr-TXT        { color:#15803d }
.rr-NS         { color:#be185d }
.rr-PTR        { color:#0f766e }
.rr-SOA        { color:#c2410c }
.rr-SRV        { color:#0e7490 }
.rr-CAA        { color:#3f6212 }
.rr-SPF        { color:#a16207 }
.rr-URI        { color:#b91c1c }
.rr-DNSKEY     { color:#5b21b6 }
.rr-CDNSKEY    { color:#4c1d95 }
.rr-RRSIG      { color:#6d28d9 }
.rr-NSEC       { color:#581c87 }
.rr-NSEC3      { color:#3b0764 }
.rr-NSEC3PARAM { color:#86198f }
.rr-DS         { color:#9d174d }
.rr-CDS        { color:#881337 }
.rr-DLV        { color:#854d0e }
.rr-KEY        { color:#1e40af }
.rr-TKEY       { color:#3730a3 }
.rr-TSIG       { color:#3f6212 }
.rr-SSHFP      { color:#334155 }
.rr-TLSA       { color:#5e3023 }
.rr-SMIMEA     { color:#86198f }
.rr-IPSECKEY   { color:#155e75 }
.rr-HTTPS      { color:#9d174d }
.rr-SVCB       { color:#831843 }
.rr-NAPTR      { color:#155e75 }
.rr-LOC        { color:#713f12 }
.rr-HINFO      { color:#525252 }
.rr-CERT       { color:#065f46 }
.rr-OPENPGPKEY { color:#57534e }
.rr-ALIAS      { color:#075985 }
.rr-ANAME      { color:#115e59 }
.rr-NID        { color:#9a3412 }
.rr-L32        { color:#166534 }
.rr-L64        { color:#1e40af }
.rr-LP         { color:#7e22ce }
.rr-EUI48      { color:#9b2c2c }
.rr-EUI64      { color:#7b341e }
.rr-AFSDB      { color:#22543d }
.rr-RP         { color:#744210 }
.rr-HIP        { color:#553c9a }
.rr-CSYNC      { background:#bee3f8; color:#2c5282 }
.rr-chip[data-auto-color] { background:var(--rr-bg, #e2e8f0); color:var(--rr-fg, #334155) }

/* Achtung: Hier standen 13 Dunkelmodus-Farben der Record-Pillen ein zweites Mal
   (.rr-A, .rr-AAAA, .rr-CNAME, .rr-MX, .rr-TXT, .rr-NS, .rr-PTR, .rr-SOA,
   .rr-SRV, .rr-CAA, .rr-SPF, .rr-URI, .rr-SSHFP) — mit anderen, satteren
   Werten. Gewirkt haben sie nie: der Block weiter oben (bei «Haeufigste
   Record-Typen mit hellerer Schrift») setzt dieselben Selektoren mit
   `!important`, und `!important` schlaegt die spaetere Regel unabhaengig von
   der Reihenfolge. Wer die Farbe hier aenderte, sah keine Wirkung — und
   `templates/migration/index.php` hatte genau diese tote Fassung kopiert.
   Die Dunkelmodus-Farben stehen jetzt nur noch oben.
   `CssHasNoDeadOverrideTest` haelt das fest. */
[data-theme="dark"] .rr-DNSKEY,
[data-theme="dark"] .rr-CDNSKEY,
[data-theme="dark"] .rr-RRSIG,
[data-theme="dark"] .rr-NSEC,
[data-theme="dark"] .rr-NSEC3,
[data-theme="dark"] .rr-NSEC3PARAM { color:#a78bfa }
[data-theme="dark"] .rr-DS,
[data-theme="dark"] .rr-CDS,
[data-theme="dark"] .rr-DLV        { color:#fb7185 }
[data-theme="dark"] .rr-KEY,
[data-theme="dark"] .rr-TKEY,
[data-theme="dark"] .rr-TSIG       { color:#86efac }
[data-theme="dark"] .rr-TLSA,
[data-theme="dark"] .rr-SMIMEA,
[data-theme="dark"] .rr-HTTPS,
[data-theme="dark"] .rr-SVCB       { color:#f0abfc }
[data-theme="dark"] .rr-IPSECKEY,
[data-theme="dark"] .rr-NAPTR,
[data-theme="dark"] .rr-ALIAS,
[data-theme="dark"] .rr-ANAME,
[data-theme="dark"] .rr-AFSDB      { color:#67e8f9 }
[data-theme="dark"] .rr-LOC,
[data-theme="dark"] .rr-NID,
[data-theme="dark"] .rr-EUI48,
[data-theme="dark"] .rr-EUI64,
[data-theme="dark"] .rr-RP         { color:#fdba74 }
[data-theme="dark"] .rr-HINFO,
[data-theme="dark"] .rr-OPENPGPKEY { color:#94a3b8 }
[data-theme="dark"] .rr-CERT,
[data-theme="dark"] .rr-L32        { color:#86efac }
[data-theme="dark"] .rr-L64        { color:#7dd3fc }
[data-theme="dark"] .rr-LP,
[data-theme="dark"] .rr-HIP        { color:#c4b5fd }

/* ── Scrollbar ──────────────────────────────────────────────
   Globaler, dezenter Stil im Geist der Navigationsleiste: schlank,
   transparente Spur, gerundeter Thumb mit Hover-/Active-Verstärkung.
   Firefox bekommt thin + scrollbar-color (sonst klobiger OS-Balken).
   Eigene Container-Regeln (.sidebar-nav, .ana-ins-list, .zd-options …)
   sind spezifischer und überschreiben das hier bewusst. */
html { scrollbar-width: thin; scrollbar-color: var(--border-2) transparent; }
::-webkit-scrollbar       { width: 8px; height: 8px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: var(--border-2); border-radius: 6px;
  border: 2px solid transparent; background-clip: padding-box;
  transition: background-color .2s ease;
}
/* ::-webkit-scrollbar-thumb:hover/:active werden per JS nur in Chromium injiziert
   (zd.js, gwInjectWebkitScroll) — sonst Firefox-Parse-Warnung „ungültiger Selektor". */
::-webkit-scrollbar-corner { background: transparent; }

/* ── Navigation ein-/ausklappen (Topbar) ─────────────────────────────────────
   14.09.2026: neues Symbol zum Einklappen der Navigation. Bis hier drei Balken, die sich bei offener Leiste zu einem «×» drehten.
   Ein «×» liest man als schliessen, nicht als Einklappen. Jetzt das Seitenleisten-Symbol: Rahmen,
   Seitenfeld, Pfeil. Offen: Feld gefuellt, Pfeil nach links (einklappen). Eingeklappt: Feld leer,
   Pfeil nach rechts (ausklappen). Strich-Icon wie im Haus, Hover wie die Reiter (Textfarbe 8 %). */
.nav-toggle {
  display: inline-flex; align-items: center; justify-content: center;
  width: 36px; height: 36px; padding: 0; flex-shrink: 0;
  border: none; border-radius: 8px; background: transparent;
  color: var(--text-3); cursor: pointer;
  transition: background .15s, color .15s;
}
/* Dezentes Symbol:
   18 px, duenner Strich (base.php 1.5), gedaempfte Farbe, Seitenfeld nur angedeutet — erst beim
   Darauffahren kraeftiger. */
.nav-toggle:hover { background: color-mix(in srgb, var(--text-1) 8%, transparent); color: var(--text-1); }
.nav-toggle:focus-visible { outline: 2px solid var(--gw); outline-offset: 1px; }
.nav-toggle-ico { width: 18px; height: 18px; display: block; }
.nav-toggle-pane { fill: currentColor; opacity: .10; transition: opacity .2s ease; }
.nav-toggle-chev { transform-box: fill-box; transform-origin: center; transition: transform .25s ease; }
.nav-toggle:hover .nav-toggle-pane { opacity: .2; }
body.sidebar-mini .nav-toggle-pane { opacity: 0; }
body.sidebar-mini .nav-toggle-chev { transform: scaleX(-1); }
@media (prefers-reduced-motion: reduce) { .nav-toggle-pane, .nav-toggle-chev { transition: none; } }

/* ── Toggle switch ───────────────────────────────────────── */
.switch { position: relative; display: inline-block; width: 40px; height: 22px; flex-shrink: 0; }
.switch input { opacity: 0; width: 0; height: 0; }
.switch-slider {
  position: absolute; cursor: pointer; inset: 0;
  background: #cbd5e1; border-radius: 22px;
  transition: background .18s ease;
}
.switch-slider::before {
  position: absolute; content: ""; left: 3px; top: 3px;
  width: 16px; height: 16px; background: #fff; border-radius: 50%;
  box-shadow: 0 1px 3px rgba(0,0,0,.2);
  transition: transform .18s ease;
}
.switch input:checked + .switch-slider { background: var(--gw); }
.switch input:checked + .switch-slider::before { transform: translateX(18px); }
.switch input:focus-visible + .switch-slider { box-shadow: 0 0 0 3px rgba(0,152,239,.25); }

/* ── Selectable chip (für TTL/Zone-Typen/Record-Typen Listen) ─
 * Light-tint active state — clear separation from filled-blue primary buttons.
 * Per-Item-Farbe per CSS-Custom-Properties: --chip-accent, --chip-accent-light, --chip-accent-dark.
 */
.chip-list { display: flex; flex-wrap: wrap; gap: 7px; }
.chip {
  --chip-accent: var(--gw);
  --chip-accent-light: var(--gw-light);
  --chip-accent-dark: var(--gw-dark);
  position: relative;
  display: inline-flex; align-items: center; gap: 8px;
  padding: 7px 13px 7px 11px;
  border-radius: 8px;
  border: 1px solid var(--border-2);
  background: #fff;
  color: var(--text-2);
  font-size: 13px;
  font-weight: 500;
  letter-spacing: -.005em;
  cursor: pointer;
  user-select: none;
  transition: background .15s ease, border-color .15s ease, color .15s ease, box-shadow .15s ease;
}
/* Inaktiver Zustand: leerer Checkbox-Indikator vor dem Text */
.chip::before {
  content: "";
  width: 15px; height: 15px;
  border-radius: 4px;
  border: 1.5px solid var(--border-2);
  background: #fff;
  flex-shrink: 0;
  transition: all .15s ease;
}
.chip:hover {
  border-color: var(--chip-accent);
  color: var(--text-1);
  box-shadow: 0 1px 2px rgba(15,23,42,.06);
}
.chip:hover::before { border-color: var(--chip-accent); }
.chip input { position: absolute; opacity: 0; width: 0; height: 0; pointer-events: none; }

/* Aktiver Zustand: dezenter Tint im Akzent-Farbton */
.chip.is-on {
  background: var(--chip-accent-light);
  border-color: var(--chip-accent);
  color: var(--chip-accent-dark);
}
.chip.is-on:hover {
  filter: brightness(.96);
  box-shadow: 0 1px 2px rgba(15,23,42,.1);
}
.chip.is-on::before {
  background: var(--chip-accent);
  border-color: var(--chip-accent);
  /* Generischer weisser Checkmark — funktioniert für jede Akzentfarbe */
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'><polyline points='20 6 9 17 4 12'/></svg>");
  background-size: 11px 11px; background-position: center; background-repeat: no-repeat;
}
.chip:focus-within {
  outline: none;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--chip-accent) 25%, transparent);
  border-color: var(--chip-accent);
}
/* Mono-Schrift für Record-Type-Chips (A, AAAA, MX, …) */
.chip.chip-mono { font-family: var(--font-mono); font-weight: 700; letter-spacing: .3px; }

/* ── Option-Cards (Radio-Gruppen mit Icon + Beschreibung) ─────────── */
.opt-card-group { display: flex; flex-direction: column; gap: 8px; }
.opt-card {
  position: relative;
  display: flex; align-items: flex-start; gap: 12px;
  padding: 12px 14px;
  border-radius: 10px;
  border: 1.5px solid var(--border-2);
  background: #fff;
  cursor: pointer;
  transition: background .15s, border-color .15s, box-shadow .15s;
}
.opt-card input { position: absolute; opacity: 0; width: 0; height: 0; pointer-events: none; }
.opt-card:hover { border-color: var(--gw); background: #fafcfe; }
.opt-card.is-on {
  border-color: var(--gw);
  background: var(--gw-light);
  box-shadow: 0 1px 2px rgba(0,152,239,.18);
}
.opt-card-icon {
  width: 36px; height: 36px; border-radius: 9px;
  background: #f1f5f9; color: var(--gw);
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0; transition: background .15s;
}
.opt-card.is-on .opt-card-icon { background: #fff; }
.opt-card-body { flex: 1; min-width: 0; }
.opt-card-title { font-size: 13.5px; font-weight: 600; color: var(--text-1); margin-bottom: 2px; }
.opt-card-sub   { font-size: 12px; color: var(--text-3); line-height: 1.4; }
.opt-card.is-on .opt-card-sub { color: var(--gw-dark); }

/* ── Passwort-Stärke-Indikator ────────────────────────────────────── */
.pw-strength { margin-top: 8px; }
.pw-strength-bar {
  height: 4px; background: #e2e8f0; border-radius: 2px; overflow: hidden; display: flex; gap: 2px;
}
.pw-strength-seg {
  flex: 1; background: #e2e8f0; border-radius: 2px; transition: background .15s;
}
.pw-strength-bar.is-1 .pw-strength-seg:nth-child(-n+1),
.pw-strength-bar.is-2 .pw-strength-seg:nth-child(-n+2),
.pw-strength-bar.is-3 .pw-strength-seg:nth-child(-n+3),
.pw-strength-bar.is-4 .pw-strength-seg:nth-child(-n+4) { background: var(--strength-color, var(--gw)); }
.pw-strength-bar.is-1 { --strength-color: var(--err); }
.pw-strength-bar.is-2 { --strength-color: #f59e0b; }
.pw-strength-bar.is-3 { --strength-color: var(--gw); }
.pw-strength-bar.is-4 { --strength-color: var(--ok); }
.pw-strength-label {
  margin-top: 6px; font-size: 11.5px; color: var(--text-3);
  display: flex; justify-content: space-between; gap: 8px;
}
.pw-strength-label .pw-strength-text { font-weight: 600; }
.pw-strength-label.is-1 .pw-strength-text { color: var(--err); }
.pw-strength-label.is-2 .pw-strength-text { color: #d97706; }
.pw-strength-label.is-3 .pw-strength-text { color: var(--gw); }
.pw-strength-label.is-4 .pw-strength-text { color: var(--ok); }
.pw-rules { margin-top: 8px; display: flex; flex-direction: column; gap: 3px; }
.pw-rule {
  display: flex; align-items: center; gap: 7px;
  font-size: 11.5px; color: var(--text-4);
  transition: color .12s;
}
.pw-rule.is-met { color: var(--ok); }
.pw-rule-icon {
  width: 14px; height: 14px; border-radius: 50%;
  background: var(--bg); border: 1px solid var(--border-2);
  display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0;
  transition: background .12s, border-color .12s;
}
.pw-rule.is-met .pw-rule-icon {
  background: var(--ok); border-color: var(--ok);
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'><polyline points='20 6 9 17 4 12'/></svg>");
  background-size: 9px 9px; background-position: center; background-repeat: no-repeat;
}

/* ── Editable list-row (für Nameserver/IP-Whitelist) ─────── */
.list-row {
  display: flex; gap: 8px; align-items: center;
  padding: 6px 0;
}
.list-row .inp { height: 34px; font-size: 13px; }
.list-row-del {
  width: 32px; height: 32px; border-radius: 8px;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--border); background: var(--surface);
  color: var(--text-4); cursor: pointer; flex-shrink: 0;
  transition: all .12s;
}
.list-row-del:hover { border-color: var(--err); color: var(--err); background: var(--err-bg); }
.list-empty { font-size: 12.5px; color: var(--text-4); padding: 6px 2px; font-style: italic; }

/* ── Geo-Cell (Standort / Provider in Audit-Tabellen) ───── */
.geo-cell { font-size: 12px; line-height: 1.4; max-width: 100%; }
.geo-cell-country {
  display: flex; align-items: center; gap: 5px;
  color: var(--text-2);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.geo-cell-provider {
  display: block; font-size: 11px; color: var(--text-4);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  margin-top: 1px;
}


/* ============================================================================
   Neon-Farb-Polish im Dark-Mode (kein Glow/Leucht-Effekt — nur saturierte
   Neon-Farben + dunkle Backdrops + saubere 1px Akzent-Borders)
   ============================================================================ */

/* Buttons — neon-farbige Akzente, dezenter Backdrop, kein Shadow-Glow */
[data-theme="dark"] .btn { transition: background .12s, border-color .12s, color .12s; }
[data-theme="dark"] .btn-primary {
  background: var(--gw) !important;
  border-color: var(--gw) !important;
  color: #fff !important;
}
[data-theme="dark"] .btn-primary:hover { background: var(--gw-dark) !important; border-color: var(--gw-dark) !important; }
[data-theme="dark"] .btn-primary:disabled,
[data-theme="dark"] .btn-primary[disabled] { opacity: .55; }
[data-theme="dark"] .btn-secondary {
  background: rgba(255,255,255,.04) !important;
  border-color: var(--border-2) !important;
  color: var(--text-1) !important;
}
[data-theme="dark"] .btn-secondary:hover {
  border-color: var(--gw) !important;
  color: var(--gw) !important;
  background: rgba(0,152,239,.08) !important;
}
[data-theme="dark"] .btn-ghost {
  color: var(--text-2) !important;
  border-color: var(--border-2) !important;
}
[data-theme="dark"] .btn-ghost:hover {
  background: rgba(255,255,255,.06) !important;
  color: var(--text-1) !important;
  border-color: var(--gw) !important;
}
[data-theme="dark"] .btn-ok {
  background: rgba(22,163,74,.12) !important;
  border-color: rgba(22,163,74,.50) !important;
  color: #4ade80 !important;
}
[data-theme="dark"] .btn-ok:hover {
  background: rgba(22,163,74,.22) !important;
  border-color: var(--ok) !important;
  color: #fff !important;
}
[data-theme="dark"] .btn-danger {
  background: rgba(220,38,38,.10) !important;
  border-color: rgba(220,38,38,.50) !important;
  color: #fb7185 !important;
}
[data-theme="dark"] .btn-danger:hover {
  background: rgba(220,38,38,.20) !important;
  border-color: var(--err) !important;
  color: #fff !important;
}
[data-theme="dark"] .btn-warning {
  background: rgba(250,204,21,.10) !important;
  border-color: rgba(217,119,6,.50) !important;
  color: #facc15 !important;
}
[data-theme="dark"] .btn-warning:hover {
  border-color: var(--warn) !important;
  background: rgba(250,204,21,.18) !important;
}

/* KPI-Card Hover — saubere Border, kein Glow */
[data-theme="dark"] .kpi-card.kpi-card--full:hover { border-color: var(--gw) !important; }

/* Modal-Backdrop bleibt dunkler Blur, Modal selbst ohne Glow */
[data-theme="dark"] .modal-overlay { background: rgba(2,8,23,.75) !important; backdrop-filter: blur(4px); }

/* Sidebar: aktive nav-item mit einheitlichem Brand-Backdrop, kein Inset-Streifen
   links (wirkte als „komischer hellblauer Rand"), kein Drop-Shadow. */
[data-theme="dark"] .nav-item.active {
  background: rgba(0,152,239,.20) !important;
}
[data-theme="dark"] .nav-item.active .nav-item-icon { color: var(--gw); }

/* zd-Dropdown — sauberer Brand-Border im aktiven/offenen Zustand, kein Glow */
[data-theme="dark"] .zd.open .zd-trigger { box-shadow: 0 0 0 1px var(--gw); }
[data-theme="dark"] .zd.active .zd-trigger { box-shadow: inset 3px 0 0 0 var(--gw); }
[data-theme="dark"] .zd-panel { box-shadow: 0 0 0 1px rgba(0,152,239,.20), 0 12px 36px rgba(0,0,0,.55) !important; }

/* zd-Optionen Hover/Selected — Brand-Tint, kein Shadow */
[data-theme="dark"] .zd-opt:hover { background: rgba(0,152,239,.10) !important; }
[data-theme="dark"] .zd-opt.selected {
  background: rgba(0,152,239,.18) !important;
  color: #38bdf8 !important;
}

/* Toast-Notifications mit Akzent-Border, kein Shadow-Glow */
[data-theme="dark"] .zd-toast      { background: var(--surface) !important; color: var(--text-1) !important; border-left: 3px solid var(--gw) !important; box-shadow: 0 12px 36px rgba(0,0,0,.5) !important; }
[data-theme="dark"] .zd-toast.ok   { color: #34d399 !important; border-left-color: #16a34a !important; }
[data-theme="dark"] .zd-toast.err  { color: #fb7185 !important; border-left-color: var(--err) !important; }

/* Action-Buttons — Hover Brand-Border, kein Shadow */
[data-theme="dark"] .action-btn:hover { border-color: var(--gw) !important; background: rgba(0,152,239,.08) !important; }
[data-theme="dark"] .action-btn.action-btn--danger:hover { border-color: var(--err) !important; background: rgba(220,38,38,.10) !important; color: #fb7185 !important; }
[data-theme="dark"] .action-btn.action-btn--propagation:hover { border-color: #a78bfa !important; background: rgba(167,139,250,.10) !important; color: #a78bfa !important; }

/* Status-Tabs (rec-status) Active-State — Brand-Backdrop, kein Glow */
[data-theme="dark"] .rec-status button.active {
  color: #38bdf8 !important;
  background: rgba(0,152,239,.10) !important;
  box-shadow: 0 0 0 1px rgba(0,152,239,.30) !important;
}

/* Topbar mit feinem Brand-Akzent unten — kein Shadow */
[data-theme="dark"] .topbar { border-bottom: 1px solid rgba(0,152,239,.25); }
/* Kopfleiste im Dunkelmodus in der Farbe der Seitenleiste (#0a1120, s. [data-theme="dark"] .sidebar), damit Logo und
   Seitentitel oben eine Flaeche bilden. Hell sind beide schon weiss. */
[data-theme="dark"] .topbar { background: #0a1120; }

/* Tabellen-Hover: hier stand ein zweiter Dunkel-Hover auf der Zeile (.records-table und .zone-table,
   rgba(0,152,239,.05)) — verdeckt von der Zellen-Regel oben (#243044). Zwei Werte fuer dieselbe Sache:
   entfallen 14.09.2026, es gilt --row-hover. Achtung: Die Regel war eine SELEKTOR-GRUPPE ueber zwei Zeilen;
   die erste Ersetzung nahm nur die letzte Zeile weg, die erste haengte sich an den naechsten Block
   (Rot-Toenung) — RowHoverIsOneColorTest hat es gefunden. */

/* Approval-Toggle-Dark-States entfernt (v4.55.13) → records.css ist alleinige
   Quelle (siehe .zr-approval-toggle dort). Die !important-Regeln hier verhinderten
   den sichtbaren Dark-Hover. */

/* ────────────────────────────────────────────────────────────────────────────
   Dark-Mode-Patches für inline-styled Pastell-Backgrounds
   ────────────────────────────────────────────────────────────────────────────
   Viele Komponenten (DMARC-Reiter, Auto-Setup-Modal, Admin-Settings-Boxen,
   Wizards, Konflikt-Anzeigen) setzen via `style="background:#…"` direkt eine
   helle Tönung — auf weiss ok, auf dunkel ein knalliger heller Block.
   Wir matchen über Attribut-Selektoren auf die häufigsten Pastell-Tokens
   und tauschen Background+Border gegen gedämpfte rgba-Varianten.
   Vordergrundfarben (color:#…) bleiben unangetastet — die kontrastieren
   gegen den dunkleren Hintergrund weiterhin gut. */

/* Light-Red-Blöcke (z.B. Konflikt-„Bestehender Wert", ds-parent-empty,
   DMARC-Auto-Setup-Konflikt) */
[data-theme="dark"] [style*="#fef2f2" i] {
  background-color: rgba(239,68,68,.10) !important;
  border-color: rgba(252,165,165,.30) !important;
}
[data-theme="dark"] [style*="#fee2e2" i] {
  background-color: rgba(239,68,68,.14) !important;
  border-color: rgba(252,165,165,.30) !important;
}

/* Light-Amber-Warnboxen (Settings-Info, „Was passiert beim Anwenden") */
[data-theme="dark"] [style*="#fffbeb" i],
[data-theme="dark"] [style*="#fef3c7" i] {
  background-color: rgba(245,158,11,.10) !important;
  border-color: rgba(253,224,71,.30) !important;
}

/* Light-Green-Erfolg-Blöcke (Status-„bereits vorhanden" als block, nicht badge) */
[data-theme="dark"] [style*="#dcfce7" i] {
  background-color: rgba(34,197,94,.12) !important;
  border-color: rgba(134,239,172,.30) !important;
}

/* Light-Blue-Info-Blöcke (z.B. „wird angelegt"-Badges als grosse Block-Variante,
   Tipp-Boxen in Admin-Settings) */
[data-theme="dark"] [style*="#dbeafe" i],
[data-theme="dark"] [style*="#eff6ff" i] {
  background-color: rgba(59,130,246,.12) !important;
  border-color: rgba(147,197,253,.30) !important;
}

/* Light-Indigo / Purple Banner (z.B. DMARC-„Wie es funktioniert"-Info) */
[data-theme="dark"] [style*="#eef2ff" i],
[data-theme="dark"] [style*="#f5f3ff" i] {
  background-color: rgba(99,102,241,.12) !important;
  border-color: rgba(165,180,252,.30) !important;
}

/* Auto-Setup-Card: bei Konflikt setzen wir border-left:4px solid #ef4444 –
   bleibt im Dark-Mode korrekt, da die Stripe-Farbe Statusfarbe ist. Aber
   die `code`-Bestehend-Box muss noch lesbaren Vordergrund bekommen. */
[data-theme="dark"] [style*="#7f1d1d" i] {
  color: #fca5a5 !important;
}
[data-theme="dark"] [style*="#991b1b" i] {
  color: #fca5a5 !important;
}

/* DMARC-Tab + andere Stellen mit hardcoded `color:#15803d` (Disposition-Pass-Zähler) */
[data-theme="dark"] [style*="#15803d" i] {
  color: #4ade80 !important;
}
/* DMARC-Tab Disposition-Fail-Zähler — nur auf Text-Vordergrund (color:) scopen.
   Der frühere bare `[style*="#dc2626"]`-Match traf auch Tenant-Avatare mit
   `background:#dc2626` (Initialen L/T hashen auf diese Palette-Farbe) und
   überschrieb deren `color:#fff` zu Salmon → Buchstabe wirkte unweiss/dünn. */
[data-theme="dark"] [style*="color:#dc2626" i],
[data-theme="dark"] [style*="color: #dc2626" i] {
  color: #f87171 !important;
}

/* `settings-info`-Container im Admin-Settings (gelb-getöntes Tipp-Banner) */
[data-theme="dark"] .settings-info {
  background-color: rgba(245,158,11,.10) !important;
  border-color: rgba(253,224,71,.30) !important;
  color: var(--text-2) !important;
}
[data-theme="dark"] .settings-info strong { color: var(--text-1); }

/* Light-Slate-Blöcke (Workflow-Tipps, Code-Boxen mit hellgrauem Hintergrund,
   Redirector-Section-Hinweise etc.). Auf weiss: dezenter Akzent. Auf dunkel:
   knallt komplett heraus — wir mappen auf var(--bg) bzw. var(--surface)-Töne. */
[data-theme="dark"] [style*="#f1f5f9" i],
[data-theme="dark"] [style*="#f8fafc" i] {
  background-color: var(--bg) !important;
  border-color: var(--border) !important;
}
[data-theme="dark"] [style*="#e2e8f0" i] {
  background-color: var(--surface) !important;
  border-color: var(--border) !important;
}
/* Dunkel-Slate-Textfarben (für Headlines/Akzente in den Slate-Tipps) */
[data-theme="dark"] [style*="#0f172a" i],
[data-theme="dark"] [style*="#1e293b" i] {
  color: var(--text-1) !important;
}
[data-theme="dark"] [style*="#475569" i],
[data-theme="dark"] [style*="#64748b" i] {
  color: var(--text-2) !important;
}

/* settings-tip — semantischer Tipp-Block (Workflow/Schritt-für-Schritt). */
.settings-tip {
  background: #f1f5f9;
  border: 1px solid var(--border);
  color: #475569;
}
.settings-tip b { color: #0f172a; }
[data-theme="dark"] .settings-tip {
  background: var(--bg) !important;
  border-color: var(--border) !important;
  color: var(--text-2) !important;
}
[data-theme="dark"] .settings-tip b { color: var(--text-1) !important; }

/* ── Globale Hero-Card v3.32.80 ─────────────────────────────────────────
   Wiederverwendbares Pattern für „ein wichtiger Wert zum Kopieren". Analog
   zur DMARC-Mailbox-Card (.dz-mbx) und DS-Hero (.dnssec-ds-hero), aber
   generisch nutzbar — API-Tokens, Vanity-NS-Hostnamen, Webhook-URLs etc.
   Vier Varianten: brand (grün-blau, „erfolgreich angelegt"), warn (orange-
   blau, „Aktion offen"), info (blau-violet, „read-only-Info"), danger
   (rot-orange, „sensitiv / nur einmal sichtbar"). */
.gw-hero-card {
  display:flex; gap:14px; align-items:center;
  padding:13px 14px; border-radius:10px; flex-wrap:wrap;
  background:linear-gradient(135deg, rgba(34,197,94,.06) 0%, rgba(0,152,239,.06) 100%);
  border:1px solid rgba(34,197,94,.28);
}
[data-theme="dark"] .gw-hero-card {
  background:linear-gradient(135deg, rgba(34,197,94,.10) 0%, rgba(0,152,239,.10) 100%);
  border-color:rgba(34,197,94,.35);
}
.gw-hero-card__icon {
  width:40px; height:40px; border-radius:10px; flex:0 0 40px;
  display:flex; align-items:center; justify-content:center;
  background:rgba(34,197,94,.18); color:#15803d;
}
[data-theme="dark"] .gw-hero-card__icon { background:rgba(34,197,94,.22); color:#86efac; }
.gw-hero-card__body { flex:1; min-width:240px; display:flex; flex-direction:column; gap:3px; }
.gw-hero-card__lbl {
  font-size:10.5px; font-weight:700; text-transform:uppercase;
  letter-spacing:.45px; color:var(--text-3);
  display:flex; align-items:center; gap:8px; flex-wrap:wrap;
}
.gw-hero-card__val {
  font-family:var(--font-mono); font-size:13.5px; font-weight:600;
  color:var(--text-1); word-break:break-all; user-select:all; line-height:1.45;
}
.gw-hero-card__sub {
  font-size:11.5px; color:var(--text-3); margin-top:2px; line-height:1.5;
}
.gw-hero-card__sub strong { color:var(--text-2); font-weight:600; }
.gw-hero-card__badge {
  display:inline-block; font-size:9.5px; font-weight:700;
  padding:1px 7px; border-radius:99px;
  background:#dcfce7; color:#166534; border:1px solid #bbf7d0;
  letter-spacing:.3px; text-transform:uppercase;
}
[data-theme="dark"] .gw-hero-card__badge { background:rgba(34,197,94,.18); color:#86efac; border-color:rgba(34,197,94,.40); }
.gw-hero-card__copy {
  background:transparent; border:1px solid var(--border); color:var(--text-2);
  padding:7px 12px; border-radius:7px; font-size:11.5px; font-weight:600;
  cursor:pointer; display:inline-flex; align-items:center; gap:5px;
  transition:background-color .12s, color .12s, border-color .12s;
  flex-shrink:0; font-family:var(--font);
}
.gw-hero-card__copy:hover { background:var(--surface); color:var(--text-1); border-color:var(--gw); }
.gw-hero-card__copy svg { width:13px; height:13px; }

/* Varianten */
.gw-hero-card--warn {
  background:linear-gradient(135deg, rgba(245,158,11,.08) 0%, rgba(0,152,239,.06) 100%);
  border-color:rgba(245,158,11,.30);
}
[data-theme="dark"] .gw-hero-card--warn {
  background:linear-gradient(135deg, rgba(245,158,11,.12) 0%, rgba(0,152,239,.10) 100%);
  border-color:rgba(245,158,11,.40);
}
.gw-hero-card--warn .gw-hero-card__icon { background:rgba(245,158,11,.18); color:#b45309; }
[data-theme="dark"] .gw-hero-card--warn .gw-hero-card__icon { color:#fbbf24; background:rgba(245,158,11,.22); }

.gw-hero-card--info {
  background:linear-gradient(135deg, rgba(0,152,239,.06) 0%, rgba(99,102,241,.06) 100%);
  border-color:rgba(0,152,239,.30);
}
[data-theme="dark"] .gw-hero-card--info {
  background:linear-gradient(135deg, rgba(0,152,239,.10) 0%, rgba(99,102,241,.10) 100%);
  border-color:rgba(0,152,239,.40);
}
.gw-hero-card--info .gw-hero-card__icon { background:rgba(0,152,239,.18); color:#0c5392; }
[data-theme="dark"] .gw-hero-card--info .gw-hero-card__icon { color:#7dd3fc; background:rgba(0,152,239,.22); }

.gw-hero-card--danger {
  background:linear-gradient(135deg, rgba(239,68,68,.07) 0%, rgba(245,158,11,.05) 100%);
  border-color:rgba(239,68,68,.30);
}
[data-theme="dark"] .gw-hero-card--danger {
  background:linear-gradient(135deg, rgba(239,68,68,.12) 0%, rgba(245,158,11,.08) 100%);
  border-color:rgba(239,68,68,.40);
}
.gw-hero-card--danger .gw-hero-card__icon { background:rgba(239,68,68,.18); color:#b91c1c; }
[data-theme="dark"] .gw-hero-card--danger .gw-hero-card__icon { color:#fca5a5; background:rgba(239,68,68,.22); }

/* Stack-Variante für mehrere Hero-Cards untereinander */
.gw-hero-stack { display:flex; flex-direction:column; gap:8px; }

/* ── Erklär-Tooltips für Kennzahl-Kacheln ([data-help]) ──────────────────────
   Schwebendes Panel, von app.js positioniert (Maus, Tastatur-Fokus & Touch).
   Global, weil der Renderer (app.js) global ist: greift auf der Analytics-Seite
   (.ana-kpi / .ana-kpi2), im Security-Cockpit (.sd-kpi) und in den Zonen-/
   Record-Traffic-Modals. Optik an .dz-tip angelehnt, dark-safe über Tokens. Ein
   dezentes ⓘ am Label signalisiert, dass eine Erklärung bereitsteht. */
.ana-kpi[data-help], .ana-kpi2[data-help], .sd-kpi[data-help] { cursor: help; }
/* Über Trendleisten/Sparklines gilt der eigene Hover — neutraler Cursor. */
.ana-kpi2[data-help] .ana-kpi2-trend, .ana-kpi2[data-help] [data-tip] { cursor: default; }
.ana-kpi[data-help] .ana-kpi-lbl::after,
.ana-kpi2[data-help] .ana-kpi2-lbl span::after,
.sd-kpi[data-help] .sd-kpi-top span::after {
  content: '\24D8'; margin-left: 5px; font-size: .92em; font-weight: 400;
  color: var(--text-4); opacity: .6; transition: color .15s ease, opacity .15s ease;
}
.ana-kpi[data-help]:hover .ana-kpi-lbl::after,
.ana-kpi2[data-help]:hover .ana-kpi2-lbl span::after,
.sd-kpi[data-help]:hover .sd-kpi-top span::after,
.ana-kpi[data-help]:focus-visible .ana-kpi-lbl::after,
.ana-kpi2[data-help]:focus-visible .ana-kpi2-lbl span::after,
.sd-kpi[data-help]:focus-visible .sd-kpi-top span::after { color: var(--gw, #0098ef); opacity: 1; }
/* Tastatur-Fokus sichtbar; Maus-/Touch-Fokus bleibt schlicht (kein Ring). */
.ana-kpi[data-help]:focus { outline: none; }
.ana-kpi2[data-help]:focus, .sd-kpi[data-help]:focus { outline: none; }
.ana-kpi[data-help]:focus-visible,
.ana-kpi2[data-help]:focus-visible,
.sd-kpi[data-help]:focus-visible {
  outline: 2px solid var(--gw, #0098ef); outline-offset: 2px; border-radius: 10px;
}
.ana-tip-layer { position: fixed; inset: 0; overflow: hidden; pointer-events: none; z-index: 2147483000; }
/* Fachbegriff-Hinweis (gloss-hints.js, 27.09.2026): kleines «?» hinter einer Beschriftung mit data-gloss; Tooltip aus
   [data-help], Klick öffnet das Glossar. Dezent (Textfarbe), beim Überfahren Hausblau. */
.gw-gloss { display:inline-flex; align-items:center; justify-content:center; width:16px; height:16px; margin-left:4px; vertical-align:-2px;
  border-radius:50%; color:var(--text-4); text-decoration:none; cursor:help; flex:none }
.gw-gloss:hover, .gw-gloss:focus-visible { color:var(--gw); background:color-mix(in srgb, var(--gw) 10%, transparent); outline:none }
@media print { .gw-gloss { display:none } }
.ana-tip {
  position: absolute; pointer-events: none; min-width: 180px; max-width: 320px;
  padding: 11px 13px; background: var(--surface); border: 1px solid var(--border);
  border-radius: 11px; box-shadow: 0 8px 28px rgba(0,0,0,.16), 0 2px 6px rgba(0,0,0,.08);
  font-size: 12px; line-height: 1.5; color: var(--text-1);
}
[data-theme="dark"] .ana-tip { box-shadow: 0 10px 32px rgba(0,0,0,.55); }
.ana-tip__t {
  display: flex; align-items: center; gap: 7px; font-size: 12.5px; font-weight: 700;
  color: var(--text-1); margin-bottom: 6px;
}
.ana-tip__t::before { content: ''; width: 7px; height: 7px; border-radius: 50%; background: var(--gw, #0098ef); flex: none; }
.ana-tip__b { color: var(--text-2); }
.ana-tip__m { margin-top: 8px; padding-top: 7px; border-top: 1px solid var(--border); font-size: 11px; color: var(--text-3); }
/* Tooltip-Mini-Markup (von app.js gerendert): **Highlight**, "- " Bullets, "---" Trennlinie. */
.ana-tip__b > div + div, .ana-tip__m > div + div { margin-top: 3px; }
.ana-tip__hl { color: var(--text-1); font-weight: 700; }
/* Farbige Legenden-Swatch (Traffic-Spark-Tooltip: Aktuelle Woche / Vorwoche / rcodes) */
.ana-tip__sw { display: inline-block; width: 9px; height: 9px; border-radius: 2px; margin-right: 6px;
  vertical-align: baseline; box-shadow: inset 0 0 0 1px rgba(0,0,0,.18); }
.ana-tip__hr { border: 0; border-top: 1px solid var(--border); margin: 8px 0; }
.ana-tip__sp { height: 5px; }
.ana-tip__ul { margin: 4px 0 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 4px; }
.ana-tip__ul li { position: relative; padding-left: 14px; }
.ana-tip__ul li::before { content: ''; position: absolute; left: 3px; top: .52em; width: 4px; height: 4px; border-radius: 50%; background: var(--gw, #0098ef); }

/* ── Kompakter Zeitraum-Wähler (Dropdown) ───────────────────────────────────
   app.js faltet lange .ana-range[data-hours]-Leisten (DNS-Analytics, Zonen-/
   Record-Traffic) in ein Trigger-Dropdown, sobald sie mehr als ~5 Fenster
   tragen — die Buttons bleiben im DOM (Klick-Handler unverändert), nur versteckt
   im Popover. Die 3er-Auto-Refresh-Leiste (data-secs) bleibt unberührt. */
.ana-range--compact { position: relative; padding: 0; gap: 0; background: none; border: 0; }
.ana-range-trigger { display: inline-flex; align-items: center; gap: 7px; border: 1px solid var(--border); background: var(--surface); color: var(--text-1); border-radius: 9px; padding: 6px 11px; font-size: 12.5px; font-weight: 600; cursor: pointer; white-space: nowrap; transition: border-color .12s ease; }
.ana-range-trigger:hover { border-color: var(--text-4); }
.ana-range-trigger__ico { width: 14px; height: 14px; opacity: .7; flex: none; color: var(--text-3); }
.ana-range-trigger__chev { width: 13px; height: 13px; opacity: .6; transition: transform .15s ease; flex: none; }
/* Lead-Icon für kurze (nicht gefaltete) Tages-Picker — wie das Uhr-Icon der
   Auto-Refresh-Leiste. */
.ana-range-lead { display: inline-flex; align-items: center; padding: 0 1px 0 6px; color: var(--text-3); }
.ana-range-lead svg { width: 14px; height: 14px; }
.ana-range.is-open .ana-range-trigger__chev { transform: rotate(180deg); }
.ana-range--sm.ana-range--compact .ana-range-trigger { padding: 4px 9px; font-size: 11.5px; border-radius: 7px; }
/* position:fixed + hohes z-index, damit das Menü nicht vom overflow:hidden eines
   Dialogs (.zd-dlg) abgeschnitten oder hinter dem Modal-Backdrop verdeckt wird —
   gleiche Begründung wie .zd-panel. Koordinaten (top/bottom/left) setzt app.js
   place() inline per getBoundingClientRect. */
.ana-range-menu { position: fixed; z-index: 10002; left: 0; top: 0; min-width: 150px; max-height: 340px; overflow-y: auto; display: none; flex-direction: column; gap: 1px; padding: 5px; background: var(--surface); border: 1px solid var(--border); border-radius: 10px; box-shadow: 0 8px 28px rgba(0,0,0,.16), 0 2px 6px rgba(0,0,0,.08); }
[data-theme="dark"] .ana-range-menu { box-shadow: 0 10px 32px rgba(0,0,0,.55); }
.ana-range.is-open .ana-range-menu { display: flex; }
.ana-range--compact .ana-range-btn { display: flex; align-items: center; justify-content: space-between; gap: 14px; width: 100%; text-align: left; border-radius: 7px; padding: 6px 10px; }
.ana-range--compact .ana-range-btn:hover { background: var(--bg-2, #eef1f5); }
[data-theme="dark"] .ana-range--compact .ana-range-btn:hover { background: rgba(255,255,255,.06); }
.ana-range--compact .ana-range-btn.is-active { background: transparent; box-shadow: none; color: var(--text-1); }
.ana-range--compact .ana-range-btn.is-active::after { content: '\2713'; color: var(--gw, #0098ef); font-weight: 700; }
.ana-range--compact .ana-range-btn--long:first-of-type { margin: 0; padding-left: 10px; border-left: 0; border-radius: 7px; }
.ana-range-grp-div { height: 1px; background: var(--border); margin: 4px 2px; flex: none; }

/* ── Einheitlicher horizontaler Tabellen-Scroll (v4.67.409) ──────────────────
   Jede Tabelle bekommt einen horizontalen Scrollbalken nur dann, wenn sie nicht
   vollstaendig auf die Seite passt (overflow-x:auto). Passt sie, kein Balken.
   Gilt fuer alle feature-spezifischen *-table-wrap-Container und den generischen
   .gw-table-scroll-Wrapper, den app.js automatisch um ungewrappte <table> legt. */
[class*="table-wrap"],
.gw-table-scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}
.gw-table-scroll { max-width: 100%; }

/* ── Secret-Feld mit Loeschknopf ──────────────────────────────────────────────
   Ein Passwort-/Schluesselfeld, das einen hinterlegten Wert als Bullet-Maske zeigt
   und daneben ein ✕ zum bewussten Loeschen anbietet. Lag frueher nur im <style>-Block
   von admin/settings.php und stand damit dem Proxy-Einstellungs-Modal nicht zur
   Verfuegung — dort sah dasselbe Feld anders aus als in den System-Einstellungen.
   Eine Definition fuer beide Orte. */
.gw-secret-wrap { display: flex; align-items: stretch; width: 100%; }
.gw-secret-wrap > .inp { flex: 1; min-width: 0; }
.gw-secret-wrap:has(.gw-secret-clear) > .inp {
  border-top-right-radius: 0;
  border-bottom-right-radius: 0;
  border-right-width: 0;
}
/* hidden-Attribut wirkt nur ueber die UA-Vorgabe display:none — eine eigene display-Regel schlaegt sie. */
.gw-secret-clear[hidden] { display:none; }
.gw-secret-clear {
  display: inline-flex; align-items: center; justify-content: center;
  width: 38px; padding: 0; margin: 0;
  background: var(--bg, #f8fafc);
  color: var(--text-3, #64748b);
  border: 1px solid var(--border);
  border-top-right-radius: var(--r-md, 8px);
  border-bottom-right-radius: var(--r-md, 8px);
  border-top-left-radius: 0; border-bottom-left-radius: 0;
  cursor: pointer; line-height: 1;
  transition: background-color .15s ease, color .15s ease, border-color .15s ease;
}
.gw-secret-clear svg {
  width: 14px; height: 14px; display: block;
  transition: transform .15s ease;
}
.gw-secret-clear:hover {
  background: #fee2e2; color: #b91c1c; border-color: #fca5a5;
}
.gw-secret-clear:hover svg { transform: rotate(90deg); }
.gw-secret-clear:active { background: #fecaca; }
.gw-secret-clear:focus  { outline: 2px solid var(--gw, #2563eb); outline-offset: -2px; }
/* Wenn das Input grad gefocused ist, soll der Border-Look weiter konsistent
   bleiben (Input bekommt normal einen Focus-Border) — wir matchen das am Button. */
.gw-secret-wrap:focus-within > .gw-secret-clear { border-color: var(--gw, #2563eb); }

/* Zeichen-Zaehler in zd.prompt (opts.minLength/maxLength): zeigt den Fortschritt eines
   Pflichtfelds. «is-short» = Minimum noch nicht erreicht, der Bestaetigen-Knopf ist dann
   gesperrt — der Nutzer sieht sofort, wie viel fehlt. */
.zd-dlg-fieldfoot { display:flex; align-items:baseline; justify-content:space-between; gap:12px; margin-top:6px }
.zd-dlg-minhint { font-size:11.5px; color:var(--text-4) }
.zd-dlg-minhint.is-short { color:var(--warn-text); font-weight:600 }
.zd-dlg-count { font-size:11.5px; color:var(--text-4); font-variant-numeric:tabular-nums; white-space:nowrap }
.zd-dlg-count.is-short { color:var(--warn-text) }

/* ── Zeitspalte der Record-Tabellen (.td-modified) ───────────────────────────
   eine Spalte statt «Erstellt» + «Geaendert»: die Relativzeit fuehrt (das ist die
   Frage beim Suchen), der Urheber steht kleiner darunter, beide Absolutdaten
   stehen im title der Zelle.

   Achtung: Warum hier und nicht in records.css: die Spalte gibt es an zwei Orten — im
   Zoneneditor (.records-table, records.css) und in der globalen Records-Tabelle
   (.zone-table, eigener <style>-Block, records.css wird dort nicht geladen).
   Als Kopie waeren die beiden nur so lange gleich, bis jemand eine anfasst
   (Lehre v7.3.25). Darum ohne Tabellen-Praefix in main.css, das beide Seiten
   laden. Die Breite bleibt tabellenspezifisch — sie haengt an den Nachbarn. */
.td-modified .rec-when {
  font-size:11.5px; font-weight:600; color:var(--text-2); line-height:1.35;
}
.td-modified .rec-who {
  font-size:10.5px; color:var(--text-4); line-height:1.3;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
  /* Wie frueh der Urheber abschneidet, haengt an der Spalte, nicht am Baustein:
     im Zoneneditor sind es 128 px, in der globalen Tabelle 150. Darum eine
     Variable statt einer zweiten Regel — 118 px ist der Zoneneditor-Wert. */
  max-width:var(--rec-who-w, 118px);
}
.td-modified .rec-who-mark { font-style:italic; opacity:.85 }

/* ── Ladezustaende: ein Muster fuer das ganze Haus ───────────────────────────
   Hintergrund (09.09.2026): Ladeuebergaenge wirkten hart und uneinheitlich.

   Gemessen, bevor etwas gebaut wurde: es gab bereits drei Skelett-Fassungen
   (.dash-skel, .sec-skel, .ana-skel/.gw-spark-skel) in drei Dateien und drei
   eigene Shimmer-Animationen (dashSkelShimmer, secSkelShimmer, zrHpShimmer) —
   fuer dieselbe Sache, dreimal erfunden. Und wo gar keine war (DMARC-Reiter),
   stand nur ein Satz «wird geladen …» ueber einer leeren Seite, den der Inhalt
   dann schlagartig ersetzt hat. Genau dieser Sprung war das Problem.

   Zwei Bausteine, die zusammengehoeren:
     .gw-skel     — ein Platzhalter in der FORM des kommenden Inhalts. Er sagt
                    «hier kommt eine Karte», nicht «warte».
     .gw-fade-in  — das Eintreffen. Kurz und klein: 180 ms und 4 px, mehr wirkt
                    traege statt ruhig.
   Wer Bewegung abbestellt hat (prefers-reduced-motion), bekommt beides ohne
   Animation — ein Ladezustand darf niemand koerperlich stoeren. */
@keyframes gw-skel-shimmer { 100% { transform: translateX(100%); } }

/* Achtung: Die ALIAS-Namen stehen bewusst hier mit drin. Gemessen am 09.09.2026 gab es
   26 Skelett-Klassennamen in 20 Dateien und drei Shimmer-Animationen — inhaltlich
   dieselbe Optik, dreimal abgeschrieben (identischer Verlauf, identische 1.3 s).
   Sie hier aufzuzaehlen ist haesslicher als ein sauberer Namensraum, aber es ist
   eine Wahrheit: wer die Ladeoptik aendert, aendert sie ueberall. Neue Stellen
   nehmen `.gw-skel`; `LoadingLooksTheSameEverywhereTest` verbietet neue Namen. */
.gw-skel,
.dash-skel, .sec-skel, .sec-skel-num, .sec-skel-sub, .sec-skel-pill,
.ana-skel, .ana-skel--kpi, .gw-spark-skel,
.mt-skel, .sd-skel, .diag-skel,
.notif-skeleton__icon, .notif-skeleton__line, .zr-hp-loading {
  position: relative; overflow: hidden;
  border-radius: 8px;
  background: color-mix(in srgb, var(--text-4) 12%, transparent);
}
.gw-skel::after,
.dash-skel::after, .sec-skel::after, .sec-skel-num::after, .sec-skel-sub::after,
.sec-skel-pill::after, .ana-skel::after, .ana-skel--kpi::after, .gw-spark-skel::after,
.mt-skel::after, .sd-skel::after, .diag-skel::after,
.notif-skeleton__icon::after, .notif-skeleton__line::after, .zr-hp-loading::after {
  content: ""; position: absolute; inset: 0; transform: translateX(-100%);
  background: linear-gradient(90deg,
    transparent 0%,
    color-mix(in srgb, var(--surface) 55%, transparent) 50%,
    transparent 100%);
  animation: gw-skel-shimmer 1.35s ease-in-out infinite;
}
/* Formen: hoch wie das, was kommt — sonst springt das Layout beim Eintreffen,
   und genau das Springen soll weg. */
.gw-skel--line  { height: 11px; border-radius: 5px; }
.gw-skel--line + .gw-skel--line { margin-top: 7px; }
.gw-skel--title { height: 15px; border-radius: 5px; width: 42%; }
.gw-skel--hero  { height: 68px; }
.gw-skel--kpi   { height: 78px; }
.gw-skel--chart { height: 160px; }
/* Eine Listen-/Tabellenzeile. Die Hoehe ist die einer echten Zeile im Haus (34 px
   Inhalt + Trenner) — ein zu flacher Platzhalter laesst die Liste beim Eintreffen
   aufspringen, und genau das Springen war die Meldung. */
.gw-skel--row   { height: 34px; border-radius: 7px; }
.gw-skel--row + .gw-skel--row { margin-top: 8px; }
/* Kachelreihe: dieselbe Aufteilung wie die fertigen KPI-Reihen (auto-fit ab 150 px),
   damit die Zahl der Platzhalter der Zahl der Kacheln entspricht. */
.gw-skel-grid   { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 10px; }
/* Der Rahmen um einen Platzhaltersatz — der Abstand, den der fertige Inhalt auch hat. */
.gw-skel-box    { padding: 10px 2px; }
.gw-skel-box > * + * { margin-top: 10px; }
/* Mehrere Platzhalter nebeneinander laufen leicht versetzt — gleichzeitig
   blinkende Bloecke lesen sich als Fehler, nicht als Ladevorgang. */
.gw-skel:nth-child(2)::after { animation-delay: .12s; }
.gw-skel:nth-child(3)::after { animation-delay: .24s; }
.gw-skel:nth-child(4)::after { animation-delay: .36s; }

.gw-fade-in { animation: gw-fade-in .18s ease-out both; }
@keyframes gw-fade-in { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }

@media (prefers-reduced-motion: reduce) {
  .gw-skel::after,
  .dash-skel::after, .sec-skel::after, .ana-skel::after, .gw-spark-skel::after,
  .mt-skel::after, .sd-skel::after, .diag-skel::after,
  .notif-skeleton__icon::after, .notif-skeleton__line::after { animation: none; opacity: .5; }
  .gw-fade-in { animation: none; }
}

/* ── Leeren-× der Suchfelder — eine Fassung (search_clear.js) ─────────────────
   Manche Suchfelder hatten rechts ein ×, andere nicht. Jetzt einheitlich und optisch abgegrenzt.
   Gemessen: sieben eigene Knoepfe (je Seite eigenes CSS), sieben native type="search"-×
   (nur Chromium), zwei Felder ohne. Jetzt: das native × ist aus, jedes angemeldete Feld
   bekommt denselben Knopf — kleine Kapsel mit Strich-SVG, links durch eine Haarlinie vom
   Text abgesetzt, Grund erst beim Darauffahren. Sichtbar nur mit Text (`hidden` am Knopf;
   darum hier kein display ausser im nicht-versteckten Zustand). */
input.gw-has-clear::-webkit-search-cancel-button,
input.gw-has-clear::-webkit-search-decoration { -webkit-appearance: none; appearance: none; display: none; }
.gw-clear-wrap { position: relative; }
/* Achtung: Glyphe im × wurde abgeschnitten. Die Huelle traegt
   `.zf-search svg { position:absolute; left:12px }` — die Regel traf auch das svg im × und
   schob die Glyphe an den Feldrand. Solche Nachfahren-Regeln (`.x svg`, `.x button`) stehen
   in vielen Huellen und in <style>-Bloecken nach main.css. Darum hier die Geometrie von Knopf
   und Glyphe mit doppelter Klasse und !important: sie gehoert dem Baustein, nicht der Huelle.
   Lage und Groesse setzt search_clear.js gemessen je Feld (links/top/Breite/Hoehe inline):
   innerhalb der sichtbaren Feldflaeche, rechts derselbe Abstand wie die Lupe links. */
button.gw-clear.gw-clear {
  position: absolute !important; right: auto !important; bottom: auto !important; transform: none !important;
  box-sizing: border-box !important; margin: 0 !important; padding: 0 !important;
  min-width: 0 !important; min-height: 0 !important; max-width: none !important; max-height: none !important;
  flex: none !important; float: none !important;
  display: inline-flex; align-items: center; justify-content: center;
  border: 0 !important; border-radius: 6px; background: transparent; box-shadow: none;
  color: var(--text-4); cursor: pointer; line-height: 0; font-size: 0; z-index: 2;
  transition: background .12s, color .12s;
}
button.gw-clear.gw-clear[hidden] { display: none !important; }
button.gw-clear.gw-clear::before {
  content: ''; position: absolute; left: -5px; top: 20%; bottom: 20%; width: 1px;
  background: var(--border); pointer-events: none;
}
button.gw-clear.gw-clear > svg {
  position: static !important; left: auto !important; top: auto !important; right: auto !important; bottom: auto !important;
  transform: none !important; margin: 0 !important; padding: 0 !important;
  width: 12px !important; height: 12px !important; min-width: 12px; flex: none !important;
  display: block !important; opacity: 1 !important; pointer-events: none;
  fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; color: inherit;
}
button.gw-clear.gw-clear:hover { background: color-mix(in srgb, var(--text-1) 8%, transparent); color: var(--text-1); }
button.gw-clear.gw-clear:active { background: color-mix(in srgb, var(--text-1) 14%, transparent); }
button.gw-clear.gw-clear:focus-visible { outline: 2px solid var(--gw); outline-offset: -2px; }
/* Topbar: der Tastenhinweis «Ctrl F» weicht dem ×, sobald Text im Feld steht. */
.topbar-search:has(> .gw-clear:not([hidden])) .topbar-search-kbd { display: none; }
@media (max-width: 768px) { .topbar-search > button.gw-clear.gw-clear { display: none !important; } }

/* ── Snapshot-Detail: Export-Zeile (14.09.2026) ─────────────────────────────────────────────
   Die Info-Karte (Raster, Notiz, Kacheln) steht seit dem Umbau «futuristisch» einmal in
   snapshot_view.css (.sdx-*); hier bleibt nur der Export-Verbund, den snapExportHtml() baut. */
/* Export-Zeile: Label + Segment-Verbund nach dem Muster .zf-status-group (eine Umrandung,
   Haarlinien zwischen den Segmenten), Hoehe 30 px wie .btn-sm, Hover mit Markenton-Tint. */
.snapx { display: flex; align-items: center; justify-content: flex-end; gap: 10px; flex-wrap: wrap; }
.snapx__lbl { display: inline-flex; align-items: center; gap: 5px; font-size: 11.5px; font-weight: 600; color: var(--text-3); white-space: nowrap; }
.snapx__lbl svg { width: 13px; height: 13px; flex-shrink: 0; color: var(--text-4); }
.snapx__seg { display: inline-flex; align-items: stretch; height: 30px; box-sizing: border-box; border: 1px solid var(--border); border-radius: 8px; background: var(--surface); overflow: hidden; }
.snapx__opt { display: inline-flex; align-items: center; gap: 6px; padding: 0 11px; font-family: var(--font); font-size: 12px; font-weight: 600; color: var(--text-2); text-decoration: none; white-space: nowrap; transition: background .12s, color .12s; }
.snapx__opt + .snapx__opt { border-left: 1px solid var(--border); }
.snapx__opt svg { width: 13px; height: 13px; flex-shrink: 0; color: var(--text-4); transition: color .12s; }
.snapx__ext { font-family: var(--font-mono); font-size: 10.5px; font-weight: 500; color: var(--text-3); }  /* --text-4 mass 2.7–3.1:1 */
.snapx__opt:hover { background: color-mix(in srgb, var(--gw) 10%, transparent); color: var(--gw); }
.snapx__opt:hover svg, .snapx__opt:hover .snapx__ext { color: var(--gw); }
.snapx__opt:focus-visible { outline: 2px solid var(--gw); outline-offset: -2px; }
@media (max-width: 640px) { .snapx__lbl { display: none; } }

/* Seitenabstand der offenen Leiste: Eintraege 2 statt 6 px vom
   Rand der Scroll-Spur, Gruppentitel und Bearbeiten-Kasten ziehen mit. Nicht in der schmalen Leiste (769 bis 1024 px
   oder .mini): dort zentriert der 6-px-Rand die Symbole in der 56-px-Spalte. */
@media (min-width: 1025px), (max-width: 768px) {
  .sidebar:not(.mini) .nav-item { margin-left: 2px; margin-right: 2px; }
  .sidebar:not(.mini) .nav-section-label { margin-left: 8px; margin-right: 8px; }
  .sidebar:not(.mini) .nav-edit-bar { margin-left: 2px; margin-right: 2px; }
}

/* Favoriten (templates/layout/_nav_quick.php). Ausgeschaltete Gruppe (.is-nq-off, NavPrefs quick)
   ist weg. Im Modus «Leiste anpassen» steht nur der Titel da, mit Auge und Griff; die Zonen selbst lassen sich dort
   nicht verschieben. */
.nav-quick.is-nq-off { display: none !important; }
.sidebar.is-editing .nav-item.nav-quick { display: none !important; }
.sidebar.is-editing .nav-section-label.nav-quick { display: flex !important; cursor: default; }
.sidebar.is-editing .nav-section-label.nav-quick.is-nq-off > span:first-child { opacity: .4; }
.nq-eye { display: none; margin-left: auto; width: 26px; height: 26px; align-items: center; justify-content: center; border: none;
  border-radius: 6px; background: none; color: var(--sidebar-fg-muted); cursor: pointer; padding: 0; flex-shrink: 0;
  margin-right: 22px;   /* in der Spalte der Augen der Eintraege (rechts davon steht dort der Griff) */ }
.nq-eye svg { width: 15px; height: 15px; }
.nq-eye:hover { background: var(--sidebar-hover); color: var(--sidebar-fg); }
.sidebar.is-editing .nq-eye { display: flex; }
.nav-item.nav-quick-more .nav-item-label { color: var(--sidebar-fg-muted); }

/* Gruppen im Modus «Leiste anpassen» (18.09.2026): Titel als eigene Kopfzeile, damit Gruppe und Eintrag unterscheidbar
   sind — getoente Flaeche, abgerundet, kraeftigere Schrift, keine Trennlinie. Rechts Auge (ganze Gruppe
   aus/ein) und Griff (Auf-/Ab-Pfeile) in denselben Spalten wie bei den Eintraegen; der Titel ist dann ziehbar.
   Die Favoriten haben ihr eigenes Auge (.nq-eye) und denselben Griff. */
.nav-edit-g { display: none; }
.sidebar.is-editing .nav-section-label {
  display: flex; align-items: center; margin: 10px 2px 2px; padding: 6px 6px 6px 12px; min-height: 38px; box-sizing: border-box;
  border-top-color: transparent; border-radius: 8px; color: var(--sidebar-fg-strong);
  background: color-mix(in srgb, var(--gw) 8%, transparent);
}
.sidebar.is-editing .nav-section-label:not(.nav-quick) { cursor: grab; }
.sidebar.is-editing .nav-section-label.is-grp-off > span:first-child,
.sidebar.is-editing .nav-section-label.is-nq-off > span:first-child { opacity: .4; }
.sidebar.is-editing .nav-edit-g { display: flex; align-items: center; gap: 2px; margin-left: auto; flex-shrink: 0; }
.nav-edit-gcol, .nav-edit-geye, .nav-edit-gdrag { width: 26px; height: 26px; display: flex; align-items: center; justify-content: center; border: none;
  border-radius: 6px; background: none; color: var(--sidebar-fg-muted); padding: 0; }
.nav-edit-gcol, .nav-edit-geye { cursor: pointer; }
.nav-edit-gcol:hover, .nav-edit-geye:hover { background: var(--sidebar-hover); color: var(--sidebar-fg); }
.nav-edit-gcol svg, .nav-edit-geye svg, .nav-edit-gdrag svg { width: 15px; height: 15px; }
/* Eingeklappt gewaehlt: Pfeil in Hausfarbe, damit der Zustand auf einen Blick lesbar ist. */
.nav-edit-gcol[aria-pressed="true"] { color: var(--gw); }
.sidebar.is-editing .nq-eye { margin-right: 2px; }   /* Favoriten: Auge, dahinter ihr Griff */
.sidebar.is-editing .nav-section-label.nav-quick .nav-edit-g { margin-left: 0; }
.nav-section-label.is-dragging { opacity: .5; }
.nav-section-label.is-drop-before { box-shadow: inset 0 2px 0 var(--gw); }

/* Oberste sichtbare Gruppe ohne Trennlinie und ohne Luft davor (gwNavFirst in base.php). */
.nav-section-label.is-first-vis { border-top-color: transparent; margin-top: 0; padding-top: 6px; }


/* WAN-Adresse des Proxy-Servers im Fenster «Allgemein › Ursprung»:
   genau diese Adresse sieht der Ursprungs-Server als Absender. Als ruhige Pille in Hausblau,
   Zahl in der Schreibmaschinenschrift wie alle Adressen im Haus. */
.rps-wans { display: inline-flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.rps-wans[hidden] { display: none; }   /* `hidden` verliert sonst gegen das display oben (Hausregel). */
.rps-wan {
  display: inline-flex; align-items: center; gap: 5px; height: 24px; padding: 0 9px;
  border-radius: 999px; font-family: var(--font-mono); font-size: 12px; font-weight: 600;
  color: var(--gw); background: color-mix(in srgb, var(--gw) 10%, transparent);
  border: 1px solid color-mix(in srgb, var(--gw) 28%, transparent); white-space: nowrap; cursor: help;
}
.rps-wan svg { flex: none; opacity: .85; }

/* ── Ereignis-Detail: ein Fenster fuer Aktivitaeten und Changelog ────────────
   Dieselbe Funktion an beiden Orten statt doppelt geschrieben. Das Markup baut gwEventDetail()
   in _helpers_impl.php, die Darstellung steht hier — global, weil die beiden
   Seiten verschiedene Stylesheets laden. Die Diff-Zeilen (.cl-diff) sind aus
   records.css hierher gezogen, aus demselben Grund. */
  /* Bis v7.4.535 war jede Zeile ein eigenes Grid mit fester 90-px-Spalte. Lange
     Beschriftungen («Antwort-Härtung · Status-Codes maskieren») passten da nicht
     hinein, liefen ueber den Wert-Kasten und brachen mitten im Wort um. Jetzt traegt der block das Grid und die Zeilen reichen
     ihre Zellen per display:contents hinein: die Beschriftungs-Spalte richtet sich
     an der laengsten aus — fuer alle Zeilen gleich — und waechst hoechstens bis
     210 px (fit-content). Danach bricht sie um, statt zu ueberlaufen. */
  .cl-diff      { margin-top:8px; display:grid; grid-template-columns:fit-content(210px) minmax(0, max-content) 16px minmax(0, max-content); align-items:center; gap:5px 9px; padding:8px 10px; background:var(--bg); border:1px dashed var(--border); border-radius:8px; font-size:11.5px; line-height:1.4 }
  .cl-diff-row  { display:contents }
  /* Einseitig (Create oder Delete): kein →-Arrow vorhanden → Wert-Spalte bekommt
     die ganze restliche Breite, sonst klebt z.B. ein DKIM-Key in halber Breite. */
  /* Zeile ohne Pfeil (nur alt oder nur neu): der eine Wert nimmt den Rest der Breite. */
  .cl-diff-row:not(:has(.cl-diff-arrow)) .cl-diff-cell { grid-column:2 / -1 }
  /* Keine Grossschreibung mehr: die Beschriftungen sind seit v7.4.536 echte Woerter
     («Anmelde-Schutz · Aktiv»), keine technischen Pfade. Umbruch nur an Leerzeichen —
     nie mitten im Wort; der Trenner klebt per geschuetztem Leerzeichen am Wort davor. */
  .cl-diff-lbl  { font-size:11px; font-weight:600; color:var(--text-3); letter-spacing:.1px; min-width:0; overflow-wrap:break-word; align-self:center }
  .cl-diff-cell { font-family:var(--font-mono); font-size:11.5px; padding:3px 8px; border-radius:5px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; min-width:0 }
  .cl-diff-cell:hover { cursor:help }
  .cl-diff-old  { background:#fee2e2; color:#991b1b; border:1px solid #fecaca; text-decoration:line-through; text-decoration-color:rgba(153,27,27,.45) }
  .cl-diff-new  { background:#dcfce7; color:#15803d; border:1px solid #bbf7d0 }
  .cl-diff-arrow{ text-align:center; color:var(--text-4); font-weight:600; font-size:13px }
  /* Dark-Mode: transparent-Tints (gleiches Pattern wie .sev-pill / .snap-types__diff-chip). */
  [data-theme="dark"] .cl-item:hover { border-color: var(--gw) }
  [data-theme="dark"] .cl-diff-old { background:rgba(239,68,68,.14); color:#fca5a5; border-color:rgba(239,68,68,.40); text-decoration-color:rgba(252,165,165,.45) }
  [data-theme="dark"] .cl-diff-new { background:rgba(34,197,94,.14); color:#86efac; border-color:rgba(34,197,94,.40) }

.gwev__hero   { display:flex; align-items:center; gap:10px; padding:0 0 12px; border-bottom:1px solid var(--border); margin-bottom:14px; flex-wrap:wrap }
.gwev__hero::before { content:''; width:9px; height:9px; border-radius:50%; background:var(--gwev-color,#94a3b8); flex:none }
.gwev__act    { font-weight:700; font-size:14px; color:var(--text-1) }
.gwev__when   { font-family:var(--font-mono); font-size:12.5px; color:var(--text-3); margin-left:auto }
.gwev__sec    { background:var(--surface); border:1px solid var(--border); border-radius:10px; padding:12px 14px; margin-bottom:10px }
.gwev__h      { font-size:10.5px; font-weight:700; letter-spacing:.5px; text-transform:uppercase; color:var(--text-4); margin-bottom:8px }
.gwev__kv     { display:grid; grid-template-columns:max-content minmax(0,1fr); gap:6px 14px; font-size:12.5px; align-items:baseline }
.gwev__kv > span:nth-child(odd) { color:var(--text-3) }
.gwev__kv code{ font-family:var(--font-mono); font-size:11.5px; background:var(--bg); border:1px solid var(--border); border-radius:4px; padding:1px 5px; word-break:break-all }
.gwev__txt    { font-size:12.5px; color:var(--text-2); line-height:1.5 }
.gwev__leer   { color:var(--text-4); font-style:italic }
.gwev__rawk   { font-family:var(--font-mono); font-size:10.5px; color:var(--text-4); margin:6px 0 3px }
.gwev__json   { font-family:var(--font-mono); font-size:11px; line-height:1.45; background:var(--bg); border:1px solid var(--border); border-radius:6px; padding:8px 10px; margin:0; overflow:auto; max-height:260px; color:var(--text-2); white-space:pre-wrap; word-break:break-word }
.gwev__sec .cl-diff { margin-top:0; border-style:solid }
/* Felder, die gleich blieben, treten zurueck — geaendert wurde etwas anderes. */
.gwev__sec .cl-diff-row.is-same .cl-diff-cell { opacity:.55 }
.gwev__link   { display:inline-block; margin-top:8px; font-size:12px; font-weight:600; color:var(--gw); text-decoration:none }
.gwev__link:hover { text-decoration:underline }

/* JSON-Konsole der Detail-Fenster — global, weil sie an zwei Orten steht
   (Aktivitaeten-Protokoll und Changelog des Zoneneditors). Kam aus audit.php. */
.pa-json { margin:0;padding:12px 14px;border-radius:8px;background:#0f172a;border:1px solid #1e293b;color:#e2e8f0;font-family:var(--font-mono);font-size:12px;line-height:1.6;white-space:pre-wrap;overflow-wrap:anywhere;max-height:420px;overflow:auto }
.pa-json .pa-jk { color:#7dd3fc } .pa-json .pa-js { color:#86efac } .pa-json .pa-jn { color:#fbbf24 } .pa-json .pa-jb { color:#c4b5fd } .pa-json .pa-jp { color:#64748b }
.gwev__sec .pa-json { max-height:320px }

/* Seitenfenster «Details zum Eintrag» — gleich an beiden Orten: Aktivitaeten-
   Protokoll (#paPanel) und Changelog des Zoneneditors (#cl-panel). Kam aus
   audit.php, wo es nur die eine Seite erreichte. */
#paPanel, #cl-panel { width:520px;max-width:94vw }
#paPanel .slide-head, #cl-panel .slide-head { gap:6px }
#paPanel .slide-body, #cl-panel .slide-body { background:var(--bg);padding:16px 18px }
.pa-pn__nav { display:flex;gap:4px }
.pa-pn__nav button { width:30px;height:30px;display:inline-flex;align-items:center;justify-content:center;border:1px solid var(--border);border-radius:8px;background:var(--surface);color:var(--text-2);cursor:pointer }
.pa-pn__nav button:disabled { opacity:.4;cursor:default }
.pa-pn__nav button:not(:disabled):hover { border-color:var(--gw);color:var(--gw) }
.pa-pn__keys { font-size:11px;color:var(--text-4);margin-right:auto }
/* Die Karte, deren Detail gerade offen steht. */
.cl-item.is-open { border-color:var(--gw); box-shadow:0 0 0 1px var(--gw) inset }
/* Nachweis-Karte im Detail des Aktivitaeten-Protokolls: das Urteil steht als erste
   Zeile, darunter Platz in der Kette und Pruefsumme. Kein Knopf mehr — die Pruefung
   kommt mit der Liste (v7.4.570). */
.pa-chain__state { display:flex; align-items:center; gap:8px; margin-bottom:10px;
  padding:7px 10px; border-radius:8px; font-size:12.5px; font-weight:600; line-height:1.4 }
.pa-chain__dot { width:8px; height:8px; border-radius:50%; flex:none }
.pa-chain__state.is-ok  { background:rgba(34,197,94,.10); color:var(--ok-text, #15803d) }
.pa-chain__state.is-ok  .pa-chain__dot { background:#16a34a }
.pa-chain__state.is-bad { background:rgba(239,68,68,.10); color:var(--err-text, #b91c1c) }
.pa-chain__state.is-bad .pa-chain__dot { background:#dc2626 }
/* Die Pruefsumme (64 Zeichen) bricht um, statt gekuerzt zu werden — sie ist der
   Nachweis und muss ganz lesbar sein. */
.pa-pn__hash { display:inline-block; max-width:100%; font-size:10.5px; line-height:1.5;
  word-break:break-all; white-space:normal }
.pa-chain__kv { row-gap:8px }
.pa-chain__pdf { margin-top:12px; display:inline-flex; align-items:center; gap:7px; text-decoration:none }
/* Nachweis-Karte im Zonen-Verlauf: nur Ueberschrift und Knopf — der Abstand
   kommt sonst vom Werteblock darueber, den es hier nicht gibt. */
.cl-pn__pdf .pa-chain__pdf { margin-top:8px }

/* Marken neben dem Seitentitel in der Kopfzeile (Mandant, Warnung, 4-Augen).
   Sie stehen direkt am Titel und weichen der Suche, wenn es eng wird. */
/* Die Marken tragen dieselbe Form wie die Bedienelemente daneben: gleiche Hoehe,
   gleicher Rahmen, Hausschrift, passend zu den Navigationselementen rechts. Farbe steckt nur noch im Symbol und in der Zahl. */
/* Kein eigenes margin-left:auto: .topbar-actions hat bereits eines, und zwei
   Blöcke mit auto-Rand werden auseinandergezogen — die Marken schwebten dann frei
   zwischen Suche und Aktionen. Sie gehören unmittelbar an die Aktionen. */
.topbar-badges { display:flex; align-items:center; gap:6px; flex-shrink:0; margin:0 0 0 auto; padding-right:8px; min-width:0 }
.topbar-badges + .topbar-actions { margin-left:0 }
.topbar-badges > * { flex:none }
.topbar-badges .zone-tag,
.topbar-badges .health-indicator,
.topbar-badges .zr-ums-pill {
  display:inline-flex; align-items:center; gap:6px; height:30px; padding:0 11px;
  background:var(--surface) !important; border:1px solid var(--border) !important; border-radius:8px !important;
  font-size:12px; font-weight:600; color:var(--text-2) !important; box-shadow:none !important;
  text-decoration:none; white-space:nowrap }
.topbar-badges .zone-tag:hover,
.topbar-badges .health-indicator:hover { border-color:var(--gw) !important; color:var(--text-1) !important }
/* Der Hinweis selbst bleibt erkennbar: Symbol und Anzahl behalten ihre Farbe. */
.topbar-badges .health-indicator svg { color:#d97706 }
.topbar-badges .health-critical svg { color:#dc2626 }
.topbar-badges .health-indicator .hi-count {
  display:inline-flex; align-items:center; justify-content:center; min-width:18px; height:18px; padding:0 5px;
  border-radius:9px; background:var(--bg); color:var(--text-2); font-size:11px; font-weight:700 }
.topbar-badges .zone-tag svg { color:var(--text-4) }
@media (max-width: 1100px) { .topbar-badges { display:none } }

/* ── Migration: Status- und Quell-Pillen ───────────────────────────────────────
   Gemeinsam fuer die Liste auf «Neue Migration» und den Verlauf (vorher nur in
   migration/index.php; der Verlauf hatte eigene Pillen mit anderen Farben). */
.mw-state-pill { display:inline-block; padding:2px 8px; border-radius:999px; font-size:10.5px; font-weight:700; text-transform:uppercase; letter-spacing:.3px; white-space:nowrap }
.mw-state-pill.source    { background:#e0e7ff; color:#3730a3 }
.mw-state-pill.records   { background:#fef3c7; color:#92400e }
.mw-state-pill.staged    { background:#fce7f3; color:#9d174d }
.mw-state-pill.ns_switch { background:#fed7aa; color:#9a3412 }
.mw-state-pill.live      { background:#dcfce7; color:#15803d }
.mw-state-pill.aborted   { background:#fee2e2; color:#991b1b }
[data-theme="dark"] .mw-state-pill.source    { background:rgba(99,102,241,.18); color:#a5b4fc }
[data-theme="dark"] .mw-state-pill.records   { background:rgba(234,179,8,.18);  color:#fcd34d }
[data-theme="dark"] .mw-state-pill.staged    { background:rgba(236,72,153,.18); color:#f9a8d4 }
[data-theme="dark"] .mw-state-pill.ns_switch { background:rgba(249,115,22,.20); color:#fdba74 }
[data-theme="dark"] .mw-state-pill.live      { background:rgba(34,197,94,.18);  color:#86efac }
[data-theme="dark"] .mw-state-pill.aborted   { background:rgba(239,68,68,.18);  color:#fca5a5 }

/* Source-Kind-Tag (analog .zone-tag aus zones/index) */
.mw-kind-tag { display:inline-block; padding:2px 7px; border-radius:5px; font-size:10.5px; font-weight:600; letter-spacing:.2px; white-space:nowrap }
.mw-kind-tag.recursive { background:#e0f2fe; color:#075985 }
.mw-kind-tag.axfr      { background:#dcfce7; color:#15803d }
.mw-kind-tag.zonefile  { background:#fef3c7; color:#92400e }
[data-theme="dark"] .mw-kind-tag.recursive { background:rgba(56,189,248,.18); color:#7dd3fc }
[data-theme="dark"] .mw-kind-tag.axfr      { background:rgba(34,197,94,.18);  color:#86efac }
[data-theme="dark"] .mw-kind-tag.zonefile  { background:rgba(234,179,8,.18);  color:#fcd34d }



/* ══ Klickbar erkennbar — Variante A «Zeichen in der Ecke» ═══════════════
   Was man anklicken kann, zeigt es im Ruhezustand, nicht erst beim Ueberfahren:
     Trichter  = filtert diese Seite          (.gw-click--filter)
     ›         = fuehrt weiter / oeffnet Detail (.gw-click--go)
     kein Zeichen = nur Anzeige — und dann auch kein Heben beim Ueberfahren.
   Kacheln: das Zeichen oben rechts. Zeilen (tr): › am Ende der letzten Zelle.
   Bestehende klickbare Formen bekommen das Zeichen hier automatisch (gwKpi mit Link, .ana-fclick-
   Kacheln, Kachel-Links); Stellen, die nur per JavaScript klickbar sind, tragen die Klasse selbst.
   Riegel: ClickableThingsCarryAMarkTest. */
:root {
  /* PNG, nie SVG (im Firefox-Profil gemessen): Firefox zeichnet eine CSS-Maske nicht auf der
     Grafikkarte, sondern rastert sie bei jedem Neuaufbau der Zeichenliste neu. Bei einem SVG setzt jedes
     Rastern dessen Animationsuhr (VectorImage::Draw → SVGSVGElement::SetCurrentTime) und fordert damit eine
     neue Stilberechnung an — ein Kreislauf, der sich selbst erhaelt: 20'000 Neuberechnungen in 22 s, 4'500
     Layout-Durchlaeufe pro Sekunde. Firefox kam mit dem Zeichnen nicht mehr nach (leere Hover-Karten, nicht
     gezeichnete Flaechen, Fenstergroesse nicht mehr uebernommen). Ein PNG hat keine Uhr. Gleiche Formen wie
     vorher (24er-Raster, Trichter Strich 2.2, Pfeil Strich 2.8), dreifach aufgeloest (48 px). */
  --gw-mark-filter: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAADf0lEQVR4AeyZS6hNURzGDzJgICbyGMhEKckc5VUkZGCgMJGkKJl5lDLwGFKIyMArA0qUGHiUx0hSMjGRAUqKJAby+H73Wrv/Xmct+7XOdk+d2/etx7f+6//Ye5199z13dKfPfwYF/O8b6N+BaUpo0QjnFOWXwRZwQepb8f4I53vld0AcgitgomYbxX7BfiU6S+y4AsYz6TN+IF9XwDtNLon9gnNK9LOY3QHGW9U8E0PYLHFxyySmQnaBHHc41d0B5t/UrBL5kKjLYbdmT8UHLZEkialwOZAbOX53qi0ADYOVGmQGGgM+MFc18O0lJccYebwuElNdBnIiN3LMxFBCz7W6XvwtWizX5JjYaxCD42rjkAs5kZvVc58Bu3BDk32iD87eFl9MOMf39oC/vdLISV0eoTvgLA5rcFH0cUqCf4UkNQY+8e07Iocjvujm/yoAG54EjxkYxs6oMak85Lxz7vFtNxObHKyWGxcV8EPWq8XXosUETW6Lk8SmwAe+8Gl9EZPY5GD13LioAIw/qVkhfhEtZmpyUxwr1gV78YEv64NYxCS21bvGZQpg0ys1a8WfosV8TfitqK4W2IsPu5kYxCKm1YPjsgWwmbfUbQw88hIY+qXjmXVN90hhr7ociEGsnBibVCkAH2fVnBB9HJKwRiwLbA8GjI9LI4a6cqhaAF53qvGv0ChpV8R5YhGwwZY91vaOJvhWVx4VCsicxs7oOFncEqeKMbCGDbbWhvO+TsIvsRLqFECA2FMiliB7SJrksWHuyJOGJ85XJ1Tp6xZADJ7TvBkytuSInLbC3/EZ9aypywEf+MqJZSdNCiDGEzUbRB+bJEwWHaZrELJDw4eW66FpAUS9rCb0ROEbDi0NwT82iOxhL+PaTFEAwXmPobf0nzJ2jfE1mqZMVUAojyLfReshn11aEiddXlsUBgW0eLGDoQZ3IHhZWhQHd6DFix0MNbgDwcsyLM4Y7qItr+XRxbILqe4A35z5MXlVuCtxgRiC/xVKyKZQS1XAm0ikJdIfiudFH5X/ePEdME9VwEc5OyrGMDu20FRPVQB57FKzULwnlkGS2EmcmGwfabxUrFKIzOsjdQHDmXQ6thA+yE63fe57frtQZdyrAlwOFLJME/+OnJTG/+XUNUOvC3DZUQhHa46EuWLofwCSq6OtAlxmLzV4ISZD2wUkS9w56vsC/gAAAP//r0X9oAAAAAZJREFUAwBzhrhhPPl2UAAAAABJRU5ErkJggg==");
  --gw-mark-go: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAABhUlEQVR4AeyYTWoCQRCFh+xyioTcKJskZJFTJGSRVRaCoJdwJXgpxUu41PcQN1I9tlbVa4SWetNY89Pv69Kh6Ifhzj8doHUBewV6BZwr0H9CzgV0394rgCX8gjbQGvqApOGtwBvcLqAn6BlaQt+QLLwAE8PpDDkZhBcAXs2QQXgB/kz7x6QEwguwgtcfqBTpEF4AGp/j0AwiAgD+h2YQUQDNICIBmkBEA8ghMgCkEFcA0NdVkvyxMwFIWwPxygtvVTYAfV2CsPop3lclBQCN7HHYQVbwnJWvyikAfuGEVXjEaMW/lazNZQOwrZ6OmGELwn5q5JLxU5kANM9mruSA5lmZ0vmqfBaAxDwJMwBk5jMApOajAeTmIwGamI8CaGY+AoD7QumvShotyfsWGutjQt7zJeOnvBfg9JzzUWKek3oBrH0hmfkIAPYxn3jQFuLm7jtGd3uAZ1SHtwKciBu63Nx9wRcCYdBFBIDOrTFTBzAWZRiEyV4B4WKbU/UKmMsiTN59BQ4AAAD//zGo/PwAAAAGSURBVAMAHSA8YWUaiv0AAAAASUVORK5CYII=");
  --gw-mark-warn: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAD50lEQVR4AeyZOasUQRSFW3+APkQFEzdwCxQUBUVMxEg0E3P3BVFcI3FFUXBHEEXM3DXVxBU08B9o4oKBgSKIYCKi5+t51dyp1z3T3VX9ZoT3uGfuvVVdt+55M2eqZ2Z08p//jRDo9RPY9DMwTQQnC41ZEwQmqdsbwkfhvfBJ+CBcF5iTi2exCUxQay+FdcIUwdlUBRsE5sbJR7OYBMaqKxqcIV9kzL3Q5BghisUkcFIdzRGs8dL5bAcUzxVOCFEsFoH56ma7YO2UkukCIj4nb22HEtbIhVksAle9Nt4qPyg4O6CAMbnM/DXZRJUgBgHEucjbdKPyP4IzYsZcjmfNeoIQhBIY0Oa8VOQyu6noteAbY7e9wdPKqSFXz0IJINzxZuufivcLRbZXE78EZ6wNEnQIgXnqYqtg7bCSL0KRMXfIm9ymnFpy1S2EACfrKLMlIr1k8qLwgia4Vi41alArTao+1CVQRrhFvUQVdB0CiO6M190t5YhULrO1ivhPA2KlmXHtnSxrBbUEXYcAwoVEa9skQbj7XGL8McWzBkGssM32KAsWdFUCiM0X7hE1gjjl2ozm3YCN3RhrEL3L8ZUFXZUAYkN0bAZ4eVwkqAnWUsMtpzZ7uLyrr0IgRLhFjfzWRNAJXZbAQJIkvnA5VRGjeggyatz1KpQWdFkCecLlVPX2rZ3u1spagi5DIE+4R7UhIpSLYtSipi1WStBlCCAqxOWKIzpOU5fH8udViM/QcqmxJ3unSdFDNwJNCLeoFwS92ZvsesvdiQCHVYhw35lmbGyGh4RPNXJfsNZR0J0I+MJFZFWEy10njQNi21SneJcm2UsutY633EUE8oRLE4gtrVri4Z6umT0IYoWljD38W49CQRcRQDyIyO3YlHBdfd/zJUApQecRGE7h+o27vLSgfQJ5wuW2l9PSFR8uj6AfeJsNEbRPIE+43PZ6dUqlfAbgpQeISy3yLtqpvKOgLYE84XK7i6hUp7IhRG6jAXHlAlrA3sflrbUJ2hLIEy6no13ci/isNi0UtCOwRBdx6sllBlM+v2YDFQPedjkDAHHF5dnlCHpTlrUCel1K6AisJjFAuHyLbIYqh7z31zkH8jZ6psGHgrWVJI7AKhKDJm7WTPlaod9TGwF7aNWq3qtF7hl45DVwWflMoV+MXvj8bPtJe3YEHtsZxQsFxPdXvh9ALwvUi7W0Z0eAn4ae29k+j5+ov/TuwBHgv7xGg2+EcGu2wiuVp1d6ThwBjSXf9bBY4Kcino1vivvFvqoR7o22yC8TfgipWQLpgB6uCMsFfjLl3akfMFH9rBCuCW2WR6Dtgn5PRgj0+hn6BwAA//+2En9jAAAABklEQVQDAAcxymEFvLJ6AAAAAElFTkSuQmCC");
  --gw-mark-chev-down: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAACYUlEQVR4AezWu4oUQRQG4MHU1AuouaiRYKaor6KBsYGvYWAsgo/iLVHQUDE28IJmPoD/B9tQUzSzPV09LcvWcv6pOqfO+c9td9gzmxP+0xv43wvsG+gbaJxA/xVqHGBzeN9A8wgbCfoGGgfYHN430DzCRoJTtYErGdaLI1zKubTM4p+6gbOp9n3w8Aifcl4PlpIbIfoYDPwfcpczx26Z2sCT0JRTvxj9dXA1aBUcr0JyIRjkci6Pg2NlagNjROdifBcoIMcsEYsD1yyCqQ08DfuPoBaJ38Z4LdhXxIjFUcf+jOFZcKxMbeBvmO4Hv4NazsfwJjDNHJOErxixdYAc92KUM8dumdrAZrPZfA3VnUCCHFtiin4VFLb1MKLw4SumfsYth1z126i+TwMIEEsgEb2EghSmwNJe3r3x4Vva3XHiloM+Cfs2gFQCiSSkl1CYAhVa2t3ZvPGhl8CFE3dpP/Y+pwGkEkkoMb2EAhWq4MHuzuZtsA0nDlw4B9vkc24DEkgosQLoJRSqYIWDO1vp4y4WBy763mhpQDKJfWP8oVRQsK9JcK+eN2LE4qjfJuutDUj0OR+3A9PMsSW+JmHLGIWvGLFR58sSDchuiqZpqvRd4MNXzC6/SW9LNSCZaZqq6dLH4I0P37H3vW1LNiC5qfqjVCi9BJs3PqW96b50A4pR4N1cfgWD+N+GzdtgW+Q8RAMK+5KPW8HL4HlwM2DLsawcqgFVfsvHg+BR8D04iByygYMUXJP2BuqJrK33Daw98Tpf30A9kbX1voHRia9o7BtYcdijqfoGRseyovHEb+AfAAAA///44sDKAAAABklEQVQDAIVcVmHfF1GvAAAAAElFTkSuQmCC");
}
/* Kacheln */
.gw-click--filter, .gw-click--go,
.ana-kpi.ana-fclick, .aut-stat--btn, a.jb-kpi,
a.ana-kpi, a.gw-kpi-card, a.anaw-kpi, a.pxw-kpi, a.dnssec-w-stat,
.stat-grid a.stat-card, a.td-stat, a.rd-card, a.sys-group { position: relative; cursor: pointer }
.gw-click--filter::after, .gw-click--go::after,
.ana-kpi.ana-fclick::after, .aut-stat--btn::after, a.jb-kpi::after,
a.ana-kpi::after, a.gw-kpi-card::after, a.anaw-kpi::after, a.pxw-kpi::after, a.dnssec-w-stat::after,
.stat-grid a.stat-card::after, a.td-stat::after, a.rd-card::after, a.sys-group::after {
  content: ""; position: absolute; top: 9px; right: 10px; width: 13px; height: 13px; pointer-events: none;
  background-color: var(--text-4); transition: background-color .15s;
  -webkit-mask: var(--gw-mark-go) center / contain no-repeat; mask: var(--gw-mark-go) center / contain no-repeat;
}
.gw-click--filter::after, .ana-kpi.ana-fclick:not(.gw-click--go)::after, .aut-stat--btn::after, a.jb-kpi::after {
  -webkit-mask-image: var(--gw-mark-filter); mask-image: var(--gw-mark-filter);
}
:is(.gw-click--filter, .gw-click--go, .ana-kpi.ana-fclick, .aut-stat--btn, a.jb-kpi, a.ana-kpi, a.gw-kpi-card,
    a.anaw-kpi, a.pxw-kpi, a.dnssec-w-stat, .stat-grid a.stat-card, a.td-stat, a.rd-card, a.sys-group):is(:hover, :focus-visible)::after,
:is(.ana-fclick--on, .is-on, .is-active).gw-click--filter::after,
.ana-kpi.ana-fclick--on::after, .aut-stat--btn.is-on::after, a.jb-kpi.is-on::after { background-color: var(--gw) }
/* .kpi-card (Dashboard) traegt sein › schon selbst in der Kopfzeile; .rd-card hat oben rechts den Balken. */
a.rd-card::after { top: auto; bottom: 8px }
/* Zeilen: jede <tr> mit Klick-Aktion (data-act ohne data-act-on), .gw-click, und die Zeilen, die ihr
   Skript per Listener klickbar macht (Liste aus der Bestandsaufnahme 21.09.2026 — neue Stellen
   nehmen .gw-click). Filter-Zeilen (Trichter): .gw-click--filter, [data-atk-ip], .pst-reprow. */
:is(tr[data-act]:not([data-act-on]), tr.gw-click, tr.health-row, tr.dm-row-click, tr.tlsrpt-rep-row, tr.apk-key-row,
    tr.tfa-row-open, tr.tf-row-open, tr.snp-row, tr.ak-row, tr.wh-row, tr.pa-row, tr.sec-clickable, tr.pst-drill,
    tr.pst-rq, tr.pst-mlrow, tr.pst-reprow, tr[data-mh-open], tr[data-fl-node], tr[data-bl-row], tr[data-st-row],
    tr[data-avp-row], tr[data-bl-kind], tr[data-atk-ip]) > td:last-child {
  /* !important: etliche Tabellen setzen padding inline (z.B. «Letzte Reports» im DMARC-Reiter) —
     ohne Vorrang lag das › ueber dem Zelltext. */
  position: relative; padding-right: 30px !important;
}
/* Kopf der letzten Spalte ruecken wie die Zellen darunter, sonst steht rechtsbuendiger Kopf
   20 px neben seinen Zahlen. */
table:has(> tbody > :is(tr[data-act]:not([data-act-on]), tr.gw-click, tr.health-row, tr.dm-row-click, tr.tlsrpt-rep-row,
    tr.apk-key-row, tr.tfa-row-open, tr.tf-row-open, tr.snp-row, tr.ak-row, tr.wh-row, tr.pa-row, tr.sec-clickable,
    tr.pst-drill, tr.pst-rq, tr.pst-mlrow, tr.pst-reprow, tr[data-mh-open], tr[data-fl-node], tr[data-bl-row],
    tr[data-st-row], tr[data-avp-row], tr[data-bl-kind], tr[data-atk-ip])) > thead > tr > th:last-child {
  padding-right: 30px !important;
}
/* Nicht klickbare Zeile in einer Tabelle mit klickbaren Zeilen (z.B. gesperrte Firewall): gleicher Abstand rechts
   wie dort, wo das › steht — sonst rutschen ihre Knöpfe aus der Spalte. */
table:has(> tbody > :is(tr[data-act]:not([data-act-on]), tr.gw-click, tr.health-row, tr.dm-row-click, tr.tlsrpt-rep-row,
    tr.apk-key-row, tr.tfa-row-open, tr.tf-row-open, tr.snp-row, tr.ak-row, tr.wh-row, tr.pa-row, tr.sec-clickable,
    tr.pst-drill, tr.pst-rq, tr.pst-mlrow, tr.pst-reprow, tr[data-mh-open], tr[data-fl-node], tr[data-bl-row],
    tr[data-st-row], tr[data-avp-row], tr[data-bl-kind], tr[data-atk-ip])) > tbody > tr > td:last-child {
  padding-right: 30px !important;
}
:is(tr[data-act]:not([data-act-on]), tr.gw-click, tr.health-row, tr.dm-row-click, tr.tlsrpt-rep-row, tr.apk-key-row,
    tr.tfa-row-open, tr.tf-row-open, tr.snp-row, tr.ak-row, tr.wh-row, tr.pa-row, tr.sec-clickable, tr.pst-drill,
    tr.pst-rq, tr.pst-mlrow, tr.pst-reprow, tr[data-mh-open], tr[data-fl-node], tr[data-bl-row], tr[data-st-row],
    tr[data-avp-row], tr[data-bl-kind], tr[data-atk-ip]) { cursor: pointer }
:is(tr[data-act]:not([data-act-on]), tr.gw-click, tr.health-row, tr.dm-row-click, tr.tlsrpt-rep-row, tr.apk-key-row,
    tr.tfa-row-open, tr.tf-row-open, tr.snp-row, tr.ak-row, tr.wh-row, tr.pa-row, tr.sec-clickable, tr.pst-drill,
    tr.pst-rq, tr.pst-mlrow, tr.pst-reprow, tr[data-mh-open], tr[data-fl-node], tr[data-bl-row], tr[data-st-row],
    tr[data-avp-row], tr[data-bl-kind], tr[data-atk-ip]) > td:last-child::after {
  content: ""; position: absolute; right: 10px; top: 50%; width: 13px; height: 13px; margin-top: -6.5px; pointer-events: none;
  background-color: var(--text-4); transition: background-color .15s;
  -webkit-mask: var(--gw-mark-go) center / contain no-repeat; mask: var(--gw-mark-go) center / contain no-repeat;
}
:is(tr.gw-click--filter, tr.pst-reprow, tr[data-atk-ip]) > td:last-child::after { -webkit-mask-image: var(--gw-mark-filter); mask-image: var(--gw-mark-filter) }
:is(tr[data-act]:not([data-act-on]), tr.gw-click, tr.health-row, tr.dm-row-click, tr.tlsrpt-rep-row, tr.apk-key-row,
    tr.tfa-row-open, tr.tf-row-open, tr.snp-row, tr.ak-row, tr.wh-row, tr.pa-row, tr.sec-clickable, tr.pst-drill,
    tr.pst-rq, tr.pst-mlrow, tr.pst-reprow, tr[data-mh-open], tr[data-fl-node], tr[data-bl-row], tr[data-st-row],
    tr[data-avp-row], tr[data-bl-kind], tr[data-atk-ip]):is(:hover, :focus-visible) > td:last-child::after { background-color: var(--gw) }
/* Listen-Eintraege, die keine Tabellenzeilen sind: › als letztes Element der Zeile (Flex-Zeilen) bzw.
   rechts mittig (Karten/Spalten-Zeilen). Bewusst aussen vor: das Paket-Widget (.pkg-row, feste Hoehe
   per Container) und die Benachrichtigungen (.notif-card, Raster mit wechselnder Spaltenzahl). */
.w-list a.w-row::after, .tc-row::after, a.sd-row-link::after {
  content: ""; flex: none; width: 12px; height: 12px; align-self: center; pointer-events: none;
  background-color: var(--text-4); transition: background-color .15s;
  -webkit-mask: var(--gw-mark-go) center / contain no-repeat; mask: var(--gw-mark-go) center / contain no-repeat;
}
.sess-row[data-act], .cl-item.is-clickable { position: relative; padding-right: 32px }
.sess-row[data-act]::after, .cl-item.is-clickable::after {
  content: ""; position: absolute; right: 12px; top: 50%; width: 12px; height: 12px; margin-top: -6px; pointer-events: none;
  background-color: var(--text-4); transition: background-color .15s;
  -webkit-mask: var(--gw-mark-go) center / contain no-repeat; mask: var(--gw-mark-go) center / contain no-repeat;
}
:is(.w-list a.w-row, .tc-row, a.sd-row-link, .sess-row[data-act], .cl-item.is-clickable):is(:hover, :focus-visible)::after { background-color: var(--gw) }
/* Analytics-Listen, die ein Detail oeffnen (Top-Hosts, Top-Pfade, Kontingent je Host,
   Sperr-Kandidaten …): › an derselben Stelle wie der Trichter der Filter-Zeilen (analytics.css). */
.ana-mbar:is(.pst-drill, .ana-pivot) .ana-mbar-val::after, .pst-tr-row::after {
  content: ""; flex: none; align-self: center; width: 11px; height: 11px; margin-left: 2px; pointer-events: none;
  background-color: var(--text-4); transition: background-color .12s;
  -webkit-mask: var(--gw-mark-go) center / contain no-repeat; mask: var(--gw-mark-go) center / contain no-repeat;
}
.pst-rep-sumcard[role="button"]::after {
  content: ""; flex: none; align-self: center; width: 11px; height: 11px; pointer-events: none;
  background-color: var(--text-4); transition: background-color .12s;
  -webkit-mask: var(--gw-mark-filter) center / contain no-repeat; mask: var(--gw-mark-filter) center / contain no-repeat;
}
.pst-bc-row[data-bc-row], .pst-rule-row[role="button"], .ptm-ban-row--clk { position: relative; padding-right: 30px }
.pst-bc-row[data-bc-row]::after, .pst-rule-row[role="button"]::after, .ptm-ban-row--clk::after {
  content: ""; position: absolute; right: 10px; top: 50%; width: 12px; height: 12px; margin-top: -6px; pointer-events: none;
  background-color: var(--text-4); transition: background-color .12s;
  -webkit-mask: var(--gw-mark-go) center / contain no-repeat; mask: var(--gw-mark-go) center / contain no-repeat;
}
.ana-mbar:is(.pst-drill, .ana-pivot):is(:hover, :focus-visible) .ana-mbar-val::after,
:is(.pst-tr-row, .pst-rep-sumcard[role="button"], .pst-rep-sumcard.is-active, .pst-bc-row[data-bc-row], .pst-rule-row[role="button"], .ptm-ban-row--clk):is(:hover, :focus-visible)::after,
.pst-rep-sumcard.is-active::after { background-color: var(--gw) }
/* Weitere ganze Zeilen/Karten mit Klick (Suche nach div[data-act], 21.09.2026): Propagation-Resolver,
   KEV-Katalog (Einstellungen), DMARC-Ausrichtungskarte. */
.kev-cat-row[data-act]::after {
  content: ""; flex: none; width: 12px; height: 12px; margin-left: auto; pointer-events: none;
  background-color: var(--text-4); transition: background-color .12s;
  -webkit-mask: var(--gw-mark-go) center / contain no-repeat; mask: var(--gw-mark-go) center / contain no-repeat;
}
.prop-row-head[data-act] { position: relative; padding-right: 32px }
.prop-row-head[data-act]::after, .dm-card-click::after {
  content: ""; position: absolute; right: 12px; top: 50%; width: 12px; height: 12px; margin-top: -6px; pointer-events: none;
  background-color: var(--text-4); transition: background-color .12s;
  -webkit-mask: var(--gw-mark-go) center / contain no-repeat; mask: var(--gw-mark-go) center / contain no-repeat;
}
.dm-card-click { position: relative }
.dm-card-click::after { top: 9px; right: 10px; margin-top: 0 }
:is(.kev-cat-row[data-act], .prop-row-head[data-act], .dm-card-click):is(:hover, :focus-visible)::after { background-color: var(--gw) }

/* ── Hilfe-Lasche rechts ─────────────────────────────────────────────
   Markup templates/layout/_help_drawer.php, Verhalten assets/js/help_drawer.js. Schmale Lasche am
   rechten Rand, senkrecht mittig; Klick schiebt die Schublade mit den passenden Anleitungen heraus.
   Kein Leuchten, kein Pulsieren. Farben nur ueber die Haus-Variablen (hell/dunkel). */
.gh-tab {
  position: fixed; right: 0; top: 50%; transform: translateY(-50%); z-index: 880;
  /* Etwas höher: mehr Luft oben/unten. */
  display: flex; flex-direction: column; align-items: center; gap: 11px;
  padding: 19px 5px 21px 4px; border: 1px solid var(--border); border-right: 0;
  border-radius: 10px 0 0 10px; background: var(--surface); color: var(--gw);
  box-shadow: -1px 1px 4px rgba(0,0,0,.06); cursor: pointer; font: inherit;
  transition: background-color .15s ease, padding .15s ease;
}
.gh-tab svg { width: 17px; height: 17px; flex-shrink: 0 }
.gh-tab__txt { writing-mode: vertical-rl; transform: rotate(180deg); font-size: 12.5px; font-weight: 600; letter-spacing: .4px; line-height: 1 }
.gh-tab:hover { background: var(--gw-light); padding-right: 6px }
.gh-tab:focus-visible { outline: 2px solid var(--gw); outline-offset: 2px }
body.gh-open .gh-tab { visibility: hidden }
/* Öffnet rechts ein Seitenfenster (Record-, Proxy-, Weiterleitungs-, Stream-Einstellungen)
   oder ein Dialog, verschwindet die Lasche; sie läge sonst über dem Fensterrand. Statische Dialoge stehen
   mit style="display:none" im Markup, dynamische (Weiterleitung #redirect-modal, zd.confirm) werden beim
   Schliessen entfernt: «nicht none» heisst also offen. */
body:has(.slide-panel.open, .zd-dlg-backdrop:not([style*="none"])) .gh-tab { opacity: 0; visibility: hidden; pointer-events: none }

.gh-backdrop {
  position: fixed; inset: 0; z-index: 1190; background: rgba(15,23,42,.18);
  opacity: 0; visibility: hidden; transition: opacity .2s ease, visibility 0s linear .2s;
}
.gh-backdrop.is-open { opacity: 1; visibility: visible; transition: opacity .2s ease }
/* Per Maus geöffnet (öffnet beim Darüberfahren, schliesst beim Wegfahren): kein
   Abdunkeln, die Seite bleibt bedienbar. Per Klick/Tastatur geöffnet bleibt es beim Abdunkeln. */
.gh-backdrop.is-open.is-hover { opacity: 0; visibility: hidden; pointer-events: none }

/* Schublade: leicht
   durchscheinender Hintergrund mit Weichzeichner, Kopf mit Symbol + Haus-Verlaufslinie, Suchfeld ab 5
   Einträgen, Einträge als Karten (Symbol-Kachel, 2 Zeilen, Pfeil rückt beim Hover), erster Eintrag als
   «Empfohlen», gestaffeltes Einblenden (--i aus help_drawer.js). Schatten neutral, nie farbig/leuchtend. */
.gh-drawer {
  position: fixed; top: 0; right: 0; bottom: 0; z-index: 1195;
  width: 400px; max-width: calc(100vw - 32px);
  display: flex; flex-direction: column;
  background: var(--surface); color: var(--text-1); border-left: 1px solid var(--border);
  box-shadow: -18px 0 48px -16px rgba(15,23,42,.22);
  transform: translateX(100%); visibility: hidden;
  transition: transform .28s cubic-bezier(.22,.8,.26,1), visibility 0s linear .28s;
}
@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .gh-drawer {
    background: color-mix(in srgb, var(--surface) 90%, transparent);
    -webkit-backdrop-filter: blur(18px) saturate(150%); backdrop-filter: blur(18px) saturate(150%);
  }
}
[data-theme="dark"] .gh-drawer { box-shadow: -18px 0 48px -16px rgba(0,0,0,.6) }
.gh-drawer.is-open { transform: none; visibility: visible; transition: transform .28s cubic-bezier(.22,.8,.26,1) }

.gh-head { position: relative; padding: 20px 18px 16px 20px; border-bottom: 1px solid var(--border) }
.gh-head::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -1px; height: 1px;
  background: linear-gradient(90deg, var(--gw) 0%, color-mix(in srgb, var(--gw) 35%, transparent) 45%, transparent 80%);
}
.gh-head__row { display: flex; align-items: center; gap: 12px }
.gh-head__icon {
  width: 38px; height: 38px; border-radius: 11px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center; color: var(--gw);
  background: linear-gradient(140deg, var(--gw-light) 0%, color-mix(in srgb, var(--gw-light) 35%, var(--surface)) 100%);
  border: 1px solid color-mix(in srgb, var(--gw) 22%, transparent);
}
.gh-head__icon svg { width: 19px; height: 19px }
.gh-head__txt { flex: 1; min-width: 0 }
.gh-kicker { font-size: 11.5px; font-weight: 600; color: var(--gw); letter-spacing: .2px; line-height: 1.3 }
.gh-title { margin: 1px 0 0; font-size: 17px; font-weight: 700; line-height: 1.3; letter-spacing: -.01em; color: var(--text-1); overflow-wrap: anywhere }
.gh-close {
  flex-shrink: 0; align-self: flex-start; width: 30px; height: 30px; display: flex; align-items: center; justify-content: center;
  border: 1px solid transparent; border-radius: 8px; background: transparent; color: var(--text-3); cursor: pointer;
  transition: background-color .15s ease, color .15s ease, border-color .15s ease;
}
.gh-close svg { width: 17px; height: 17px }
.gh-close:hover { background: var(--bg); border-color: var(--border); color: var(--text-1) }
.gh-close:focus-visible { outline: 2px solid var(--gw); outline-offset: 1px }

.gh-search { position: relative; margin-top: 14px }
.gh-search[hidden] { display: none !important }
.gh-search > svg { position: absolute; left: 11px; top: 50%; transform: translateY(-50%); width: 15px; height: 15px; color: var(--text-4); pointer-events: none }
.gh-search input {
  width: 100%; height: 36px; box-sizing: border-box; padding: 0 12px 0 34px;
  border: 1px solid var(--border); border-radius: 9px; background: var(--bg); color: var(--text-1);
  font: inherit; font-size: 13px; outline: none; transition: border-color .15s ease, background-color .15s ease, box-shadow .15s ease;
}
.gh-search input::placeholder { color: var(--text-4) }
.gh-search input:focus { border-color: var(--gw); background: var(--surface); box-shadow: 0 0 0 3px var(--gw-light) }

.gh-body { flex: 1; overflow-y: auto; padding: 12px 14px 14px; scrollbar-width: thin; scrollbar-color: var(--border) transparent }
.gh-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px }
.gh-list[hidden], .gh-list > li[hidden] { display: none !important }
.gh-list > li { opacity: 0; transform: translateX(10px); transition: opacity .12s ease, transform .12s ease }
.gh-drawer.is-open .gh-list > li {
  opacity: 1; transform: none;
  transition: opacity .26s ease, transform .3s cubic-bezier(.22,.8,.26,1);
  transition-delay: calc(90ms + var(--i, 0) * 28ms);
}
.gh-item {
  display: flex; align-items: center; gap: 12px; padding: 10px 12px;
  border: 1px solid color-mix(in srgb, var(--border) 75%, transparent); border-radius: 12px;
  background: var(--surface); text-decoration: none; color: inherit;
  transition: background-color .16s ease, border-color .16s ease;
}
.gh-item:hover, .gh-item:focus-visible {
  background: color-mix(in srgb, var(--gw-light) 60%, var(--surface));
  border-color: color-mix(in srgb, var(--gw) 38%, var(--border)); outline: none;
}
.gh-item:focus-visible { outline: 2px solid var(--gw); outline-offset: 1px }
.gh-item__icon {
  width: 36px; height: 36px; border-radius: 10px; flex-shrink: 0; align-self: flex-start;
  display: flex; align-items: center; justify-content: center; color: var(--gw);
  background: linear-gradient(140deg, var(--gw-light) 0%, color-mix(in srgb, var(--gw-light) 40%, var(--surface)) 100%);
  border: 1px solid color-mix(in srgb, var(--gw) 16%, transparent);
}
.gh-item__icon svg { width: 17px; height: 17px }
.gh-item__txt { flex: 1; display: flex; flex-direction: column; min-width: 0 }
.gh-item__title { font-size: 13.5px; font-weight: 600; color: var(--text-1); line-height: 1.35 }
.gh-item__desc {
  font-size: 12px; color: var(--text-3); line-height: 1.45; margin-top: 1px;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.gh-item__go { flex-shrink: 0; width: 16px; height: 16px; color: var(--text-4); transition: transform .18s ease, color .18s ease }
.gh-item__go svg { width: 16px; height: 16px; display: block }
.gh-item:hover .gh-item__go, .gh-item:focus-visible .gh-item__go { color: var(--gw); transform: translateX(3px) }
.gh-item__badge { display: inline-block; margin-left: 4px; padding: 0 6px; border-radius: 999px; background: var(--bg); border: 1px solid var(--border); color: var(--text-3); font-size: 10.5px; font-weight: 600; line-height: 16px; vertical-align: 1px; white-space: nowrap }
/* Erster Eintrag = wichtigste Anleitung der Seite */
.gh-item--top {
  padding: 12px;
  background: linear-gradient(160deg, color-mix(in srgb, var(--gw-light) 80%, var(--surface)) 0%, var(--surface) 75%);
  border-color: color-mix(in srgb, var(--gw) 30%, var(--border));
}
.gh-item--top .gh-item__icon { width: 40px; height: 40px; border-radius: 11px; background: var(--gw); border-color: transparent; color: #fff }
.gh-item--top .gh-item__icon svg { width: 19px; height: 19px }
.gh-item--top .gh-item__title { font-size: 14px }
.gh-item__rec {
  align-self: flex-start; display: inline-flex; align-items: center; gap: 4px; margin-bottom: 4px;
  padding: 0 8px 0 6px; border-radius: 999px; font-size: 10.5px; font-weight: 600; line-height: 16px;
  color: var(--gw); background: var(--surface); border: 1px solid color-mix(in srgb, var(--gw) 30%, var(--border));
}
.gh-item__rec svg { width: 11px; height: 11px }

.gh-empty { display: flex; flex-direction: column; align-items: center; gap: 8px; padding: 36px 12px; color: var(--text-3); font-size: 13px; text-align: center }
.gh-empty[hidden] { display: none !important }
.gh-empty svg { width: 22px; height: 22px; color: var(--text-4) }

.gh-foot {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 14px 18px 16px 20px; border-top: 1px solid var(--border);
  background: color-mix(in srgb, var(--bg) 45%, transparent);
}
.gh-all {
  display: inline-flex; align-items: center; gap: 8px; height: 36px; padding: 0 12px 0 14px; border-radius: 9px;
  background: var(--gw); color: #fff; font-size: 13px; font-weight: 600; text-decoration: none; white-space: nowrap;
  transition: background-color .15s ease;
}
.gh-all svg { width: 16px; height: 16px }
.gh-all .gh-all__go { transition: transform .18s ease }
.gh-all:hover { background: color-mix(in srgb, var(--gw) 86%, #000); color: #fff; text-decoration: none }
.gh-all:hover .gh-all__go { transform: translateX(3px) }
.gh-all:focus-visible { outline: 2px solid var(--gw); outline-offset: 2px }
.gh-hint { display: inline-flex; align-items: center; gap: 6px; font-size: 11.5px; color: var(--text-4); white-space: nowrap }
.gh-hint kbd {
  font: inherit; font-size: 10.5px; font-weight: 600; line-height: 1; padding: 3px 6px; border-radius: 5px;
  color: var(--text-3); background: var(--surface); border: 1px solid var(--border); border-bottom-width: 2px;
}
/* Leseansicht: eine Anleitung in der Schublade lesen. Die Schublade wird breiter; die Bildspalte
   der Anleitung bricht in der schmalen Fläche von selbst unter den Text (@container ≤ 720px oben), hier in voller
   Breite untereinander, damit man sie lesen kann. Kein iframe (Firefox, Mobil-Sperre im Rahmen). */
.gh-drawer.is-reading { width: 660px }
/* Nebeneinander (der empfohlene Beitrag direkt rechts von der Liste): links Kopf, Themen und Fuss wie gewohnt, rechts die Anleitung über die volle Höhe. Nur wo beides Platz hat
   (help_drawer.js SPLIT_MIN), sonst schaltet die Schublade zwischen Liste und Anleitung um. */
.gh-drawer.is-split { width: min(1060px, calc(100vw - 32px)); display: grid; grid-template-columns: 380px minmax(0, 1fr); grid-template-rows: auto minmax(0, 1fr) auto }
.gh-drawer.is-split .gh-head { grid-column: 1; grid-row: 1 }
.gh-drawer.is-split .gh-body { grid-column: 1; grid-row: 2 }
.gh-drawer.is-split .gh-foot { grid-column: 1; grid-row: 3; flex-wrap: wrap }
.gh-drawer.is-split .gh-reader { grid-column: 2; grid-row: 1 / 4; border-left: 1px solid var(--border); min-width: 0 }
.gh-drawer.is-split .gh-reader__back { display: none }
.gh-reader__title { display: none }
.gh-drawer.is-split .gh-reader__title { display: block; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 14px; font-weight: 700; color: var(--text-1) }
.gh-drawer.is-split .gh-reader__bar { padding: 14px 16px 12px 20px; min-height: 56px }
.gh-item.is-active { background: color-mix(in srgb, var(--gw-light) 70%, var(--surface)); border-color: color-mix(in srgb, var(--gw) 55%, var(--border)); box-shadow: inset 3px 0 0 var(--gw) }
.gh-body[hidden], .gh-reader[hidden] { display: none }
.gh-reader { flex: 1; min-height: 0; display: flex; flex-direction: column }
.gh-reader__bar { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 10px 14px 10px 16px; border-bottom: 1px solid var(--border) }
.gh-reader__back, .gh-reader__full {
  display: inline-flex; align-items: center; gap: 6px; height: 30px; padding: 0 10px; border-radius: 8px; font: inherit; font-size: 12.5px;
  font-weight: 600; color: var(--text-2); background: var(--surface); border: 1px solid var(--border); text-decoration: none; cursor: pointer; white-space: nowrap;
}
.gh-reader__back svg, .gh-reader__full svg { width: 14px; height: 14px; flex: none }
.gh-reader__acts { display: inline-flex; gap: 6px; margin-left: auto }
.gh-reader__back:hover, .gh-reader__full:hover { color: var(--gw); border-color: color-mix(in srgb, var(--gw) 45%, var(--border)); text-decoration: none }
.gh-reader__back:focus-visible, .gh-reader__full:focus-visible { outline: 2px solid var(--gw); outline-offset: 2px }
.gh-reader__doc { flex: 1; min-height: 0; overflow-y: auto; padding: 16px 18px 28px; outline: none; scrollbar-width: thin; scrollbar-color: var(--border) transparent }
.gh-reader__doc .qs-section:first-of-type { margin-top: 0 }
.gh-reader__doc .gd-shot-stack { flex-direction: column }
.gh-reader__doc .gd-shot-stack .gd-shot--thumb { width: 100% }
.gh-reader__doc .gd-shots .gd-shot { max-width: 100% }

/* Alle Anleitungs-Tabellen ab 3 Spalten (guide-tables.js setzt .qs-table--stack + data-label) in schmalen Flächen als
   Karten (in der Hilfe-Lasche brach «Wann nehmen?» sonst nach jedem Wort um). Je Zeile eine Karte: die
   erste Spalte ist ihr Titel (ohne Beschriftung), darunter Beschriftung links und Wert rechts, eine Linie zwischen den
   Karten und keine darin (die Seiten-Regeln
   .qs-table td/tr:last-child td aus _user_styles.php stehen nach main.css; darum doppelte Klasse = höhere Spezifität).
   Unter 380 px steht die Beschriftung wieder über dem Wert. Hilfe-Lasche: Container ghdoc, Handy: Viewport.
   Beschriftung als Float in einem flow-root: absolut gesetzt wuchs die Zeile
   nicht mit — zweizeilige Beschriftungen lagen über der nächsten, «Angriffskampagne» lief in den Wert. Breite mit der
   Fläche (30 %, 106–170 px), lange Wörter trennen. */
/* Spaltenbreiten der Anleitungs-Tabellen (guide-tables.js, 07.10.2026): kurze Spalten einzeilig (.gt-nw), solange alles
   passt. .gt-m-max/.gt-m-min nur für die Messung (einzeilig bzw. so schmal wie möglich; feste Inline-Breiten aus). */
table.gt-m-max { width: max-content !important; max-width: none !important; table-layout: auto !important; }
table.gt-m-max td { white-space: nowrap !important; } table.gt-m-max th, table.gt-m-max td { width: auto !important; }
table.gt-m-min { width: min-content !important; table-layout: auto !important; }
table.gt-m-min th, table.gt-m-min td { width: auto !important; }
.gt-nw { white-space: nowrap; }
/* Tabelle liefe über: lange Code-Felder brechen an ihren Trennstellen (<wbr> nach _ . / -), sonst bleiben sie einzeilig. */
table.gt-weich td code, table.gt-weich td code[data-cp-done][data-cp-done] { white-space: normal; }
/* Ohne Überlauf sind die Trennstellen aus — alle übrigen Tabellen bleiben exakt wie vorher. */
table:not(.gt-weich) td code wbr { display: none; }
.gh-reader__doc { container: ghdoc / inline-size; }
@container ghdoc (max-width: 720px) {
  table.qs-table--stack, table.qs-table--stack > tbody { display: block; width: auto; }
  table.qs-table--stack > thead, table.qs-table--stack .qs-table__head { display: none; }
  table.qs-table--stack.qs-table--stack tr { display: block; padding: 12px 16px; border-bottom: 1px solid var(--border); }
  table.qs-table--stack.qs-table--stack tr:last-child { border-bottom: none; }
  table.qs-table--stack.qs-table--stack tr td { display: flow-root; border: 0; padding: 3px 0 3px calc(var(--gt-lw) + 12px); min-height: 22px;
    --gt-lw: clamp(106px, 30cqw, 170px); }
  table.qs-table--stack.qs-table--stack tr td[data-label]::before { content: attr(data-label); float: left; width: var(--gt-lw);
    margin: 3px 0 0 calc(-1 * (var(--gt-lw) + 12px)); white-space: normal; overflow-wrap: anywhere; hyphens: auto;
    font-size: 10.5px; font-weight: 700; letter-spacing: .4px; line-height: 1.3; text-transform: uppercase; color: var(--text-3); }
  table.qs-table--stack.qs-table--stack tr td:first-child { padding: 0 0 6px; font-weight: 650; color: var(--text-1); }
  table.qs-table--stack.qs-table--stack tr td:first-child::before { content: none; }
}
@container ghdoc (max-width: 380px) {
  table.qs-table--stack.qs-table--stack tr td { padding-left: 0; }
  table.qs-table--stack.qs-table--stack tr td[data-label]::before { float: none; display: block; width: auto; margin: 0 0 1px; }
}
@media (max-width: 720px) {
  table.qs-table--stack, table.qs-table--stack > tbody { display: block; width: auto; }
  table.qs-table--stack > thead, table.qs-table--stack .qs-table__head { display: none; }
  table.qs-table--stack.qs-table--stack tr { display: block; padding: 12px 16px; border-bottom: 1px solid var(--border); }
  table.qs-table--stack.qs-table--stack tr:last-child { border-bottom: none; }
  table.qs-table--stack.qs-table--stack tr td { display: flow-root; border: 0; padding: 3px 0 3px calc(var(--gt-lw) + 12px); min-height: 22px;
    --gt-lw: clamp(106px, 30vw, 170px); }
  table.qs-table--stack.qs-table--stack tr td[data-label]::before { content: attr(data-label); float: left; width: var(--gt-lw);
    margin: 3px 0 0 calc(-1 * (var(--gt-lw) + 12px)); white-space: normal; overflow-wrap: anywhere; hyphens: auto;
    font-size: 10.5px; font-weight: 700; letter-spacing: .4px; line-height: 1.3; text-transform: uppercase; color: var(--text-3); }
  table.qs-table--stack.qs-table--stack tr td:first-child { padding: 0 0 6px; font-weight: 650; color: var(--text-1); }
  table.qs-table--stack.qs-table--stack tr td:first-child::before { content: none; }
}
@media (max-width: 380px) {
  table.qs-table--stack.qs-table--stack tr td { padding-left: 0; }
  table.qs-table--stack.qs-table--stack tr td[data-label]::before { float: none; display: block; width: auto; margin: 0 0 1px; }
}
.gh-reader__err { padding: 18px 4px; font-size: 13px; color: var(--text-3) }
/* Treffer der Suche: Liste unter dem Feld, über der Themenliste. «Lösungen» = Abschnitte der vorgeschlagenen
   Anleitungen, darunter alle Anleitungen im Stil des Suchbalkens der Anleitungen. */
.gh-results {
  position: absolute; left: 0; right: 0; top: calc(100% + 6px); z-index: 5; max-height: min(66vh, 560px); overflow-y: auto;
  padding: 6px; background: var(--surface); border: 1px solid var(--border); border-radius: 10px;
  box-shadow: 0 12px 32px rgba(15,23,42,.14); scrollbar-width: thin;
}
[data-theme="dark"] .gh-results { box-shadow: 0 12px 32px rgba(0,0,0,.5) }
.gh-results[hidden] { display: none }
.gh-res__head { padding: 8px 8px 4px; font-size: 11px; font-weight: 700; letter-spacing: .4px; text-transform: uppercase; color: var(--text-4) }
.gh-res__head + .gh-res { margin-top: 0 }
.gh-res { display: flex; align-items: center; gap: 10px; padding: 7px 8px; border-radius: 8px; color: var(--text-1); text-decoration: none }
.gh-res:hover, .gh-res.is-kb { background: color-mix(in srgb, var(--gw) 8%, transparent); text-decoration: none }
.gh-res.is-kb { box-shadow: inset 3px 0 0 var(--gw) }
.gh-res--sol { flex-direction: column; align-items: stretch; gap: 1px; padding-left: 12px; border-left: 2px solid color-mix(in srgb, var(--gw) 35%, var(--border)); border-radius: 0 8px 8px 0; margin: 2px 0 2px 4px }
.gh-res__ico { width: 28px; height: 28px; border-radius: 7px; flex: none; display: flex; align-items: center; justify-content: center;
  background: color-mix(in srgb, var(--cat) 12%, transparent); color: var(--cat) }
[data-theme="dark"] .gh-res__ico { background: color-mix(in srgb, var(--cat) 24%, transparent); color: color-mix(in srgb, var(--cat) 55%, #fff) }
.gh-res__ico svg { width: 15px; height: 15px }
.gh-res__txt { flex: 1; min-width: 0; display: flex; flex-direction: column }
.gh-res__g { font-weight: 500; color: var(--text-4) }
.gh-res__t { font-size: 13px; font-weight: 600; line-height: 1.3; overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
.gh-res__d { font-size: 12px; color: var(--text-3); line-height: 1.4; overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
.gh-res mark { background: color-mix(in srgb, var(--gw) 16%, transparent); color: inherit; border-radius: 3px; padding: 0 1px }
.gh-res__more { display: flex; justify-content: space-between; gap: 8px; margin-top: 4px; padding: 8px 10px; border-top: 1px solid var(--border);
  font-size: 12.5px; font-weight: 600; color: var(--gw); text-decoration: none }
.gh-res__more:hover { text-decoration: none; background: color-mix(in srgb, var(--gw) 6%, transparent) }
.gh-res__none { padding: 16px 10px; font-size: 13px; color: var(--text-3); text-align: center }
.gh-res__skel { padding: 6px }

@media (hover: none) { .gh-hint { display: none } }
@media (max-width: 640px) {
  .gh-tab { padding: 8px 3px 10px }
  .gh-tab__txt { font-size: 10.5px }
}
@media (prefers-reduced-motion: reduce) {
  .gh-drawer, .gh-drawer.is-open, .gh-backdrop, .gh-backdrop.is-open, .gh-tab { transition: none }
  .gh-list > li, .gh-drawer.is-open .gh-list > li { opacity: 1; transform: none; transition: none }
  .gh-item__go, .gh-all .gh-all__go { transition: none }
}
/* «Weiterlesen» am Ende einer Anleitung (GuidesController::moreBlock, 25.09.2026). */
.gd-more { margin:28px 0 8px; padding-top:18px; border-top:1px solid var(--border) }
.gd-more__t { font-size:16px; font-weight:700; color:var(--text-1); margin:0 0 12px }
.gd-more__g { display:grid; grid-template-columns:repeat(auto-fill, minmax(240px, 1fr)); gap:10px }
.gd-more__c { display:flex; gap:10px; align-items:flex-start; padding:12px 14px; border:1px solid var(--border); border-radius:10px; background:var(--surface); text-decoration:none; color:inherit }
.gd-more__c:hover { border-color:var(--gw); text-decoration:none }
.gd-more__c svg { flex:none; width:18px; height:18px; color:var(--gw); margin-top:2px }
.gd-more__c b { display:block; font-size:13.5px; color:var(--text-1); margin-bottom:2px }
.gd-more__c small { display:block; font-size:12px; line-height:1.45; color:var(--text-3) }
@media print { .gd-more { display:none } }

/* Glossar-Begriffe im Text (guide-glossar.js, 25.09.2026): gepunktet unterstrichen, Farbe des Fliesstexts — ein
   Hinweis, kein zweiter Link-Stil; Hover/Fokus in Hausfarbe. Druck: normaler Text. */
.gw-gl { color:inherit; text-decoration:underline dotted; text-decoration-color:color-mix(in srgb, var(--gw, #0098ef) 70%, transparent);
  text-decoration-thickness:1.5px; text-underline-offset:3px; cursor:help }
.gw-gl:hover, .gw-gl:focus-visible { color:var(--gw, #0098ef); text-decoration-color:currentColor; text-decoration-style:solid }
@media print { .gw-gl { text-decoration:none; color:inherit } }
/* Links im Anleitungstext ohne eigene Klasse (z.B. dnsviz.net, Anker-Sprünge) standen im Browser-Standardblau mit
   Unterstrich: Hausblau, Unterstrich erst beim Überfahren; externe Ziele mit kleinem ↗.
   Ausgenommen: Links im Begriffsnetz-SVG (.gd-terms) und die Pillen .qs-toc — die haben ihren eigenen Stil. */
:where(.gd-body, #ghDoc) a:not([class]):where(:not(svg a, .qs-toc a)) { color:var(--gw, #0098ef); text-decoration:none }
:where(.gd-body, #ghDoc) a:not([class]):where(:not(svg a, .qs-toc a)):is(:hover, :focus-visible) { text-decoration:underline; text-underline-offset:2px }
:where(.gd-body, #ghDoc) a:not([class]):where(:not(svg a, .qs-toc a))[href^="http"]::after { content:"↗"; display:inline-block; margin-left:2px; font-size:.8em; line-height:1; opacity:.75; text-decoration:none }
@media print { :where(.gd-body, #ghDoc) a:not([class]):where(:not(svg a, .qs-toc a)) { color:inherit; text-decoration:underline } :where(.gd-body, #ghDoc) a:not([class]):where(:not(svg a, .qs-toc a))[href^="http"]::after { content:none } }

/* Anker-Link je Abschnitt (GuideAnchors, 25.09.2026): rechts im Abschnittskopf, dezent; Häkchen nach dem Kopieren. */
.qs-section__head > .gd-anchor { order:9; margin-left:auto }
.gd-anchor { flex:none; display:inline-flex; align-items:center; justify-content:center; width:30px; height:30px; padding:0; border:1px solid transparent;
  border-radius:8px; background:none; color:var(--text-4); cursor:pointer }
.gd-anchor:hover, .gd-anchor:focus-visible { color:var(--gw, #0098ef); border-color:var(--border); background:var(--surface) }
.gd-anchor .gd-anchor__ok { display:none }
.gd-anchor.is-done { color:var(--ok, #16a34a) }
.gd-anchor.is-done .gd-anchor__ok { display:inline }
.gd-anchor.is-done .gd-anchor__link { display:none }
@media print { .gd-anchor { display:none !important } }

/* «Auf einen Blick» oben in jeder Anleitung: Mindestrolle und nötige Funktion (GuideMeta, 25.09.2026). */
.gd-meta { display:flex; flex-wrap:wrap; align-items:center; gap:6px 16px; margin:0 0 14px; padding:8px 12px; border-radius:10px;
  border:1px solid color-mix(in srgb, var(--gw) 22%, var(--border)); background:color-mix(in srgb, var(--gw) 5%, var(--surface)); font-size:12.5px; color:var(--text-2) }
.gd-meta__h { font-size:10.5px; font-weight:750; text-transform:uppercase; letter-spacing:.07em; color:var(--text-4) }
.gd-meta__i { display:inline-flex; align-items:center; gap:6px }
.gd-meta__i svg { flex:none; color:var(--gw) }
.gd-meta b { color:var(--text-1); font-weight:650 }

/* Druckansicht (Anleitungs-Prüfung 25.09.2026): gedruckt wird nur die Anleitung selbst — ohne Seitenleiste, Kopfzeile,
   Anleitungs-Suche, Navigationsbaum und Inhaltsleiste, immer in der hellen Fassung (app.js nimmt den Dunkelmodus für den
   Druck zurück), und ohne dass ein Abschnitt, Bild oder Schritt mitten durch die Seite bricht. */
@media print {
  .gh-tab, .gh-drawer, .gh-backdrop, .sidebar, .topbar, #guidesSearchBar, .gw-stick-sentinel, .gd-nav, .gd-toc,
  .notif-toast-stack, .toast-container, .qs-pre__copy, .zo-bar, .zo-tip, .gw-uq { display: none !important }
  html, body { background: #fff !important }
  /* Ein paar Pixel Luft: Kastenränder rechts und der erste Buchstabe links wurden sonst an der Blattkante abgeschnitten. */
  .gd-body { display: block !important; margin: 0 !important; padding: 0 3px !important; width: auto !important; max-width: none !important; overflow: visible !important }
  *, *::before, *::after { box-sizing: border-box }
  .app-shell, .app-main, .gd-layout { display: block !important; margin: 0 !important; padding: 0 !important;
    width: auto !important; max-width: none !important; overflow: visible !important; box-shadow: none !important }
  .gd-shot__img--dark { display: none !important }
  .gd-shot__img--light { display: block !important }
  /* Der blaue Kopf druckt ohne «Hintergrundgrafiken» weiss — weisser Text wäre dann unsichtbar. */
  .qs-hero { background: none !important; color: #0b1a2b !important; border: 1px solid #c7d2df; box-shadow: none !important }
  .qs-hero__icon, .qs-hero__badge { background: none !important; border: 1px solid #c7d2df }
  /* Kleine Bausteine nicht trennen; ganze Abschnitte schon — sonst springt ein langer Abschnitt auf die nächste Seite und
     lässt eine fast leere zurück. */
  .qs-card, .gd-shot, .zo-map, .zo-legend__item, ol.qs-steps > li, figure, .qs-tip, .qs-warn, .qs-info, .qs-rec, .wc-bsp, .wc-bp { break-inside: avoid }
  .qs-section__head { break-after: avoid }
  .zo-area { display: none !important }
  /* Nichts abschneiden: Bilder und Rahmen nie breiter als das Blatt,
     Tabellen und Code umbrechen statt scrollen, die Bildspalte steht auf Papier unter dem Text. */
  img, svg, figure, .gd-shot, .zo-map, .qs-card, .wc-fn, table { max-width: 100% !important }
  .gd-shot { width: auto !important }
  .gd-shot img, .zo-map img { height: auto !important }
  pre, .qs-pre, .qs-card pre { white-space: pre-wrap !important; word-break: break-word; overflow: visible !important }
  .wc-tbw, .gw-table-scroll, .gd-body, .qs-section__body { overflow: visible !important }
  table { width: 100% !important; table-layout: auto }
  .gd-shot-cols { display: block !important }
  .gd-shot-stack { position: static !important; max-width: 100% !important; margin-top: 10px }
  .gd-shot-stack--deck .gd-deck__strip, .gd-shot-stack--deck .gd-deck__ctl { display: none !important }
  .gd-shot-stack--deck .gd-deck__item > * { visibility: visible !important }
  .gd-shot-stack--deck .gd-deck__item { display: block !important; position: static !important; opacity: 1 !important; transform: none !important; box-shadow: none !important }
  .gd-shot-stack--deck .gd-deck__item .gd-shot__cap { visibility: visible !important }
  /* Drucken aus der Hilfe-Lasche (html.gw-print-drawer, help_drawer.js): nur die geöffnete Anleitung, kein zweiter Tab. */
  html.gw-print-drawer body > *:not(.gh-drawer) { display: none !important }
  html.gw-print-drawer .gh-drawer { display: block !important; position: static !important; transform: none !important;
    visibility: visible !important; width: auto !important; max-width: none !important; box-shadow: none !important; border: 0 !important; background: #fff !important }
  html.gw-print-drawer .gh-head, html.gw-print-drawer .gh-body, html.gw-print-drawer .gh-foot, html.gw-print-drawer .gh-reader__bar { display: none !important }
  html.gw-print-drawer .gh-reader, html.gw-print-drawer .gh-reader__doc { display: block !important; overflow: visible !important; height: auto !important; padding: 0 3px !important; border: 0 !important; box-shadow: none !important }
}
/* Seitenränder auf dem Blatt. */
@page { margin: 16mm 14mm }

/* Übersichtsbilder mit Nummern in den Anleitungen (templates/guides/_overview_map.php, guide-map.js; 25.09.2026).
   Hier statt in der Vorlage, damit Seite und Hilfe-Lasche denselben Stil haben. */
.zo-map { margin:4px 0 0; border:1px solid var(--border); border-radius:12px; background:var(--surface) }
/* Kein overflow:hidden am Rahmen: die Blase darf über den Bildrand auf die Seite ragen (25.09.2026). Die Ecken runden
   darum Leiste, Bild und Abdunkelung selbst. */
.zo-map .zo-bar { border-radius:11px 11px 0 0 }
.zo-map__img, .zo-dim { border-radius:0 0 11px 11px }
.zo-map__frame { position:relative; line-height:0; container-type:inline-size }
.zo-map__img { display:block; width:100%; height:auto }
.zo-map__img.gd-shot__img--dark { display:none }
[data-theme="dark"] .zo-map__img.gd-shot__img--light { display:none }
[data-theme="dark"] .zo-map__img.gd-shot__img--dark { display:block }
/* Scheinwerfer: ein Element je Bild, das von Bereich zu Bereich gleitet (guide-map.js setzt left/top/width/height aus
   der .zo-area-Box). Alles ausserhalb wird abgedunkelt (70 %; 55 % war zu schwach), der Bereich bekommt
   einen hellen und einen dunklen Rand — ein blauer Rahmen allein ging auf blauen Knöpfen unter. .zo-dim schneidet die
   Abdunkelung am Bildrand ab, sonst lag sie über der Leiste. .zo-area bleibt unsichtbar: nur Mass und Anker. */
/* Farbe der Nummern und des Scheinwerfer-Rands (nicht blau, weil vieles im Bild selbst
   blau ist, z.B. Knöpfe und Rahmen). Magenta kommt in der App-Oberfläche nicht vor und hebt sich hell wie dunkel ab;
   Nummer im Bild, in der Sprechblase und in der Druckliste tragen dieselbe Farbe. */
:root { --zo-mark:#d0197a }
[data-theme="dark"] { --zo-mark:#d42a7c }
.zo-area { position:absolute; pointer-events:none; visibility:hidden }
/* Hineinzoomen auf den gewählten Bereich (die Schrift im verkleinerten Bild war kaum lesbar).
   guide-map.js setzt transform und --zo-s auf beide Ebenen (Bild + Nummern); die Nummern schrumpfen gegen, damit sie
   gleich gross bleiben. Beim Zoom schneidet der Rahmen ab — die Blase liegt ausserhalb und darf weiter überstehen. */
.zo-zoom { position:relative; transform-origin:0 0; transition:transform .45s cubic-bezier(.4,0,.2,1) }
.zo-zoom--pins { position:absolute; inset:0; z-index:2; pointer-events:none }
.zo-zoom--pins .zo-pin { pointer-events:auto }
.zo-map.is-zoom .zo-map__frame { overflow:hidden; border-radius:0 }   /* unten folgt die Fusszeile .zo-note */
@media (prefers-reduced-motion: reduce) { .zo-zoom { transition:none } }
@media print { .zo-zoom { transform:none !important; --zo-s:1 !important } }
.zo-dim { position:absolute; inset:0; overflow:hidden; pointer-events:none; z-index:1 }
.zo-spot { position:absolute; border-radius:10px; opacity:0; transition:opacity .2s ease;
  box-shadow:0 0 0 2px #fff, 0 0 0 4px var(--zo-mark), 0 0 0 100vmax rgba(15,23,42,.66) }
.zo-map.is-spot .zo-spot { opacity:1; transition:opacity .2s ease, left .45s cubic-bezier(.4,0,.2,1), top .45s cubic-bezier(.4,0,.2,1),
  width .45s cubic-bezier(.4,0,.2,1), height .45s cubic-bezier(.4,0,.2,1) }
/* Grösse wächst mit der Bildbreite (cqw): bei schmalem Bild sonst gedrängt, die Nummern der Kopfzeile stehen dicht. */
.zo-pin { position:absolute; transform:translate(-50%,-50%) scale(calc(1 / var(--zo-s, 1))); width:clamp(16px, 2cqw, 24px); height:clamp(16px, 2cqw, 24px); padding:0;
  border-radius:50%; border:2px solid var(--surface); background:var(--zo-mark); color:#fff; font-weight:700;
  font-size:clamp(9px, 1cqw, 12px); line-height:1; display:flex; align-items:center; justify-content:center;
  cursor:pointer; box-shadow:0 1px 3px rgba(15,23,42,.35); z-index:2; transition:transform .45s cubic-bezier(.4,0,.2,1), background .15s }
.zo-pin:hover, .zo-pin.is-on { background:var(--text-1); color:var(--surface) }
.zo-pin.is-on { transform:translate(-50%,-50%) scale(calc(1.2 / var(--zo-s, 1))); background:var(--zo-mark); color:#fff; border-color:#fff }
.zo-map.is-spot .zo-pin:not(.is-on) { opacity:.55 }
.zo-map.is-spot .zo-pin:not(.is-on):hover { opacity:1 }
.zo-pin:focus-visible { outline:2px solid var(--text-1); outline-offset:2px }

/* Leiste über dem Bild wie ein Player: runder Abspiel-Knopf, ‹ ›, je Nummer ein Segment (das aktuelle füllt sich im
   Takt von 4,5 s wie Takt in guide-map.js), Stand «3 / 9». */
.zo-map { position:relative; container-type:inline-size; container-name:zomap }
.zo-map:has(.zo-tip.is-open) { z-index:15 }
.zo-bar { display:flex; align-items:center; gap:8px; padding:10px 12px; border-bottom:1px solid var(--border); background:var(--surface) }
.zo-bar button { font:inherit; cursor:pointer }
.zo-bar__play { flex:none; display:inline-flex; align-items:center; gap:8px; height:32px; padding:0 14px 0 6px; border:0; border-radius:999px;
  background:var(--gw); color:#fff; font-size:12.5px; font-weight:650; white-space:nowrap; transition:filter .15s }
.zo-bar__play:hover { filter:brightness(1.08) }
.zo-bar__play:focus-visible, .zo-bar__nav:focus-visible, .zo-seg:focus-visible { outline:2px solid var(--gw); outline-offset:2px }
.zo-bar__i-play, .zo-bar__i-pause { width:22px; height:22px; border-radius:50%; background:rgba(255,255,255,.2); align-items:center; justify-content:center }
.zo-bar__i-play { display:inline-flex; padding-left:1px }
.zo-bar__i-pause, .zo-map.is-playing .zo-bar__i-play { display:none }
.zo-map.is-playing .zo-bar__i-pause { display:inline-flex }
.zo-bar__nav { flex:none; width:30px; height:30px; padding:0; border:1px solid var(--border); border-radius:50%; background:var(--surface);
  color:var(--text-2); display:inline-flex; align-items:center; justify-content:center; transition:background .15s, color .15s }
.zo-bar__nav:hover { background:var(--bg); color:var(--text-1) }
.zo-bar__segs { flex:1; min-width:60px; display:flex; gap:3px; align-items:center }
.zo-seg { flex:1; min-width:4px; height:18px; padding:0; border:0; background:transparent; display:flex; align-items:center }
.zo-seg i { display:block; width:100%; height:4px; border-radius:2px; background:color-mix(in srgb, var(--text-3) 28%, transparent);
  position:relative; overflow:hidden; transition:height .15s }
.zo-seg:hover i { height:6px }
.zo-seg i::after { content:''; position:absolute; inset:0; width:0; background:var(--gw); border-radius:inherit }
.zo-seg.is-done i::after, .zo-seg.is-cur i::after { width:100% }
.zo-seg.is-run i::after { animation:zo-seg 4.5s linear forwards }
@keyframes zo-seg { from { width:0 } to { width:100% } }
.zo-bar__pos { flex:none; font-size:12px; font-weight:650; color:var(--text-2); min-width:46px; text-align:right; font-variant-numeric:tabular-nums; white-space:nowrap }
@container zomap (max-width: 520px) { .zo-bar__lbl { display:none } .zo-bar__play { padding:0 5px } }

/* Sprechblase: Inhalt kommt aus dem Legenden-Eintrag. Schwebend neben dem Bereich (Lage und Pfeil rechnet
   guide-map.js, sie gleitet mit dem Scheinwerfer). Passt sie nicht ins Bild, hängt sie darunter über den Bildrand
   hinaus — darum hebt .zo-map mit offener Blase sich über den folgenden Inhalt. */
.zo-tip { position:absolute; z-index:20; box-sizing:border-box; padding:16px 16px 12px; border:1px solid color-mix(in srgb, var(--border) 80%, transparent); border-radius:14px;
  background:var(--surface);
  box-shadow:0 24px 48px -16px rgba(15,23,42,.5), 0 2px 8px rgba(15,23,42,.12); line-height:1.5;
  opacity:0; visibility:hidden; transform:translateY(4px);
  transition:opacity .2s ease, transform .2s ease, visibility 0s linear .2s, left .45s cubic-bezier(.4,0,.2,1), top .45s cubic-bezier(.4,0,.2,1) }
.zo-tip.is-open { opacity:1; visibility:visible; transform:none;
  transition:opacity .2s ease, transform .2s ease, visibility 0s, left .45s cubic-bezier(.4,0,.2,1), top .45s cubic-bezier(.4,0,.2,1) }
.zo-tip.no-move { transition:none }
.zo-tip__arrow { position:absolute; width:12px; height:12px; background:var(--surface); border:1px solid var(--border); display:none }
.zo-tip[data-side] .zo-tip__arrow { display:block }
.zo-tip[data-side="r"] .zo-tip__arrow { left:-7px; top:calc(var(--zo-arrow, 24px) - 6px); transform:rotate(45deg); border-width:0 0 1px 1px }
.zo-tip[data-side="l"] .zo-tip__arrow { right:-7px; top:calc(var(--zo-arrow, 24px) - 6px); transform:rotate(45deg); border-width:1px 1px 0 0 }
.zo-tip[data-side="b"] .zo-tip__arrow { top:-7px; left:calc(var(--zo-arrow, 24px) - 6px); transform:rotate(45deg); border-width:1px 0 0 1px }
.zo-tip[data-side="t"] .zo-tip__arrow { bottom:-7px; left:calc(var(--zo-arrow, 24px) - 6px); transform:rotate(45deg); border-width:0 1px 1px 0 }
.zo-tip__x { position:absolute; top:8px; right:8px; width:26px; height:26px; padding:0; border:0; border-radius:50%; background:transparent;
  color:var(--text-3); cursor:pointer; display:flex; align-items:center; justify-content:center }
.zo-tip__x:hover { background:var(--bg); color:var(--text-1) }
.zo-tip__head { display:flex; gap:11px; align-items:center; padding-right:24px }
.zo-tip__n { flex:none; width:30px; height:30px; border-radius:9px; background:var(--zo-mark); color:#fff;
  font-weight:750; font-size:13.5px; display:inline-flex; align-items:center; justify-content:center }
.zo-tip__eyebrow { font-size:10.5px; font-weight:700; letter-spacing:.06em; color:var(--text-3); font-variant-numeric:tabular-nums; line-height:1.2 }
.zo-tip__t { font-weight:700; color:var(--text-1); font-size:14.5px; line-height:1.3 }
.zo-tip__d { font-size:13px; color:var(--text-2); margin:10px 0 0 }
.zo-tip__foot { display:flex; align-items:center; gap:10px; margin-top:12px; padding-top:10px; border-top:1px solid var(--border) }
.zo-tip__link { flex:1; min-width:0 }
.zo-tip__a { display:inline-flex; align-items:center; gap:4px; font-size:12.5px; font-weight:650; color:var(--gw); text-decoration:none }
.zo-tip__a:hover { text-decoration:underline }
.zo-tip__nav { flex:none; display:flex; gap:6px }
.zo-tip__btn { width:28px; height:28px; padding:0; border:1px solid var(--border); border-radius:50%; background:var(--surface); color:var(--text-2);
  display:inline-flex; align-items:center; justify-content:center; cursor:pointer; transition:background .15s, color .15s }
.zo-tip__btn:hover:not(:disabled) { background:var(--bg); color:var(--text-1) }
.zo-tip__btn--next { background:var(--gw); border-color:var(--gw); color:#fff }
.zo-tip__btn--next:hover:not(:disabled) { background:var(--gw); color:#fff; filter:brightness(1.08) }
.zo-tip__btn:disabled { opacity:.35; cursor:default }
/* Fusszeile der Bildkarte (07.10.2026; vorher darunter auf dem Seitenhintergrund). */
.zo-note { margin:0; padding:9px 14px 10px; border-top:1px solid var(--border); font-size:12px; color:var(--text-3) }
@media (prefers-reduced-motion: reduce) {
  .zo-spot, .zo-map.is-spot .zo-spot, .zo-tip, .zo-tip.is-open, .zo-pin { transition:none }
  .zo-seg.is-run i::after { animation:none; width:100% }
}

/* Liste unter dem Bild: am Bildschirm nicht mehr sichtbar, die Grafik zeigt die
   Punkte bereits. Sie bleibt im Dokument — Textquelle der Blase, Screenreader —
   und erscheint im Druck (unten). */
.zo-legend { position:absolute !important; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0); clip-path:inset(50%); white-space:nowrap }
@media print { .zo-legend { position:static !important; width:auto; height:auto; overflow:visible; clip:auto; clip-path:none; white-space:normal } }
.zo-legend { list-style:none; margin:14px 0 0; padding:0; display:grid; grid-template-columns:repeat(2, minmax(0, 1fr)); gap:2px 18px }
@media (max-width: 760px) { .zo-legend { grid-template-columns:minmax(0, 1fr) } }
.zo-legend__item { display:flex; gap:10px; align-items:flex-start; padding:8px 10px; border-radius:8px; line-height:1.45; cursor:pointer;
  scroll-margin-top:80px; transition:background .15s }
.zo-legend__item:hover, .zo-legend__item.is-on { background:color-mix(in srgb, var(--gw) 8%, transparent) }
.zo-legend__n { flex:none; width:20px; height:20px; border-radius:50%; background:var(--zo-mark); color:#fff; font-weight:700; font-size:11px;
  display:inline-flex; align-items:center; justify-content:center; margin-top:1px }
.zo-legend__item > div { min-width:0 }
.zo-legend__t { font-weight:650; color:var(--text-1); font-size:13px }
.zo-legend__d { font-size:12.5px; color:var(--text-2); margin:1px 0 0; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden }
.zo-legend__a { display:inline-block; margin-top:2px; font-size:12px; font-weight:600; color:var(--gw); text-decoration:none }
.zo-legend__a:hover, .zo-tip .zo-legend__a:hover { text-decoration:underline }
@media print { .zo-bar, .zo-tip, .zo-dim, .zo-note { display:none !important } .zo-legend__d { display:block; -webkit-line-clamp:unset; overflow:visible } }

/* Gruppen-Ueberschrift in Feature-Freigabe-Listen (Pakete, Tenants), 08.10.2026: Kategorien statt flacher Liste.
   Spannt die ganze Rasterbreite; die erste ohne Abstand nach oben. */
.feat-pick-grp { grid-column:1 / -1; font-size:10.5px; font-weight:700; letter-spacing:.5px; text-transform:uppercase; color:var(--text-3); margin:8px 0 0; padding-top:8px; border-top:1px dashed var(--border) }
.feat-pick-grp:first-child { margin-top:0; padding-top:0; border-top:0 }

/* ── Tabellenzellen der Tenant-Freigaben (share_cells.js, 15.10.2026) — /shares und Reiter «Freigaben» ─────────── */
.shc-scope__h { display:inline-flex; align-items:center; gap:7px; font-weight:600; color:var(--text-1); white-space:nowrap }
.shc-scope__h > svg { color:var(--text-3); flex:none }
.shc-scope__sub, .shc-sub { margin-top:3px; font-size:12px; color:var(--text-3); display:flex; align-items:center; gap:5px }
.shc-n { font-size:11px; font-weight:700; padding:1px 7px; border-radius:10px; background:color-mix(in srgb, var(--gw) 12%, transparent); color:var(--gw); font-variant-numeric:tabular-nums }
.shc-pills { margin-top:6px; display:flex; flex-wrap:wrap; gap:5px; align-items:center }
.shc-rr { display:inline-flex; align-items:center; gap:6px; padding:2px 3px 2px 8px; border:1px solid var(--border); border-radius:7px; background:var(--surface); line-height:1.4 }
.shc-rr__n { font-family:var(--font-mono); font-size:12px; color:var(--text-1); background:none !important; padding:0 !important; border:0 !important }
.shc-rr .rr-chip { font-size:10px; padding:0 6px; line-height:17px; border-radius:5px }
.shc-more { font-size:12px; color:var(--text-3); padding:2px 8px; border:1px dashed var(--border); border-radius:7px; cursor:help; white-space:nowrap }
.shc-rights { display:flex; flex-wrap:wrap; gap:5px }
.shc-right { display:inline-flex; align-items:center; gap:5px; padding:2px 9px 2px 7px; border-radius:999px; font-size:12px; font-weight:600; white-space:nowrap;
  background:color-mix(in srgb, var(--gw) 10%, transparent); color:var(--gw) }
.shc-right--read { background:color-mix(in srgb, var(--text-3) 12%, transparent); color:var(--text-2) }
.shc-st { display:inline-flex; align-items:center; gap:6px; padding:2px 10px 2px 8px; border-radius:999px; font-size:12px; font-weight:600; white-space:nowrap }
.shc-st__dot { width:7px; height:7px; border-radius:50%; background:currentColor; flex:none }
.shc-st.is-ok   { background:color-mix(in srgb, #16a34a 13%, transparent); color:#15803d }
.shc-st.is-warn { background:color-mix(in srgb, #f59e0b 16%, transparent); color:#b45309 }
.shc-st.is-off  { background:color-mix(in srgb, var(--text-3) 12%, transparent); color:var(--text-3) }
[data-theme="dark"] .shc-st.is-ok { color:#86efac } [data-theme="dark"] .shc-st.is-warn { color:#fcd34d }
.shc-date { white-space:nowrap; color:var(--text-1) }
.shc-unl { color:var(--text-3) }
.shc-scope__h { cursor:default } .shc-scope__h .shc-rr { margin-left:2px; font-weight:400 }
.shc-user { display:inline-flex; align-items:center; gap:9px; min-width:0 }
.shc-user__av { width:28px; height:28px; border-radius:8px; display:flex; align-items:center; justify-content:center; font-size:11px; font-weight:700; color:#fff; flex:none }
.shc-user__t { display:flex; flex-direction:column; min-width:0; line-height:1.3 }
.shc-user__n { font-weight:600; color:var(--text-1); white-space:nowrap; overflow:hidden; text-overflow:ellipsis }
.shc-user__u { font-size:11.5px; color:var(--text-3); font-family:var(--font-mono); white-space:nowrap }
