/* ============================================================
   Designsystem „Lagebild“ (0.88)
   Jede Ebene (Flotte, Kunde, Gerät, Lizenz) öffnet mit derselben Lagezeile: Lampen mit Zahl, bei denen der Zustand Form und Farbe hat,
   und das 7-Tage-Band je Stunde. Farbe nur für Zustand (ok, Warnung, kritisch, Info für Abläufe) und Marke (Akzent), Flächen in Graphit
   auf dem Markendunkel #161B1F. Schrift: IBM Plex Sans für Text, IBM Plex Sans Condensed für Titel und Kennzahlen (beide selbst
   ausgeliefert aus wwwroot/fonts, Lizenz SIL OFL), Plex Mono bleibt dem Terminal und Kennungen vorbehalten.
   Themen: Nacht (Vorgabe), Tag und System (folgt dem Betriebssystem), gesetzt als data-theme am html-Element.
   Whitelabel: Die Akzentfarbe kommt aus den Einstellungen; alles Weitere leitet sich aus den Tokens ab.
   Aufbau: Schriften, Tokens, Themen, Basis, Layout, Seitenleiste, Seitenbausteine, Tabellen, Formulare, Schaltflächen, Tabs, Dialoge,
   Toasts, Anmeldung, Seiten-Spezifisches, Responsive, danach die Themenblöcke je Version (der Block „Lagebild 0.88“ trägt die
   gemeinsamen Bausteine der Neugestaltung und gewinnt durch seine Stellung am Ende).
   ============================================================ */

/* Schriften: eine variable Datei je Zeichenvorrat für den Text (Gewichte 400 bis 600), zwei feste Schnitte der Condensed für Titel und
   Kennzahlen. Die Dateien liegen im Image; es wird nichts von fremden Servern geladen. */
@font-face { font-family: "IBM Plex Sans"; font-style: normal; font-weight: 400 600; font-display: swap; src: url("../fonts/plex-sans-latin.woff2") format("woff2"); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "IBM Plex Sans"; font-style: normal; font-weight: 400 600; font-display: swap; src: url("../fonts/plex-sans-latin-ext.woff2") format("woff2"); unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF; }
@font-face { font-family: "IBM Plex Sans Condensed"; font-style: normal; font-weight: 500; font-display: swap; src: url("../fonts/plex-sans-condensed-500-latin.woff2") format("woff2"); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "IBM Plex Sans Condensed"; font-style: normal; font-weight: 500; font-display: swap; src: url("../fonts/plex-sans-condensed-500-latin-ext.woff2") format("woff2"); unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF; }
@font-face { font-family: "IBM Plex Sans Condensed"; font-style: normal; font-weight: 600; font-display: swap; src: url("../fonts/plex-sans-condensed-600-latin.woff2") format("woff2"); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "IBM Plex Sans Condensed"; font-style: normal; font-weight: 600; font-display: swap; src: url("../fonts/plex-sans-condensed-600-latin-ext.woff2") format("woff2"); unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF; }

/* Nacht: Graphit auf dem Markendunkel, in klaren Stufen von der Seite (dunkelste Fläche) über Leiste und Karte bis zur erhöhten
   Fläche. Gilt auch ohne data-theme. Alle Paare mit Normziel erfüllen WCAG AA (Text 4,5:1, Bedienelemente und Grafik 3:1);
   DesignTests rechnet sie nach. */
:root {
  color-scheme: dark;

  /* Flächen: Seite, Leiste (Seitenleiste und Kopfzeile), Karte, erhöhte Fläche (Tabellenköpfe, Knöpfe), Überfahren, Eingabe */
  --c-bg: #161b1f;
  --c-chrome: #1b2126;
  --c-surface: #1f262c;
  --c-elev: #262e35;
  --c-hover: #2d363e;
  --c-input: #141a1e;

  /* Ränder: leise Trenner, Standard (auch Unterkante der Tabellenköpfe), kräftig (Knöpfe), Eingaben (mindestens 3:1) */
  --c-border-soft: #2a333b;
  --c-border: #353f49;
  --c-border-strong: #4a5663;
  --c-border-input: #6c7b88;

  /* Text: normal, gedämpft, schwach (statt Deckkraft für zurückgenommene Zeilen; erreicht noch 4,5:1) */
  --c-text: #edf1f4;
  --c-muted: #aeb8c2;
  --c-faint: #95a1ad;

  /* Marke (Whitelabel-Akzent): Fläche, Text und Linie. Text und Linie gibt der Server je Thema aus (4,5:1 bzw. 3:1
     gegen alle Flächen, BrandingCss); bis dahin gilt hier der Akzent selbst. */
  --c-accent: #1aa8e2;
  /* Füllung für Knöpfe und angehakte Felder: der Akzent selbst, außer der Server muss ihn für 4,5:1 zur Schrift abdunkeln oder
     aufhellen (--c-accent-fill in BrandingCss). Überfahren entfernt sich von der Schriftfarbe; der Server gibt den Wert ebenfalls aus. */
  --c-accent-fill: var(--c-accent);
  --c-accent-hover: color-mix(in srgb, var(--c-accent-fill) 85%, white);
  --c-accent-contrast: #06222e;
  --c-accent-ink: var(--c-accent);
  --c-accent-line: var(--c-accent);
  /* Fokus: deckend in der Linienfarbe, 2 px Kontur mit 2 px Abstand */
  --c-focus: var(--c-accent-line);
  --focus-w: 2px;
  /* Tönungen des Akzents: Hauch (ungespeichert), Tönung (aktiver Eintrag, Pillen, Segmente), kräftig (Suchtreffer),
     Rand (über dem Standardrand), ausgewählte Zeile */
  --c-accent-wash: color-mix(in srgb, var(--c-accent) 6%, transparent);
  --c-accent-tint: color-mix(in srgb, var(--c-accent) 16%, transparent);
  --c-accent-tint-strong: color-mix(in srgb, var(--c-accent) 26%, transparent);
  --c-accent-border: color-mix(in srgb, var(--c-accent) 50%, var(--c-border));
  --c-selected: color-mix(in srgb, var(--c-accent) 18%, transparent);

  /* Status: kräftig für Lampen, Balken und Kanten; *-ink für Text; *-bg als ruhige, feste Tönung; on-* für Text auf voller Farbe.
     Info ist der vierte Ton für Abläufe ohne Wertung (läuft, Test, geplant, Wartung) und hält Abstand zum Markenakzent. Jeder Zustand
     trägt zusätzlich eine Form (Kreis, Dreieck, Achteck, Kreis mit i), damit er auch ohne Farbe lesbar bleibt. */
  --c-ok: #3ecf8e;
  --c-warn: #f0b429;
  --c-crit: #f2574f;
  --c-info: #8f9cff;
  --c-ok-ink: #5fdcb2;
  --c-warn-ink: #f5c45a;
  --c-crit-ink: #ff8a82;
  --c-info-ink: #aab5ff;
  --c-ok-bg: #19382d;
  --c-warn-bg: #3d321a;
  --c-crit-bg: #45221f;
  --c-info-bg: #272c4d;
  --c-neutral-bg: #2b343d;
  --c-on-crit: #1c0504;
  --c-on-warn: #1d1405;

  /* Stufen einer Reihenfolge (Pakete Basic, Standard, Pro): eine Farbe, hell nach dunkel; keine Zustandsfarbe. */
  --c-ord-1: #b7e3f6;
  --c-ord-2: #4fbfeb;
  --c-ord-3: #0f87ba;
  --c-on-ord-1: #0b3446;
  --c-on-ord-2: #06222e;
  --c-on-ord-3: #ffffff;

  /* Diagrammreihen: Reihe 1 in der Akzentlinie, Reihe 2 neutral und gestrichelt (keine Zustandsfarben als Reihenfarben);
     Spur und Raster leise eine Stufe von der Fläche entfernt. */
  --c-series-1: var(--c-accent-line);
  --c-series-2: #c9d4de;
  --c-track: #2d363e;
  --c-grid: #2a333b;

  /* Code und Ausgaben; das Terminal bleibt in beiden Themen dunkel */
  --c-code-bg: #070a0d;
  --c-code-text: #d9e3ec;
  --c-term-bg: #0b0f13;
  --c-term-text: #d7e2ea;

  /* Syntaxfarben des Skript-Editors (0.93): nur für Code, nie für Zustände; je Thema mindestens 4,5:1 gegen Eingabe- und
     Codefläche, bei hohem Kontrast 7:1 */
  --c-syn-comment: #7fa77a;
  --c-syn-keyword: #d197f0;
  --c-syn-call: #e3d79a;
  --c-syn-string: #e6a27e;
  --c-syn-variable: #8fd3ff;
  --c-syn-type: #5fd4bd;
  --c-syn-number: #b9d99a;
  --c-syn-param: #a5b4c3;
  --c-syn-operator: #c9d1d9;
  --c-syn-template: #ff9fd2;

  --c-backdrop: rgba(4, 7, 10, .62);
  --shadow: 0 14px 36px rgba(0, 0, 0, .45);
  --shadow-soft: 0 4px 14px rgba(0, 0, 0, .3);

  --radius: 8px;
  --radius-sm: 5px;
  --radius-lg: 12px;
  --sidebar-w: 224px;
  /* Eingeklappte Schiene: nur die Symbole (Block „Lagebild 0.88“). */
  --sidebar-w-collapsed: 64px;
  /* Kopfzeile mit Suche, Kunden-Kontext und Benutzermenü; klebende Teile des Inhalts halten mit top: calc(var(--header-h) + …) Abstand zu
     ihr. Auf schmalen Bildschirmen steht hier die Höhe der klebenden Kopfleiste (Marke, Menü, Suche), siehe „Kopfzeile und Benutzermenü“. */
  --header-h: 52px;

  /* Schrift: Fließtext in Plex Sans, Titel und Kennzahlen in Plex Sans Condensed; die Systemschriften stehen als Ersatz, bis die
     Dateien geladen sind. */
  --font: "IBM Plex Sans", "Segoe UI Variable Text", "Segoe UI", system-ui, -apple-system, BlinkMacSystemFont, Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-display: "IBM Plex Sans Condensed", "Bahnschrift", "DIN Alternate", "Segoe UI Variable Display", "Segoe UI", system-ui, sans-serif;
  --mono: "Cascadia Mono", "Cascadia Code", Consolas, "SF Mono", ui-monospace, monospace;

  /* Schriftgrößen: Etikett, Nebentext, Text, Abschnitt, Seitentitel, Kennzahl */
  --fs-label: .857rem;
  --fs-small: .929rem;
  --fs-body: 1rem;
  --fs-section: 1.071rem;
  --fs-title: 1.65rem;
  --fs-kpi: 1.9rem;

  /* Abstände: ein 4-Pixel-Raster für alle Seiten */
  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 12px;
  --sp-4: 16px;
  --sp-5: 20px;
  --sp-6: 24px;
  --sp-8: 32px;

  /* Bedienelemente: eine Höhe für Eingaben und Schaltflächen */
  --control-h: 34px;
  --control-h-sm: 28px;
}

/* Tag: kühles, helles Grau als Seite, Leiste und Karten heller darauf, Eingaben weiß; dunkle Tinte in der Markenfarbe. Zustandsfarben als
   Text dunkler, damit sie lesbar bleiben; Warnung ist so dunkel, dass Schrift darauf weiß steht. */
html[data-theme="light"] {
  color-scheme: light;
  --c-bg: #eef1f4;
  --c-chrome: #f6f8fa;
  --c-surface: #ffffff;
  --c-elev: #f2f5f7;
  --c-hover: #e8edf1;
  --c-input: #ffffff;
  --c-border-soft: #e1e6eb;
  --c-border: #d0d8df;
  --c-border-strong: #a9b5c0;
  --c-border-input: #768491;
  --c-text: #161b1f;
  --c-muted: #455360;
  --c-faint: #57646f;
  --c-accent-hover: color-mix(in srgb, var(--c-accent-fill) 85%, black);
  --c-accent-ink: color-mix(in srgb, var(--c-accent) 70%, #0b1a24);
  --c-accent-line: color-mix(in srgb, var(--c-accent) 70%, #0b1a24);
  --c-accent-wash: color-mix(in srgb, var(--c-accent) 8%, transparent);
  --c-accent-tint: color-mix(in srgb, var(--c-accent) 18%, transparent);
  --c-accent-tint-strong: color-mix(in srgb, var(--c-accent) 30%, transparent);
  --c-selected: color-mix(in srgb, var(--c-accent) 20%, transparent);
  --c-ok: #0f8a5f;
  --c-warn: #9a6b00;
  --c-crit: #d0302f;
  --c-info: #4b5bd6;
  --c-ok-ink: #0a684e;
  --c-warn-ink: #7a5200;
  --c-crit-ink: #a3241f;
  --c-info-ink: #3a48b0;
  --c-ok-bg: #d9efe5;
  --c-warn-bg: #f5ead0;
  --c-crit-bg: #f9dedc;
  --c-info-bg: #e4e7f9;
  --c-neutral-bg: #e3e8ec;
  --c-on-crit: #ffffff;
  --c-on-warn: #ffffff;
  --c-ord-1: #54bde7;
  --c-ord-2: #1693c9;
  --c-ord-3: #0a5f85;
  --c-on-ord-1: #0b3446;
  --c-on-ord-2: #ffffff;
  --c-on-ord-3: #ffffff;
  --c-series-2: #3f4c59;
  --c-track: #e3e8ec;
  --c-grid: #e6ebef;
  --c-code-bg: #eef2f5;
  --c-code-text: #18232e;
  --c-syn-comment: #3d6b35;
  --c-syn-keyword: #8a1fb0;
  --c-syn-call: #6b4f0c;
  --c-syn-string: #a3321b;
  --c-syn-variable: #0b4f8f;
  --c-syn-type: #14616e;
  --c-syn-number: #1d6b3a;
  --c-syn-param: #4a5866;
  --c-syn-operator: #2f3a44;
  --c-syn-template: #a01a6a;
  --c-backdrop: rgba(22, 27, 31, .4);
  --shadow: 0 14px 36px rgba(22, 27, 31, .16);
  --shadow-soft: 0 4px 14px rgba(22, 27, 31, .1);
}

/* System: folgt der Einstellung des Betriebssystems (dieselben Werte wie „Tag“; DesignTests gleicht die Blöcke ab). */
@media (prefers-color-scheme: light) {
  html[data-theme="system"] {
    color-scheme: light;
    --c-bg: #eef1f4;
    --c-chrome: #f6f8fa;
    --c-surface: #ffffff;
    --c-elev: #f2f5f7;
    --c-hover: #e8edf1;
    --c-input: #ffffff;
    --c-border-soft: #e1e6eb;
    --c-border: #d0d8df;
    --c-border-strong: #a9b5c0;
    --c-border-input: #768491;
    --c-text: #161b1f;
    --c-muted: #455360;
    --c-faint: #57646f;
    --c-accent-hover: color-mix(in srgb, var(--c-accent-fill) 85%, black);
    --c-accent-ink: color-mix(in srgb, var(--c-accent) 70%, #0b1a24);
    --c-accent-line: color-mix(in srgb, var(--c-accent) 70%, #0b1a24);
    --c-accent-wash: color-mix(in srgb, var(--c-accent) 8%, transparent);
    --c-accent-tint: color-mix(in srgb, var(--c-accent) 18%, transparent);
    --c-accent-tint-strong: color-mix(in srgb, var(--c-accent) 30%, transparent);
    --c-selected: color-mix(in srgb, var(--c-accent) 20%, transparent);
    --c-ok: #0f8a5f;
    --c-warn: #9a6b00;
    --c-crit: #d0302f;
    --c-info: #4b5bd6;
    --c-ok-ink: #0a684e;
    --c-warn-ink: #7a5200;
    --c-crit-ink: #a3241f;
    --c-info-ink: #3a48b0;
    --c-ok-bg: #d9efe5;
    --c-warn-bg: #f5ead0;
    --c-crit-bg: #f9dedc;
    --c-info-bg: #e4e7f9;
    --c-neutral-bg: #e3e8ec;
    --c-on-crit: #ffffff;
    --c-on-warn: #ffffff;
    --c-ord-1: #54bde7;
    --c-ord-2: #1693c9;
    --c-ord-3: #0a5f85;
    --c-on-ord-1: #0b3446;
    --c-on-ord-2: #ffffff;
    --c-on-ord-3: #ffffff;
    --c-series-2: #3f4c59;
    --c-track: #e3e8ec;
    --c-grid: #e6ebef;
    --c-code-bg: #eef2f5;
    --c-code-text: #18232e;
    --c-syn-comment: #3d6b35;
    --c-syn-keyword: #8a1fb0;
    --c-syn-call: #6b4f0c;
    --c-syn-string: #a3321b;
    --c-syn-variable: #0b4f8f;
    --c-syn-type: #14616e;
    --c-syn-number: #1d6b3a;
    --c-syn-param: #4a5866;
    --c-syn-operator: #2f3a44;
    --c-syn-template: #a01a6a;
    --c-backdrop: rgba(22, 27, 31, .4);
    --shadow: 0 14px 36px rgba(22, 27, 31, .16);
    --shadow-soft: 0 4px 14px rgba(22, 27, 31, .1);
  }
}

/* Hoher Kontrast: data-contrast am html-Element (normal, high oder system; Benutzermenü, Cookie rmm.contrast, Vorgabe in den
   Einstellungen). Text und Ränder kräftiger, dazu unterstrichene Links, 3 px Fokus, Tabellenzeilen mit dem Standardrand und Pillen
   mit Rand in ihrer Textfarbe (Regeln am Ende der Datei). Der Tag-Block setzt dieselben Eigenschaften wie der Nacht-Block und gewinnt
   durch die höhere Spezifität. „system“ folgt prefers-contrast: more mit wörtlichen Kopien der Blöcke (DesignTests prüft das). */
html[data-contrast="high"] {
  --c-text: #f4f7fa;
  --c-muted: #c3ccd5;
  --c-faint: #aeb9c4;
  --c-border-soft: #3d4b59;
  --c-border: #56677a;
  --c-border-input: #8796a5;
  --focus-w: 3px;
  --c-syn-comment: #9cc795;
  --c-syn-keyword: #e2b6fa;
  --c-syn-call: #f2e9b8;
  --c-syn-string: #f5c0a3;
  --c-syn-variable: #b5e3ff;
  --c-syn-type: #8ee8d6;
  --c-syn-number: #d2ecb8;
  --c-syn-param: #c9d4de;
  --c-syn-operator: #e6ebf0;
  --c-syn-template: #ffc2e3;
}
html[data-theme="light"][data-contrast="high"] {
  --c-text: #0a1118;
  --c-muted: #33404b;
  --c-faint: #44515c;
  --c-border-soft: #b3bfca;
  --c-border: #98a5b1;
  --c-border-input: #5c6a77;
  --focus-w: 3px;
  --c-syn-comment: #2a4f24;
  --c-syn-keyword: #6a138a;
  --c-syn-call: #4f3a06;
  --c-syn-string: #80240f;
  --c-syn-variable: #073a6b;
  --c-syn-type: #0b4650;
  --c-syn-number: #124f2a;
  --c-syn-param: #33404b;
  --c-syn-operator: #1b242c;
  --c-syn-template: #7a1150;
}
@media (prefers-color-scheme: light) {
  html[data-theme="system"][data-contrast="high"] {
    --c-text: #0a1118;
    --c-muted: #33404b;
    --c-faint: #44515c;
    --c-border-soft: #b3bfca;
    --c-border: #98a5b1;
    --c-border-input: #5c6a77;
    --focus-w: 3px;
    --c-syn-comment: #2a4f24;
    --c-syn-keyword: #6a138a;
    --c-syn-call: #4f3a06;
    --c-syn-string: #80240f;
    --c-syn-variable: #073a6b;
    --c-syn-type: #0b4650;
    --c-syn-number: #124f2a;
    --c-syn-param: #33404b;
    --c-syn-operator: #1b242c;
    --c-syn-template: #7a1150;
  }
}
@media (prefers-contrast: more) {
  html[data-contrast="system"] {
    --c-text: #f4f7fa;
    --c-muted: #c3ccd5;
    --c-faint: #aeb9c4;
    --c-border-soft: #3d4b59;
    --c-border: #56677a;
    --c-border-input: #8796a5;
    --focus-w: 3px;
    --c-syn-comment: #9cc795;
    --c-syn-keyword: #e2b6fa;
    --c-syn-call: #f2e9b8;
    --c-syn-string: #f5c0a3;
    --c-syn-variable: #b5e3ff;
    --c-syn-type: #8ee8d6;
    --c-syn-number: #d2ecb8;
    --c-syn-param: #c9d4de;
    --c-syn-operator: #e6ebf0;
    --c-syn-template: #ffc2e3;
  }
  html[data-theme="light"][data-contrast="system"] {
    --c-text: #0a1118;
    --c-muted: #33404b;
    --c-faint: #44515c;
    --c-border-soft: #b3bfca;
    --c-border: #98a5b1;
    --c-border-input: #5c6a77;
    --focus-w: 3px;
    --c-syn-comment: #2a4f24;
    --c-syn-keyword: #6a138a;
    --c-syn-call: #4f3a06;
    --c-syn-string: #80240f;
    --c-syn-variable: #073a6b;
    --c-syn-type: #0b4650;
    --c-syn-number: #124f2a;
    --c-syn-param: #33404b;
    --c-syn-operator: #1b242c;
    --c-syn-template: #7a1150;
  }
}
@media (prefers-contrast: more) and (prefers-color-scheme: light) {
  html[data-theme="system"][data-contrast="system"] {
    --c-text: #0a1118;
    --c-muted: #33404b;
    --c-faint: #44515c;
    --c-border-soft: #b3bfca;
    --c-border: #98a5b1;
    --c-border-input: #5c6a77;
    --focus-w: 3px;
    --c-syn-comment: #2a4f24;
    --c-syn-keyword: #6a138a;
    --c-syn-call: #4f3a06;
    --c-syn-string: #80240f;
    --c-syn-variable: #073a6b;
    --c-syn-type: #0b4650;
    --c-syn-number: #124f2a;
    --c-syn-param: #33404b;
    --c-syn-operator: #1b242c;
    --c-syn-template: #7a1150;
  }
}

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

html, body {
  margin: 0;
  min-height: 100%;
  background: var(--c-bg);
  color: var(--c-text);
  font-family: var(--font);
  font-size: 14px;
  line-height: 1.45;
  -webkit-text-size-adjust: 100%;
}

/* ---------- Basis ---------- */

a { color: var(--c-accent-ink); text-decoration: none; }
a:hover { color: var(--c-accent-ink); text-decoration: underline; }

/* Seitentitel in der Anzeigeschrift; Abschnitte und Karten in der Textschrift, halbfett. */
h1 { font-family: var(--font-display); font-size: var(--fs-title); margin: 0; font-weight: 600; line-height: 1.2; letter-spacing: .005em; }
h2 { font-size: var(--fs-section); margin: 0 0 var(--sp-3); font-weight: 600; line-height: 1.3; }
h3 { font-size: var(--fs-body); margin: 0 0 var(--sp-2); font-weight: 600; }
:focus-visible { outline: var(--focus-w) solid var(--c-focus); outline-offset: 2px; }
p { margin: 0 0 .75rem; }
p:last-child { margin-bottom: 0; }

::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-thumb { background: var(--c-border); border-radius: 6px; }
::-webkit-scrollbar-track { background: transparent; }

.mono { font-family: var(--mono); font-size: .92em; }
.muted { color: var(--c-muted); }
.num { text-align: right; }
.compact { margin: 0 !important; }
.mt8 { margin-top: var(--sp-2); }
.stack { display: flex; flex-direction: column; gap: var(--sp-2); }
.warn-text { color: var(--c-warn-ink); font-weight: 600; }
.hint { margin-top: var(--sp-2); font-size: var(--fs-small); }
.steps { margin: 0; padding-left: 1.2rem; }
.steps li { margin: 6px 0; }

/* ---------- Layout ---------- */

.app-shell {
  display: grid;
  grid-template-columns: var(--sidebar-w) 1fr;
  min-height: 100vh;
}

.content {
  padding: var(--sp-5) 28px 40px;
  min-width: 0;
}

/* ---------- Seitenleiste ----------
   Oben Marke, Suche und „Agent installieren“, darunter die Gruppen; die aktive Seite trägt eine Akzentkante.
   Benutzer, Darstellung und Versionszeile stehen im Benutzermenü der Kopfzeile (Block „Kopfzeile und Benutzermenü“). */

.sidebar {
  display: flex;
  flex-direction: column;
  background: var(--c-chrome);
  border-right: 1px solid var(--c-border-soft);
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;
  /* Eigener Stapelkontext über dem Inhalt: Dialoge der Inseln in der Seitenleiste (Suche, Changelog, Agent installieren)
     liegen sonst unter den klebenden Tabellenköpfen der Seite. */
  z-index: 30;
}

.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 16px 16px 12px;
  font-family: var(--font-display);
  font-size: 1.15rem;
  font-weight: 600;
  letter-spacing: .01em;
}

.brand-logo { color: var(--c-accent); font-size: 1.15rem; }
.brand-logo-img { height: 22px; width: auto; max-width: 130px; object-fit: contain; display: block; }
.brand-logo-img.big, .brand-logo.big { height: 40px; max-width: 200px; font-size: 1.9rem; }
/* Steht das Logo ohne Schriftzug daneben, darf es den Platz des Namens mitnutzen. */
.brand-logo-img.wide { height: 28px; max-width: 170px; }
.brand-logo-img.big.wide { height: 48px; max-width: 260px; }

.nav { flex: 1; padding: 0 8px 12px; }

.nav-item {
  position: relative;
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 30px;
  padding: 5px 10px 5px 12px;
  margin: 1px 0;
  border-radius: var(--radius-sm);
  color: var(--c-text);
  font-weight: 400;
}

.nav-item:hover { background: var(--c-hover); text-decoration: none; color: var(--c-text); }

/* Aktive Seite: ruhige Tönung und eine Kante in der Akzentfarbe, der Text bleibt in der Textfarbe. */
.nav-item.active {
  background: var(--c-accent-tint);
  color: var(--c-text);
  font-weight: 600;
}
.nav-item.active::before {
  content: "";
  position: absolute;
  left: 0;
  top: 6px;
  bottom: 6px;
  width: 3px;
  border-radius: 2px;
  background: var(--c-accent-line);
}

.nav-item.disabled { color: var(--c-muted); cursor: default; }
.nav-item.disabled:hover { background: transparent; }

.nav-action {
  display: flex; align-items: center; justify-content: center; width: calc(100% - 8px); min-height: 32px; margin: 0 4px 6px;
  padding: 6px 12px; border-radius: var(--radius-sm); border: 1px solid var(--c-border);
  background: transparent; color: var(--c-text); font: inherit; font-weight: 600; cursor: pointer;
}
.nav-action:hover { background: var(--c-hover); border-color: var(--c-accent-border); }

.badge {
  margin-left: auto;
  font-size: .72rem;
  font-weight: 600;
  padding: 1px 7px;
  border-radius: 999px;
  background: var(--c-neutral-bg);
  color: var(--c-muted);
}

.linklike {
  background: none; border: 0; padding: 0;
  color: var(--c-muted); font: inherit; font-size: var(--fs-label);
  cursor: pointer; text-decoration: none;
}
.linklike:hover { color: var(--c-text); text-decoration: underline; }

.support-info { font-size: var(--fs-label); color: var(--c-muted); line-height: 1.5; }
.support-info .support-name { font-weight: 600; color: var(--c-text); }
.support-info .support-lines { display: flex; flex-wrap: wrap; gap: 4px 10px; }
.support-info a { color: var(--c-muted); text-decoration: none; }
.support-info a:hover { color: var(--c-text); }
.support-info.on-login { margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--c-border); text-align: center; }
.support-info.on-login .support-lines { justify-content: center; }

.build-info { font-size: .76rem; color: var(--c-muted); font-variant-numeric: tabular-nums; }
.build-info.dev { color: var(--c-warn-ink); }
.build-link { font: inherit; color: inherit; text-decoration: underline dotted; text-underline-offset: 2px; }
.build-link:hover { color: var(--c-text); }

/* Changelog im Dialog hinter der Versionsnummer */
.changelog-entry + .changelog-entry { margin-top: var(--sp-4); padding-top: var(--sp-3); border-top: 1px solid var(--c-border-soft); }
.changelog-version { display: flex; align-items: center; gap: 8px; margin: 0 0 6px; font-size: .95rem; }
.changelog-date { margin-left: auto; font-size: .8rem; font-weight: 400; }
.changelog-items { margin: 0; padding-left: 18px; }
.changelog-items li { margin: 3px 0; line-height: 1.45; }
.changelog-entry ~ .btn { margin-top: var(--sp-4); }

/* Menü auf schmalen Bildschirmen: verstecktes Kontrollkästchen, die Beschriftung ist die Schaltfläche. */
.nav-check { position: absolute; width: 1px; height: 1px; margin: -1px; opacity: 0; pointer-events: none; }
.nav-toggle .when-open { display: none; }
.nav-check:checked ~ .brand .when-closed { display: none; }
.nav-check:checked ~ .brand .when-open { display: inline; }
.nav-check:focus-visible ~ .brand .nav-toggle { outline: var(--focus-w) solid var(--c-focus); outline-offset: 2px; }

.nav-toggle {
  display: none;
  margin-left: auto;
  user-select: none;
  background: transparent;
  border: 1px solid var(--c-border);
  color: var(--c-text);
  border-radius: var(--radius-sm);
  padding: 6px 12px;
  font: inherit;
  font-size: .85rem;
  font-weight: 600;
  line-height: 1;
  cursor: pointer;
}

/* ---------- Seitenkopf, Werkzeugleisten, Suche ---------- */

.page-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--sp-3) var(--sp-4);
  margin-bottom: var(--sp-4);
}
/* Reicht der Platz nicht für Titel und Aktionen nebeneinander, rutschen die Aktionen unter den Titel, statt ihn zu quetschen. */
.page-head-main { flex: 1 1 320px; min-width: 0; }
.page-head .sub { margin: 4px 0 0; color: var(--c-muted); font-size: var(--fs-small); }
.page-actions, .form-actions { display: flex; flex-wrap: wrap; gap: var(--sp-2); align-items: center; }
.page-actions { justify-content: flex-end; flex: 0 1 auto; }

.crumb { font-size: var(--fs-label); color: var(--c-muted); margin-bottom: 4px; }
.crumb a { color: var(--c-muted); }
.crumb a:hover { color: var(--c-text); }

h1 .pill { vertical-align: middle; margin-left: 8px; font-family: var(--font); font-size: .75rem; letter-spacing: 0; }

.toolbar { display: flex; flex-wrap: wrap; gap: var(--sp-2); align-items: center; margin-bottom: var(--sp-3); }
.toolbar select { width: auto; max-width: 220px; }
.search { flex: 1 1 260px; max-width: 560px; }

.tab-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  margin-bottom: var(--sp-3);
}
.tab-toolbar .search { max-width: 420px; }
.tab-toolbar .count { color: var(--c-muted); font-size: var(--fs-small); white-space: nowrap; }

/* Abschnittstitel: normale Schreibung, halbfett, in Textfarbe; eine Zahl dahinter steht leiser. */
.section-title {
  margin: var(--sp-5) 0 var(--sp-2);
  font-size: var(--fs-section);
  font-weight: 600;
  color: var(--c-text);
}
.section-title:first-child { margin-top: 0; }
.card-grid + .section-title { margin-top: var(--sp-5); }
.section-title .count, .card h2 .count, .modal-section .count { color: var(--c-muted); font-weight: 500; }
.chip-button .count { color: var(--c-muted); font-weight: 500; margin-left: 2px; }
.card h2 > .pill { margin-left: 8px; vertical-align: middle; }

/* ---------- Karten und Kennzahlen ---------- */

.card {
  background: var(--c-surface);
  border: 1px solid var(--c-border-soft);
  border-radius: var(--radius);
  --card-px: 16px;
  --card-py: 14px;
  padding: var(--card-py) var(--card-px);
  margin-bottom: var(--sp-3);
}

/* Leer-Zustand: kurz, ruhig, ohne große Fläche. Innerhalb von Karten und Dialogen die leichtere .empty-note. */
.card.empty { color: var(--c-muted); text-align: center; padding: 20px 16px; }
.empty-note { color: var(--c-muted); margin: 0; padding: 4px 0; }
.card-lead { margin: -4px 0 var(--sp-3); font-size: var(--fs-small); color: var(--c-muted); }
.card-foot { margin-top: auto; padding-top: var(--sp-3); }
.card-head-row { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); flex-wrap: wrap; margin-bottom: var(--sp-3); }
.card-head-row h2 { margin: 0; }
.card > .card-head-row + .code-view { margin-top: 12px; }
.card .table-wrap { border-radius: var(--radius-sm); }
.card .table-wrap + .card-foot { padding-top: 12px; }
.card + .table-wrap, .table-wrap + .card { margin-top: var(--sp-4); }
.token-card { border-color: var(--c-accent-border); }
.monitor-card { margin-bottom: var(--sp-4); }

/* Kachelraster auf 12 Spalten. Breite der Kacheln und die mittig gesetzte letzte Reihe regelt der Block
   „Kundenseite und Kachelraster“ am Ende der Datei. */
.card-grid {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: var(--sp-3);
  align-items: stretch;
  margin-bottom: var(--sp-3);
}
.card-grid .card { margin-bottom: 0; min-width: 0; display: flex; flex-direction: column; }
.card-grid .card > h2 {
  padding-bottom: var(--sp-2);
  margin-bottom: var(--sp-3);
  border-bottom: 1px solid var(--c-border-soft);
}
.card-grid dl.kv dd .pill { margin-left: 6px; vertical-align: middle; }

.stat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
  gap: var(--sp-3);
  margin-bottom: var(--sp-4);
}

.stat-card {
  background: var(--c-surface);
  border: 1px solid var(--c-border-soft);
  border-radius: var(--radius);
  padding: 12px 14px;
}

.stat-label {
  font-size: var(--fs-label);
  font-weight: 600;
  color: var(--c-muted);
  margin-bottom: 4px;
}

/* Kennzahlen in der Anzeigeschrift, Ziffern gleich breit. */
.stat-value { font-family: var(--font-display); font-size: var(--fs-kpi); font-weight: 600; line-height: 1.1; font-variant-numeric: tabular-nums; }
.stat-value.ok { color: var(--c-ok-ink); }
.stat-value.warn { color: var(--c-warn-ink); }
.stat-value.crit { color: var(--c-crit-ink); }
.stat-value.info { color: var(--c-info-ink); }
.stat-hint { margin-top: 4px; font-size: var(--fs-label); color: var(--c-muted); }

/* Statuskante: das Erkennungszeichen. Links an Kennzahlen, Karten und Tabellenzeilen, in der Farbe des Zustands. */
.stat-card.edge-ok, .card.edge-ok { box-shadow: inset 3px 0 0 var(--c-ok); }
.stat-card.edge-warn, .card.edge-warn { box-shadow: inset 3px 0 0 var(--c-warn); }
.stat-card.edge-crit, .card.edge-crit { box-shadow: inset 3px 0 0 var(--c-crit); }
.stat-card.edge-info, .card.edge-info { box-shadow: inset 3px 0 0 var(--c-info); }
.stat-card.edge-muted, .card.edge-muted { box-shadow: inset 3px 0 0 var(--c-border-strong); }
tr.edge-ok > td:first-child { box-shadow: inset 3px 0 0 var(--c-ok); }
tr.edge-warn > td:first-child { box-shadow: inset 3px 0 0 var(--c-warn); }
tr.edge-crit > td:first-child { box-shadow: inset 3px 0 0 var(--c-crit); }
tr.edge-info > td:first-child { box-shadow: inset 3px 0 0 var(--c-info); }
tr.edge-muted > td:first-child { box-shadow: inset 3px 0 0 var(--c-border-strong); }

dl.kv { display: grid; grid-template-columns: 140px 1fr; gap: 6px 16px; margin: 0; }
dl.kv dt { color: var(--c-muted); font-size: var(--fs-small); }
dl.kv dd { margin: 0; word-break: break-word; }

.chips { display: flex; flex-wrap: wrap; gap: 6px; }
.chip {
  background: var(--c-neutral-bg);
  border-radius: 999px;
  padding: 2px 9px;
  font-size: var(--fs-label);
}

/* ---------- Pillen, Hinweise, Fortschritt ---------- */

/* Marke: normale Schreibung, getönt in der Farbe des Zustands. */
.pill {
  display: inline-block;
  padding: 1px 8px;
  border-radius: 999px;
  font-size: .78rem;
  font-weight: 600;
  line-height: 1.5;
  white-space: nowrap;
}
.pill.ok { background: var(--c-ok-bg); color: var(--c-ok-ink); }
.pill.warn { background: var(--c-warn-bg); color: var(--c-warn-ink); }
.pill.crit { background: var(--c-crit-bg); color: var(--c-crit-ink); }
.pill.info { background: var(--c-info-bg); color: var(--c-info-ink); }
.pill.muted { background: var(--c-neutral-bg); color: var(--c-muted); }

/* Kennzeichnung ohne Wertung (z. B. WICHTIG): Akzentfarbe statt einer Statusfarbe. */
.pill.accent { background: var(--c-accent-tint); color: var(--c-accent-ink); }
.hints { display: flex; flex-wrap: wrap; gap: 4px; max-width: 260px; }

/* Hinweis: nur für Zustände, die bestehen bleiben (Datenbank weg, Gerät offline, Neustart ausstehend).
   Rückmeldungen zu Aktionen sind Toasts. */
.notice {
  border-radius: var(--radius-sm);
  padding: 10px 12px;
  margin-bottom: var(--sp-3);
  font-size: var(--fs-small);
  background: var(--c-elev);
  border: 1px solid var(--c-border-soft);
  border-left: 3px solid var(--c-muted);
}
.notice.warn { border-left-color: var(--c-warn); background: color-mix(in srgb, var(--c-warn-bg) 60%, var(--c-elev)); }
.notice.error { border-left-color: var(--c-crit); background: color-mix(in srgb, var(--c-crit-bg) 60%, var(--c-elev)); }
.notice.ok { border-left-color: var(--c-ok); background: color-mix(in srgb, var(--c-ok-bg) 60%, var(--c-elev)); }
.notice.info { border-left-color: var(--c-info); background: color-mix(in srgb, var(--c-info-bg) 60%, var(--c-elev)); }
.notice.compact { padding: 8px 12px; margin-bottom: var(--sp-2); }
.notice.compact:last-child { margin-bottom: 0; }
/* Web-Zugriff: Hinweis „Sitzung bereit“ mit dem Link rechts daneben, auf schmalen Schirmen darunter. */
.notice.web-ready { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); flex-wrap: wrap; margin-top: var(--sp-3); }
.notice.web-ready .muted { display: block; font-family: var(--mono); font-size: var(--fs-label); overflow-wrap: anywhere; }
.notice a { font-weight: 600; }

.usage { display: flex; align-items: center; gap: 10px; }
.usage .pct { min-width: 42px; text-align: right; font-variant-numeric: tabular-nums; }
.bar { flex: 1; height: 8px; background: var(--c-elev); border-radius: 999px; overflow: hidden; min-width: 100px; }
.bar-fill { height: 100%; background: var(--c-ok); }
.bar-fill.warn { background: var(--c-warn); }
.bar-fill.crit { background: var(--c-crit); }

.progress { height: 10px; border-radius: 999px; background: var(--c-neutral-bg); overflow: hidden; margin: 12px 0 8px; }
.progress-bar { height: 100%; background: var(--c-accent); border-radius: 999px; transition: width .6s ease; min-width: 2%; }
.update-progress { margin-bottom: var(--sp-4); }

.vol-list { display: flex; flex-direction: column; gap: 12px; }
.vol-head { display: flex; justify-content: space-between; gap: 12px; font-size: .85rem; margin-bottom: 4px; }
.vol-head .muted { font-variant-numeric: tabular-nums; }

.need-list { display: flex; flex-direction: column; gap: 12px; }
.need-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.need-row .num { font-weight: 700; font-size: 1.15rem; font-variant-numeric: tabular-nums; }
.need-row .num.ok { color: var(--c-ok-ink); }
.need-row .num.warn { color: var(--c-warn-ink); }
.need-row .num.crit { color: var(--c-crit-ink); }

.sec-list { display: flex; flex-direction: column; gap: 10px; }
.sec-group {
  font-size: var(--fs-label);
  font-weight: 600;
  color: var(--c-muted);
  margin-top: 6px;
}
.sec-group:first-child { margin-top: 0; }
.sec-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.sec-name { font-weight: 600; min-width: 0; }
.sec-sub { font-size: .78rem; font-weight: 400; color: var(--c-muted); }
.sec-row .chips { justify-content: flex-end; }

/* ---------- Tabellen ---------- */

.table-wrap {
  background: var(--c-surface);
  border: 1px solid var(--c-border-soft);
  border-radius: var(--radius);
  overflow-x: auto;
}
.table-wrap + .table-wrap { margin-top: var(--sp-4); }
/* In einer Karte keine zweite Umrandung: die Tabelle liegt bündig auf der Karte. */
.card > .table-wrap { border: 0; border-radius: 0; background: transparent; margin: 0 calc(-1 * var(--card-px)); }
.card > .table-wrap:last-child { margin-bottom: calc(-1 * var(--card-py)); border-radius: 0 0 var(--radius) var(--radius); }
.card > .table-wrap th:first-child, .card > .table-wrap td:first-child { padding-left: var(--card-px); }
.card > .table-wrap th:last-child, .card > .table-wrap td:last-child { padding-right: var(--card-px); }

table { width: 100%; border-collapse: collapse; }

th, td {
  text-align: left;
  padding: 8px 12px;
  border-bottom: 1px solid var(--c-border-soft);
  white-space: nowrap;
  vertical-align: middle;
}

/* Spaltenköpfe: normale Schreibung, leise, klebend. */
th {
  font-size: var(--fs-label);
  font-weight: 600;
  color: var(--c-muted);
  background: var(--c-elev);
  border-bottom-color: var(--c-border);
  position: sticky;
  top: 0;
}
th.sortable { cursor: pointer; user-select: none; }
th.sortable:hover, th.sortable.active { color: var(--c-accent-ink); }
th.actions-col { text-align: right; }

tbody tr:hover { background: var(--c-hover); }
tbody tr:last-child td { border-bottom: 0; }
tr.clickable { cursor: pointer; }
tr.clickable:hover td { background: var(--c-hover); }
tr.selected td { background: var(--c-selected); }
tr.row-problem td { background: color-mix(in srgb, var(--c-crit) 9%, transparent); }
tr.muted-row td, tr.muted-row td .cell-sub, tr.muted-row td.dim, tr.muted-row td .muted { color: var(--c-faint); }
tr.monitored td:first-child { box-shadow: inset 3px 0 0 var(--c-accent-line); }
.output-row td { background: var(--c-elev); white-space: normal; }

.cell-main { font-weight: 600; }
.cell-sub { font-size: var(--fs-label); color: var(--c-muted); }
td.num { font-variant-numeric: tabular-nums; }
td.wrap, th.wrap { white-space: normal; }
td.dim { color: var(--c-muted); font-size: var(--fs-small); }
.row-actions { text-align: right; }
.row-actions .btn + .btn { margin-left: 4px; }
/* In schmalen Karten brechen die Zeilenaktionen um, statt die Tabelle seitlich scrollen zu lassen. */
.card-grid td.row-actions { white-space: normal; }
.card-grid td.row-actions .btn { margin: 2px 0 2px 4px; }
.mono-small { font-family: var(--mono); font-size: .74rem; max-width: 420px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.select-col { width: 36px; text-align: center; }
.select-col input { width: 16px; height: 16px; margin: 0; }
.selection-bar {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 12px;
  padding: 10px 14px;
  border-radius: var(--radius-sm);
  background: var(--c-accent-tint);
  border: 1px solid var(--c-accent-border);
}

.fields-table td { white-space: normal; }
.fields-table input { width: 100%; }

.activity td.when { white-space: nowrap; color: var(--c-muted); font-variant-numeric: tabular-nums; }
.activity td.msg { white-space: normal; max-width: 64ch; }
.activity .msg-line { display: flex; align-items: center; gap: 8px; min-width: 0; }
.activity .msg-text { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.activity .msg-line .btn { flex: 0 0 auto; }
.activity .pill.actor-user { background: var(--c-accent-tint); color: var(--c-accent-ink); }
.activity .pill.actor-agent { background: var(--c-neutral-bg); color: var(--c-muted); }
.activity .pill.actor-system { background: var(--c-warn-bg); color: var(--c-warn-ink); }


/* ---------- Formulare ---------- */

input, select, textarea {
  background: var(--c-input);
  border: 1px solid var(--c-border-input);
  border-radius: var(--radius-sm);
  color: var(--c-text);
  padding: 6px 10px;
  font: inherit;
  width: 100%;
  min-height: var(--control-h);
}
textarea { min-height: 0; line-height: 1.45; }
select { padding-right: 30px; }

input:focus, select:focus, textarea:focus {
  outline: var(--focus-w) solid var(--c-focus);
  outline-offset: 2px;
  border-color: var(--c-accent-line);
}
input:disabled, select:disabled, textarea:disabled { opacity: .55; cursor: not-allowed; }
/* Kontrollkästchen und Optionsfelder selbst gezeichnet: dunkel wie die Eingabefelder statt der weißen Standarddarstellung,
   angehakt in der Akzentfarbe. Kein Bild, kein Skript; das Häkchen ist ein ausgeschnittenes Rechteck. */
input[type=checkbox], input[type=radio] {
  appearance: none;
  -webkit-appearance: none;
  flex: 0 0 auto;
  display: inline-grid;
  place-content: center;
  width: 16px;
  height: 16px;
  min-height: 0;
  margin: 0;
  padding: 0;
  border: 1px solid var(--c-border-input);
  border-radius: 4px;
  background: var(--c-input);
  cursor: pointer;
  vertical-align: middle;
  transition: background-color .12s, border-color .12s;
}
input[type=radio] { border-radius: 50%; }
input[type=checkbox]:hover:not(:disabled), input[type=radio]:hover:not(:disabled) { border-color: var(--c-accent-line); }
input[type=checkbox]:checked, input[type=checkbox]:indeterminate, input[type=radio]:checked {
  background: var(--c-accent-fill);
  border-color: var(--c-accent-line);
}
input[type=checkbox]::before {
  content: "";
  width: 60%;
  height: 60%;
  background: var(--c-accent-contrast);
  clip-path: polygon(14% 44%, 0 65%, 50% 100%, 100% 16%, 80% 0%, 43% 62%);
  transform: scale(0);
  transition: transform .12s;
}
input[type=checkbox]:checked::before { transform: scale(1); }
input[type=checkbox]:indeterminate::before { clip-path: none; height: 2px; transform: scale(1); }
input[type=radio]::before {
  content: "";
  width: 40%;
  height: 40%;
  border-radius: 50%;
  background: var(--c-accent-contrast);
  transform: scale(0);
  transition: transform .12s;
}
input[type=radio]:checked::before { transform: scale(1); }
/* Beim Anklicken mit der Maus kein Rahmen, bei Tastaturbedienung schon. */
input[type=checkbox]:focus:not(:focus-visible), input[type=radio]:focus:not(:focus-visible) { outline: none; border-color: var(--c-border-input); }
input[type=checkbox]:checked:focus:not(:focus-visible), input[type=radio]:checked:focus:not(:focus-visible) { border-color: var(--c-accent-line); }

input[type=number]::-webkit-inner-spin-button,
input[type=number]::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }
input[type=number] { -moz-appearance: textfield; appearance: textfield; }

.field { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.field > span { font-size: var(--fs-label); font-weight: 600; color: var(--c-muted); }
.field.inline { flex-direction: row; align-items: center; gap: 8px; }
.field.inline > span { white-space: nowrap; }

.form-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--sp-3);
  margin-bottom: var(--sp-3);
}
.form-grid:last-child { margin-bottom: 0; }
.form-grid + .field { margin-bottom: var(--sp-3); }

.switch { display: inline-flex; align-items: center; gap: 10px; cursor: pointer; user-select: none; }
.switch input { width: 18px; height: 18px; }

.input-unit { display: flex; align-items: center; gap: 8px; width: 100%; }
.input-unit input[type=number] { text-align: right; }
.input-unit span { color: var(--c-muted); font-size: .85rem; min-width: 28px; }
.input-unit input[type=color] { width: 46px; height: var(--control-h); padding: 2px 4px; flex: 0 0 auto; cursor: pointer; }

.weekday-pick { display: inline-flex; gap: 4px; flex-wrap: wrap; }
.weekday { min-width: 34px; background: transparent; font: inherit; cursor: pointer; }
.weekday:hover { color: var(--c-text); }

.code-editor { font-family: var(--mono); font-size: .85rem; line-height: 1.45; min-height: 200px; resize: vertical; white-space: pre; tab-size: 4; }
textarea.notes { min-height: 160px; resize: vertical; }

.token-value {
  background: var(--c-elev);
  border: 1px dashed var(--c-accent-line);
  border-radius: var(--radius-sm);
  padding: 12px 14px;
  margin: 10px 0;
  font-size: 1rem;
  word-break: break-all;
  user-select: all;
}

.code-block {
  background: var(--c-code-bg);
  color: var(--c-code-text);
  border: 1px solid var(--c-border-soft);
  border-radius: var(--radius-sm);
  padding: 12px 14px;
  margin: 8px 0 14px;
  overflow-x: auto;
  word-break: break-all;
  user-select: all;
}

.code-view, .output {
  font-family: var(--mono);
  font-size: .82rem;
  line-height: 1.45;
  background: var(--c-code-bg);
  color: var(--c-code-text);
  border: 1px solid var(--c-border-soft);
  border-radius: var(--radius-sm);
  padding: 12px 14px;
  margin: 0;
  white-space: pre-wrap;
  word-break: break-word;
  max-height: 420px;
  overflow: auto;
}

/* Rollen-Editor */
.perm-groups {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: var(--sp-3);
  margin: 6px 0 16px;
}
.perm-group {
  border: 1px solid var(--c-border-soft);
  border-radius: var(--radius-sm);
  padding: 10px 14px 14px;
  margin: 0;
}
.perm-group[disabled] { opacity: .6; }
.perm-group legend {
  font-size: var(--fs-label);
  font-weight: 600;
  color: var(--c-muted);
  padding: 0 6px;
}
.perm-check {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: center;
  gap: 8px;
  padding: 4px 0;
  cursor: pointer;
}
.perm-check .perm-code {
  grid-column: 2;
  font-family: var(--mono);
  font-size: .72rem;
  color: var(--c-muted);
}
code.perm-code { font-family: var(--mono); font-size: .78rem; color: var(--c-muted); }

/* Geräteauswahl in Dialogen */
.picker-head { display: flex; align-items: center; gap: 12px; margin: 14px 0 8px; flex-wrap: wrap; }
.picker-head .search { max-width: none; flex: 1 1 200px; }
.picker-head select { width: auto; flex: 0 1 auto; max-width: 220px; }
.device-picker { max-height: 300px; overflow-y: auto; border: 1px solid var(--c-border-soft); border-radius: var(--radius-sm); background: var(--c-elev); }
.picker-row { display: grid; grid-template-columns: auto 1fr auto auto; align-items: center; gap: 10px; padding: 8px 12px; border-bottom: 1px solid var(--c-border-soft); cursor: pointer; }
.picker-row:last-child { border-bottom: 0; }
.picker-row:hover { background: var(--c-hover); }
.picker-name { font-weight: 600; }
.picker-groups { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin: 8px 0; }
.chip-button {
  background: var(--c-neutral-bg); border: 1px solid var(--c-border-soft); border-radius: 999px;
  padding: 4px 11px; font: inherit; font-size: .78rem; color: var(--c-text); cursor: pointer;
}
.chip-button:hover { background: var(--c-hover); }
.chip-button.on { background: var(--c-accent-tint); border-color: var(--c-accent-line); color: var(--c-accent-ink); font-weight: 600; }
.picker-name .cell-sub { display: block; }

.version-row { display: flex; align-items: center; gap: 10px; margin-top: 12px; flex-wrap: wrap; }

/* Fehlertext unter einer Eingabe (Richtlinien, Agent installieren). */
.setting-error { font-size: var(--fs-label); color: var(--c-crit-ink); margin-top: 4px; }

.logo-input { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.logo-preview {
  padding: 8px 10px; border-radius: var(--radius-sm);
  border: 1px solid var(--c-border); background: var(--c-elev);
}
.logo-preview img { height: 28px; max-width: 160px; object-fit: contain; display: block; }
/* Das Logo erscheint in beiden Themen; die Vorschau zeigt es deshalb auf den festen Flächen der Seitenleiste in Nacht und Tag. */
.logo-preview.on-dark { background: #12181f; border-color: #3a4856; }
.logo-preview.on-light { background: #f3f6f8; border-color: #c4ced6; }

/* ---------- Schaltflächen (Blueprint) ----------
   Vier Ausprägungen, überall gleich:
   .btn          Standard (zweitrangige Aktion)
   .btn.primary  die eine Hauptaktion einer Ansicht
   .btn.danger   gefährliche Aktion (Löschen, Deinstallieren): steht immer unten bzw. rechts
   .btn.ghost    leise Aktion (Abbrechen, Zeilenaktionen)
   Größen: .small für Tabellenzeilen, .block für volle Breite. */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  min-height: var(--control-h);
  border: 1px solid var(--c-border-strong);
  background: var(--c-elev);
  color: var(--c-text);
  border-radius: var(--radius-sm);
  padding: 5px 14px;
  font: inherit;
  font-weight: 600;
  line-height: 1.2;
  cursor: pointer;
  white-space: nowrap;
  text-decoration: none;
}
.btn:hover { background: var(--c-hover); border-color: var(--c-accent-border); color: var(--c-text); text-decoration: none; }
.btn:focus-visible { outline: var(--focus-w) solid var(--c-focus); outline-offset: 2px; }
.btn:disabled { opacity: .45; cursor: not-allowed; }
.btn:disabled:hover { background: var(--c-elev); }

.btn.primary { background: var(--c-accent-fill); border-color: var(--c-accent-fill); color: var(--c-accent-contrast); }
.btn.primary:hover { background: var(--c-accent-hover); border-color: var(--c-accent-hover); color: var(--c-accent-contrast); }
.btn.primary:disabled:hover { background: var(--c-accent-fill); }

.btn.danger { background: var(--c-crit-bg); border-color: color-mix(in srgb, var(--c-crit) 45%, transparent); color: var(--c-crit-ink); }
.btn.danger:hover { background: color-mix(in srgb, var(--c-crit) 22%, var(--c-surface)); color: var(--c-crit-ink); }
.btn.danger:disabled:hover { background: var(--c-crit-bg); }

.btn.ghost { background: transparent; border-color: var(--c-border); }
.btn.ghost:hover { background: var(--c-hover); border-color: var(--c-border-strong); }
.btn.ghost:disabled:hover { background: transparent; }

.btn.small { min-height: var(--control-h-sm); padding: 3px 10px; font-size: var(--fs-small); }
.btn.block { width: 100%; }

.link-button { background: none; border: 0; padding: 0; color: var(--c-accent-ink); font: inherit; font-weight: 600; cursor: pointer; text-align: left; }
.link-button:hover { text-decoration: underline; }

.upload-label { position: relative; overflow: hidden; cursor: pointer; }
.upload-label input[type="file"] { position: absolute; inset: 0; opacity: 0; cursor: pointer; width: 100%; min-height: 0; }

/* ---------- Tabs ---------- */

.tabs {
  display: flex;
  gap: 2px;
  flex-wrap: wrap;
  border-bottom: 1px solid var(--c-border-soft);
  margin: 0 0 var(--sp-4);
}
.tab {
  background: transparent;
  border: 0;
  border-bottom: 2px solid transparent;
  color: var(--c-muted);
  padding: 8px 12px;
  font: inherit;
  font-weight: 600;
  cursor: pointer;
  margin-bottom: -1px;
  white-space: nowrap;
}
.tab:hover { color: var(--c-text); }
.tab.active { color: var(--c-text); border-bottom-color: var(--c-accent-line); }
/* Reiter als Verweis zwischen Seiten (Geräte und Software, 0.78): ohne Unterstreichung wie die Schaltflächen. */
a.tab, a.tab:hover { text-decoration: none; display: inline-block; }
/* Zähler für Handlungsbedarf am Reiter (von Can gewünschtes Muster). */
.tab-badge {
  margin-left: 6px;
  font-size: .72rem;
  font-weight: 700;
  padding: 0 6px;
  border-radius: 999px;
  background: var(--c-crit);
  color: var(--c-on-crit);
}
.tab-badge.warn { background: var(--c-warn); color: var(--c-on-warn); }
/* Neutrale Zählung am Reiter (kein Handlungsbedarf). */
.tab-badge.muted { background: var(--c-neutral-bg); color: var(--c-muted); }

/* ---------- Dialoge (Blueprint) ----------
   Ein Dialog besteht aus Kopf (Titel, Schließen), scrollbarem Inhalt und einer Fußzeile
   mit den Schaltflächen: Abbrechen links (leise), Hauptaktion rechts. Gefährliche
   Aktionen stehen in einer eigenen Zone ganz unten (.danger-zone). */

.modal-backdrop {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: grid;
  place-items: center;
  padding: 20px;
  background: var(--c-backdrop);
  backdrop-filter: blur(2px);
  overflow-y: auto;
  overscroll-behavior: contain;
}
/* Drei feste Breiten: schmal für kurze Formulare, mittel für Tabellen und Auswahlen, breit für Browser (Dateien, Registry). */
.modal {
  width: 100%;
  max-width: 580px;
  max-height: calc(100vh - 40px);
  display: flex;
  flex-direction: column;
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
}
.modal.medium { max-width: 840px; }
.modal.wide { max-width: 1180px; width: 96vw; height: 86vh; }
.modal.wide .modal-body { flex: 1 1 auto; overflow-y: scroll; }
.modal-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 14px 18px 12px;
  border-bottom: 1px solid var(--c-border-soft);
  flex-shrink: 0;
}
.modal-head h2 { margin: 0; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 1.1rem; }
.modal-close {
  flex-shrink: 0;
  background: transparent;
  border: 0;
  color: var(--c-muted);
  font-size: 1.5rem;
  line-height: 1;
  padding: 2px 8px;
  border-radius: var(--radius-sm);
  cursor: pointer;
}
.modal-close:hover { color: var(--c-text); background: var(--c-hover); }
.modal-body { padding: 14px 18px; overflow-y: auto; overscroll-behavior: contain; }
/* Solange ein Dialog offen ist, scrollt die Seite dahinter nicht mit (kein JavaScript nötig). */
body:has(.modal-backdrop) { overflow: hidden; }
html { scrollbar-gutter: stable; }
.modal-body > :last-child { margin-bottom: 0; }
.modal-body .action-row:first-child { border-top: 0; padding-top: 0; }
.modal-foot {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--sp-2);
  padding: 12px 18px 14px;
  border-top: 1px solid var(--c-border-soft);
  flex-shrink: 0;
}
.modal-foot .spacer { flex: 1; }
.modal-foot .muted { font-size: .82rem; }
.modal .form-grid { margin-bottom: 14px; }
.modal textarea.code-editor { min-height: 160px; }
.modal input[type=datetime-local] { width: 100%; }

.confirm-warn { color: var(--c-warn-ink); font-weight: 600; margin-bottom: 8px; }

/* Aktionszeile: links Titel und Erklärung, rechts genau eine Schaltfläche. Die rechte Spalte ist überall gleich breit,
   damit die Schaltflächen bündig untereinander stehen, egal wie lang ihre Beschriftung ist. */
.action-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 176px;
  align-items: center;
  gap: 8px 24px;
  padding: 12px 0;
  border-top: 1px solid var(--c-border-soft);
}
.action-row:first-of-type { border-top: 0; }
.modal-section + .action-row, .modal-section + * > .action-row:first-child { border-top: 0; padding-top: 4px; }
.action-row > .btn { width: 100%; justify-content: center; text-align: center; }
.action-title { font-weight: 600; }
.action-desc { font-size: var(--fs-small); color: var(--c-muted); max-width: 64ch; margin-top: 2px; }
.action-row input:not([type=checkbox]):not([type=radio]), .action-row select.action-input { width: 100%; max-width: 420px; margin-top: 10px; }

.danger-zone {
  margin-top: 18px;
  padding: 14px 16px 4px;
  border: 1px solid color-mix(in srgb, var(--c-crit) 40%, transparent);
  border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--c-crit-bg) 50%, transparent);
}
.danger-zone .danger-zone-title {
  font-size: var(--fs-small);
  font-weight: 600;
  color: var(--c-crit-ink);
  margin-bottom: 4px;
}
.danger-zone .action-row { border-top-color: color-mix(in srgb, var(--c-crit) 25%, transparent); }
.danger-zone .action-row:first-of-type { border-top: 0; }

/* ---------- Toasts: Rückmeldungen zu Aktionen, von unten eingeblendet ---------- */

.toast-stack { position: fixed; left: 50%; bottom: 22px; transform: translateX(-50%); z-index: 2000; display: flex; flex-direction: column; gap: 8px; align-items: center; pointer-events: none; width: min(92vw, 560px); }
.toast {
  pointer-events: auto; display: flex; align-items: flex-start; gap: 12px; width: 100%;
  padding: 11px 14px; border-radius: var(--radius-sm); border: 1px solid var(--c-border-soft); border-left-width: 3px;
  background: var(--c-elev); color: var(--c-text); box-shadow: var(--shadow);
  animation: toast-in .22s ease-out; font-size: .9rem; line-height: 1.4;
}
.toast.ok { border-left-color: var(--c-ok); }
.toast.info { border-left-color: var(--c-info); }
.toast { font-size: var(--fs-small); }
.toast.warn { border-left-color: var(--c-warn); }
.toast.error { border-left-color: var(--c-crit); }
.toast-text { flex: 1 1 auto; word-break: break-word; }
.toast-close { flex: 0 0 auto; background: none; border: 0; color: var(--c-muted); font-size: 1.1rem; line-height: 1; cursor: pointer; padding: 0 2px; }
.toast-close:hover { color: var(--c-text); }
.toast-link { flex: 0 0 auto; font-weight: 600; color: inherit; text-decoration: underline; white-space: nowrap; }
@keyframes toast-in { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: translateY(0); } }

/* ---------- Anmeldung ---------- */

.empty-layout { min-height: 100vh; }

.login-wrap {
  min-height: 100vh;
  display: grid;
  place-items: center;
  padding: 24px;
  background:
    radial-gradient(1100px 500px at 20% -10%, var(--c-accent-wash), transparent),
    var(--c-bg);
}

.login-card {
  width: 100%;
  max-width: 380px;
  background: var(--c-surface);
  border: 1px solid var(--c-border-soft);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
  padding: 28px 28px 22px;
}

.login-brand {
  display: flex;
  align-items: center;
  gap: 10px;
  font-family: var(--font-display);
  font-size: 1.35rem;
  font-weight: 600;
  margin-bottom: 4px;
}

.login-sub { color: var(--c-muted); margin: 0 0 18px; font-size: .9rem; }
.login-card .field { margin-bottom: 14px; }
.login-foot { margin: 16px 0 0; font-size: .76rem; color: var(--c-muted); text-align: center; }
.login-links { margin-top: 14px; display: flex; justify-content: center; gap: 16px; font-size: .76rem; }
.login-links a { color: var(--c-muted); text-decoration: none; }
.login-links a:hover { color: var(--c-text); }
/* Impressum: dieselbe Karte wie die Anmeldung, nur breiter und mit Fließtext. */
.login-card.legal-card { max-width: 640px; }
.legal-card h1 { font-size: 1.3rem; margin: 18px 0 10px; }
.legal-card h2 { font-size: 1rem; margin: 22px 0 6px; }
.linked-text { white-space: pre-wrap; overflow-wrap: anywhere; line-height: 1.55; }
.legal-foot { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-top: 26px; padding-top: 14px; border-top: 1px solid var(--c-border); font-size: .76rem; }
.login-or { margin: 14px 0; text-align: center; color: var(--c-muted); font-size: .8rem; }
.login-or::before, .login-or::after { content: ""; display: inline-block; width: 34%; height: 1px; background: var(--c-border); vertical-align: middle; margin: 0 8px; }

/* Zwei-Faktor-Einrichtung */
.setup-steps { margin: 4px 0 0; padding-left: 20px; display: grid; gap: 18px; }
.setup-steps li::marker { color: var(--c-muted); font-weight: 600; }
.qr-box {
  width: 200px; margin: 8px 0;
  padding: 8px; border-radius: 8px; background: #fff;
  border: 1px solid var(--c-border);
}
.qr-box svg { display: block; width: 100%; height: auto; }
.recovery-codes {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 8px;
  margin-top: 12px; padding: 14px;
  border: 1px solid var(--c-border); border-radius: 8px; background: var(--c-elev);
  font-size: .95rem; letter-spacing: .04em;
}

/* ---------- Live-Fernzugriff: Terminal, Dateien, Registry ---------- */

.terminal-bar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 10px; }
.terminal-wrap {
  display: flex; flex-direction: column-reverse;  /* hält die Ansicht am Ende der Ausgabe */
  height: 460px; overflow: auto;
  background: var(--c-term-bg); border: 1px solid var(--c-border-soft); border-radius: var(--radius-sm);
}
.terminal {
  font-family: var(--mono); font-size: .82rem; line-height: 1.45; color: var(--c-term-text);
  padding: 12px 14px; margin: 0; white-space: pre-wrap; word-break: break-word;
}
.terminal-input { display: flex; align-items: center; gap: 8px; margin-top: 8px; }
.terminal-input input { flex: 1; font-family: var(--mono); }
.terminal-hint { margin: -4px 0 10px; font-size: .82rem; }

.files-bar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 10px; }
.files-bar .path-input { flex: 1 1 320px; min-width: 200px; }
.files-inline { align-items: center; margin-top: 6px; }
.files-inline input { max-width: 320px; }

.reg-crumb { margin: 4px 0 12px; color: var(--c-muted); font-size: .82rem; word-break: break-all; }
.reg-editor { margin-bottom: 14px; }
.reg-data { max-width: 520px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ---------- Globale Suche, zuletzt angesehen ---------- */

/* Namen von Geräten und Kunden bleiben in der Textfarbe; dass sie ein Link sind, zeigt sich beim Überfahren. */
a.plain { color: inherit; }
a.plain:hover { color: inherit; text-decoration: underline; }

.nav-search {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  width: calc(100% - 24px); min-height: 32px; margin: 0 12px 8px; padding: 5px 10px;
  border-radius: var(--radius-sm); border: 1px solid var(--c-border-soft);
  background: var(--c-elev); color: var(--c-muted); font: inherit; cursor: pointer; text-align: left;
}
.nav-search:hover { background: var(--c-hover); color: var(--c-text); }

.kbd {
  font-size: .72rem; color: var(--c-muted);
  border: 1px solid var(--c-border); border-radius: 4px; padding: 0 5px; white-space: nowrap;
}

/* Menügruppen sind Schaltflächen zum Ein- und Ausklappen: ruhige Beschriftung, der Pfeil steht rechts. */
button.nav-group {
  display: flex; align-items: center; gap: 6px; width: 100%;
  padding: 4px 10px 2px 12px; margin: 10px 0 2px;
  background: transparent; border: 0; border-radius: var(--radius-sm); cursor: pointer; text-align: left; font: inherit;
  font-size: var(--fs-label); font-weight: 600; color: var(--c-muted);
}
button.nav-group::after { content: "\25be"; margin-left: auto; font-size: .7rem; line-height: 1; transition: transform .12s ease; }
button.nav-group:hover { color: var(--c-text); }

/* Welche Gruppe eingeklappt ist, steht am html-Element (wwwroot/js/app.js). So überlebt der Zustand jede Navigation. */
html[data-nav-collapsed~="overview"] [data-nav-items="overview"],
html[data-nav-collapsed~="customers"] [data-nav-items="customers"],
html[data-nav-collapsed~="automation"] [data-nav-items="automation"],
html[data-nav-collapsed~="admin"] [data-nav-items="admin"],
html[data-nav-collapsed~="recent"] [data-nav-items="recent"] { display: none; }
html[data-nav-collapsed~="overview"] [data-nav-group="overview"]::after,
html[data-nav-collapsed~="customers"] [data-nav-group="customers"]::after,
html[data-nav-collapsed~="automation"] [data-nav-group="automation"]::after,
html[data-nav-collapsed~="admin"] [data-nav-group="admin"]::after,
html[data-nav-collapsed~="recent"] [data-nav-group="recent"]::after { transform: rotate(-90deg); }

.search.wide { max-width: none; width: 100%; }
.search-group { margin: 14px 0 6px; font-size: var(--fs-label); font-weight: 600; color: var(--c-muted); }
.search-list { border: 1px solid var(--c-border-soft); border-radius: var(--radius-sm); background: var(--c-elev); }
.search-hit {
  display: grid; grid-template-columns: 1fr auto; align-items: center; gap: 4px 12px;
  padding: 9px 12px; border-bottom: 1px solid var(--c-border-soft); color: var(--c-text);
}
.search-hit:last-child { border-bottom: 0; }
.search-hit:hover { background: var(--c-hover); text-decoration: none; color: var(--c-text); }
.search-title { grid-column: 1; grid-row: 1; font-weight: 600; }
.search-sub { grid-column: 1; grid-row: 2; font-size: .8rem; color: var(--c-muted); word-break: break-word; }
.search-hit .pill { grid-column: 2; grid-row: 1 / span 2; justify-self: end; }

/* Verzeichnis (AD): feste Spalten, damit die Tabelle beim Wechsel der Ansicht nicht springt. */
/* Software-Liste: feste Spalten. Lange Namen werden gekürzt (voller Name beim Überfahren), Erklärungen stehen hinter dem
   Fragezeichen; so schiebt keine Meldung mehr die Aktionen aus dem Bild. */
table.software-table { table-layout: fixed; }
table.software-table td { overflow: hidden; text-overflow: ellipsis; }
table.software-table td .cell-main, table.software-table td .cell-sub { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
table.software-table td.row-actions { overflow: visible; white-space: normal; }
table.software-table td.row-actions .btn { margin: 2px 0 2px 4px; }
table.software-table .help { vertical-align: middle; margin-left: 4px; }
.cell-line { display: flex; align-items: center; gap: 6px; min-width: 0; }
.cell-line > .pill, .cell-line > .help { flex: 0 0 auto; margin-left: 0; }
.cell-line > .cell-fill { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

table.ad-table { table-layout: fixed; }
table.ad-table td { overflow: hidden; text-overflow: ellipsis; }
table.ad-table td .cell-sub { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Spalten mit mehreren Merkmalen: umbrechen statt abschneiden, sonst fehlt auf schmalen Schirmen das zweite Kennzeichen. */
table.ad-table td.pills { white-space: normal; }
table.ad-table td.pills .pill { margin-bottom: 2px; }

/* ---------- Aktionen als Raster ----------
   Zwei Kacheln je Zeile mit Titel, kurzem Zustand und einer Schaltfläche. Der Aktionen-Dialog am Gerät zeigt zusätzlich eine
   sichtbare Beschreibung je Kachel (ActionCard, Regeln im Block „Aktionen am Gerät“ am Ende). */

.action-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-2); margin-bottom: var(--sp-3); }
.action-card {
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3);
  border: 1px solid var(--c-border); border-radius: var(--radius-sm); background: var(--c-elev); padding: 10px 12px;
}
.action-card-text { min-width: 0; }
.action-card .action-title { font-weight: 600; display: flex; align-items: center; gap: 6px; }
.action-card .action-state { font-size: .8rem; color: var(--c-muted); margin-top: 2px; }
.action-card .btn { flex: 0 0 auto; }

/* Erklärung hinter dem Fragezeichen: Kreis als Schaltfläche, die Blase öffnet app.js (Block „Hilfe und Ladeknöpfe“). */
.help {
  display: inline-grid; place-items: center; width: 16px; height: 16px; border-radius: 50%;
  border: 1px solid var(--c-border-strong); color: var(--c-muted); font-size: .7rem; font-weight: 700; cursor: help; flex: 0 0 auto;
}
.help:hover, .help:focus-visible { color: var(--c-text); border-color: var(--c-accent-line); }
.help:focus { outline: none; }
/* Im Fließtext, neben Überschriften, Labels und Spaltenköpfen etwas Abstand; in den Kacheln und einzeiligen Zellen sorgt schon die
   Lücke des Flex-Layouts dafür. */
.help { margin-left: 6px; vertical-align: middle; }
.action-card .action-title > .help, .cell-line > .help { margin-left: 0; }

.danger-zone .action-grid { margin-bottom: 0; }

/* ---------- Leistungsanzeige ---------- */

.perf-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: var(--sp-4); }
.perf-chart { width: 100%; height: 90px; display: block; margin: 6px 0 2px; }
.perf-grid-line { stroke: var(--c-border); stroke-width: 1; }

/* ---------- Responsive ----------
   Tablet (bis 1280): Kartenraster zweispaltig.
   Schmal (bis 900, Tablet hochkant und Telefon): Seitenleiste wird zur Kopfzeile mit Menü.
   Telefon (bis 640): alles einspaltig, Dialoge als Vollbild, Schaltflächen in voller Breite. */

@media (max-width: 900px) {
  .app-shell { grid-template-columns: 1fr; }
  .sidebar {
    position: sticky;
    top: 0;
    height: auto;
    z-index: 20;
    border-right: 0;
    border-bottom: 1px solid var(--c-border-soft);
    overflow: visible;
  }
  .sidebar:has(> .nav-check:checked) {
    position: fixed;
    inset: 0;
    height: 100dvh;
    overflow-y: auto;
    z-index: 200;
    border-bottom: 0;
  }
  .brand { padding: 12px 16px; }
  .nav-toggle { display: inline-flex; }
  .nav { display: none; }
  .nav-check:checked ~ .nav { display: block; }
  .nav-item { padding: 11px 12px; }
  .content { padding: 18px 16px 40px; }
  h1 { font-size: 1.3rem; }
  .page-head { flex-direction: column; align-items: stretch; }
  .page-actions { justify-content: flex-start; }
  .tabs { flex-wrap: nowrap; overflow-x: auto; -webkit-overflow-scrolling: touch; scrollbar-width: thin; }
  .tab { padding: 9px 11px; }
  .tab-toolbar { flex-direction: column; align-items: stretch; }
  .tab-toolbar .search { max-width: none; }
  .search { max-width: none; }
  th, td { padding: 9px 10px; }
}

@media (max-width: 640px) {
  .content { padding: 14px 12px 32px; }
  dl.kv { grid-template-columns: 1fr; gap: 2px 0; }
  dl.kv dt { margin-top: 8px; }
  .stat-value { font-size: 1.5rem; }
  .card { --card-px: 14px; --card-py: 12px; }
  .form-actions .btn, .page-actions .btn { flex: 1 1 auto; }
  .toolbar > * { flex: 1 1 100%; max-width: none; }
  .terminal-wrap { height: 320px; }
  .mono-small { max-width: 200px; }
  .modal-backdrop { padding: 0; }
  .modal, .modal.wide { max-width: none; width: 100%; height: 100dvh; max-height: 100dvh; border-radius: 0; border: 0; }
  .modal.wide .modal-body { overflow-y: auto; }
  .modal-body { flex: 1 1 auto; }
  .modal-foot .btn { flex: 1 1 auto; }
  .action-row { grid-template-columns: minmax(0, 1fr); }
  .action-grid { grid-template-columns: minmax(0, 1fr); }
  .action-row .form-actions .btn { width: 100%; }
  .toast-stack { width: calc(100vw - 20px); bottom: 10px; }
}

@media (pointer: coarse) {
  button.nav-group { min-height: 40px; padding: 10px 8px; }
  .nav-search { min-height: 44px; }
  .btn { min-height: 42px; }
  .btn.small { min-height: 36px; }
  .nav-item { padding: 11px 12px; }
  .tab { padding: 11px 12px; }
}

/* Abschnittskopf: Titel links, Schaltfläche rechts */
.section-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin: 22px 0 10px; flex-wrap: wrap; }
.section-head .section-title, .section-head .modal-section { margin: 0; }
.section-head.first { margin-top: 0; }
.section-head > p { margin: 0; }
.section-actions { display: flex; gap: 8px; flex-wrap: wrap; }
.form-actions select { width: auto; }
.mt16 { margin-top: var(--sp-4); }
.mt12 { margin-top: var(--sp-3); }
.mb12 { margin-bottom: var(--sp-3); }
.perm-check.inline { display: inline-grid; margin-right: 8px; }
.cell-sub.error { color: var(--c-crit-ink); }
.form-grid .span-all { grid-column: 1 / -1; }
.version-row select { width: auto; }
.picker-empty { padding: 10px; }
.card.sub { margin: 8px 0; padding: 10px 12px; }
.doc-preview h3 { margin: 18px 0 6px; }
.doc-preview .part-heading { margin: 10px 0 4px; font-weight: 600; }
.doc-preview .doc-text { white-space: pre-wrap; margin: 4px 0; }

/* Cockpit: Kennzahlen in einer Karte */
.kpi-row { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--sp-3); margin-bottom: var(--sp-3); }
.kpi-label { font-size: var(--fs-label); font-weight: 600; color: var(--c-muted); margin-bottom: 2px; }
.kpi-value { font-family: var(--font-display); font-size: 1.55rem; font-weight: 600; line-height: 1.1; font-variant-numeric: tabular-nums; }
.kpi-value.ok { color: var(--c-ok-ink); }
.kpi-value.warn { color: var(--c-warn-ink); }
.kpi-value.crit { color: var(--c-crit-ink); }
.card .section-title { margin-top: var(--sp-4); font-size: var(--fs-body); }

/* Werkzeugleiste mit linker Gruppe (Suche, Schalter) und rechter Gruppe (Aktionen) */
.toolbar-group { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; min-width: 0; }
.toolbar-group:first-child { flex: 1 1 auto; }
.toolbar-group .search { flex: 1 1 240px; }
.toolbar-group select { width: auto; flex: 0 0 auto; }
.toolbar-group.right { justify-content: flex-end; flex-shrink: 0; }

/* Warn-Dialog: Aufzählung der Risiken und Liste der betroffenen Einträge */
.confirm-points { margin: 0 0 .75rem; padding-left: 1.2rem; }
.confirm-points li { margin: 4px 0; }
.confirm-list { max-height: 220px; overflow-y: auto; overscroll-behavior: contain; border: 1px solid var(--c-border-soft); border-radius: var(--radius-sm); background: var(--c-elev); }
.confirm-list-row { display: flex; justify-content: space-between; gap: 12px; padding: 7px 12px; border-bottom: 1px solid var(--c-border-soft); font-size: .88rem; }
.confirm-list-row:last-child { border-bottom: 0; }

/* ---------- Pakete: Funktionen, die im Paket fehlen, bleiben sichtbar und sind ausgegraut ---------- */
.btn.locked { opacity: .62; border-style: dashed; }
.btn.locked:hover { opacity: .85; }
.btn.primary.locked { background: var(--c-elev); border-color: var(--c-border); color: var(--c-text); }
.lock-tag {
  margin-left: 2px; padding: 0 6px; border-radius: 999px; font-size: .72rem; font-weight: 600;
  background: var(--c-neutral-bg); color: var(--c-muted);
}
.nav-item.locked { color: var(--c-muted); }
.nav-item.locked.active { color: var(--c-muted); background: var(--c-hover); }
.tab.locked { color: var(--c-faint); }
.tab .badge { margin-left: 6px; }
.feature-locked {
  border: 1px dashed var(--c-border); border-radius: var(--radius); background: var(--c-surface);
  padding: 22px 24px; margin-bottom: var(--sp-4); max-width: 760px;
}
.feature-locked.compact { padding: 14px 16px; border-radius: var(--radius-sm); max-width: none; }
.feature-locked-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 8px; font-size: 1.02rem; }
.feature-locked.compact .feature-locked-head { font-size: .95rem; }

/* Paketvergleich */
table.compare th.compare-col, table.compare td.compare-col { text-align: center; width: 130px; }
table.compare .compare-col.current { background: var(--c-accent-wash); }
table.compare th.compare-col.current { color: var(--c-accent-ink); }
tr.group-row td {
  background: var(--c-elev); font-size: var(--fs-label); font-weight: 600; color: var(--c-muted);
}
tbody tr.group-row:hover { background: transparent; }
table.compare .compare-yes { color: var(--c-ok-ink); font-weight: 700; font-size: 1.05rem; line-height: 1; }
table.compare .compare-yes.off { color: var(--c-muted); }
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }

/* Dialog-Abschnitte und Geheimnisse, die sich mit einem Klick markieren lassen (Kopieren ohne JavaScript). */
/* Abschnitt im Dialog: kleiner als ein Seitenabschnitt, aber als Überschrift erkennbar. */
.modal-section { margin: var(--sp-4) 0 var(--sp-2); font-size: var(--fs-body); font-weight: 600; color: var(--c-text); }
.modal-section:first-child { margin-top: 0; }
/* Marken hinter einem Namen in Tabellenzellen brauchen Abstand, auch wenn das Markup kein Leerzeichen liefert. */
.cell-main > .pill { margin-left: 8px; vertical-align: middle; }
.select-all { user-select: all; -webkit-user-select: all; }
.secret-box { display: flex; align-items: center; gap: 10px; margin-top: 10px; }
.secret-box input { flex: 1 1 auto; font-size: 1.05rem; letter-spacing: .06em; }
.key-field { width: 100%; min-width: 16rem; letter-spacing: .04em; }

/* Ereignisanzeige: zwei Filterzeilen, darunter die Tabelle mit festen Spalten (lange Quellen werden gekürzt). */
.eventlog-filters { display: flex; flex-direction: column; gap: var(--sp-2); margin-bottom: var(--sp-3); }
.chip-set { display: inline-flex; flex-wrap: wrap; gap: 4px; }
.eventlog-narrow { width: 10rem; }
table.eventlog-table { table-layout: fixed; min-width: 48rem; }
table.eventlog-table td { overflow: hidden; text-overflow: ellipsis; }
table.eventlog-table .col-when { width: 9.5rem; }
table.eventlog-table .col-level { width: 7.5rem; }
table.eventlog-table .col-source { width: 14rem; }
table.eventlog-table .col-id { width: 5rem; }

/* Skriptauswahl: Kategorien als Kacheln, darin die Skripte als Zeilen; gewählt bleibt eine Zeile mit „Ändern“. */
.tabs.tabs-tight { margin: 0 0 var(--sp-3); }
.script-picker { display: flex; flex-direction: column; gap: var(--sp-2); margin-bottom: var(--sp-3); }
.script-picker-head { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; }
.script-picker-head .search { flex: 1 1 14rem; }
.script-picker-title { font-weight: 600; }
.script-tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr)); gap: var(--sp-2); }
.script-tile {
  display: flex; flex-direction: column; align-items: flex-start; gap: 4px; text-align: left;
  padding: 12px 14px; border: 1px solid var(--c-border); border-radius: var(--radius-sm);
  background: var(--c-elev); color: var(--c-text); font: inherit; cursor: pointer;
}
.script-tile:hover, .script-tile:focus-visible { border-color: var(--c-accent-line); background: var(--c-hover); }
.script-tile-name { font-weight: 600; }
.script-tile-meta { color: var(--c-muted); font-size: .8rem; }
.script-list { display: flex; flex-direction: column; border: 1px solid var(--c-border-soft); border-radius: var(--radius-sm); max-height: 22rem; overflow-y: auto; }
.script-item {
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); text-align: left;
  padding: 9px 12px; border: 0; border-bottom: 1px solid var(--c-border-soft); background: transparent;
  color: var(--c-text); font: inherit; cursor: pointer;
}
.script-item:last-child { border-bottom: 0; }
.script-item:hover, .script-item:focus-visible { background: var(--c-hover); }
.script-item.on { background: var(--c-accent-tint); }
.script-item.unfit, .script-item.unfit .script-item-meta { color: var(--c-faint); }
.script-item-text { display: flex; flex-direction: column; min-width: 0; }
.script-item-meta { display: flex; gap: var(--sp-2); color: var(--c-muted); font-size: .8rem; white-space: nowrap; }
.script-chosen {
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3);
  padding: 10px 12px; border: 1px solid var(--c-accent-line); border-radius: var(--radius-sm);
  background: var(--c-accent-wash);
}
.card.empty.compact { padding: 16px; margin: 0; }
@media (max-width: 640px) {
  .script-item { flex-direction: column; align-items: flex-start; }
  .script-item-meta { white-space: normal; flex-wrap: wrap; }
}

/* Hinweis mit einer Schaltfläche rechts; aufgeklappte Detailzeile einer Tabelle mit eingerückter Untertabelle. */
.notice.with-action { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
tr.detail-row > td { background: var(--c-elev); padding: 12px 16px 16px; }
tr.detail-row:hover { background: transparent; }
table.inner-table { width: 100%; border-collapse: collapse; }
table.inner-table th { background: transparent; }
table.inner-table tbody tr:hover { background: transparent; }

/* Richtlinie der Update-Automatik: je Geräteklasse eine Spalte mit Wochentagen, Uhrzeit, nächstem Lauf und Neustart. */
.policy-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; margin-top: 4px; }
.policy-col { padding: 16px; border: 1px solid var(--c-border-soft); border-radius: var(--radius-sm); background: var(--c-elev); }
.policy-col.off, .policy-col.off dl.kv dt, .policy-col.off .cell-sub { color: var(--c-faint); }
.policy-col.off .weekday.on { background: var(--c-neutral-bg); border-color: var(--c-border); color: var(--c-faint); }
.policy-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 12px; }
.policy-title { font-weight: 700; font-size: 1rem; }
.weekday-row { display: grid; grid-template-columns: repeat(7, minmax(0, 40px)); gap: 6px; }
.weekday { padding: 5px 0; text-align: center; font-size: .78rem; font-weight: 600; border-radius: 6px; border: 1px solid var(--c-border); color: var(--c-muted); }
.weekday.on { background: var(--c-accent-tint); border-color: var(--c-accent-border); color: var(--c-text); font-weight: 600; }
.policy-time { margin: 12px 0 14px; font-family: var(--font-display); font-size: 1.35rem; font-weight: 600; letter-spacing: .01em; }
.policy-col dl.kv { margin: 0; }
.policy-foot { margin: 14px 0 0; }

/* Auswahl zwischen wenigen Möglichkeiten im Dialog: Optionsfeld links, Titel und Erklärung rechts. */
.choice-list { display: flex; flex-direction: column; gap: 12px; margin: 14px 0; }
.choice-row { display: grid; grid-template-columns: 22px minmax(0, 1fr); gap: 10px; align-items: start; cursor: pointer; font-size: .9rem; }
.choice-row input { width: 18px; height: 18px; margin-top: 2px; }
.choice-row .muted { font-size: .82rem; }

/* Prüfliste: Marke links, Aussage rechts (Self-Service, Zuordnung prüfen). */
.check-list { display: flex; flex-direction: column; gap: 10px; }
.check-row { display: grid; grid-template-columns: 74px minmax(0, 1fr); gap: 12px; align-items: start; font-size: .9rem; }
.check-row .pill { justify-self: start; }
.hidden { display: none; }

/* Eigene Felder als ruhige Liste (Kunden-Übersicht): Name links, Wert rechts, ohne Tabellenkopf. */
table.fields-table.readonly { width: 100%; border-collapse: collapse; }
table.fields-table.readonly td { padding: 8px 0; border-top: 1px solid var(--c-border-soft); vertical-align: top; }
table.fields-table.readonly tr:first-child td { border-top: 0; padding-top: 0; }
table.fields-table.readonly td:first-child { width: 42%; color: var(--c-muted); padding-right: 12px; }
table.fields-table.readonly tbody tr:hover { background: transparent; }

/* Vorgänge (Software-Warteschlange): feste Spalten, damit eine hochzählende Dauer nichts verschiebt. */
table.ops-table { table-layout: fixed; min-width: 860px; }
table.ops-table col.col-status { width: 190px; }
table.ops-table col.col-time { width: 150px; }
table.ops-table col.col-duration { width: 110px; }
table.ops-table col.col-code { width: 120px; }
table.ops-table col.col-actions { width: 210px; }
table.ops-table td.cell-main { overflow: hidden; text-overflow: ellipsis; }
.num-fixed { font-variant-numeric: tabular-nums; white-space: nowrap; }

/* Update-Freigaben: Kennzahlen als Filter, Freigaberegel als Eingabe, Richtlinien je Kunde/Gerät */
.approval-filter { grid-template-columns: repeat(5, minmax(0, 1fr)); }
.approval-filter .stat-card {
  display: flex; flex-direction: column; align-items: flex-start; text-align: left;
  font: inherit; color: inherit; cursor: pointer;
}
.approval-filter .stat-card:hover { border-color: var(--c-border); }
.approval-filter .stat-card.active { border-color: var(--c-accent-line); box-shadow: 0 0 0 1px var(--c-accent-line) inset; }
.approval-filter .stat-card.active.edge-ok { box-shadow: inset 3px 0 0 var(--c-ok), 0 0 0 1px var(--c-accent-line) inset; }
.approval-filter .stat-card.active.edge-warn { box-shadow: inset 3px 0 0 var(--c-warn), 0 0 0 1px var(--c-accent-line) inset; }
.approval-filter .stat-card.active.edge-crit { box-shadow: inset 3px 0 0 var(--c-crit), 0 0 0 1px var(--c-accent-line) inset; }
td.approval-title { min-width: 280px; }
.rule-input { display: flex; flex-direction: column; align-items: flex-end; gap: 6px; }
.rule-input .input-unit input { width: 64px; }

/* ---------- Responsive, Nachträge ----------
   Steht bewusst am Ende der Datei: Bausteine, die nach dem Abschnitt „Responsive“ dazukamen, würden dessen Regeln
   sonst überschreiben. Schmal = bis 900 px (Tablet hochkant, Telefon), Telefon = bis 640 px. */

@media (max-width: 900px) {
  /* Im Spaltenlayout würde die Basisbreite des Titelblocks zur Höhe. */
  .page-head-main { flex: 0 0 auto; }
  .page-actions { flex: 0 0 auto; }
  .toolbar-group, .toolbar-group.right { justify-content: flex-start; flex: 1 1 100%; }
  .toolbar-group .count { flex: 1 1 100%; }
  table.compare th.compare-col, table.compare td.compare-col { width: 84px; }
  .legal-foot { flex-direction: column-reverse; align-items: stretch; text-align: center; }
}

@media (max-width: 640px) {
  /* Filter paarweise statt je eine Zeile: halbiert die Höhe der Filterleiste. */
  .toolbar > select { flex: 1 1 calc(50% - 5px); min-width: 0; max-width: none; }
  .toolbar-group .search { flex: 1 1 100%; }
  .toolbar-group .btn { flex: 1 1 auto; }
  /* Kennzahlen zu zweit nebeneinander, kompakter. */
  .stat-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
  .stat-card { padding: 12px 14px; }
  .kpi-row { gap: 8px; }
  .kpi-value { font-size: 1.25rem; }
  .section-head { margin-top: 18px; }
  .card-head-row .btn { flex: 0 0 auto; }
  /* Schaltflächen im Seitenkopf: höchstens zwei je Zeile, gleich breit. */
  .page-actions .btn { flex: 1 1 calc(50% - 5px); }
  .page-actions .btn:only-child { flex-basis: 100%; }
  .feature-locked { padding: 16px; }
  .login-card { padding: 24px 20px 20px; }
  .confirm-list { max-height: 40dvh; }
  /* Lange Werte (Adressen, Kennungen) umbrechen, statt die Karte zu sprengen. */
  dl.kv dd, .cell-sub, .action-desc { overflow-wrap: anywhere; }
}

@media (max-width: 900px) {
  /* Richtlinie der Update-Automatik: Workstations und Server untereinander. */
  .policy-grid { grid-template-columns: minmax(0, 1fr); }
  .action-row > .btn { margin-top: 4px; }
  /* Freigaberegeln: Eingabe unter der Beschriftung. */
  .rule-input { align-items: flex-start; }
  td.approval-title { min-width: 200px; }
  .approval-filter { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  /* Geöffnetes Menü: eigener Rollbereich, der die Seite dahinter nicht mitzieht. */
  .sidebar:has(> .nav-check:checked) { overscroll-behavior: contain; }
}

@media (pointer: coarse) {
  /* Kleine Textlinks brauchen auf dem Touchscreen eine greifbare Höhe. */
  .user-panel-links .linklike, .login-links a { display: inline-block; padding: 8px 0; }
  .user-panel-links { gap: 0 16px; }
  .modal-close { min-width: 44px; min-height: 44px; }
  input[type="checkbox"] { min-width: 20px; min-height: 20px; }
}


@media (max-width: 640px) {
  /* Freigabe-Filter auf dem Telefon zu zweit wie die übrigen Kennzahlen. */
  .approval-filter { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ============================================================
   Bereiche der Version 0.69 bis 0.71. Jeder Block gehört zu einem Thema; neue Regeln des Themas stehen direkt
   unter seiner Überschrift, einschließlich eigener @media-Regeln. So bleiben die Themen getrennt.
   ============================================================ */

/* ---------- Seitenleiste: Symbole der Gruppen, zuletzt angesehene Geräte ---------- */

/* Gruppenköpfe mit Symbol (NavIcon): ruhig in der Nebenfarbe, beim Überfahren in der Textfarbe, weil das Symbol die
   Farbe des Textes übernimmt. Die Einträge rücken bis unter die Beschriftung ein; so bleibt die Gliederung ohne Linien
   erkennbar. Mitte des Symbols: 12 px Innenabstand + 8 px = 20 px, Beschriftung und Einträge beginnen bei 36 px. */
button.nav-group { gap: 8px; }
.nav-icon { display: block; flex: 0 0 auto; width: 16px; height: 16px; }
.nav-items .nav-item { padding-left: 36px; }

/* Zahl an „Alarme“: rot getönt mit kritischen Alarmen, sonst gelb. */
.badge.count { min-width: 22px; text-align: center; font-variant-numeric: tabular-nums; }
.badge.crit { background: var(--c-crit-bg); color: var(--c-crit-ink); }
.badge.warn { background: var(--c-warn-bg); color: var(--c-warn-ink); }
.badge.info { background: var(--c-info-bg); color: var(--c-info-ink); }

/* Zuletzt angesehen: Sprungliste am Ende der Navigation, etwas kleiner als die Menüpunkte. Der Status-Punkt steht in
   der Spalte des Symbols, die Namen fluchten mit den übrigen Einträgen und enden bei Platzmangel mit Auslassungspunkten. */
button.nav-group[data-nav-group="recent"] { margin-top: 18px; }
.nav-recent-item { font-size: var(--fs-small); min-height: 28px; }
.nav-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nav-dot {
  position: absolute; left: 16px; top: 50%; width: 8px; height: 8px; margin-top: -4px;
  border-radius: 50%; background: var(--c-border-strong);
}
.nav-dot.ok { background: var(--c-ok); }
/* Das gerade geöffnete Gerät: ruhig hervorgehoben; die Akzentkante bleibt beim Menüpunkt „Geräte“. */
.nav-recent-item.current { background: var(--c-hover); font-weight: 600; }

@media (pointer: coarse) {
  /* Größere Tippfläche am Gruppenkopf, das Symbol bleibt in der Spalte der Status-Punkte. */
  button.nav-group { padding-left: 12px; padding-right: 10px; }
  .nav-recent-item { min-height: 44px; }
}

/* Auf dem Desktop scrollt nur die Navigation; Marke und Suche oben bleiben immer sichtbar, auch wenn viele Gruppen offen
   sind. Nur ab 600 px Höhe: In niedrigen Fenstern (Telefon quer, starke Vergrößerung) bliebe unter Marke und Suche kaum
   Platz für das Menü, dort scrollt wieder die ganze Leiste. Auf schmalen Bildschirmen gilt das Klappmenü (siehe @media 900px). */
@media (min-width: 901px) and (min-height: 600px) {
  .sidebar { overflow: hidden; }
  .sidebar > .nav { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; scrollbar-width: thin; scrollbar-color: var(--c-border) transparent; }
}

/* Ende Seitenleiste */

/* ---------- Dashboard und Alarm-Seite ---------- */

/* Fünf Kennzahlen ohne Leerfeld: breit in einer Reihe, mittel drei und zwei (Raster aus sechs Spalten), schmal zu zweit. */

/* Kennzahl als Link: die ganze Kachel führt auf die passende Liste. Ohne Recht bleibt sie ein a ohne href und damit ein reiner Wert. */
a.stat-card, a.stat-card:hover { display: block; color: var(--c-text); text-decoration: none; }
a.stat-card.link { transition: background-color .12s ease, border-color .12s ease; }
a.stat-card.link:hover { background: var(--c-hover); border-color: var(--c-border-strong); }
a.stat-card.link:hover .stat-label { color: var(--c-accent-ink); }

/* Handlungsbedarf: jede Zeile öffnet die gefilterte Geräteliste, die Zahl bleibt rechts. */
a.need-row, a.need-row:hover { color: var(--c-text); text-decoration: none; }
.need-list.need-links { gap: 2px; }
.need-links a.need-row { margin: 0 calc(-1 * var(--sp-2)); padding: 7px var(--sp-2); border-radius: var(--radius-sm); }
.need-links a.need-row:hover { background: var(--c-hover); }
.need-links a.need-row:hover > span:first-child { color: var(--c-accent-ink); }

/* Alarm-Karte: Titel links, kompakte Suche und Schwere rechts; unten Blättern und der Weg zur Seite „Alarme“. */
.dash-tools { display: flex; align-items: center; gap: var(--sp-2); flex: 0 1 440px; min-width: 0; }
.dash-tools .search { flex: 1 1 200px; max-width: none; min-width: 0; }
.dash-tools input, .dash-tools select { min-height: var(--control-h-sm); padding: 3px 8px; font-size: var(--fs-small); }
.dash-tools select { width: auto; flex: 0 0 auto; }
.dash-alerts > .empty-note { padding-top: 0; }
.dash-foot { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-2) var(--sp-3); flex-wrap: wrap; }
.dash-foot .dash-all { margin-left: auto; font-weight: 600; }
.dash-remediation {
  margin: var(--sp-3) calc(-1 * var(--card-px)) 0;
  padding: var(--sp-3) var(--card-px) 0;
  border-top: 1px solid var(--c-border-soft);
}
.dash-sub-head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--sp-3); margin-bottom: var(--sp-2); }
.dash-sub-head h3 { margin: 0; }
.dash-sub-head h3 .count { color: var(--c-muted); font-weight: 500; }
.dash-remediation .need-list { gap: 6px; }

/* Blättern: Bereich links, Zurück und Weiter daneben. */
.pager { display: flex; align-items: center; gap: var(--sp-2) var(--sp-3); flex-wrap: wrap; margin-top: var(--sp-3); }
.card-foot .pager { margin-top: 0; }
.pager-range { color: var(--c-muted); font-size: var(--fs-small); font-variant-numeric: tabular-nums; white-space: nowrap; }
.pager-buttons { display: flex; gap: var(--sp-1); }

/* Seite „Alarme“: ein gesetzter Gerätefilter als Marke mit „entfernen“. */
.filter-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  min-height: var(--control-h);
  padding: 3px 10px;
  border-radius: var(--radius-sm);
  background: var(--c-neutral-bg);
  font-size: var(--fs-small);
  white-space: nowrap;
}

/* Alarm-Tabellen: Die Meldung bricht erst ab einer lesbaren Breite um, sonst würden die Zeilen auf dem Tablet sehr hoch.
   Die Beschriftungen braucht nur die gestapelte Telefonansicht ohne Spaltenköpfe. */
.alert-table td.al-msg { min-width: 240px; }
.alert-table td.al-fix { min-width: 180px; }
.alert-table .al-label { display: none; }
.dash-remediation .need-row > span:last-child { white-space: nowrap; }

@media (max-width: 640px) {
  /* Fünf Kennzahlen zu zweit: die letzte nimmt die ganze Breite statt ein Leerfeld zu lassen. */
  .dash-tools { flex: 1 1 100%; }
  .dash-tools select { flex: 0 1 auto; min-width: 0; }
  /* Blättern kompakt in einer Zeile: Bereich links, Schaltflächen rechts; der Link steht darunter. */
  .pager { flex-wrap: nowrap; justify-content: space-between; width: 100%; }
  .pager .btn.small { padding: 3px 9px; }
  .toolbar > .filter-chip { justify-content: space-between; }

  /* Alarm-Tabellen gestapelt: Schwere, Gerät und Zeit in der ersten Zeile, darunter Check und Kunde, dann die Meldung.
     Ohne das würde die Meldung in einer seitlich rollenden Tabelle zu sehr hohen Zeilen umbrechen. */
  .alert-table thead { display: none; }
  .alert-table, .alert-table tbody { display: block; }
  .alert-table tr {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    grid-template-areas: "sev dev time" "check check cust" "msg msg msg" "fix fix fix";
    align-items: center;
    gap: 3px var(--sp-2);
    padding: 10px var(--sp-3);
    border-bottom: 1px solid var(--c-border-soft);
  }
  .alert-table.no-sev tr { grid-template-areas: "dev dev time" "check check cust" "msg msg msg" "fix fix fix"; }
  .alert-table tbody tr:last-child { border-bottom: 0; }
  .card > .table-wrap .alert-table td, .table-wrap .alert-table td { display: block; padding: 0; border: 0; min-width: 0; box-shadow: none; }
  .card > .table-wrap .alert-table tr { padding: 10px var(--card-px); }
  /* Die Statuskante wandert von der ersten Zelle an die ganze Zeile. */
  .alert-table tr.edge-crit { box-shadow: inset 3px 0 0 var(--c-crit); }
  .alert-table tr.edge-warn { box-shadow: inset 3px 0 0 var(--c-warn); }
  .alert-table tr.edge-crit > td:first-child, .alert-table tr.edge-warn > td:first-child { box-shadow: none; }
  .alert-table .al-sev { grid-area: sev; }
  .alert-table .al-dev { grid-area: dev; overflow: hidden; text-overflow: ellipsis; }
  .alert-table .al-dev .cell-main { overflow: hidden; text-overflow: ellipsis; }
  .alert-table .al-time { grid-area: time; font-size: var(--fs-small); text-align: right; }
  .alert-table .al-check { grid-area: check; overflow: hidden; text-overflow: ellipsis; }
  .alert-table .al-cust { grid-area: cust; font-size: var(--fs-small); text-align: right; overflow: hidden; text-overflow: ellipsis; max-width: 48vw; }
  .alert-table .al-msg { grid-area: msg; font-size: var(--fs-small); }
  .alert-table .al-fix { grid-area: fix; font-size: var(--fs-small); }
  .alert-table .al-opened { display: none; }
  .alert-table .al-label { display: inline; }
}

/* Ende Dashboard und Alarm-Seite */

/* ---------- Kundenseite und Kachelraster ---------- */

/* Kachelraster (.card-grid) auf 12 Spalten: drei Kacheln je Reihe belegen je 4 Spalten, zwei (.cols-2) je 6.
   Eine unvollständige letzte Reihe steht mittig statt links mit einer Lücke rechts.
   Nach Anzahl: genau eine Kachel volle Breite, genau zwei je halbe Breite, genau vier als 2 × 2.
   Gezählt werden nur Kacheln; .span-all (volle Breite, z. B. die Kataloge im Self-Service) und ein geöffneter Dialog
   zählen nicht mit. Bis 1280 px zwei Kacheln je Reihe, bis 900 px eine. Karten einer Reihe sind gleich hoch. */
.card-grid > * { grid-column: span 6; min-width: 0; }
.card-grid > .span-all { grid-column: 1 / -1; }
.card-grid > :nth-child(1 of :not(.span-all, .modal-backdrop)):nth-last-child(1 of :not(.span-all, .modal-backdrop)) { grid-column: 1 / -1; }

@media (min-width: 1281px) {
  .card-grid:not(.cols-2) > :not(.span-all) { grid-column: span 4; }
  /* Eine übrig: Spalten 5 bis 8. Zwei übrig: 3 bis 6 und 7 bis 10. */
  .card-grid:not(.cols-2) > :nth-child(3n+4 of :not(.span-all, .modal-backdrop)):nth-last-child(1 of :not(.span-all, .modal-backdrop)) { grid-column: 5 / span 4; }
  .card-grid:not(.cols-2) > :nth-child(3n+4 of :not(.span-all, .modal-backdrop)):nth-last-child(2 of :not(.span-all, .modal-backdrop)) { grid-column: 3 / span 4; }
  .card-grid:not(.cols-2) > :nth-child(3n+5 of :not(.span-all, .modal-backdrop)):nth-last-child(1 of :not(.span-all, .modal-backdrop)) { grid-column: 7 / span 4; }
  /* Genau zwei oder genau vier Kacheln: halbe Breite. */
  .card-grid:not(.cols-2):has(> :nth-child(1 of :not(.span-all, .modal-backdrop)):nth-last-child(2 of :not(.span-all, .modal-backdrop))) > :not(.span-all),
  .card-grid:not(.cols-2):has(> :nth-child(1 of :not(.span-all, .modal-backdrop)):nth-last-child(4 of :not(.span-all, .modal-backdrop))) > :not(.span-all) { grid-column: span 6; }
  /* Zwei je Reihe: eine einzelne letzte Kachel mittig. */
  .card-grid.cols-2 > :nth-child(2n+3 of :not(.span-all, .modal-backdrop)):nth-last-child(1 of :not(.span-all, .modal-backdrop)) { grid-column: 4 / span 6; }
}

@media (min-width: 901px) and (max-width: 1280px) {
  .card-grid > :nth-child(2n+3 of :not(.span-all, .modal-backdrop)):nth-last-child(1 of :not(.span-all, .modal-backdrop)) { grid-column: 4 / span 6; }
}

@media (max-width: 900px) {
  .card-grid { grid-template-columns: minmax(0, 1fr); }
  .card-grid > * { grid-column: 1 / -1; }
}


/* Fünf Kennzahlen (.stat-grid.cols-5, Dashboard und Kundenseite): auf breiten Bildschirmen in einer Reihe, darunter 3 + 2 mittig
   statt 4 + 1 mit Lücke, auf dem Telefon 2 + 2 + 1. */
.stat-grid.cols-5 { grid-template-columns: repeat(5, minmax(0, 1fr)); }
@media (min-width: 641px) and (max-width: 1180px) {
  .stat-grid.cols-5 { grid-template-columns: repeat(6, minmax(0, 1fr)); }
  .stat-grid.cols-5 > * { grid-column: span 2; }
  .stat-grid.cols-5 > :nth-child(4) { grid-column: 2 / span 2; }
  .stat-grid.cols-5 > :nth-child(5) { grid-column: 4 / span 2; }
}

/* Kennzahlen auf dem Telefon (zwei je Reihe): eine einzelne letzte Kachel nimmt die ganze Reihe ein. */
@media (max-width: 640px) {
  .stat-grid.cols-5 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .stat-grid > .stat-card:nth-child(odd):last-child { grid-column: 1 / -1; }
}

/* Kundenseite, Reiter Standorte: Anschrift und Notiz dürfen umbrechen, damit die Tabelle auf dem Desktop nicht seitlich scrollt. */
.sites-table td.site-name { white-space: normal; min-width: 200px; }
.sites-table td.site-name .cell-sub { max-width: 44ch; }
.sites-table td.site-address { white-space: normal; min-width: 180px; }

/* Ende Kundenseite und Kachelraster */

/* ---------- Aktionen am Gerät ---------- */

/* Kacheln mit sichtbarer Beschreibung (ActionCard): Titel, darunter leise die Beschreibung, unten links der Zustand und rechts die
   Schaltfläche. Die Kacheln einer Zeile sind gleich hoch und die Fußzeile sitzt unten, damit die Schaltflächen bündig stehen. */
.action-card.described {
  flex-direction: column; align-items: stretch; justify-content: flex-start; gap: var(--sp-3);
  padding: var(--sp-3);
}
.action-card.described .action-title { line-height: 1.3; }
.action-card .action-desc { max-width: none; margin-top: var(--sp-1); font-size: var(--fs-small); line-height: 1.4; color: var(--c-muted); }
.action-card.described .action-state { margin-top: 0; font-size: var(--fs-small); color: var(--c-text); }
.action-card.described .action-card-text > .action-state { margin-top: var(--sp-2); }
.action-card .action-state.tone-warn { color: var(--c-warn-ink); }
.action-card .action-state.tone-info { color: var(--c-info-ink); }
.action-card-foot { display: flex; align-items: center; flex-wrap: wrap; gap: var(--sp-2); margin-top: auto; }
.action-card-foot > .action-state { flex: 1 1 auto; min-width: 0; }
.action-card-foot > .btn { margin-left: auto; }
.action-card-foot > .action-input { flex: 1 1 160px; min-width: 0; max-width: 360px; }
/* Bleibt bei ungerader Zahl eine Kachel allein, nimmt sie die ganze Zeile ein statt eine Lücke zu lassen. */
.action-grid > .action-card.described:last-child:nth-child(odd) { grid-column: 1 / -1; }

/* Energie-Dialog: Schalter untereinander, der erklärende Satz ohne eigene Absatzabstände. */
.power-options { align-items: flex-start; }
.power-options > .hint { margin: 0; }

/* Ende Aktionen am Gerät */

/* ---------- Einstellungen ---------- */

/* Aufbau wie ein Nachschlagewerk: links das Verzeichnis der Gruppen, das beim Scrollen stehen bleibt, rechts Seitenkopf und je
   Gruppe Einleitung, Bereiche und Zeilen mit sichtbarer Beschreibung. Erkennungszeichen ist die Kante links an der Zeile:
   Akzent = ungespeichert, kritisch = ungültig, neutral = gespeichert und vom Standard abweichend.
   Der Seitenkopf steht in der rechten Spalte: So beginnt das Verzeichnis schon an seiner klebenden Stelle unter der Kopfzeile
   und springt beim Scrollen nicht nach oben, während Titel und Einleitung rechts normal wegscrollen. */
.set-layout {
  --set-desc: color-mix(in srgb, var(--c-text) 76%, var(--c-muted));
  display: grid;
  grid-template-columns: 212px minmax(0, 1fr);
  grid-template-rows: auto 1fr;
  grid-template-areas: "index head" "index main";
  gap: var(--sp-6) var(--sp-8);
  align-items: start;
  /* Sprung „nach oben“ (set-top): ganz an den Anfang. Den Abstand zur Kopfzeile hält scroll-padding-top am html-Element. */
  scroll-margin-top: var(--sp-5);
}
.set-layout > .page-head { grid-area: head; max-width: 1040px; margin-bottom: 0; }
.set-main { grid-area: main; min-width: 0; max-width: 1040px; }
.page-actions .set-search { flex: 0 1 320px; width: 320px; max-width: 100%; }

/* Verzeichnis: Gruppen wie die Seitenleiste, die aktive Gruppe klappt ihre Bereiche als Sprungmarken auf. */
.set-index {
  grid-area: index;
  position: sticky;
  top: calc(var(--header-h) + var(--sp-5));
  max-height: calc(100vh - var(--header-h) - 2 * var(--sp-5));
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: thin;
}
.set-index-pick { display: none; }
.set-index-list, .set-index-sections { list-style: none; margin: 0; padding: 0; }
.set-index-group, .set-index-section {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  width: 100%;
  background: transparent;
  border: 0;
  border-radius: var(--radius-sm);
  color: var(--c-text);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.set-index-group { min-height: 32px; padding: 5px 10px 5px 12px; margin: 1px 0; }
.set-index-group:hover, .set-index-section:hover { background: var(--c-hover); color: var(--c-text); }
.set-index-group.active { background: var(--c-accent-tint); font-weight: 600; }
.set-index-group.active::before {
  content: "";
  position: absolute;
  left: 0;
  top: 7px;
  bottom: 7px;
  width: 3px;
  border-radius: 2px;
  background: var(--c-accent-line);
}
.set-index-group.dim { color: var(--c-muted); }
.set-index-name { flex: 1 1 auto; min-width: 0; }
.set-index-count { font-size: var(--fs-label); color: var(--c-muted); font-weight: 400; font-variant-numeric: tabular-nums; }
.set-index .tab-badge { margin-left: 0; }
.set-index-sections { margin: 2px 0 var(--sp-2) 14px; padding-left: var(--sp-2); border-left: 1px solid var(--c-border-soft); }
.set-index-section { min-height: 28px; padding: 4px 8px; font-size: var(--fs-small); color: var(--c-muted); }
/* Wo man gerade liest, setzt das Skript beim Scrollen (aria-current). */
.set-index-section[aria-current] { color: var(--c-text); font-weight: 600; }
.set-index-section[aria-current]::before {
  content: "";
  position: absolute;
  left: calc(-1 * var(--sp-2) - 1px);
  top: 6px;
  bottom: 6px;
  width: 2px;
  border-radius: 2px;
  background: var(--c-accent-line);
}
.set-index-sep { margin-top: var(--sp-2); padding-top: var(--sp-2); border-top: 1px solid var(--c-border-soft); }

/* Zeichenerklärung unter dem Verzeichnis. */
.set-legend {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-top: var(--sp-5);
  padding: var(--sp-3) var(--sp-3) 0;
  border-top: 1px solid var(--c-border-soft);
  font-size: var(--fs-label);
  color: var(--c-muted);
}
.set-legend-row { display: flex; align-items: center; gap: var(--sp-2); }
.set-legend-edge { flex: 0 0 auto; width: 3px; height: 14px; border-radius: 2px; background: var(--c-border-strong); }
.set-legend-edge.dirty { background: var(--c-accent-line); }
.set-legend-edge.invalid { background: var(--c-crit); }
.set-legend-note { margin: 4px 0 0; line-height: 1.45; }

/* Kopf der Gruppe: Titel in der Anzeigeschrift, darunter die Einleitung in voller Textgröße. */
.set-group-head { padding-bottom: var(--sp-4); border-bottom: 1px solid var(--c-border-soft); }
.set-group-title { margin: 0; font-family: var(--font-display); font-size: 1.45rem; font-weight: 600; line-height: 1.2; letter-spacing: .005em; }
.set-group-lead { margin: var(--sp-2) 0 0; max-width: 76ch; line-height: 1.55; color: var(--set-desc); }
.set-group-lead .linklike { font-size: inherit; color: var(--c-accent-ink); margin-left: 4px; }

/* Bereich: Überschrift und Einleitung über einer Karte mit den Zeilen. */
.set-section { margin-top: var(--sp-6); scroll-margin-top: var(--sp-4); }
.set-section-head { margin-bottom: var(--sp-3); }
.set-section-head .section-title { display: flex; flex-wrap: wrap; align-items: center; gap: 4px var(--sp-2); margin: 0; }
.set-section-head-row { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: var(--sp-3); }
.set-section-lead { margin: 4px 0 0; max-width: 76ch; font-size: var(--fs-small); line-height: 1.5; color: var(--c-muted); }
.set-crumb { color: var(--c-muted); font-weight: 500; }
.set-section > .feature-locked { margin-bottom: var(--sp-3); }

.card.set-card { padding: 0; margin-bottom: 0; overflow: hidden; }
.card.set-card.is-locked, .card.set-card.is-locked .set-desc, .card.set-card.is-locked .set-meta { color: var(--c-faint); }

/* Zeile: Text links, Bedienelement rechts in fester Spalte; lange Texte, Wochentage und Regeln darunter in voller Breite. */
.set-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 320px;
  gap: var(--sp-2) var(--sp-6);
  align-items: start;
  padding: 14px var(--sp-4) 14px 18px;
  border-top: 1px solid var(--c-border-soft);
  scroll-margin-top: var(--sp-6);
}
.set-row:first-child { border-top: 0; }
.set-row.stacked { grid-template-columns: minmax(0, 1fr); gap: var(--sp-3); }
.set-row.custom { box-shadow: inset 3px 0 0 var(--c-border-strong); }
.set-row.dirty { box-shadow: inset 3px 0 0 var(--c-accent-line); background: var(--c-accent-wash); }
.set-row.invalid { box-shadow: inset 3px 0 0 var(--c-crit); background: color-mix(in srgb, var(--c-crit) 6%, transparent); }
.set-text { min-width: 0; }
.set-label { display: block; font-weight: 600; }
.set-desc { margin: 3px 0 0; max-width: 72ch; font-size: var(--fs-small); line-height: 1.5; color: var(--set-desc); }
.set-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 2px var(--sp-4);
  margin-top: 6px;
  font-size: var(--fs-label);
  color: var(--c-muted);
}
.set-meta strong { color: var(--c-text); font-weight: 600; }
.set-meta .linklike, .set-meta .linklike:hover { color: var(--c-accent-ink); }
.set-error { margin-top: 6px; font-size: var(--fs-small); font-weight: 600; color: var(--c-crit-ink); }
.set-row.invalid .set-control input:not([type=checkbox]), .set-row.invalid .set-control select, .set-row.invalid .set-control textarea { border-color: var(--c-crit); }

.set-control { display: flex; justify-content: flex-end; min-width: 0; }
.set-control > input, .set-control > select { width: 100%; }
.set-control > .input-unit { width: auto; }
.set-control .input-unit input[type=number] { width: 110px; flex: 0 0 auto; }
.set-control .input-unit > span { min-width: 34px; }
.set-control .input-unit input.mono { width: 120px; flex: 0 0 auto; }
.set-row.stacked .set-control { justify-content: flex-start; }
.set-row.stacked .set-control > textarea { width: 100%; min-height: 160px; resize: vertical; }
/* Regeln (Freigabe, Behebung) lesen sich in voller Breite wie ein Satz: Auswahl, dann die Tage bzw. die Wartezeit. */
.set-row.stacked .rule-input { flex-direction: row; flex-wrap: wrap; align-items: center; gap: var(--sp-2) var(--sp-5); }
.set-row.stacked .rule-input > select { width: auto; min-width: 220px; max-width: 100%; }
.set-control .rule-input .input-unit { width: auto; }
.set-control .rule-input .input-unit input[type=number] { width: 72px; }
.set-control .rule-input .input-unit > span { min-width: 0; }
/* Logo: Datei-Auswahl als Schaltfläche statt des Standardfelds des Browsers. */
.set-control .logo-input .upload-label:focus-within { outline: var(--focus-w) solid var(--c-focus); outline-offset: 2px; }
.set-control .logo-input .upload-label.disabled { opacity: .45; pointer-events: none; }

/* Suchtreffer: ruhig getönt statt gelb, damit die Zeile lesbar bleibt. */
.set-layout mark { background: var(--c-accent-tint-strong); color: inherit; border-radius: 3px; padding: 0 1px; }

/* Umschalter für Ein und Aus (auch im Richtlinien-Dialog): Zustand als Wort davor, Knopf in der Spur. */
.switch.toggle { gap: var(--sp-2); }
.toggle-state { min-width: 2em; font-size: var(--fs-small); color: var(--c-muted); text-align: right; }
.toggle input[type=checkbox] {
  width: 38px;
  min-width: 38px;
  height: 22px;
  min-height: 22px;
  padding: 0 3px;
  border-radius: 999px;
  border-color: var(--c-border-input);
  background: var(--c-elev);
  place-content: center start;
}
.toggle input[type=checkbox]::before {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  clip-path: none;
  background: var(--c-muted);
  transform: none;
  transition: transform .15s ease, background-color .15s ease;
}
.toggle input[type=checkbox]:checked { background: var(--c-accent-fill); border-color: var(--c-accent-line); }
.toggle input[type=checkbox]:checked::before { background: var(--c-accent-contrast); transform: translateX(16px); }

/* Speicherleiste: erscheint nur bei Änderungen, klebt am unteren Rand des Inhalts und zeigt auf Wunsch die Liste. */
.set-savebar {
  position: sticky;
  bottom: var(--sp-4);
  z-index: 30;
  margin-top: var(--sp-6);
  border: 1px solid var(--c-border);
  border-radius: var(--radius);
  background: var(--c-elev);
  box-shadow: inset 3px 0 0 var(--c-accent-line), var(--shadow);
  animation: toast-in .22s ease-out;
}
.set-savebar.has-invalid { box-shadow: inset 3px 0 0 var(--c-crit), var(--shadow); }
.set-savebar-row { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--sp-3); padding: 10px 12px 10px 18px; }
.set-savebar-state { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px var(--sp-3); min-width: 0; }
.set-savebar-invalid { font-size: var(--fs-small); font-weight: 600; color: var(--c-crit-ink); }
.set-savebar-state .linklike, .set-savebar-state .linklike:hover { font-size: var(--fs-small); color: var(--c-accent-ink); }
.set-savebar-actions { display: flex; gap: var(--sp-2); }
.set-changes { list-style: none; margin: 0; padding: 6px; max-height: min(40vh, 320px); overflow-y: auto; border-bottom: 1px solid var(--c-border-soft); }
.set-change {
  display: grid;
  grid-template-columns: minmax(0, 15rem) minmax(0, 1fr) auto;
  align-items: baseline;
  gap: var(--sp-3);
  width: 100%;
  padding: 6px 10px;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--c-text);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.set-change:hover { background: var(--c-hover); }
.set-change-where { overflow: hidden; font-size: var(--fs-label); color: var(--c-muted); white-space: nowrap; text-overflow: ellipsis; }
.set-change-what { font-weight: 600; }
.set-change-value { font-size: var(--fs-small); color: var(--c-muted); text-align: right; }
.set-change.invalid .set-change-value { color: var(--c-crit-ink); }
/* Toasts erscheinen über der Leiste statt auf ihr. */
body:has(.set-savebar) .toast-stack { bottom: 92px; }

@media (prefers-reduced-motion: reduce) {
  .toggle input[type=checkbox]::before { transition: none; }
  .set-savebar { animation: none; }
}

/* Mittlere Breite: Neben Seitenleiste und Verzeichnis bliebe dem Text zu wenig Platz; das Bedienelement rückt unter den Text. */
@media (max-width: 1240px) {
  .set-layout { grid-template-columns: 188px minmax(0, 1fr); gap: var(--sp-6); }
  .set-row { grid-template-columns: minmax(0, 1fr); gap: var(--sp-3); }
  .set-control { justify-content: flex-start; }
  .set-control > input, .set-control > select { max-width: 460px; }
}

/* Schmal und Telefon: das Verzeichnis wird zur Auswahl über dem Inhalt, das Bedienelement rückt unter den Text. */
@media (max-width: 900px) {
  .page-actions .set-search { flex: 1 1 100%; width: 100%; }
  .set-layout { grid-template-columns: minmax(0, 1fr); grid-template-rows: none; grid-template-areas: "head" "index" "main"; gap: var(--sp-4); }
  .set-index { position: static; max-height: none; overflow: visible; }
  .set-index-list, .set-legend { display: none; }
  .set-index-pick { display: block; }
  .set-row { grid-template-columns: minmax(0, 1fr); gap: var(--sp-3); padding: 12px 14px 12px 16px; }
  .set-control { justify-content: flex-start; }
  .set-control > input, .set-control > select { max-width: 460px; }
  .set-change { grid-template-columns: minmax(0, 1fr); gap: 0; }
  .set-change-value { text-align: left; }
}

@media (max-width: 640px) {
  .set-group-title { font-size: 1.25rem; }
  .set-section { margin-top: var(--sp-5); }
  .set-savebar { bottom: var(--sp-2); }
  .set-savebar-row { padding: 10px 12px 12px 16px; }
  .set-savebar-actions { width: 100%; }
  .set-savebar-actions .btn { flex: 1 1 0; }
  .set-row.stacked .rule-input { flex-direction: column; align-items: flex-start; }
  .set-control .rule-input .input-unit > span:first-child { min-width: 4.6em; }
  body:has(.set-savebar) .toast-stack { bottom: 132px; }
}

/* Ende Einstellungen */

/* ---------- Proxy für den Agent ---------- */

/* Installationsdialog: Feld „Proxy (optional)“ zwischen Token und Befehlen. */
.install-proxy { margin-bottom: var(--sp-3); }
.install-proxy input { font-family: var(--mono); }
/* Hinweis zur Anmeldung am Proxy unter Linux: Optionen wie --proxy-user nicht am Bindestrich umbrechen. */
.install-hint .mono { white-space: nowrap; }
/* Warnung „http:// und Proxy“ im Bereich Proxy der Einstellungen und Richtlinien. */
.notice.proxy-http-warning { padding: 8px 12px; margin: var(--sp-2) 0 var(--sp-3); }
/* Agent-Karte: Proxy-Adresse bricht an den vorgesehenen Stellen um (nach Punkten, vor dem Port), mitten im Wort nur im Notfall. */
.agent-proxy-address { overflow-wrap: break-word; word-break: normal; }

/* Ende Proxy für den Agent */

/* ---------- Kopfzeile und Benutzermenü ---------- */

/* Aufbau: links die Seitenleiste über die ganze Höhe, rechts oben die Kopfzeile, die beim Scrollen stehen bleibt, darunter der
   Inhalt. Die Kopfzeile trägt rechts den angemeldeten Benutzer; sein Menü ist ein details-Element (Layout/UserMenu.razor), das
   wwwroot/js/app.js bei Klick daneben, mit Esc und nach einem Seitenwechsel schließt. Marke und Kopfzeile bilden zusammen eine
   durchgehende Leiste. Die erste Reihe ist so hoch wie ihr Inhalt (Kopfzeile, auf schmalen Bildschirmen die Kopfleiste der
   Seitenleiste), der Rest gehört der Seite; sonst streckte das Raster bei kurzen Seiten die erste Reihe. */
.app-shell { grid-template-rows: auto 1fr; }
.sidebar { grid-column: 1; grid-row: 1 / span 2; }
.app-header { grid-column: 2; grid-row: 1; }
.content { grid-column: 2; grid-row: 2; }
/* Sprungziele, Anker und per Tab fokussierte Elemente landen unter der Kopfzeile statt dahinter (auf schmalen Bildschirmen unter
   der klebenden Kopfleiste). Eigene Abstände der Ziele kommen mit scroll-margin-top dazu. */
html { scroll-padding-top: var(--header-h); }

.app-header {
  position: sticky;
  top: 0;
  z-index: 40;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  height: var(--header-h);
  padding: 0 var(--sp-4) 0 28px;
  background: var(--c-chrome);
  border-bottom: 1px solid var(--c-border-soft);
}
.brand { height: var(--header-h); padding: 0 16px; margin-bottom: var(--sp-3); border-bottom: 1px solid var(--c-border-soft); }
/* Marke und Suche haben feste Höhen; auch wenn die ganze Leiste scrollt (niedriges Fenster, geöffnetes Menü auf dem Telefon),
   staucht die Flexbox sie nicht. */
.sidebar > .brand, .sidebar > .nav-search { flex-shrink: 0; }

/* Dialoge aus den Inseln der Seitenleiste (Suche, Agent installieren) und des Menüs (Changelog) liegen über allem außer Toasts. */
.sidebar:has(.modal-backdrop), .app-header:has(.modal-backdrop) { z-index: 230; }
/* Auch bei geöffnetem Menü auf schmalen Bildschirmen (dort liegt die Kopfleiste mit 201 über der Seitenleiste mit 200). */
.sidebar:has(> .nav-check:checked):has(.modal-backdrop) { z-index: 230; }

/* Knopf: Kürzel im Kreis, Name und Pfeil, ruhig wie die Einträge der Seitenleiste. */
.user-menu { position: relative; }
.user-trigger {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  max-width: 280px;
  min-height: 38px;
  padding: 3px 10px 3px 4px;
  border: 1px solid transparent;
  border-radius: 999px;
  color: var(--c-text);
  font-size: var(--fs-small);
  font-weight: 600;
  list-style: none;
  cursor: pointer;
  user-select: none;
}
.user-trigger::-webkit-details-marker { display: none; }
.user-trigger:hover { background: var(--c-hover); }
.user-menu[open] > .user-trigger { background: var(--c-hover); border-color: var(--c-border); }
.user-trigger-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.user-trigger-caret::after { content: "\25be"; display: inline-block; font-size: .7rem; line-height: 1; color: var(--c-muted); transition: transform .12s ease; }
.user-menu[open] .user-trigger-caret::after { transform: rotate(180deg); }

.user-avatar {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: var(--c-accent-tint);
  color: var(--c-accent-ink);
  font-size: .78rem;
  font-weight: 700;
}
.user-avatar.big { width: 64px; height: 64px; font-size: 1.35rem; }

/* Karte unter dem Knopf: oben Rolle und „Abmelden“, dann der Benutzer mit „Mein Konto“, die Darstellung und leise die Angaben
   zu Version, Paket, Betreuung und die Links. */
.user-panel {
  position: absolute;
  top: calc(100% + 7px);
  right: 0;
  z-index: 2;
  width: 340px;
  max-width: calc(100vw - 2 * var(--sp-4));
  max-height: calc(100vh - var(--header-h) - var(--sp-4));
  overflow-y: auto;
  overscroll-behavior: contain;
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
  animation: user-panel-in .12s ease-out;
}
.user-panel:focus { outline: none; }
@keyframes user-panel-in { from { opacity: 0; } to { opacity: 1; } }

.user-panel-top { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); padding: 8px 8px 0 var(--sp-4); }
.user-panel-role { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--fs-label); font-weight: 600; color: var(--c-muted); }
.user-panel-top form { flex: 0 0 auto; margin: 0; }
.user-signout {
  min-height: var(--control-h-sm);
  padding: 4px 10px;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--c-text);
  font: inherit;
  font-size: var(--fs-small);
  cursor: pointer;
}
.user-signout:hover { background: var(--c-hover); }

.user-panel-id { display: flex; align-items: center; gap: var(--sp-4); padding: var(--sp-2) var(--sp-4) var(--sp-4); }
.user-panel-who { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; min-width: 0; }
.user-panel-name { font-size: var(--fs-section); font-weight: 600; line-height: 1.3; overflow-wrap: anywhere; }
.user-panel-mail { font-size: var(--fs-small); color: var(--c-muted); overflow-wrap: anywhere; }
.user-panel-account { margin-top: 4px; font-size: var(--fs-small); font-weight: 600; }

.user-panel-section { padding: var(--sp-3) var(--sp-4) var(--sp-4); border-top: 1px solid var(--c-border-soft); }
.user-panel-label { margin-bottom: 6px; font-size: var(--fs-label); font-weight: 600; color: var(--c-muted); }

/* Darstellung: drei gleich breite Felder, das gewählte hebt sich ab. Umgeschaltet wird ohne Neuladen (wwwroot/js/app.js). */
.theme-switch {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 2px;
  padding: 2px;
  border: 1px solid var(--c-border-soft);
  border-radius: var(--radius-sm);
  background: var(--c-elev);
}
.theme-switch button {
  min-height: var(--control-h-sm);
  border: 0;
  border-radius: 4px;
  background: transparent;
  color: var(--c-muted);
  font: inherit;
  font-size: var(--fs-small);
  font-weight: 600;
  cursor: pointer;
}
.theme-switch button:hover { color: var(--c-text); }
.theme-switch button[aria-pressed="true"] { background: var(--c-surface); color: var(--c-text); box-shadow: 0 0 0 1px var(--c-border); }

.user-panel-info {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: var(--sp-3) var(--sp-4) 14px;
  border-top: 1px solid var(--c-border-soft);
  background: var(--c-elev);
  font-size: var(--fs-label);
}
.user-panel-info .build-info { font-size: var(--fs-label); }
.user-panel-support { margin-top: 6px; }
.user-panel-support .user-panel-label { margin-bottom: 2px; }
.support-info.in-menu { margin: 0; }
.user-panel-links { display: flex; flex-wrap: wrap; gap: 2px var(--sp-3); margin-top: 6px; }

@media (prefers-reduced-motion: reduce) {
  .user-panel { animation: none; }
  .user-trigger-caret::after { transition: none; }
}

/* Schmal und Telefon: Die Seitenleiste ist die klebende Kopfleiste (Marke mit „Menü“, darunter die Suche). Der Benutzerknopf
   sitzt rechts in ihrer ersten Zeile, das Menü öffnet darunter als Blatt in voller Breite über abgedunkeltem Inhalt; ein Tipp
   daneben schließt es (die Abdunklung gehört zum Knopf). --header-h ist hier die Höhe der ganzen Leiste. */
@media (max-width: 900px) {
  :root { --bar-h: 56px; --header-h: 97px; }
  .sidebar, .content { grid-column: 1; grid-row: auto; }
  .app-header {
    position: fixed;
    top: 0;
    right: 0;
    z-index: 21;
    height: var(--bar-h);
    padding: 0 12px 0 0;
    background: transparent;
    border-bottom: 0;
  }
  /* Über dem geöffneten Menü der Seitenleiste bleibt der Knopf an seiner Stelle. */
  .app-shell:has(> .sidebar > .nav-check:checked) > .app-header { z-index: 201; }
  .brand { height: var(--bar-h); padding: 0 64px 0 16px; margin-bottom: 0; border-bottom: 0; }
  .nav-search { height: 32px; min-height: 32px; }
  /* Im geöffneten Menü bleibt die Zeile mit Marke und „Schließen“ oben stehen. */
  .nav-check:checked ~ .brand { position: sticky; top: 0; z-index: 1; background: var(--c-chrome); }

  .user-trigger { min-width: 40px; min-height: 40px; padding: 4px; }
  .user-trigger:hover { background: transparent; }
  .user-trigger-name, .user-trigger-caret { display: none; }
  .user-menu[open] > .user-trigger { background: transparent; border-color: transparent; }
  .user-menu[open] > .user-trigger .user-avatar { box-shadow: 0 0 0 2px var(--c-accent-line); }
  .user-menu[open] > .user-trigger::before {
    content: "";
    position: fixed;
    inset: var(--bar-h) 0 0 0;
    background: var(--c-backdrop);
    cursor: default;
  }
  /* Tablet: Karte rechts unter der Leiste; Telefon (bis 640 px): Blatt in voller Breite. */
  .user-panel {
    position: fixed;
    top: var(--bar-h);
    right: 0;
    width: 380px;
    max-width: 100vw;
    max-height: calc(100dvh - var(--bar-h));
    border-width: 1px 0 1px 1px;
    border-radius: 0 0 0 var(--radius-lg);
  }
  .user-avatar.big { width: 56px; height: 56px; font-size: 1.2rem; }
}

@media (max-width: 640px) {
  .user-panel { left: 0; width: auto; border-width: 1px 0; border-radius: 0; }
}

@media (max-width: 900px) and (pointer: coarse) {
  :root { --header-h: 109px; }
  .nav-search { height: 44px; }
  .user-trigger { min-width: 44px; min-height: 44px; }
  .user-signout { min-height: 44px; padding: 8px 12px; }
  .theme-switch button { min-height: 40px; }
}

/* Ende Kopfzeile und Benutzermenü */

/* ---------- Skript-Bibliothek ---------- */

/* Aufbau wie die Einstellungen: links das Verzeichnis der Kategorien, das beim Scrollen stehen bleibt, rechts die Übersicht als
   Kacheln, eine Kategorie mit ihren Skripten oder die Treffer der Suche. Abstand oben mit --header-h, falls eine Kopfzeile klebt. */
.lib-layout {
  --lib-desc: color-mix(in srgb, var(--c-text) 76%, var(--c-muted));
  display: grid;
  grid-template-columns: 212px minmax(0, 1fr);
  /* Seitenkopf in der rechten Spalte wie bei den Einstellungen: Das Verzeichnis springt beim Scrollen nicht. */
  grid-template-rows: auto 1fr;
  grid-template-areas: "index head" "index main";
  gap: var(--sp-6) var(--sp-8);
  align-items: start;
}
.lib-layout > .page-head { grid-area: head; max-width: 1180px; margin-bottom: 0; }
.lib-index { grid-area: index; }
.lib-main { grid-area: main; min-width: 0; max-width: 1180px; }
.page-actions .lib-search { flex: 0 1 320px; width: 320px; max-width: 100%; }

/* Verzeichnis: Übersicht, Kategorien mit Zahl, „Ohne Kategorie“; darunter Anlegen und Herkunft. */
.lib-index {
  position: sticky;
  top: calc(var(--header-h, 0px) + var(--sp-5));
  max-height: calc(100vh - var(--header-h, 0px) - 2 * var(--sp-5));
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: thin;
}
.lib-index-pick { display: none; }
.lib-index-list { list-style: none; margin: 0; padding: 0; }
.lib-index-item {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  min-height: 32px;
  padding: 5px 10px 5px 12px;
  margin: 1px 0;
  border-radius: var(--radius-sm);
  color: var(--c-text);
  text-decoration: none;
}
.lib-index-item:hover { background: var(--c-hover); color: var(--c-text); text-decoration: none; }
.lib-index-item:focus-visible { outline: var(--focus-w) solid var(--c-focus); outline-offset: -2px; }
.lib-index-item.active { background: var(--c-accent-tint); font-weight: 600; }
.lib-index-item.active::before {
  content: "";
  position: absolute;
  left: 0;
  top: 7px;
  bottom: 7px;
  width: 3px;
  border-radius: 2px;
  background: var(--c-accent-line);
}
.lib-index-item.dim { color: var(--c-muted); }
.lib-index-name { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; }
.lib-index-count { font-size: var(--fs-label); color: var(--c-muted); font-weight: 400; font-variant-numeric: tabular-nums; }
.lib-index-sep { margin-top: var(--sp-2); padding-top: var(--sp-2); border-top: 1px solid var(--c-border-soft); }

.lib-index-tools { display: flex; flex-direction: column; gap: var(--sp-4); margin-top: var(--sp-3); }
.lib-index-add { width: 100%; }
.lib-origin {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: var(--sp-3) var(--sp-3) 0;
  border-top: 1px solid var(--c-border-soft);
}
.lib-origin-label { font-size: var(--fs-label); color: var(--c-muted); }
/* Umschalter mit drei Stellungen: ein Rahmen, die gewählte Stellung im Akzent getönt. */
.lib-seg { display: flex; border: 1px solid var(--c-border); border-radius: var(--radius-sm); overflow: hidden; }
.lib-seg-btn {
  flex: 1 1 auto;
  min-height: var(--control-h-sm);
  padding: 2px 8px;
  border: 0;
  border-left: 1px solid var(--c-border);
  background: transparent;
  color: var(--c-muted);
  font: inherit;
  font-size: var(--fs-label);
  white-space: nowrap;
  cursor: pointer;
}
.lib-seg-btn:first-child { border-left: 0; }
.lib-seg-btn:hover { background: var(--c-hover); color: var(--c-text); }
.lib-seg-btn:focus-visible { outline: var(--focus-w) solid var(--c-focus); outline-offset: -2px; }
.lib-seg-btn.on { background: var(--c-accent-tint); color: var(--c-accent-ink); font-weight: 600; }

/* Kopf rechts: Titel in der Anzeigeschrift, darunter die Beschreibung; Aktionen daneben. */
.lib-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--sp-3) var(--sp-6);
  padding-bottom: var(--sp-4);
  border-bottom: 1px solid var(--c-border-soft);
}
.lib-head-text { flex: 1 1 360px; min-width: 0; }
.lib-title {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px var(--sp-2);
  margin: 0;
  font-family: var(--font-display);
  font-size: 1.45rem;
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: .005em;
}
.lib-title .count { color: var(--c-muted); font-weight: 400; font-size: 1.05rem; font-variant-numeric: tabular-nums; }
.lib-title .pill { font-family: var(--font); letter-spacing: normal; }
.lib-lead { margin: var(--sp-2) 0 0; max-width: 76ch; line-height: 1.55; color: var(--lib-desc); }
.lib-lead.muted { color: var(--c-muted); }
.lib-lead .linklike { font-size: inherit; color: var(--c-accent-ink); margin-left: 4px; }
.lib-head-actions { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.lib-empty { margin-top: var(--sp-5); }
.lib-empty .linklike { font-size: inherit; color: var(--c-accent-ink); margin-left: 4px; }

/* Übersicht: Kategorien als Kacheln wie in der Skriptauswahl, mit Beschreibung. */
.lib-tiles {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(17rem, 1fr));
  gap: var(--sp-3);
  margin-top: var(--sp-5);
}
.lib-tile {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
  min-width: 0;
  padding: 14px 16px;
  border: 1px solid var(--c-border);
  border-radius: var(--radius-sm);
  background: var(--c-elev);
  color: var(--c-text);
  text-decoration: none;
}
.lib-tile:hover, .lib-tile:focus-visible { border-color: var(--c-accent-line); background: var(--c-hover); color: var(--c-text); text-decoration: none; }
.lib-tile:focus-visible { outline: var(--focus-w) solid var(--c-focus); outline-offset: 2px; }
.lib-tile-head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--sp-2); width: 100%; }
.lib-tile-head .pill { flex: 0 0 auto; }
.lib-tile-name { flex: 1 1 auto; min-width: 0; font-weight: 600; overflow-wrap: anywhere; }
.lib-tile-meta { color: var(--c-muted); font-size: var(--fs-label); }
.lib-tile-desc {
  display: -webkit-box;
  margin-top: 2px;
  overflow: hidden;
  font-size: var(--fs-small);
  line-height: 1.45;
  color: var(--lib-desc);
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  line-clamp: 3;
}
.lib-tile.is-empty { border-style: dashed; background: transparent; }
.lib-tile.is-empty:hover { background: var(--c-hover); }

/* Skripte einer Kategorie oder eines Suchtreffers: ruhige Zeilen in einer Karte, Aktionen rechts. */
.lib-section { margin-top: var(--sp-5); }
.lib-section-head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 4px var(--sp-3); margin-bottom: var(--sp-2); }
.lib-section-head .section-title { margin: 0; }
.lib-section-head .lib-open { color: var(--c-accent-ink); font-size: var(--fs-small); }
.card.lib-list { padding: 0; margin-bottom: 0; overflow: hidden; }
.lib-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3) var(--sp-6);
  padding: 12px var(--sp-4) 12px 18px;
  border-top: 1px solid var(--c-border-soft);
}
.lib-row:first-child { border-top: 0; }
.lib-row:hover { background: color-mix(in srgb, var(--c-hover) 55%, transparent); }
.lib-row-text { flex: 1 1 auto; min-width: 0; }
.lib-row-title { display: flex; flex-wrap: wrap; align-items: center; gap: 4px var(--sp-2); }
.lib-row-name {
  padding: 0;
  border: 0;
  background: none;
  color: var(--c-text);
  font: inherit;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
}
.lib-row-name:hover { color: var(--c-accent-ink); text-decoration: underline; }
.lib-row-name:focus-visible { outline: var(--focus-w) solid var(--c-focus); outline-offset: 2px; border-radius: 2px; }
.lib-row-desc { margin: 3px 0 0; max-width: 84ch; font-size: var(--fs-small); line-height: 1.5; color: var(--lib-desc); }
.lib-row-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 2px var(--sp-4);
  margin-top: 6px;
  font-size: var(--fs-label);
  color: var(--c-muted);
}
.lib-row-actions { display: flex; flex: 0 0 auto; gap: var(--sp-2); }

/* Kategorie-Dialog: Beschreibung mehrzeilig, aber knapp. */
.lib-category-form textarea { min-height: 76px; resize: vertical; }

/* Suchtreffer: ruhig getönt wie in den Einstellungen. */
.lib-layout mark { background: var(--c-accent-tint-strong); color: inherit; border-radius: 3px; padding: 0 1px; }

/* Mittlere Breite: Verzeichnis schmaler. */
@media (max-width: 1240px) {
  .lib-layout { grid-template-columns: 188px minmax(0, 1fr); gap: var(--sp-6); }
}

/* Schmal und Telefon: das Verzeichnis wird zur Auswahl über dem Inhalt, Anlegen und Herkunft stehen darunter in einer Reihe. */
@media (max-width: 900px) {
  .page-actions .lib-search { flex: 1 1 100%; width: 100%; }
  .lib-layout { grid-template-columns: minmax(0, 1fr); grid-template-rows: none; grid-template-areas: "head" "index" "main"; gap: var(--sp-4); }
  .lib-index { position: static; display: flex; flex-wrap: wrap; gap: var(--sp-2) var(--sp-3); max-height: none; overflow: visible; }
  .lib-index-list { display: none; }
  .lib-index-pick { display: block; flex: 1 1 100%; width: 100%; }
  .lib-index-tools { flex: 1 1 100%; flex-direction: row; flex-wrap: wrap; align-items: center; gap: var(--sp-2) var(--sp-3); margin-top: 0; }
  .lib-index-add { width: auto; order: 2; }
  .lib-origin { flex-direction: row; align-items: center; gap: var(--sp-2); padding: 0; border-top: 0; }
  .lib-row { flex-wrap: wrap; }
}

@media (max-width: 640px) {
  .lib-title { font-size: 1.25rem; }
  .lib-head-actions { width: 100%; }
  .lib-head-actions .btn { flex: 1 1 0; }
  .lib-tiles { grid-template-columns: minmax(0, 1fr); gap: var(--sp-2); margin-top: var(--sp-4); }
  .lib-row { padding: 12px 14px; }
  .lib-row-actions { width: 100%; }
  .lib-row-actions .btn { flex: 1 1 0; }
  .lib-index-tools { justify-content: space-between; }
  .lib-origin-label { display: none; }
}

/* Ende Skript-Bibliothek */

/* ---------- Installations-Tokens ---------- */

/* Filterleiste: Suche schmaler als üblich, damit vier Auswahlen und „Filter zurücksetzen“ auf dem Desktop in eine Zeile passen. */
.tok-toolbar .search { flex-basis: 200px; }

/* Liste: Lange Notizen brechen um, statt die Tabelle zu verbreitern. Die Beschriftungen („Erzeugt“, „gültig bis“)
   braucht nur die gestapelte Telefonansicht ohne Spaltenköpfe. */
.tok-table td.tok-note { white-space: normal; min-width: 160px; max-width: 40ch; overflow-wrap: anywhere; }
.tok-table .tok-label { display: none; }
.tok-table .tok-prefix .link-button { font-size: var(--fs-small); }
/* Restlaufzeit eines bald ablaufenden Tokens, hinter dem Datum. */
.tok-soon { margin-left: var(--sp-2); color: var(--c-warn-ink); font-weight: 600; font-size: var(--fs-small); white-space: nowrap; }

/* Leer-Zustand mit Schaltfläche darunter. */
.card.empty.tok-empty p { max-width: 72ch; margin: 0 auto var(--sp-3); }

/* Detail: Eckdaten, darunter die Geräte in einer schlanken Tabelle mit eigener Rollfläche bei vielen Einträgen. */
.tok-kv { margin-bottom: var(--sp-2); }
.tok-kv dd .pill { vertical-align: baseline; }
.tok-state-note { margin-left: var(--sp-2); font-size: var(--fs-small); }
.tok-devices { max-height: 320px; overflow-y: auto; overscroll-behavior: contain; margin-bottom: var(--sp-2); }
.tok-devices th, .tok-devices td { padding: 6px 12px; }
.tok-devices td .cell-sub { display: block; }
.modal-section + .tok-hint { margin: calc(-1 * var(--sp-1)) 0 var(--sp-2); }

@media (max-width: 640px) {
  .tok-toolbar .search { flex-basis: 100%; }
  /* Tokens gestapelt: Präfix und Status oben, darunter Kunde und Registrierungen, dann Notiz und die Zeitangaben.
     Ohne das würde eine achtspaltige Tabelle auf dem Telefon seitlich rollen. */
  .tok-table thead { display: none; }
  .tok-table, .tok-table tbody { display: block; }
  .tok-table tr {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas: "prefix state" "cust uses" "note note" "created by" "expires expires";
    align-items: center;
    gap: 2px var(--sp-2);
    padding: 10px var(--sp-3);
    border-bottom: 1px solid var(--c-border-soft);
  }
  .tok-table tbody tr:last-child { border-bottom: 0; }
  .table-wrap .tok-table td { display: block; padding: 0; border: 0; min-width: 0; max-width: none; white-space: normal; box-shadow: none; }
  /* Die Statuskante wandert von der ersten Zelle an die ganze Zeile. */
  .tok-table tr.edge-warn { box-shadow: inset 3px 0 0 var(--c-warn); }
  .tok-table tr.edge-warn > td:first-child { box-shadow: none; }
  .tok-table .tok-prefix { grid-area: prefix; }
  .tok-table .tok-state { grid-area: state; text-align: right; }
  .tok-table .tok-cust { grid-area: cust; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .tok-table .tok-uses { grid-area: uses; font-size: var(--fs-small); color: var(--c-muted); }
  .tok-table .tok-note { grid-area: note; font-size: var(--fs-small); }
  .tok-table .tok-note.muted { display: none; }
  .tok-table .tok-created { grid-area: created; font-size: var(--fs-small); }
  .tok-table .tok-by { grid-area: by; font-size: var(--fs-small); text-align: right; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 45vw; }
  .tok-table .tok-expires { grid-area: expires; font-size: var(--fs-small); }
  .tok-table .tok-label { display: inline; }
  .tok-devices { max-height: none; }
}

/* Ende Installations-Tokens */

/* ---------- Verbindungsabbruch ---------- */

/* Anzeige, wenn die Verbindung zum Server abreißt (Components/Layout/ReconnectModal.razor, wwwroot/js/reconnect.js).
   Das dialog-Element liegt in der obersten Ebene über allem, auch über Dialogen und Toasts, und ist selbst die abgedunkelte
   Fläche; darin eine Karte mit der Statuskante in der Farbe des Zustands: Warnung beim Wiederverbinden, kritisch ohne Server,
   ok, wenn er wieder antwortet, neutral bei angehaltener Sitzung. Sichtbar wird sie erst nach einer halben Sekunde, damit
   kurze Aussetzer (Tab im Hintergrund, Netzwechsel) nicht aufblitzen. */
#components-reconnect-modal {
  --reconnect-tone: var(--c-warn);
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  max-width: none;
  max-height: none;
  margin: 0;
  padding: var(--sp-4);
  border: 0;
  background: var(--c-backdrop);
  backdrop-filter: blur(2px);
  color: var(--c-text);
  overflow-y: auto;
  overscroll-behavior: contain;
}
#components-reconnect-modal[open] { display: grid; place-items: center; animation: reconnect-fade .2s ease-out .5s both; }
#components-reconnect-modal::backdrop { background: transparent; }
body:has(#components-reconnect-modal[open]) { overflow: hidden; }

#components-reconnect-modal:is([data-state="failed"], [data-state="resume-failed"]) { --reconnect-tone: var(--c-crit); }
#components-reconnect-modal[data-state="rejected"] { --reconnect-tone: var(--c-ok); }
#components-reconnect-modal[data-state="paused"] { --reconnect-tone: var(--c-border-strong); }
/* Läuft ein Versuch über „Erneut versuchen“ oder „Fortsetzen“, gilt wieder die Farbe des Wiederverbindens. */
#components-reconnect-modal[data-busy] { --reconnect-tone: var(--c-warn); }

/* Je Zustand nur die passenden Zeilen und Schaltflächen (data-for in der Komponente). */
#components-reconnect-modal:not([data-state]) [data-for],
#components-reconnect-modal[data-state="connecting"] [data-for]:not([data-for~="connecting"]),
#components-reconnect-modal[data-state="waiting"] [data-for]:not([data-for~="waiting"]),
#components-reconnect-modal[data-state="failed"] [data-for]:not([data-for~="failed"]),
#components-reconnect-modal[data-state="rejected"] [data-for]:not([data-for~="rejected"]),
#components-reconnect-modal[data-state="paused"] [data-for]:not([data-for~="paused"]),
#components-reconnect-modal[data-state="resume-failed"] [data-for]:not([data-for~="resume-failed"]) { display: none; }

/* Karte: Punkt links, Text daneben; die Schaltflächen nehmen die ganze Breite der Karte. */
.reconnect-card {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  column-gap: var(--sp-3);
  width: min(440px, 100%);
  padding: var(--sp-5) var(--sp-5) var(--sp-5) calc(var(--sp-5) + 3px);
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: var(--radius-lg);
  box-shadow: inset 3px 0 0 var(--reconnect-tone), var(--shadow);
}
#components-reconnect-modal[open] .reconnect-card { animation: reconnect-rise .25s ease-out .5s both; }

.reconnect-dot {
  width: 10px;
  height: 10px;
  margin-top: .42em;
  border-radius: 50%;
  background: var(--reconnect-tone);
}
/* Der Punkt pulsiert, solange ein Versuch läuft; beim Warten auf den nächsten steht er still. */
#components-reconnect-modal:is([data-state="connecting"], [data-busy]) .reconnect-dot { animation: reconnect-pulse 1.4s ease-out infinite; }

.reconnect-body { min-width: 0; }
.reconnect-title { margin: 0 0 var(--sp-1); font-size: 1.1rem; font-weight: 600; line-height: 1.3; }
.reconnect-text { margin: 0; color: var(--c-text); }
.reconnect-meta,
.reconnect-note { margin: var(--sp-2) 0 0; font-size: var(--fs-small); color: var(--c-muted); font-variant-numeric: tabular-nums; }
.reconnect-note:empty,
.reconnect-meta:has(#components-reconnect-current-attempt:empty),
.reconnect-max:has(#components-reconnect-max-retries:empty) { display: none; }

.reconnect-actions {
  grid-column: 1 / -1;
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: var(--sp-2);
  margin-top: var(--sp-5);
}

@keyframes reconnect-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes reconnect-rise { from { transform: translateY(10px); } to { transform: none; } }
@keyframes reconnect-pulse {
  0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--reconnect-tone) 55%, transparent); }
  75%, 100% { box-shadow: 0 0 0 7px color-mix(in srgb, var(--reconnect-tone) 0%, transparent); }
}

/* Telefon: Schaltflächen teilen sich die Breite. */
@media (max-width: 640px) {
  .reconnect-card { padding: var(--sp-4) var(--sp-4) var(--sp-4) calc(var(--sp-4) + 3px); }
  .reconnect-actions { margin-top: var(--sp-4); }
  .reconnect-actions > .btn { flex: 1 1 auto; }
}

/* Weniger Bewegung: nur einblenden, der Punkt steht still. */
@media (prefers-reduced-motion: reduce) {
  #components-reconnect-modal[open] .reconnect-card { animation: none; }
  #components-reconnect-modal .reconnect-dot { animation: none !important; }
}

/* Ende Verbindungsabbruch */

/* ---------- Plattform im Job-Starter ---------- */
/* Geräte, auf denen die gewählte Shell nicht läuft (Bash auf Windows, PowerShell auf Linux): ausgegraut, nicht wählbar. */
.picker-row.unfit, .picker-row.unfit .cell-sub { color: var(--c-faint); cursor: default; }
.picker-row.unfit:hover { background: transparent; }
/* Ende Plattform im Job-Starter */

/* ---------- Zustellung der Benachrichtigungen ---------- */
/* Fußzeile einer Karte: Zähler links, Sammelaktion rechts (Bereich „Zustellung“ unter Benachrichtigungen). */
.card-foot-row { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); flex-wrap: wrap; margin-top: var(--sp-3); }
/* Ende Zustellung der Benachrichtigungen */

/* ---------- Ladeknöpfe ---------- */
/* .btn.is-busy: Die Schaltfläche arbeitet (BusyButton). Ein kleiner Kringel vor dem Text, die Fläche bleibt bedienbar
   aussehend, aber gesperrt; mit prefers-reduced-motion steht der Kringel still. */
.btn.is-busy { position: relative; cursor: progress; opacity: .85; }
.btn.is-busy::before {
  content: "";
  width: 12px;
  height: 12px;
  flex: 0 0 12px;
  border-radius: 50%;
  border: 2px solid color-mix(in srgb, currentColor 30%, transparent);
  border-top-color: currentColor;
  animation: btn-spin .8s linear infinite;
}
.btn.is-busy.small::before { width: 10px; height: 10px; flex-basis: 10px; }
@keyframes btn-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .btn.is-busy::before { animation: none; border-top-color: color-mix(in srgb, currentColor 30%, transparent); }
}
/* Ende Ladeknöpfe */

/* ---------- Hilfe und Ladeknöpfe ---------- */
/* Fragezeichen (Help.razor, span mit role="button"): schlichter Kreis, per Klick oder Tastatur öffnet sich die Erklärung als
   Blase (app.js); solange sie offen ist, bleibt der Kreis gefüllt. */
.help[data-help] {
  padding: 0;
  background: transparent;
  font-family: inherit;
  font-size: .7rem;
  font-weight: 700;
  line-height: 1;
  color: var(--c-muted);
  cursor: pointer;
}
.help[data-help]:hover, .help[data-help]:focus-visible { color: var(--c-text); border-color: var(--c-accent-line); }
.help[data-help][aria-expanded="true"] { color: var(--c-accent-contrast); background: var(--c-accent-fill); border-color: var(--c-accent-fill); }
/* In Werkzeugleisten auf dem Telefon nimmt sonst jedes Element die volle Breite. */
.toolbar > .help { flex: 0 0 auto; }

/* Die Blase: ein einziges Element am Ende des body, fest positioniert über Dialogen (100 bis 230) und unter Toasts (2000).
   app.js setzt left, top, die Seite (data-side) und die Lage des Pfeils (--help-arrow). */
.help-bubble {
  position: fixed;
  left: 0;
  top: 0;
  z-index: 1500;
  display: block;
  width: max-content;
  max-width: min(360px, calc(100vw - 24px));
  padding: 10px 12px;
  border: 1px solid var(--c-border-strong);
  border-radius: var(--radius-sm);
  background: var(--c-elev);
  color: var(--c-text);
  box-shadow: var(--shadow);
  font-family: var(--font);
  font-size: var(--fs-small);
  font-weight: 400;
  font-style: normal;
  line-height: 1.45;
  letter-spacing: normal;
  text-align: left;
  white-space: normal;
  overflow-wrap: break-word;
  animation: help-bubble-in .12s ease-out;
}
.help-bubble[hidden] { display: none; }
/* Pfeil zum Fragezeichen: ein gedrehtes Quadrat mit zwei Kanten in der Randfarbe, die Fläche deckt den Rand der Blase ab. */
.help-bubble::before {
  content: "";
  position: absolute;
  left: var(--help-arrow, 50%);
  width: 10px;
  height: 10px;
  margin-left: -5px;
  background: var(--c-elev);
  border: 0 solid var(--c-border-strong);
  transform: rotate(45deg);
}
.help-bubble[data-side="below"]::before { top: -6px; border-top-width: 1px; border-left-width: 1px; }
.help-bubble[data-side="above"]::before { bottom: -6px; border-right-width: 1px; border-bottom-width: 1px; }
@keyframes help-bubble-in { from { opacity: 0; } to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) {
  .help-bubble { animation: none; }
}
/* Ende Hilfe und Ladeknöpfe */

/* ---------- Kunden-Richtlinien und Formularhinweise ---------- */

/* Richtlinien-Dialog (Kunde und Gerät): oben Erklärung und Filter, darunter links die Gruppen, rechts die Bereiche der gewählten
   Gruppe. Der Dialog hat eine feste Höhe, damit er beim Wechsel der Gruppe nicht springt; Verzeichnis und Bereiche scrollen getrennt. */
.modal.medium:has(.pol-layout) { height: min(88vh, 920px); }
.modal-body:has(> .pol-layout) { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; overflow: hidden; padding-bottom: 0; }
.pol-top {
  flex: 0 0 auto;
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--sp-2) var(--sp-5);
  padding-bottom: var(--sp-3);
  margin-bottom: var(--sp-3);
  border-bottom: 1px solid var(--c-border-soft);
}
.pol-lead { flex: 1 1 320px; margin: 0; max-width: 68ch; font-size: var(--fs-small); line-height: 1.5; color: var(--c-muted); }
.pol-filter { flex: 0 0 auto; font-size: var(--fs-small); white-space: nowrap; }
.pol-stale { flex: 0 0 auto; margin-bottom: var(--sp-3); }

.pol-layout { flex: 1 1 auto; min-height: 0; display: grid; grid-template-columns: 204px minmax(0, 1fr); gap: 0 var(--sp-5); }
.pol-nav { min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding-right: var(--sp-2); border-right: 1px solid var(--c-border-soft); }
.pol-main { min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: 0 4px 14px 0; }

/* Verzeichnis der Gruppen wie in den Einstellungen: aktive Gruppe getönt mit Kante, die Zahl nennt die eigenen Werte. */
.pol-nav-pick { display: none; }
.pol-nav-list { list-style: none; margin: 0; padding: 0; }
.pol-nav-item {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  width: 100%;
  min-height: 34px;
  padding: 6px 8px 6px 12px;
  margin: 1px 0;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--c-text);
  font: inherit;
  font-size: var(--fs-small);
  text-align: left;
  cursor: pointer;
}
.pol-nav-item:hover { background: var(--c-hover); }
.pol-nav-item:focus-visible { outline: var(--focus-w) solid var(--c-focus); outline-offset: -2px; }
.pol-nav-item.active { background: var(--c-accent-tint); font-weight: 600; }
.pol-nav-item.active::before {
  content: "";
  position: absolute;
  left: 0;
  top: 8px;
  bottom: 8px;
  width: 3px;
  border-radius: 2px;
  background: var(--c-accent-line);
}
.pol-nav-item.dim { color: var(--c-muted); }
.pol-nav-name { flex: 1 1 auto; min-width: 0; }
.pol-nav-item .badge { flex: 0 0 auto; padding: 1px 6px; font-size: .68rem; }
.pol-nav-count {
  flex: 0 0 auto;
  min-width: 20px;
  padding: 1px 6px;
  border-radius: 999px;
  background: var(--c-accent-tint);
  color: var(--c-accent-ink);
  font-size: var(--fs-label);
  font-weight: 600;
  line-height: 1.3;
  text-align: center;
  font-variant-numeric: tabular-nums;
}
.pol-nav-count.invalid { background: var(--c-crit-bg); color: var(--c-crit-ink); }

/* Bereich: Überschrift, bei Paaren rechts daneben der Umschalter Workstations / Server, darunter Einleitung und Karte. */
.pol-area + .pol-area { margin-top: var(--sp-6); }
.pol-area-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--sp-2) var(--sp-3); margin-bottom: var(--sp-2); }
.pol-area-title { margin: 0; font-size: var(--fs-body); font-weight: 600; }
.pol-area-lead { margin: 0 0 var(--sp-3); max-width: 72ch; font-size: var(--fs-small); line-height: 1.5; color: var(--c-muted); }
.pol-area > .feature-locked { margin-bottom: 0; }
.pol-area > .hint { margin: 0 0 var(--sp-3); }
.pol-area > .proxy-http-warning { margin-bottom: var(--sp-3); }

.pol-seg { display: inline-flex; border: 1px solid var(--c-border); border-radius: var(--radius-sm); overflow: hidden; }
.pol-seg-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: var(--control-h-sm);
  padding: 2px 12px;
  border: 0;
  border-left: 1px solid var(--c-border);
  background: transparent;
  color: var(--c-muted);
  font: inherit;
  font-size: var(--fs-label);
  white-space: nowrap;
  cursor: pointer;
}
.pol-seg-btn:first-child { border-left: 0; }
.pol-seg-btn:hover { background: var(--c-hover); color: var(--c-text); }
.pol-seg-btn:focus-visible { outline: var(--focus-w) solid var(--c-focus); outline-offset: -2px; }
.pol-seg-btn.on { background: var(--c-accent-tint); color: var(--c-accent-ink); font-weight: 600; }
.pol-seg-count {
  min-width: 18px;
  padding: 0 5px;
  border-radius: 999px;
  background: color-mix(in srgb, currentColor 16%, transparent);
  font-size: .75rem;
  line-height: 1.4;
  text-align: center;
  font-variant-numeric: tabular-nums;
}

/* Einstellung: Name und Schalter „Eigener Wert“ in einer Zeile, darunter Beschreibung, Herkunft und mit eigenem Wert die Eingabe.
   Die Kante links wie auf der Einstellungs-Seite: neutral = eigener Wert, Akzent = ungespeichert, kritisch = ungültig. */
.pol-card { border: 1px solid var(--c-border-soft); border-radius: var(--radius); overflow: hidden; }
.pol-row { padding: 12px var(--sp-4) 14px 18px; border-top: 1px solid var(--c-border-soft); }
.pol-row:first-child { border-top: 0; }
.pol-row.own { box-shadow: inset 3px 0 0 var(--c-border-strong); }
.pol-row.dirty { box-shadow: inset 3px 0 0 var(--c-accent-line); background: var(--c-accent-wash); }
.pol-row.invalid { box-shadow: inset 3px 0 0 var(--c-crit); background: color-mix(in srgb, var(--c-crit) 6%, transparent); }
.pol-row-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--sp-2) var(--sp-4); }
.pol-label { flex: 1 1 200px; min-width: 0; font-weight: 600; }
.pol-own { flex: 0 0 auto; padding: 3px 4px 3px 10px; border: 1px solid var(--c-border); border-radius: 999px; background: var(--c-elev); }
.pol-own:has(input:checked) { border-color: var(--c-accent-border); }
.pol-own:has(input:disabled) { cursor: default; opacity: .7; }
.pol-own .toggle-state { min-width: 0; text-align: left; color: var(--c-text); font-size: var(--fs-label); }
.pol-desc { margin: 4px 0 0; max-width: 72ch; font-size: var(--fs-small); line-height: 1.5; }
.pol-origin { margin-top: 6px; font-size: var(--fs-label); color: var(--c-muted); overflow-wrap: anywhere; }
.pol-origin strong { color: var(--c-text); font-weight: 600; }
.pol-row .setting-error { margin-top: 6px; font-weight: 600; }

/* Eingabe in voller Breite unter dem Text; Regeln (Freigabe, Behebung) lesen sich wie ein Satz. */
.pol-input { margin-top: var(--sp-3); }
.pol-input > input, .pol-input > select { width: 100%; max-width: 420px; }
.pol-input .input-unit { width: auto; }
.pol-input .input-unit input[type=number] { width: 110px; flex: 0 0 auto; }
.pol-input .rule-input { flex-direction: row; flex-wrap: wrap; align-items: center; gap: var(--sp-2) var(--sp-5); }
.pol-input .rule-input > select { width: auto; min-width: 220px; max-width: 100%; }
.pol-input .rule-input .input-unit input[type=number] { width: 72px; }

.modal-foot .pol-foot-count { font-variant-numeric: tabular-nums; }

/* Telefon: Der Dialog füllt den Bildschirm, die Gruppen werden zur Auswahl über den Bereichen. */
@media (max-width: 640px) {
  .modal.medium:has(.pol-layout) { height: 100dvh; }
  .pol-top { padding-bottom: var(--sp-2); margin-bottom: var(--sp-2); }
  .pol-layout { grid-template-columns: minmax(0, 1fr); grid-template-rows: auto minmax(0, 1fr); gap: var(--sp-3); }
  .pol-nav { overflow: visible; padding-right: 0; border-right: 0; }
  .pol-nav-list { display: none; }
  .pol-nav-pick { display: block; width: 100%; }
  .pol-main { padding-right: 0; }
  .pol-row { padding: 12px 12px 14px 14px; }
  .pol-input .rule-input { flex-direction: column; align-items: flex-start; }
  .modal-foot .pol-foot-count { flex: 1 1 100%; }
  .modal-foot:has(.pol-foot-count) .spacer { display: none; }
}

/* Übersicht „Richtlinien“ auf der Kundenseite: Gruppe, darunter der Bereich, je Wert daneben gedämpft der globale Wert. */
.pol-sum-group + .pol-sum-group { margin-top: var(--sp-4); }
.pol-sum-title { margin: 0 0 var(--sp-1); padding-bottom: 4px; border-bottom: 1px solid var(--c-border-soft); font-size: var(--fs-small); font-weight: 600; }
.pol-sum-section { margin: var(--sp-2) 0 var(--sp-1); font-size: var(--fs-label); font-weight: 600; color: var(--c-muted); }
dl.kv.pol-sum-kv { grid-template-columns: minmax(110px, 38%) minmax(0, 1fr); gap: 4px 14px; }
.pol-sum-inherited { margin-left: 4px; font-size: var(--fs-label); color: var(--c-muted); }

/* Notizen des Kunden: Speichern und Zustand in einer Zeile. */
.notes-foot { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2) var(--sp-3); }
.notes-state { font-size: var(--fs-label); color: var(--c-muted); }

/* Hinweis unter einem Formularfeld (im label.field, aber nicht als direktes span-Kind, das ist die Beschriftung). */
.field > .field-hint { font-size: var(--fs-label); line-height: 1.4; color: var(--c-muted); }

@media (max-width: 640px) {
  dl.kv.pol-sum-kv { grid-template-columns: minmax(0, 1fr); }
}

/* Erzwungene Farben (Windows-Kontrastdesigns): Kanten der Zeilen als linker Rand, wie im Block „Erzwungene Farben“. */
@media (forced-colors: active) {
  .pol-row.own { border-left: 2px solid CanvasText; }
  .pol-row.dirty { border-left: 3px dashed CanvasText; }
  .pol-row.invalid { border-left: 4px solid CanvasText; }
  .pol-nav-item.active::before { forced-color-adjust: none; background: Highlight; }
}

/* Ende Kunden-Richtlinien und Formularhinweise */

/* ---------- Geräte-Reiter ---------- */
/* Ladezustand (Skeleton.razor): graue Platzhalterzeilen mit sanftem Schimmer. Grund und Glanz entstehen aus der Nebentextfarbe
   auf der Kartenfläche und passen so zu Tag und Nacht. Mit prefers-reduced-motion steht der Schimmer still. */
.skeleton {
  --skeleton-base: color-mix(in srgb, var(--c-muted) 14%, var(--c-surface));
  --skeleton-shine: color-mix(in srgb, var(--c-muted) 28%, var(--c-surface));
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  padding: var(--sp-4);
  background: var(--c-surface);
  border: 1px solid var(--c-border-soft);
  border-radius: var(--radius);
}
.skeleton.plain { padding: var(--sp-1) 0; background: none; border: 0; border-radius: 0; }
.skeleton-text { margin: 0 0 var(--sp-1); color: var(--c-muted); font-size: var(--fs-small); }
.skeleton-row {
  height: 12px;
  border-radius: var(--radius-sm);
  background: linear-gradient(90deg, var(--skeleton-base) 0%, var(--skeleton-base) 35%, var(--skeleton-shine) 50%, var(--skeleton-base) 65%, var(--skeleton-base) 100%);
  background-size: 300% 100%;
  animation: skeleton-shimmer 1.6s ease-in-out infinite;
}
div.skeleton-row:nth-of-type(4n+1) { width: 94%; }
div.skeleton-row:nth-of-type(4n+2) { width: 78%; }
div.skeleton-row:nth-of-type(4n+3) { width: 86%; }
div.skeleton-row:nth-of-type(4n) { width: 64%; }
@keyframes skeleton-shimmer { from { background-position: 100% 0; } to { background-position: 0 0; } }
@media (prefers-reduced-motion: reduce) {
  .skeleton-row { animation: none; background: var(--skeleton-base); }
}

/* Umschalter mit festen Stellungen in einer Reiter-Werkzeugleiste (Netzwerk: Nur mit IP, Mit MAC, Alle). */
.seg-switch { display: inline-flex; flex: 0 0 auto; border: 1px solid var(--c-border); border-radius: var(--radius-sm); overflow: hidden; }
.seg-switch-btn {
  min-height: var(--control-h-sm);
  padding: 2px 12px;
  border: 0;
  border-left: 1px solid var(--c-border);
  background: transparent;
  color: var(--c-muted);
  font: inherit;
  font-size: var(--fs-small);
  white-space: nowrap;
  cursor: pointer;
}
.seg-switch-btn:first-child { border-left: 0; }
.seg-switch-btn:hover { background: var(--c-hover); color: var(--c-text); }
.seg-switch-btn:focus-visible { outline: var(--focus-w) solid var(--c-focus); outline-offset: -2px; }
.seg-switch-btn.on { background: var(--c-accent-tint); color: var(--c-accent-ink); font-weight: 600; }
.net-suffix { color: var(--c-muted); font-size: var(--fs-small); }

/* Ereignisse: Während eine neue Abfrage läuft, tritt die alte Liste zurück, statt zu verschwinden. */
.table-wrap.refreshing { opacity: .55; transition: opacity .15s ease; }
.eventlog-state { display: inline-flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; }
@media (prefers-reduced-motion: reduce) {
  .table-wrap.refreshing { transition: none; }
}

/* Software-Vorgänge: Der Rückgabewert steht als Klartext mit Code, z. B. „Paket nicht gefunden (0x8A150014)“. */
table.ops-table { min-width: 980px; }
table.ops-table col.col-code { width: 240px; }
table.ops-table td.code-cell { white-space: normal; overflow-wrap: anywhere; }

/* Datei-Browser: Typ-Spalte schmal, sortierbare Köpfe ohne Umbruch. */
table.files-table th.sortable { white-space: nowrap; }
table.files-table td.file-type { white-space: nowrap; }

@media (max-width: 640px) {
  .seg-switch { width: 100%; }
  .seg-switch-btn { flex: 1 1 0; padding: 2px 6px; }
}
/* Ende Geräte-Reiter */

/* ---------- Geräteliste ---------- */
/* Filterleiste mit sichtbaren Bezeichnungen (FilterSelect): klein über dem Feld, damit nach einer Auswahl erkennbar bleibt, wonach
   gefiltert wird. Felder und Schaltflächen stehen auf einer Grundlinie, ein gesetzter Filter trägt einen Rand in der Akzentfarbe. */
.toolbar.device-filters { align-items: flex-end; }
.toolbar .filter { display: inline-flex; flex-direction: column; gap: 3px; min-width: 0; }
.toolbar .filter-label { font-size: var(--fs-label); font-weight: 600; color: var(--c-muted); line-height: 1.2; white-space: nowrap; }
.toolbar .filter select { width: auto; max-width: 220px; }
.toolbar .filter.is-set .filter-label { color: var(--c-accent-ink); }
.toolbar .filter.is-set select, .toolbar .filter.is-set input {
  border-color: var(--c-accent-line);
  box-shadow: inset 0 0 0 1px var(--c-accent-line);
}
.toolbar .filter-search { flex: 1 1 240px; max-width: 420px; }
.toolbar .filter-search .search { flex: 0 0 auto; width: 100%; max-width: none; }

/* Lange Betriebssystem- und Kundennamen brechen um, damit „Zuletzt gesehen“ ohne seitliches Rollen sichtbar bleibt. */
.device-table td.os-cell, .device-table td.customer-cell { white-space: normal; min-width: 130px; }

/* Sortierbare Spaltenköpfe: eine Schaltfläche im Kopf, damit die Sortierung auch per Tastatur erreichbar ist. */
th.sortable .th-sort {
  display: inline-flex; align-items: center; gap: 4px; padding: 0; border: 0; background: none;
  font: inherit; font-weight: inherit; color: inherit; letter-spacing: inherit; text-transform: inherit; cursor: pointer; white-space: nowrap;
}
th.sortable .th-sort:focus-visible { outline: var(--focus-w) solid var(--c-focus); outline-offset: 2px; border-radius: 3px; }
th.sortable .sort-arrow { display: inline-block; min-width: 1ch; font-size: .85em; }

/* Eingaben in der Fußzeile einer Kachel (Sammeldialog): Text und Schalter teilen sich die Zeile mit der Schaltfläche. */
.action-card-foot > input.action-input { flex: 1 1 180px; min-width: 0; max-width: 360px; width: auto; }
.action-card-foot > .switch { flex: 1 1 auto; min-width: 0; font-size: var(--fs-small); gap: var(--sp-2); }
.action-card-foot > .switch span { overflow-wrap: anywhere; }

@media (max-width: 640px) {
  /* Telefon: Suche über die volle Breite, die Filter paarweise darunter, „Filter zurücksetzen“ in eigener Zeile. */
  .toolbar.device-filters > .filter { flex: 1 1 calc(50% - var(--sp-2)); max-width: none; }
  .toolbar.device-filters > .filter-search { flex-basis: 100%; }
  .toolbar.device-filters .filter select { width: 100%; max-width: none; }
  .toolbar.device-filters > .filter-reset { flex: 1 1 100%; }
  .action-card-foot > input.action-input { flex-basis: 100%; max-width: none; }
}
/* Ende Geräteliste */

/* ---------- Dienste-Starttyp ---------- */
/* Dialog „Starttyp ändern“: Eckdaten oben, Hinweis zur Auswahl darunter. */
dl.kv.startmode-facts { margin-bottom: var(--sp-4); }
.startmode-hint { margin: var(--sp-2) 0 var(--sp-3); }
/* Vier Zeilenaktionen brauchen Platz: Anzeigename und Konto brechen um, die Knöpfe bleiben in einer Zeile. */
.services-table td:first-child { white-space: normal; min-width: 200px; }
.services-table td.service-account { white-space: normal; overflow-wrap: break-word; }
/* Schmale Ansicht: Die Werkzeugleiste steht als Spalte; das Suchfeld darf dann nicht in die Höhe wachsen
   (flex-basis 260px wirkt in einer Spalte als Höhe). Gilt für alle Reiter mit Suchfeld. */
@media (max-width: 900px) {
  .tab-toolbar .search { flex: 0 0 auto; }
}
/* Ende Dienste-Starttyp */

/* ---------- Jobs-Reiter und Web-Zugriff ---------- */
/* Hinweis unter der Jobliste, wenn die Begrenzung greift. */
.jobs-limit { margin: var(--sp-2) 0 0; }
/* Zeitpläne: Skript und Ziel dürfen umbrechen, damit die Zeilenaktionen auch neben der Navigation in eine Zeile passen. */
table.schedule-table td.wrap { min-width: 140px; }
/* „Zeitplan“ auf der Jobseite führt zu den Zeitplänen: als Pille, beim Darüberfahren etwas kräftiger statt unterstrichen. */
a.pill.muted:hover { color: var(--c-text); text-decoration: none; }
/* Web-Zugriff: Schnellwahl „Zuletzt“ unter dem Ziel. Die Knöpfe brechen um und tragen das Ziel in Festbreitenschrift;
   der gerade eingetragene ist mit dem Akzentrand markiert. */
.web-recent { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); margin-top: var(--sp-2); }
.web-recent .btn { font-family: var(--mono); font-weight: 500; max-width: 100%; white-space: normal; overflow-wrap: anywhere; text-align: left; }
.web-recent .btn.active { border-color: var(--c-accent-line); color: var(--c-accent-ink); }
/* Ende Jobs-Reiter und Web-Zugriff */

/* ---------- Dokumentation je Standort ---------- */
/* Filter im Reiter Dokumentation: so hoch wie die kleinen Knöpfe daneben, auf Touch-Geräten wie diese etwas höher. */
select.doc-site-filter {
  width: auto; max-width: 240px; min-height: var(--control-h-sm);
  padding: 3px 30px 3px 10px; font-size: var(--fs-small);
}
@media (pointer: coarse) { select.doc-site-filter { min-height: 36px; } }
.docs-table td.doc-site { white-space: normal; min-width: 120px; max-width: 220px; }

/* Standorte: Zeilenaktionen dürfen umbrechen, statt die Tabelle zu verbreitern; die aufgeklappte Zeile hängt optisch an ihrem Standort. */
.sites-table td.row-actions { white-space: normal; min-width: 240px; }
.sites-table td.row-actions .btn { margin: 2px 0 2px 4px; }
.sites-table tr.site-docs-open > td { border-bottom-color: transparent; background: var(--c-elev); }
.sites-table tr.site-docs-row > td { padding: 4px 16px 14px; box-shadow: inset 3px 0 0 var(--c-accent-line); }
.sites-table tr.site-docs-open > td:first-child { box-shadow: inset 3px 0 0 var(--c-accent-line); }
.sites-table tr.site-docs-row .empty-note { margin: 6px 0 0; }
.sites-table tr.site-docs-row .inner-table td.row-actions { min-width: 0; white-space: nowrap; }
.sites-table tr.site-docs-row .inner-table td.row-actions .btn { margin: 0 0 0 4px; }

/* Hinweis im Dialog „Dokument erzeugen“ für einen Standort. */
.doc-site-hint { margin-top: 10px; }
/* Lange Dialogtitel („Dokument erzeugen: Kunde, Standort“) kürzt der Kopf mit Auslassungspunkten. Ohne feste Spalte machte die
   Rasterspalte des Hintergrunds den Dialog auf schmalen Bildschirmen so breit wie den ungekürzten Titel. */
.modal-backdrop { grid-template-columns: minmax(0, 1fr); }
/* Ende Dokumentation je Standort */

/* ---------- Alarm-Arbeitsplatz ---------- */
/* Nummer, Bearbeitungsstand und Detailleiste der Alarme (0.75). Die Leiste liegt fest rechts über der Liste, auf dem Telefon als
   Blatt über die ganze Fläche. Ihr z-index liegt zwischen Kopfzeile (40) und Dialogen (100). Sie trägt kein transform, keinen
   filter und kein backdrop-filter: Jede dieser Eigenschaften machte sie zum Bezugsrahmen fester Elemente, und die Dialoge darin
   (Stummschalten, Skript, Wartung, Fernwartung) lägen dann relativ zur Leiste statt zum Fenster. Eingeblendet wird nur über die
   Deckkraft. Seit 0.82 gelten die Grundregeln der Leiste auch für die Schnellansicht der Geräteliste (.side-panel); deren eigene Regeln
   stehen im Block „Schnellansicht 0.82“. */
:root { --ap-w: 460px; }

/* Nummer in den Listen: ruhig, mit festen Ziffernbreiten, als Knopf per Tastatur erreichbar. */
.link-button.al-num { font-variant-numeric: tabular-nums; font-weight: 600; white-space: nowrap; }
.need-row .al-num { margin-right: 4px; }

/* Bearbeitungsstand unter der Meldung: quittiert, zuständig, stumm, Sammelmeldung. */
.al-work { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 5px; }
.pill.pill-link { border: 0; font-family: inherit; cursor: pointer; text-decoration: none; }
.pill.pill-link:hover { color: var(--c-text); }

.side-panel,
.alert-panel {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  z-index: 50;
  display: flex;
  flex-direction: column;
  width: var(--ap-w);
  max-width: 100vw;
  background: var(--c-surface);
  border-left: 1px solid var(--c-border);
  box-shadow: var(--shadow);
  animation: alert-panel-in .14s ease-out;
}
.side-panel:focus, .alert-panel:focus { outline: none; }
@keyframes alert-panel-in { from { opacity: 0; } to { opacity: 1; } }

.ap-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--sp-3);
  padding: 14px 14px 12px 18px;
  border-bottom: 1px solid var(--c-border-soft);
  flex-shrink: 0;
}
.ap-head-main { min-width: 0; }
.ap-head h2 { margin: 0 0 6px; font-family: var(--font-display); font-size: 1.2rem; font-variant-numeric: tabular-nums; }
.ap-pills { display: flex; flex-wrap: wrap; gap: 4px; }

.ap-body { flex: 1 1 auto; overflow-y: auto; overscroll-behavior: contain; padding: 4px 18px 24px; }
.ap-section { padding: 14px 0; border-top: 1px solid var(--c-border-soft); }
.ap-section:first-child { border-top: 0; }
.ap-section h3 { margin: 0 0 8px; font-size: var(--fs-section); }
.ap-section h3 .count { color: var(--c-muted); font-weight: 500; font-size: var(--fs-small); }
.ap-device { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 10px; }
.ap-device .muted { font-size: var(--fs-small); }
.ap-check { margin-top: 2px; font-weight: 600; }
.ap-message {
  margin: 8px 0 10px;
  padding: 8px 10px;
  border-radius: var(--radius-sm);
  background: var(--c-elev);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
dl.kv.ap-kv { grid-template-columns: 120px minmax(0, 1fr); gap: 5px 12px; }
.ap-links { display: flex; flex-wrap: wrap; gap: 2px 10px; margin-top: 4px; }
.ap-note { margin: 0 0 8px; font-size: var(--fs-small); }
.ap-reason { font-size: var(--fs-small); overflow-wrap: anywhere; }

/* Bearbeitung: Beschriftung, Zustand, Knöpfe in einer Zeile; die Knöpfe brechen bei Bedarf darunter um. */
.ap-rows { display: flex; flex-direction: column; }
.ap-row {
  display: grid;
  grid-template-columns: 110px minmax(0, 1fr);
  grid-template-areas: "label value" ". actions";
  align-items: baseline;
  gap: 6px 12px;
  padding: 8px 0;
  border-top: 1px solid var(--c-border-soft);
}
.ap-row:first-child { border-top: 0; padding-top: 0; }
.ap-row-label { grid-area: label; color: var(--c-muted); font-size: var(--fs-small); }
.ap-row-value { grid-area: value; min-width: 0; overflow-wrap: anywhere; }
.ap-row-value .ap-reason { display: block; }
.ap-row-actions { grid-area: actions; display: flex; flex-wrap: wrap; gap: 6px; }
.ap-assign { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin: 0 0 8px 122px; }
.ap-assign select { width: auto; min-width: 180px; max-width: 100%; }
.ap-actions { display: flex; flex-wrap: wrap; gap: 6px; }

.ap-history, .ap-mutes, .ap-comments { list-style: none; margin: 0; padding: 0; }
.ap-history li { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 10px; padding: 4px 0; font-size: var(--fs-small); }
.ap-history li.current .ap-num { font-weight: 700; }
.ap-history .ap-num { min-width: 56px; font-variant-numeric: tabular-nums; }
.ap-history .pill { margin-left: auto; }
.ap-mutes li { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); padding: 6px 0; border-top: 1px solid var(--c-border-soft); }
.ap-mutes li:first-child { border-top: 0; }

.ap-comments li { padding: 8px 0; border-top: 1px solid var(--c-border-soft); }
.ap-comments li:first-child { border-top: 0; padding-top: 0; }
.ap-comment-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 8px; font-size: var(--fs-small); }
.ap-comment-delete { margin-left: auto; font-size: var(--fs-small); font-weight: 500; }
.ap-comment-text { margin-top: 3px; white-space: pre-wrap; overflow-wrap: anywhere; }
.ap-comment-form { margin-top: 10px; }
.ap-comment-form textarea { width: 100%; min-height: 72px; resize: vertical; }
.ap-comment-send { display: flex; justify-content: flex-end; margin-top: 6px; }
.ap-foot { margin: 12px 0 0; font-size: var(--fs-small); }

/* Sehr breite Fenster, nur auf der Seite „Alarme“ (.push): Die Liste rückt neben die Leiste, statt unter ihr zu verschwinden.
   Dashboard und Geräteseite behalten ihr Raster, die Leiste liegt dort darüber. */
@media (min-width: 1400px) {
  .content:has(.side-panel.push), .content:has(.alert-panel.push) { padding-right: calc(var(--ap-w) + 28px); }
}

@media (max-width: 640px) {
  /* Telefon: Blatt über die ganze Fläche, die Kopfleiste der Seite liegt darunter. */
  .side-panel, .alert-panel { left: 0; width: auto; border-left: 0; box-shadow: none; }
  .ap-head { padding: 12px 10px 10px 14px; }
  .ap-body { padding: 4px 14px 28px; }
  .ap-row { grid-template-columns: minmax(0, 1fr); grid-template-areas: "label" "value" "actions"; gap: 4px; }
  .ap-row-actions .btn { flex: 1 1 auto; }
  dl.kv.ap-kv dt { margin-top: 0; }
  .ap-assign { margin-left: 0; }
  .ap-assign select { flex: 1 1 100%; }

  /* Alarm-Tabellen gestapelt, jetzt mit der Nummer vorn in der ersten Zeile. */
  .alert-table tr {
    grid-template-columns: auto auto minmax(0, 1fr) auto;
    grid-template-areas: "id sev dev time" "check check check cust" "msg msg msg msg" "fix fix fix fix";
  }
  .alert-table.no-sev tr { grid-template-areas: "id dev dev time" "check check check cust" "msg msg msg msg" "fix fix fix fix"; }
  .alert-table .al-id { grid-area: id; }
}

@media (prefers-reduced-motion: reduce) {
  .side-panel, .alert-panel { animation: none; }
}
/* Ende Alarm-Arbeitsplatz */

/* ---------- Wiederholung ---------- */
/* Eingabe einer Wiederholung (RecurrenceInput, 0.76): Beschreibung und nächste Termine unter den Feldern. */
.recurrence-input .recurrence-preview { display: flex; flex-direction: column; gap: 2px; margin: var(--sp-2) 0 0; }
.recurrence-input .recurrence-error { margin: var(--sp-2) 0 0; font-size: var(--fs-small); color: var(--c-crit-ink); }
/* auto-fill statt auto-fit: Bei „Täglich“ mit nur zwei Feldern bleiben die Spalten so breit wie bei den anderen Arten. */
.recurrence-input .form-grid { grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); }
/* Ende Wiederholung */

/* ---------- Wiederkehrende Wartung ---------- */
/* Dialog „Wartungsmodus“: Wahl Einmalig oder Wiederkehrend über den Feldern, Gültigkeit unter der Wiederholung. */
.maint-mode { margin: 0 0 var(--sp-3); }
.maint-mode-hint { margin: 0 0 var(--sp-3); }
.maint-rule-fields { margin-bottom: var(--sp-3); }
.maint-rule-fields .maint-validity { margin: var(--sp-3) 0 0; }
.maint-rule-fields > .hint { margin: var(--sp-2) 0 0; }
/* Gerätesuche im Dialog „Wiederkehrende Wartung“: höchstens 20 Treffer als Liste unter dem Suchfeld. */
.maint-device-results {
  display: flex;
  flex-direction: column;
  margin-top: var(--sp-2);
  max-height: 240px;
  overflow-y: auto;
  border: 1px solid var(--c-border-soft);
  border-radius: var(--radius-sm);
}
.maint-device-hit {
  display: flex;
  justify-content: space-between;
  gap: var(--sp-2);
  padding: 6px 10px;
  border: 0;
  border-bottom: 1px solid var(--c-border-soft);
  background: transparent;
  color: var(--c-text);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.maint-device-hit:last-child { border-bottom: 0; }
.maint-device-hit:hover, .maint-device-hit:focus-visible { background: var(--c-hover); }
.maint-device-results .hint { margin: 6px 10px; }
.maint-device-chosen { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-2); min-height: var(--control-h); }
/* Listen: Pille „Regel“ neben dem Ziel; Standortzeile der Kundenseite mit aktiver Wartung. */
.maint-table .mt-rule { margin-left: 6px; vertical-align: middle; }
/* Regeln: Ziel und Wiederholung dürfen umbrechen, damit die Aktionen ohne seitliches Rollen sichtbar bleiben. */
@media (min-width: 641px) {
  .maint-rules td.mt-target { white-space: normal; min-width: 170px; }
  .maint-rules td.mt-rec { min-width: 180px; }
}
.sites-table .site-maint { display: inline-block; margin-top: 4px; }
/* Telefon: Zeilen gestapelt, Ziel und Zustand oben, darunter Zeiten, Grund und Aktionen. */
@media (max-width: 640px) {
  .maint-table thead { display: none; }
  .maint-table, .maint-table tbody { display: block; }
  .maint-table tr {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 3px var(--sp-2);
    padding: 10px var(--sp-3);
    border-bottom: 1px solid var(--c-border-soft);
  }
  .maint-table tbody tr:last-child { border-bottom: 0; }
  .maint-table td { display: block; padding: 0; border: 0; min-width: 0; white-space: normal; }
  .maint-table td.mt-target { grid-column: 1; grid-row: 1; }
  .maint-table td.mt-state { grid-column: 2; grid-row: 1; text-align: right; }
  .maint-table td.mt-when, .maint-table td.mt-rec, .maint-table td.mt-reason, .maint-table td.mt-by { grid-column: 1 / -1; font-size: var(--fs-small); }
  .maint-table td[data-label]::before { content: attr(data-label) " "; color: var(--c-muted); }
  .maint-table td.mt-by { color: var(--c-muted); }
  .maint-table td.row-actions { grid-column: 1 / -1; text-align: left; margin-top: 4px; }
  .maint-table td.row-actions .btn:first-child { margin-left: 0; }
}
/* Ende Wiederkehrende Wartung */

/* ---------- Zeitpläne 0.76 ---------- */
/* Dialog (ScheduleModal): nächste Läufe unter dem Rhythmus, gewählte Ziele als Chips mit Entfernen, Gerätesuche als Trefferliste,
   darunter die Vorschau der Zielgeräte. */
/* Gleiche Spalten wie in der Wiederholung darunter: ein einzelnes Auswahlfeld (Art, Geräteklasse) streckt sich nicht über die
   ganze Breite. */
.schedule-modal .form-grid.schedule-grid { grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); }
.schedule-next { margin: var(--sp-2) 0 var(--sp-3); font-size: var(--fs-small); }
.schedule-next.is-error { color: var(--c-crit-ink); }
.schedule-targets { margin-top: var(--sp-2); }
.schedule-chips { display: flex; flex-wrap: wrap; gap: 6px; margin: 0 0 var(--sp-3); padding: 0; list-style: none; }
.schedule-chip {
  display: inline-flex; align-items: center; gap: 6px; max-width: 100%; min-width: 0;
  padding: 2px 3px 2px 10px; border: 1px solid var(--c-border-soft); border-radius: 999px;
  background: var(--c-neutral-bg); font-size: var(--fs-small);
}
.schedule-chip-kind { flex: 0 0 auto; color: var(--c-muted); font-size: var(--fs-label); }
.schedule-chip-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.schedule-chip-remove {
  flex: 0 0 auto; width: 24px; height: 24px; padding: 0; border: 0; border-radius: 50%;
  background: transparent; color: var(--c-muted); font: inherit; font-size: 1.05rem; line-height: 1; cursor: pointer;
}
.schedule-chip-remove:hover { background: var(--c-hover); color: var(--c-text); }
.schedule-chip-remove:focus-visible { outline: var(--focus-w) solid var(--c-focus); outline-offset: 1px; }
.modal .form-grid.schedule-target-add { margin-bottom: var(--sp-2); }
.schedule-hits {
  display: flex; flex-direction: column; max-height: 260px; overflow-y: auto; overscroll-behavior: contain;
  margin-bottom: var(--sp-2); border: 1px solid var(--c-border-soft); border-radius: var(--radius-sm);
}
.schedule-hit {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "name action" "cust action";
  align-items: center; gap: 0 var(--sp-3); padding: 7px 12px; border: 0; border-bottom: 1px solid var(--c-border-soft);
  background: transparent; color: var(--c-text); font: inherit; text-align: left; cursor: pointer;
}
.schedule-hit:last-child { border-bottom: 0; }
.schedule-hit:hover:not(:disabled) { background: var(--c-hover); }
.schedule-hit:disabled { cursor: default; }
.schedule-hit-name { grid-area: name; font-weight: 600; overflow-wrap: anywhere; }
.schedule-hit .cell-sub { grid-area: cust; }
.schedule-hit-action { grid-area: action; font-size: var(--fs-small); color: var(--c-accent-ink); }
.schedule-hit:disabled .schedule-hit-action { color: var(--c-muted); }
.schedule-preview { margin: 0 0 var(--sp-2); font-size: var(--fs-small); }
.schedule-changed { margin-top: var(--sp-3); }

/* Liste: Rhythmus und Ziel brechen um. Beschriftungen und der Fehlertext als eigene Zeile gibt es nur in der Kartenansicht,
   auf breiten Schirmen steht der Grund im Tooltip der Pille „Fehler“. */
table.schedule-table td.sc-name { min-width: 190px; }
table.schedule-table td.sc-rhythm { min-width: 150px; }
table.schedule-table td.sc-target { min-width: 180px; }
table.schedule-table td.sc-state { white-space: nowrap; }
table.schedule-table td.sc-state .pill + .pill { margin-left: 4px; }
/* Vier Aktionen brechen in zwei Reihen um, statt die Tabelle über den Rand zu schieben (wie bei den Standorten). */
table.schedule-table td.sc-actions { white-space: normal; min-width: 250px; }
table.schedule-table td.sc-actions .btn { margin: 2px 0 2px 4px; }
table.schedule-table .sc-label, table.schedule-table td.sc-error { display: none; }
table.schedule-table td.sc-state .sc-error-sub { max-width: 240px; margin-top: 4px; white-space: normal; overflow-wrap: anywhere; color: var(--c-crit-ink); }

@media (max-width: 640px) {
  /* Telefon: jede Zeile als Karte. Name und Status oben, darunter Rhythmus und Ziel, letzter und nächster Lauf nebeneinander,
     der Fehler und die Aktionen in voller Breite. */
  .schedule-table thead { display: none; }
  .schedule-table, .schedule-table tbody { display: block; }
  .schedule-table tr {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas: "name state" "rhythm rhythm" "target target" "last next" "error error" "actions actions";
    align-items: start;
    gap: 4px var(--sp-2);
    padding: 12px var(--sp-3);
    border-bottom: 1px solid var(--c-border-soft);
  }
  .schedule-table tbody tr:last-child { border-bottom: 0; }
  .table-wrap table.schedule-table td, .table-wrap table.schedule-table td.wrap {
    display: block; padding: 0; border: 0; min-width: 0; white-space: normal; box-shadow: none;
  }
  /* Die Statuskante wandert von der ersten Zelle an die ganze Karte. */
  .schedule-table tr.edge-crit { box-shadow: inset 3px 0 0 var(--c-crit); }
  .schedule-table .sc-name { grid-area: name; }
  .schedule-table .sc-state { grid-area: state; text-align: right; }
  .schedule-table .sc-rhythm { grid-area: rhythm; }
  .schedule-table .sc-target { grid-area: target; }
  .schedule-table .sc-last { grid-area: last; font-size: var(--fs-small); }
  .schedule-table .sc-next { grid-area: next; font-size: var(--fs-small); text-align: right; }
  table.schedule-table .sc-label { display: block; font-size: var(--fs-label); }
  table.schedule-table td.sc-state .sc-error-sub { display: none; }
  .table-wrap table.schedule-table td.sc-error { display: block; grid-area: error; font-size: var(--fs-small); color: var(--c-crit-ink); overflow-wrap: anywhere; }
  .table-wrap table.schedule-table td.sc-actions { grid-area: actions; display: flex; flex-wrap: wrap; gap: 6px; margin-top: 4px; text-align: left; }
  .table-wrap table.schedule-table td.sc-actions .btn { flex: 1 1 auto; margin: 0; }
}
/* Ende Zeitpläne 0.76 */

/* ---------- Jobs-Liste 0.76 ---------- */
/* Filterleiste der Job-Liste wie in der Geräteliste (FilterSelect). Auf dem Telefon bleibt die Suche stehen, die Auswahlfelder
   klappen hinter den Knopf „Filter“; mit gesetzten Filtern zeigt er deren Zahl in der Akzentfarbe. */
.toolbar.job-filters > .filter-search { flex: 1 1 200px; max-width: 300px; }
.toolbar.job-filters > .filter-toggle { display: none; }
.toolbar.job-filters > .filter-toggle.is-set { border-color: var(--c-accent-line); color: var(--c-accent-ink); }

/* Läufe eines Jobs: Statusfilter und Schalter „Nach Ausgabe gruppieren“ auf einer Grundlinie. */
.toolbar.job-run-tools { margin-top: var(--sp-4); }
.toolbar.job-run-tools .job-group-switch { min-height: 34px; }
.page-head .sub .job-rerun-of a { white-space: nowrap; }

/* Gruppen gleicher Ausgabe: Status, Anzahl und Exit-Code im Kopf, die Ausgabe einmal, die Geräte aufklappbar als Raster. */
.job-group-summary { margin: 0 0 var(--sp-2); }
.job-groups { display: flex; flex-direction: column; gap: var(--sp-3); }
.job-group { display: flex; flex-direction: column; gap: var(--sp-2); }
.job-groups > .job-group { margin: 0; }
.job-group-head { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); }
.job-group-head > .btn { margin-left: auto; }
.job-group-empty { margin: 0; }
.job-group .output { max-height: 320px; }
.job-group .notice { margin: 0; }
.job-group-devices {
  list-style: none; margin: 0; padding: var(--sp-2) 0 0; border-top: 1px solid var(--c-border-soft);
  display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 4px var(--sp-3);
}
.job-group-devices li { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 6px; min-width: 0; }
.job-group-devices li > .muted { font-size: var(--fs-small); }
.job-group-devices .job-group-error { flex-basis: 100%; overflow-wrap: anywhere; }

@media (max-width: 640px) {
  /* Suche und Knopf „Filter“ in einer Zeile, die Auswahlfelder erst nach dem Aufklappen. */
  /* Die Suche nimmt mehr als die halbe Zeile ein: So passt der Knopf daneben, die Auswahlfelder beginnen eine neue Zeile. */
  .toolbar.job-filters > .filter-search { flex: 1 1 55%; min-width: 0; max-width: none; }
  .toolbar.job-filters > .filter-toggle { display: inline-flex; flex: 0 0 auto; }
  .toolbar.job-filters:not(.filters-open) > .filter:not(.filter-search),
  .toolbar.job-filters:not(.filters-open) > .filter-reset { display: none; }

  /* Job-Liste gestapelt: Name und Zeit oben, darunter das Ergebnis, dann die Aktionen; Shell und Geräteanzahl entfallen
     (die Zähler im Ergebnis nennen die Geräte). */
  .job-table thead { display: none; }
  .job-table, .job-table tbody { display: block; }
  .job-table tr {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    grid-template-areas: "sel job time" "sel res res" "sel act act";
    align-items: center;
    gap: 4px var(--sp-2);
    padding: 10px var(--sp-3);
    border-bottom: 1px solid var(--c-border-soft);
  }
  .job-table tbody tr:last-child { border-bottom: 0; }
  .table-wrap .job-table td { display: block; padding: 0; border: 0; min-width: 0; box-shadow: none; white-space: normal; }
  .job-table tr.edge-crit { box-shadow: inset 3px 0 0 var(--c-crit); }
  .job-table tr.edge-crit > td:first-child { box-shadow: none; }
  .job-table .jl-sel { grid-area: sel; align-self: start; width: auto; }
  .job-table .jl-job { grid-area: job; overflow-wrap: anywhere; }
  /* Zeit und „Gestartet von“ höchstens 45 % der Breite: Eine lange E-Mail-Adresse endet mit „…“ (voller Text im title), statt den
     Job-Namen auf wenige Zeichen zusammenzudrücken (0.84). */
  .job-table .jl-time { grid-area: time; text-align: right; font-size: var(--fs-small); align-self: start; max-width: 45vw; }
  .job-table .jl-time > div { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .job-table .jl-res { grid-area: res; }
  .job-table .jl-res .hints { max-width: none; }
  .job-table .jl-act { grid-area: act; text-align: left; }
  .job-table .jl-act .btn:first-child { margin-left: 0; }
  .table-wrap .job-table td.jl-shell, .table-wrap .job-table td.jl-count { display: none; }

  /* Läufe eines Jobs gestapelt: Gerät und Status oben, Kunde und Exit-Code darunter, dann Zeit und „Ausgabe“. */
  .job-runs thead { display: none; }
  .job-runs, .job-runs tbody { display: block; }
  .job-runs tr:not(.output-row) {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas: "dev status" "cust exit" "time act";
    align-items: center;
    gap: 3px var(--sp-2);
    padding: 10px var(--sp-3);
    border-bottom: 1px solid var(--c-border-soft);
  }
  .table-wrap .job-runs tr:not(.output-row) td { display: block; padding: 0; border: 0; min-width: 0; box-shadow: none; }
  .job-runs tr.output-row { display: block; }
  .job-runs tr.output-row td { display: block; padding: var(--sp-2) var(--sp-3); }
  .job-runs tr.edge-crit { box-shadow: inset 3px 0 0 var(--c-crit); }
  .job-runs tr.edge-crit > td:first-child { box-shadow: none; }
  .job-runs .jr-dev { grid-area: dev; overflow: hidden; text-overflow: ellipsis; }
  .job-runs .jr-status { grid-area: status; text-align: right; }
  .job-runs .jr-cust { grid-area: cust; font-size: var(--fs-small); overflow: hidden; text-overflow: ellipsis; }
  .job-runs .jr-exit { grid-area: exit; text-align: right; font-size: var(--fs-small); }
  .job-runs .jr-time { grid-area: time; font-size: var(--fs-small); }
  .table-wrap .job-runs tr:not(.output-row) td.jr-dur { display: none; }
  .job-runs .jr-act { grid-area: act; }

  .job-group-head > .btn { margin-left: 0; }
  .job-group-devices { grid-template-columns: minmax(0, 1fr); }
}
/* Ende Jobs-Liste 0.76 */

/* ---------- Sicherung 0.77 ---------- */
/* Reiter „Sicherung“ am Gerät und „Sicherungen“ beim Kunden. Oben die Zähler und die Hilfe zur wirksamen Regel, je Produkt eine
   Tabelle; Zeilen mit Befund tragen die Kante wie die Jobs. Beschriftungen in den Zellen gibt es nur in der Kartenansicht. */
.backup-meta {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: var(--sp-2) var(--sp-4); margin-bottom: var(--sp-3);
}
.backup-rule { display: inline-flex; align-items: center; gap: 4px; font-size: var(--fs-small); color: var(--c-muted); }
.section-title.backup-product { margin-top: var(--sp-4); }
.notice.backup-error { margin: 0 0 var(--sp-2); overflow-wrap: anywhere; }
/* Breite Tabellen vermeiden: Zeiten ohne Jahr, das Alter unter der Zeit, der Typ unter dem Jobnamen, Ziel und Meldung brechen um. */
table.backup-table td.bk-job { min-width: 150px; white-space: normal; }
table.backup-table td.bk-job .pill { margin-top: 4px; }
table.backup-table td.bk-job .bk-alert { display: inline-block; margin-top: 2px; font-size: var(--fs-label); }
table.backup-table td.bk-result { white-space: nowrap; }
table.backup-table td.bk-result .pill + .pill { margin-left: 4px; }
table.backup-table td.bk-last, table.backup-table td.bk-next, table.backup-table td.bk-success { white-space: nowrap; }
table.backup-table td.bk-target { min-width: 90px; white-space: normal; overflow-wrap: anywhere; }
table.backup-table td.bk-msg { min-width: 200px; max-width: 380px; white-space: normal; overflow-wrap: anywhere; font-size: var(--fs-small); }
table.backup-table .bk-label { display: none; }
.backup-table .bk-age.warn { color: var(--c-warn-ink); }
.backup-table .bk-age.crit { color: var(--c-crit-ink); }
.toolbar.backup-toolbar { justify-content: space-between; }
.backup-counts { display: inline-flex; align-items: center; gap: 4px; }

@media (min-width: 1200px) {
  /* Ab Laptop-Breite feste Spaltenbreiten, damit die Spalten der Produkt-Tabellen am Gerät untereinander fluchten.
     Job und Meldung teilen sich den Rest; Köpfe dürfen umbrechen. Schmaler bleibt die automatische Verteilung. */
  table.backup-table.backup-jobs { table-layout: fixed; }
  table.backup-table.backup-jobs th { white-space: normal; vertical-align: bottom; }
  table.backup-table.backup-jobs th:nth-child(2) { width: 165px; }
  table.backup-table.backup-jobs th:nth-child(3) { width: 112px; }
  table.backup-table.backup-jobs th:nth-child(4) { width: 150px; }
  table.backup-table.backup-jobs th:nth-child(5) { width: 112px; }
  table.backup-table.backup-jobs th:nth-child(6) { width: 120px; }
  table.backup-table.backup-jobs td { min-width: 0; max-width: none; overflow-wrap: anywhere; }
}

@media (max-width: 640px) {
  /* Telefon: jede Zeile als Karte. Job (mit Typ) und Ergebnis oben, darunter letzter Lauf und letzte erfolgreiche Sicherung,
     nächster Lauf und Ziel nebeneinander, die Meldung in voller Breite. */
  .backup-table thead { display: none; }
  .backup-table, .backup-table tbody { display: block; }
  .backup-table tr {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas: "job result" "last success" "next target" "msg msg";
    align-items: start;
    gap: 4px var(--sp-2);
    padding: 12px var(--sp-3);
    border-bottom: 1px solid var(--c-border-soft);
  }
  .backup-table tbody tr:last-child { border-bottom: 0; }
  .table-wrap table.backup-table td, .table-wrap table.backup-table td.wrap {
    display: block; padding: 0; border: 0; min-width: 0; max-width: none; white-space: normal; box-shadow: none;
  }
  .table-wrap table.backup-table td.bk-msg:empty { display: none; }
  /* Die Statuskante wandert von der ersten Zelle an die ganze Karte. */
  .backup-table tr.edge-crit { box-shadow: inset 3px 0 0 var(--c-crit); }
  .backup-table tr.edge-warn { box-shadow: inset 3px 0 0 var(--c-warn); }
  .backup-table .bk-job { grid-area: job; overflow-wrap: anywhere; }
  .backup-table .bk-result { grid-area: result; text-align: right; }
  .backup-table .bk-last { grid-area: last; font-size: var(--fs-small); }
  .backup-table .bk-success { grid-area: success; font-size: var(--fs-small); text-align: right; }
  .backup-table .bk-next { grid-area: next; font-size: var(--fs-small); }
  .backup-table .bk-target { grid-area: target; font-size: var(--fs-small); text-align: right; }
  .backup-table .bk-msg { grid-area: msg; }
  table.backup-table .bk-label { display: block; font-size: var(--fs-label); color: var(--c-muted); }
  .table-wrap table.backup-table td.bk-result { white-space: normal; }
  .backup-table td.bk-result .pill { margin: 0 0 2px 4px; }

  /* Kundenübersicht: Gerät und Ergebnis oben, darunter Job und Produkt, dann letzte erfolgreiche Sicherung und Alter. */
  .backup-table.customer-backups tr { grid-template-areas: "dev result" "job job" "product product" "success age"; }
  .backup-table .bk-device { grid-area: dev; font-weight: 600; overflow-wrap: anywhere; }
  .backup-table .bk-product { grid-area: product; font-size: var(--fs-small); }
  .backup-table .bk-agecol { grid-area: age; font-size: var(--fs-small); text-align: right; }
  .backup-table.customer-backups .bk-success { text-align: left; }
  .toolbar.backup-toolbar { justify-content: flex-start; }
}
/* Ende Sicherung 0.77 */

/* ---------- Hyper-V 0.77 ---------- */
/* Anzeigen nah am Agent eines Hyper-V-Hosts, falls nötig. */
/* Ende Hyper-V 0.77 */

/* ---------- Virtuelle Maschinen 0.77 ---------- */
/* Reiter „Virtuelle Maschinen“: Liste, Überwachung und Aktionen. */
.vm-toolbar .vm-tracking { font-size: var(--fs-small); white-space: nowrap; }
.vm-toolbar + .notice { margin-top: 0; }
/* Gesperrt-Hinweise in kompakter Form haben keinen Außenabstand; die Liste darunter hält ihn selbst. */
.vm-toolbar ~ .compact + .table-wrap, .vm-toolbar ~ .compact + .empty-note { margin-top: var(--sp-3); }

/* Liste: Name, Zustand und Gast brechen um, Ressourcen als zwei schmale Balken (Prozessorlast, Anteil am Arbeitsspeicher des
   Hosts), die Zeilenaktionen untereinander. So passt die Tabelle neben die Seitenleiste, ohne seitlich zu scrollen. */
table.vm-table td { vertical-align: top; }
table.vm-table td.vm-name { min-width: 140px; white-space: normal; overflow-wrap: break-word; }
table.vm-table td.vm-name .pill { margin-top: 4px; }
table.vm-table td.vm-state { min-width: 130px; white-space: normal; }
table.vm-table td.vm-state .pill { margin: 0 4px 2px 0; }
table.vm-table td.vm-res { min-width: 150px; }
table.vm-table td.vm-ckpt, table.vm-table td.vm-repl { white-space: normal; min-width: 100px; }
table.vm-table td.vm-guest { white-space: normal; overflow-wrap: break-word; min-width: 100px; max-width: 180px; }
table.vm-table td.vm-act { width: 1%; }
table.vm-table td.vm-act .btn { display: block; width: 100%; margin: 0 0 4px; }
table.vm-table td.vm-act .btn:last-child { margin-bottom: 0; }
table.vm-table td.vm-act .pill { display: inline-block; }
/* Ein offener Alarm schlägt die Markierung „überwacht“ an der ersten Zelle. */
table.vm-table tr.edge-crit > td:first-child { box-shadow: inset 3px 0 0 var(--c-crit); }
.vm-res-line { font-size: var(--fs-small); }
.usage.vm-bar { gap: 6px; margin: 2px 0 4px; }
.usage.vm-bar .bar { min-width: 70px; height: 6px; }
.usage.vm-bar .pct { min-width: 36px; font-size: var(--fs-label); color: var(--c-muted); }
.vm-hb.ok { color: var(--c-ok-ink); }
.vm-hb.crit { color: var(--c-crit-ink); font-weight: 600; }
.vm-hb.muted { color: var(--c-muted); }

/* Karte „Überwachte VMs“: Knöpfe im Kopf nebeneinander, Selbstheilung und letzter Versuch dürfen umbrechen. */
.vm-monitor-tools { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
table.vm-monitor-table td.vmm-state .pill + .pill { margin-left: 4px; }
table.vm-monitor-table td.vmm-last { white-space: normal; min-width: 180px; max-width: 320px; }
table.vm-monitor-table td.vmm-heal { min-width: 150px; }
table.vm-monitor-table td.vmm-act { width: 1%; }

/* Aktionen-Dialog: Zustand der VM über den Kacheln. */
.vm-action-facts { display: flex; flex-wrap: wrap; align-items: center; gap: 6px var(--sp-2); margin: 0 0 var(--sp-3); }
.vm-host-line a { white-space: nowrap; }

@media (max-width: 640px) {
  /* Telefon: jede VM als Karte. Name und Zustand oben, Ressourcen darunter, Laufzeit und Prüfpunkte, Replikation und Gast
     nebeneinander, die Aktionen in voller Breite. */
  .vm-table thead { display: none; }
  .vm-table, .vm-table tbody { display: block; }
  .vm-table tr {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    grid-template-areas: "name state" "res res" "uptime ckpt" "repl guest" "act act";
    align-items: start;
    gap: 6px var(--sp-2);
    padding: 12px var(--sp-3);
    border-bottom: 1px solid var(--c-border-soft);
  }
  .vm-table tbody tr:last-child { border-bottom: 0; }
  .table-wrap table.vm-table td { display: block; padding: 0; border: 0; min-width: 0; white-space: normal; box-shadow: none; }
  .vm-table tr.monitored { box-shadow: inset 3px 0 0 var(--c-accent-line); }
  .vm-table tr.edge-crit { box-shadow: inset 3px 0 0 var(--c-crit); }
  .vm-table .vm-name { grid-area: name; }
  .vm-table .vm-state { grid-area: state; text-align: right; }
  .vm-table .vm-res { grid-area: res; }
  .vm-table .vm-uptime { grid-area: uptime; font-size: var(--fs-small); }
  .vm-table .vm-ckpt { grid-area: ckpt; font-size: var(--fs-small); text-align: right; }
  .vm-table .vm-repl { grid-area: repl; font-size: var(--fs-small); }
  .vm-table .vm-guest { grid-area: guest; font-size: var(--fs-small); text-align: right; }
  .vm-table td.vm-uptime::before, .vm-table td.vm-ckpt::before, .vm-table td.vm-repl::before, .vm-table td.vm-guest::before {
    content: attr(data-label); display: block; font-size: var(--fs-label); color: var(--c-muted);
  }
  .table-wrap table.vm-table td.vm-act { grid-area: act; display: flex; flex-wrap: wrap; gap: 6px; width: auto; margin-top: 4px; text-align: left; }
  .table-wrap table.vm-table td.vm-act .btn { flex: 1 1 auto; width: auto; margin: 0; }
  .vm-table td.vm-act:empty { display: none; }

  /* Überwachte VMs gestapelt: VM und Zustand oben, Selbstheilung und letzter Versuch darunter, dann die Aktionen. */
  .vm-monitor-table thead { display: none; }
  .vm-monitor-table, .vm-monitor-table tbody { display: block; }
  .vm-monitor-table tr {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas: "name state" "heal heal" "last last" "created created" "act act";
    gap: 4px var(--sp-2);
    padding: 10px var(--sp-3);
    border-bottom: 1px solid var(--c-border-soft);
  }
  .vm-monitor-table tbody tr:last-child { border-bottom: 0; }
  .table-wrap table.vm-monitor-table td { display: block; padding: 0; border: 0; min-width: 0; max-width: none; white-space: normal; }
  .vm-monitor-table .vmm-name { grid-area: name; }
  .vm-monitor-table .vmm-state { grid-area: state; text-align: right; }
  .vm-monitor-table .vmm-heal { grid-area: heal; font-size: var(--fs-small); }
  .vm-monitor-table .vmm-last { grid-area: last; font-size: var(--fs-small); }
  .vm-monitor-table .vmm-created { grid-area: created; font-size: var(--fs-small); }
  .vm-monitor-table td.vmm-heal::before, .vm-monitor-table td.vmm-last::before, .vm-monitor-table td.vmm-created::before {
    content: attr(data-label) " "; color: var(--c-muted);
  }
  .table-wrap table.vm-monitor-table td.vmm-act { grid-area: act; display: flex; gap: 6px; width: auto; margin-top: 4px; text-align: left; }
  .table-wrap table.vm-monitor-table td.vmm-act .btn { flex: 1 1 auto; margin: 0; }
  .vm-monitor-table td.vmm-act:empty { display: none; }
  .vm-monitor-tools { width: 100%; }
  .vm-monitor-tools .btn { flex: 1 1 auto; }
}
/* Ende Virtuelle Maschinen 0.77 */

/* ---------- ESXi 0.77 ---------- */
/* Übersicht des ESXi-Geräts (EsxiHostCard): drei Kacheln Host, Verbindung, Zertifikat; Fingerabdrücke brechen paarweise um. */
.notice.esxi-notice { padding: 8px 12px; margin-bottom: var(--sp-3); }
/* Fingerabdrücke brechen nur nach einem Doppelpunkt um (<wbr> aus EsxiDisplay.Fingerprint), nie mitten in einem Paar. */
.esxi-fp { font-size: .82rem; line-height: 1.45; }
.esxi-error { color: var(--c-crit-ink); overflow-wrap: anywhere; }
.esxi-actions { display: flex; flex-wrap: wrap; gap: 8px; }
.esxi-pending {
  display: flex; flex-direction: column; align-items: flex-start; gap: 6px;
  margin-top: var(--sp-3); padding: 10px 12px; border: 1px solid var(--c-border-soft); border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--c-warn-bg) 45%, var(--c-elev));
}
.esxi-cert-head { font-size: var(--fs-label); font-weight: 600; color: var(--c-muted); }
.esxi-cmd { font-family: var(--mono); font-size: .8rem; overflow-wrap: anywhere; }
/* Dialog (EsxiHostModal): Kasten zum Zertifikat unter den Feldern. */
.esxi-cert-box {
  display: flex; flex-direction: column; align-items: flex-start; gap: 6px;
  margin-top: var(--sp-3); padding: 10px 12px; border: 1px solid var(--c-border-soft); border-radius: var(--radius-sm);
  background: var(--c-neutral-bg);
}
.esxi-cert-box .pill { margin-right: 6px; }
.esxi-cert-box .esxi-cert-new { margin-top: var(--sp-2); padding-top: var(--sp-2); border-top: 1px solid var(--c-border-soft); align-self: stretch; }
.esxi-cert-kv { margin: var(--sp-2) 0 var(--sp-3); }
.esxi-section { margin-top: var(--sp-5); }
/* Kundenreiter „Virtualisierung“: Version, Brücke und Status dürfen umbrechen, die Aktionen bleiben sichtbar. */
table.esxi-table td.esxi-version, table.esxi-table td.esxi-state { white-space: normal; min-width: 150px; }
table.esxi-table td.esxi-state .pill + .pill { margin-left: 4px; }
table.esxi-table td.esxi-bridge .pill, table.esxi-table td.esxi-version .pill { margin-left: 6px; }
table.esxi-table td.esxi-row-actions { white-space: nowrap; }
table.esxi-table .esxi-error {
  max-width: 260px;
  /* Höchstens zwei Zeilen, der ganze Text steht im Tooltip und auf der Geräteseite. */
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden;
}
table.esxi-table td.esxi-err { display: none; }
@media (max-width: 640px) {
  /* Telefon: beide Tabellen als Karten. Name und Status oben, darunter die beschrifteten Werte, die Aktionen in voller Breite. */
  .hv-table thead, .esxi-table thead { display: none; }
  .hv-table, .hv-table tbody, .esxi-table, .esxi-table tbody { display: block; }
  .hv-table tr, .esxi-table tr {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: start;
    gap: 3px var(--sp-2);
    padding: 10px var(--sp-3);
    border-bottom: 1px solid var(--c-border-soft);
  }
  .hv-table tbody tr:last-child, .esxi-table tbody tr:last-child { border-bottom: 0; }
  .table-wrap table.hv-table td, .table-wrap table.esxi-table td {
    display: block; padding: 0; border: 0; min-width: 0; white-space: normal; text-align: left; box-shadow: none;
  }
  .hv-table tr.edge-crit, .esxi-table tr.edge-crit { box-shadow: inset 3px 0 0 var(--c-crit); }
  .hv-table tr.edge-warn, .esxi-table tr.edge-warn { box-shadow: inset 3px 0 0 var(--c-warn); }
  .hv-table td[data-label]::before, .esxi-table td[data-label]::before { content: attr(data-label) " "; color: var(--c-muted); font-family: var(--font); }
  .hv-table .hv-name, .esxi-table .esxi-name { grid-column: 1; grid-row: 1; font-weight: 600; }
  .table-wrap table.hv-table td.hv-state, .table-wrap table.esxi-table td.esxi-state { grid-column: 2; grid-row: 1; text-align: right; }
  .hv-table td.hv-site, .hv-table td.hv-vms, .hv-table td.hv-alerts, .hv-table td.hv-seen { grid-column: 1 / -1; font-size: var(--fs-small); }
  .esxi-table td.esxi-address, .esxi-table td.esxi-bridge, .esxi-table td.esxi-version, .esxi-table td.esxi-vms, .esxi-table td.esxi-poll {
    grid-column: 1 / -1; font-size: var(--fs-small);
  }
  .table-wrap table.esxi-table td.esxi-state .cell-sub { display: none; }
  .table-wrap table.esxi-table td.esxi-err { display: block; grid-column: 1 / -1; font-size: var(--fs-small); color: var(--c-crit-ink); overflow-wrap: anywhere; }
  .table-wrap table.esxi-table td.esxi-row-actions { grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: 6px; margin-top: 4px; }
  .table-wrap table.esxi-table td.esxi-row-actions .btn { flex: 1 1 auto; margin: 0; }
  .esxi-actions .btn { flex: 1 1 auto; }
}
/* ESXi-Host ohne Agent: Karte in der Übersicht und Reiter „Virtualisierung“ beim Kunden. */
/* Ende ESXi 0.77 */

/* ---------- Programm-Updates 0.78 ---------- */
/* Reiter „Programme“ im Patchmanagement, Karte „Programme“ der Richtlinie und Hinweise im Software-Reiter des Geräts. */
.app-auto-off { margin: 0 0 12px; }
/* Beschriftungen, die nur die Kartenansicht auf dem Telefon braucht. */
.app-label { display: none; }
td.app-name { min-width: 240px; }
table.app-table td.app-version .mono { white-space: nowrap; }
table.app-table td.app-state .pill + .pill { margin-left: 4px; }
/* Urteil der Richtlinie unter dem verfügbaren Update im Software-Reiter. */
.app-verdict { margin-top: 4px; }
.app-verdict > .pill { max-width: 100%; overflow: hidden; text-overflow: ellipsis; font-family: var(--font); }
.confirm-list-row .app-skip { margin-left: 6px; }
/* Karte der Richtlinie: Abstand zwischen den Fenstern, der Liste darunter und dem Verweis auf die Einstellungen. */
.app-policy > dl.kv { margin-top: var(--sp-4); }
.app-policy > .form-actions { margin-top: var(--sp-3); }
/* Ausgenommene Programme der Richtlinie als Pillen, umbrechend. */
dl.kv dd.app-excluded { display: flex; flex-wrap: wrap; gap: 4px; align-items: center; }
dl.kv dd.app-excluded .pill { margin: 0; }
/* Eigene Regel im Detail-Dialog: Schalter und Eingabe untereinander, linksbündig. */
.app-rule-row .switch { margin-top: 6px; }
.app-rule-row .rule-input { align-items: flex-start; margin-top: 8px; }

@media (max-width: 640px) {
  /* Telefon: jede Zeile als Karte. Auswahl links, rechts daneben das Programm, darunter Version und Geräte, der Stand und
     zuletzt Test und Details. */
  .app-table thead { display: none; }
  .app-table, .app-table tbody { display: block; }
  .app-table tr {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    grid-template-areas: "sel name name" "sel version devices" "sel state state" "sel test actions";
    align-items: start;
    gap: 4px var(--sp-2);
    padding: 12px var(--sp-3);
    border-bottom: 1px solid var(--c-border-soft);
  }
  .app-table tbody tr:last-child { border-bottom: 0; }
  .table-wrap table.app-table td, .table-wrap table.app-table td.wrap {
    display: block; padding: 0; border: 0; min-width: 0; max-width: none; white-space: normal; box-shadow: none;
  }
  /* Die Kante „zu entscheiden“ wandert von der ersten Zelle an die ganze Karte. */
  .app-table tr.edge-warn { box-shadow: inset 3px 0 0 var(--c-warn); }
  .app-table .app-select { grid-area: sel; width: auto; padding-top: 2px; }
  .app-table .app-name { grid-area: name; overflow-wrap: anywhere; }
  .app-table .app-version { grid-area: version; font-size: var(--fs-small); }
  .app-table .app-devices { grid-area: devices; text-align: right; font-size: var(--fs-small); }
  .app-table .app-state { grid-area: state; }
  .app-table .app-test { grid-area: test; align-self: center; font-size: var(--fs-small); }
  .table-wrap table.app-table td.app-actions { grid-area: actions; text-align: right; }
  .app-table .app-label { display: inline; color: var(--c-muted); }

  /* Geräte im Detail-Dialog: Gerät und Freigabe oben, Kunde und installierte Version darunter. */
  .app-devices-table thead { display: none; }
  .app-devices-table, .app-devices-table tbody { display: block; }
  .app-devices-table tr {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas: "dev verdict" "cust version";
    gap: 2px var(--sp-2);
    padding: 10px var(--sp-3);
    border-bottom: 1px solid var(--c-border-soft);
  }
  .app-devices-table tbody tr:last-child { border-bottom: 0; }
  .table-wrap table.app-devices-table td { display: block; padding: 0; border: 0; min-width: 0; white-space: normal; }
  .app-devices-table .app-dev-name { grid-area: dev; overflow-wrap: anywhere; }
  .app-devices-table .app-dev-verdict { grid-area: verdict; text-align: right; }
  .app-devices-table .app-dev-customer { grid-area: cust; font-size: var(--fs-small); }
  .app-devices-table .app-dev-version { grid-area: version; text-align: right; font-size: var(--fs-small); }

  /* Bericht: Programm, darunter das Ergebnis, dann Gerät und Version, zuletzt Zeitpunkt und Auslöser. Ausstehende Programme:
     Programm und Freigabe oben, Version und Zahl der Geräte darunter. */
  .app-report-table thead { display: none; }
  .app-report-table, .app-report-table tbody { display: block; }
  .app-report-table tr {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas: "name name" "result result" "device version" "time trigger";
    gap: 2px var(--sp-2);
    padding: 10px var(--sp-3);
    border-bottom: 1px solid var(--c-border-soft);
  }
  .app-report-table tbody tr:last-child { border-bottom: 0; }
  .table-wrap table.app-report-table td { display: block; padding: 0; border: 0; min-width: 0; white-space: normal; box-shadow: none; }
  .app-report-table tr.edge-crit { box-shadow: inset 3px 0 0 var(--c-crit); }
  .app-report-table .app-rep-name { grid-area: name; font-weight: 600; overflow-wrap: anywhere; }
  .app-report-table .app-rep-result { grid-area: result; }
  .app-report-table.app-report-missing tr { grid-template-areas: "name result" "version devices"; }
  .app-report-table.app-report-missing .app-rep-result { text-align: right; }
  .app-report-table.app-report-missing .app-rep-version { text-align: left; }
  .app-report-table.app-report-missing .app-rep-devices { grid-area: devices; text-align: right; }
  .app-report-table .app-label { display: inline; color: var(--c-muted); }
  /* In einer Karte rückt die erste Zelle sonst um den Kartenabstand ein; die Karte als Zeile hat ihren eigenen. */
  .card > .table-wrap table.app-report-table td:first-child, .card > .table-wrap table.app-table td:first-child,
  .card > .table-wrap table.software-live td:first-child { padding-left: 0; }
  .app-report-table .app-rep-device { grid-area: device; font-size: var(--fs-small); }
  .app-report-table .app-rep-devices { font-size: var(--fs-small); }
  .app-report-table .app-rep-version { grid-area: version; text-align: right; font-size: var(--fs-small); }
  .app-report-table .app-rep-time { grid-area: time; font-size: var(--fs-small); }
  .app-report-table .app-rep-trigger { grid-area: trigger; text-align: right; font-size: var(--fs-small); }

  /* Software-Reiter (Live-Liste): Programm und Quelle oben, darunter installierte und verfügbare Version mit dem Urteil der
     Richtlinie, die Aktionen in voller Breite. */
  table.software-table.software-live { table-layout: auto; }
  .software-live colgroup, .software-live thead { display: none; }
  .software-live, .software-live tbody { display: block; }
  .software-live tr {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    grid-template-areas: "name source" "installed available" "actions actions";
    align-items: start;
    gap: 4px var(--sp-2);
    padding: 12px var(--sp-3);
    border-bottom: 1px solid var(--c-border-soft);
  }
  .software-live tbody tr:last-child { border-bottom: 0; }
  .table-wrap table.software-live td { display: block; padding: 0; border: 0; min-width: 0; max-width: none; overflow: visible; white-space: normal; }
  table.software-table.software-live td .cell-main, table.software-table.software-live td .cell-sub { white-space: normal; overflow-wrap: anywhere; }
  .software-live .sw-name { grid-area: name; }
  .software-live .sw-source { grid-area: source; text-align: right; font-size: var(--fs-small); }
  .software-live .sw-installed { grid-area: installed; font-size: var(--fs-small); overflow-wrap: anywhere; }
  .software-live .sw-available { grid-area: available; }
  .table-wrap table.software-live td.sw-actions { grid-area: actions; display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 6px; }
  table.software-table.software-live td.sw-actions .btn { margin: 0; }
  .software-live .app-label { display: inline; color: var(--c-muted); font-family: var(--font); }
}
/* Ende Programm-Updates 0.78 */

/* ---------- Ereignisprotokoll 0.78 ---------- */
/* Regelsätze in den Einstellungen, Karte beim Kunden und Bereich „Überwachung“ im Reiter „Ereignisse“. */
.erules-toolbar { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-2) var(--sp-3); flex-wrap: wrap; margin-bottom: var(--sp-3); }
table.erules-table td.er-name, table.erules-rules td.er-name { min-width: 220px; }
/* Beschreibung höchstens zwei Zeilen; der ganze Text steht im Dialog des Satzes. */
table.erules-table .er-desc {
  max-width: 60ch; white-space: normal;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden;
}
table.erules-table td.er-dev { white-space: normal; min-width: 140px; color: var(--c-muted); }
table.erules-rules tr.is-off td { color: var(--c-muted); }
table.erules-rules .er-off { margin-left: 6px; }
.notice.erules-builtin { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-2) var(--sp-3); flex-wrap: wrap; margin-bottom: var(--sp-3); }
/* Zuweisung je Satz: Erben, An, Aus nebeneinander; geänderte Zeilen sind markiert, bis gespeichert ist. */
.erules-assign-lead { margin-top: 0; }
table.erules-assign td.ea-name { white-space: normal; min-width: 200px; }
table.erules-assign td.ea-inherited { white-space: nowrap; }
table.erules-assign td.ea-choice { white-space: nowrap; }
table.erules-assign tr.is-changed > td:first-child { box-shadow: inset 3px 0 0 var(--c-accent-line); }
table.erules-assign .ea-effect { margin-top: 4px; }
/* Abweichungen beim Kunden: Satz links, Wert und globaler Wert rechts, auch auf dem Telefon in einer Zeile. */
dl.kv.erules-kv { grid-template-columns: minmax(0, 1fr) auto; align-items: baseline; }
dl.kv.erules-kv dd { text-align: right; white-space: nowrap; }
.erules-global { margin: var(--sp-3) 0 0; font-size: var(--fs-small); }
/* Bereich am Gerät: Zustand, Fehler einzelner Protokolle und die wirksamen Sätze mit Herkunft. */
.erules-device { margin-bottom: var(--sp-3); }
.erules-state { display: flex; flex-wrap: wrap; gap: 4px var(--sp-3); align-items: baseline; }
/* Hinweis („Agent zu alt“, Prüfung aus) über der Zeile mit der Zahl der Regeln: derselbe Abstand wie unter der Kopfzeile. */
.erules-device > .notice + .erules-state { margin-top: var(--sp-3); }
.erules-logerrors { list-style: none; margin: var(--sp-2) 0 0; padding: 0; display: flex; flex-direction: column; gap: 4px; font-size: var(--fs-small); }
.erules-logerrors li { overflow-wrap: anywhere; }
.erules-sets { display: flex; flex-wrap: wrap; gap: 6px; margin-top: var(--sp-3); }
.erules-set {
  display: inline-flex; align-items: baseline; gap: 6px; padding: 3px 10px; font-size: var(--fs-small);
  border: 1px solid var(--c-border-soft); border-radius: 999px; background: var(--c-neutral-bg);
}
table.erules-hits td.eh-rule { white-space: normal; min-width: 200px; }
table.erules-hits td.eh-event { white-space: normal; overflow-wrap: anywhere; min-width: 140px; }
table.erules-hits td.eh-state a.pill { text-decoration: none; }
.erules-sample { max-height: 260px; white-space: pre-wrap; }
@media (max-width: 640px) {
  /* Telefon: alle Tabellen als Karten. Name oben, die beschrifteten Werte darunter, Aktionen in voller Breite. */
  .erules-table thead, .erules-rules thead, .erules-assign thead, .erules-hits thead { display: none; }
  .erules-table, .erules-table tbody, .erules-rules, .erules-rules tbody, .erules-assign, .erules-assign tbody, .erules-hits, .erules-hits tbody { display: block; }
  .erules-table tr, .erules-rules tr, .erules-assign tr, .erules-hits tr {
    display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: start; gap: 4px var(--sp-2);
    padding: 10px var(--sp-3); border-bottom: 1px solid var(--c-border-soft);
  }
  .erules-table tbody tr:last-child, .erules-rules tbody tr:last-child, .erules-assign tbody tr:last-child, .erules-hits tbody tr:last-child { border-bottom: 0; }
  .table-wrap table.erules-table td, .table-wrap table.erules-rules td, .table-wrap table.erules-assign td, .table-wrap table.erules-hits td {
    display: block; padding: 0; border: 0; min-width: 0; max-width: none; white-space: normal; text-align: left; box-shadow: none;
  }
  .erules-table td[data-label]::before, .erules-rules td[data-label]::before, .erules-assign td[data-label]::before, .erules-hits td[data-label]::before {
    content: attr(data-label) " "; color: var(--c-muted);
  }
  .erules-table td.er-name, .erules-rules td.er-name, .erules-hits td.eh-rule, .erules-assign td.ea-name { grid-column: 1; grid-row: 1; }
  .erules-table td.er-default, .erules-rules td.er-severity, .erules-hits td.eh-state { grid-column: 2; grid-row: 1; text-align: right; }
  .erules-table td.er-scope, .erules-table td.er-count, .erules-table td.er-dev, .erules-rules td.er-threshold, .erules-rules td.er-clear,
  .erules-hits td.eh-when, .erules-hits td.eh-count, .erules-hits td.eh-event, .erules-assign td.ea-inherited { grid-column: 1 / -1; font-size: var(--fs-small); }
  .table-wrap table.erules-table td.er-actions, .table-wrap table.erules-rules td.er-actions, .table-wrap table.erules-hits td.eh-actions {
    grid-column: 1 / -1; display: flex; gap: 6px; margin-top: 4px;
  }
  .table-wrap table.erules-table td.er-actions .btn, .table-wrap table.erules-rules td.er-actions .btn, .table-wrap table.erules-hits td.eh-actions .btn { flex: 1 1 auto; margin: 0; }
  .erules-assign td.ea-choice { grid-column: 1 / -1; }
  .erules-assign td.ea-choice .ea-seg { display: flex; }
  .erules-assign td.ea-choice .ea-seg > button { flex: 1 1 0; }
  .erules-hits tr.edge-crit { box-shadow: inset 3px 0 0 var(--c-crit); }
  .erules-hits tr.edge-warn { box-shadow: inset 3px 0 0 var(--c-warn); }
  .erules-assign tr.is-changed { box-shadow: inset 3px 0 0 var(--c-accent-line); }
  .erules-toolbar .btn { flex: 1 1 auto; }
}
/* Ende Ereignisprotokoll 0.78 */

/* ---------- Software 0.78 ---------- */
/* Seite Software (Übersicht und Regeln) und Befunde im Software-Reiter des Geräts. Filterleiste wie bei den Geräten, aufgeklappte
   Gruppen als eingerückte Fläche, Beschriftungen in den Zellen nur in der Kartenansicht des Telefons. */
.toolbar.sw-toolbar { align-items: flex-end; }
.sw-toolbar .sw-switch { align-self: center; white-space: nowrap; }
.sw-toolbar-actions { display: inline-flex; flex-wrap: wrap; gap: var(--sp-2); margin-left: auto; }
.sw-summary { display: flex; align-items: center; gap: 4px; margin: 0 0 var(--sp-2); }
.sw-label { display: none; }
table.sw-table td.sw-name { min-width: 220px; white-space: normal; }
table.sw-table td.sw-name .cell-main { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 6px; }
.sw-table .sw-expand { text-align: left; overflow-wrap: anywhere; }
table.sw-table td.sw-devices, table.sw-table td.sw-versions, table.sw-table td.sw-customers { font-variant-numeric: tabular-nums; }
.sw-table tr.is-open > td { background: var(--c-hover); }
.sw-table tr.sw-detail > td { padding: var(--sp-3) var(--sp-4) var(--sp-4); background: var(--c-bg); white-space: normal; }
.sw-versions-line { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 6px; margin-bottom: var(--sp-2); }
.sw-bulk {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); margin-bottom: var(--sp-2);
  padding: var(--sp-2) var(--sp-3); border: 1px solid var(--c-border-soft); border-radius: var(--radius-sm); background: var(--c-surface);
}
.sw-bulk > span { margin-right: auto; font-weight: 600; }
table.sw-device-table td.sw-d-host { font-weight: 600; overflow-wrap: anywhere; }
table.sw-device-table td.sw-d-version { overflow-wrap: anywhere; }
.sw-rules-head { margin-top: var(--sp-4); }
.sw-rules-head .section-title { display: inline-flex; align-items: center; gap: 4px; margin: 0; }
table.sw-rules-table td.sw-r-name { min-width: 200px; white-space: normal; overflow-wrap: anywhere; }
table.sw-rules-table td.sw-r-target { white-space: normal; overflow-wrap: anywhere; }
table.sw-exceptions-table td.sw-x-reason { white-space: normal; overflow-wrap: anywhere; min-width: 160px; }
.sw-rule-target { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; padding: 6px 0; }
.sw-preview {
  margin-top: var(--sp-4); padding: var(--sp-3) var(--sp-4); border: 1px solid var(--c-border-soft); border-radius: var(--radius-sm);
  background: var(--c-bg);
}
.sw-preview p { margin: 0; }
.sw-preview-title { font-size: var(--fs-label); font-weight: 600; color: var(--c-muted); margin-bottom: 4px; }
.sw-preview-names { margin: 6px 0 0; padding-left: 18px; font-size: var(--fs-small); }
.sw-preview-names li { overflow-wrap: anywhere; }
.card.sw-findings { margin-bottom: var(--sp-4); }
.sw-findings-head { display: flex; flex-wrap: wrap; align-items: center; gap: 6px var(--sp-2); margin-bottom: var(--sp-2); }
.sw-findings-head .section-title { display: inline-flex; align-items: center; gap: 4px; margin: 0 auto 0 0; }
table.sw-findings-table td.sw-f-name, table.sw-findings-table td.sw-f-rule { white-space: normal; overflow-wrap: anywhere; }
.sw-findings-since { font-size: var(--fs-small); margin: var(--sp-2) 0 0; }
.sw-findings .modal-section { margin-top: var(--sp-3); }
.sw-exceptions { list-style: none; margin: 0; padding: 0; }
.sw-exceptions li {
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-2); padding: 6px 0;
  border-top: 1px solid var(--c-border-soft); font-size: var(--fs-small);
}
.sw-exceptions li:first-child { border-top: 0; }
.sw-exceptions .sw-x-text { overflow-wrap: anywhere; }
/* Kundenseite, Karte „Richtlinien“: Link auf die Software-Regeln des Kunden mit kurzer Erklärung daneben. */
.sw-customer-foot { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2) var(--sp-3); }
.sw-customer-foot .muted { font-size: var(--fs-small); }
/* Benutzer löschen (0.78, gleicher Strang): Folgen im Warn-Dialog als knappe Liste. */
.user-delete-list { margin: 0 0 var(--sp-3); padding-left: 18px; font-size: var(--fs-small); }
.user-delete-list li + li { margin-top: 4px; }

@media (max-width: 640px) {
  /* Telefon: Gruppen, Geräte, Regeln und Befunde als Karten; Zahlen mit Beschriftung nebeneinander, Aktionen in voller Breite. */
  .sw-toolbar-actions { margin-left: 0; flex: 1 1 100%; }
  .sw-toolbar-actions .btn { flex: 1 1 auto; }
  .sw-toolbar > .filter { flex: 1 1 calc(50% - var(--sp-2)); max-width: none; }
  .sw-toolbar > .filter-search { flex-basis: 100%; }
  .sw-toolbar .filter select { width: 100%; max-width: none; }
  .sw-table thead, .sw-device-table thead, .sw-rules-table thead, .sw-findings-table thead, .sw-exceptions-table thead { display: none; }
  .sw-table, .sw-table > tbody, .sw-device-table, .sw-device-table tbody, .sw-rules-table, .sw-rules-table tbody,
  .sw-findings-table, .sw-findings-table tbody, .sw-exceptions-table, .sw-exceptions-table tbody { display: block; }
  .sw-table tr.sw-row, .sw-device-table tr, .sw-rules-table tr, .sw-findings-table tr, .sw-exceptions-table tr {
    display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 4px var(--sp-2); align-items: start;
    padding: 12px var(--sp-3); border-bottom: 1px solid var(--c-border-soft);
  }
  .table-wrap table.sw-table td, .table-wrap table.sw-device-table td, .table-wrap table.sw-rules-table td,
  .table-wrap table.sw-findings-table td, .table-wrap table.sw-exceptions-table td {
    display: block; padding: 0; border: 0; min-width: 0; max-width: none; white-space: normal; box-shadow: none; text-align: left;
  }
  .sw-label { display: block; font-size: var(--fs-label); color: var(--c-muted); }
  .sw-table tr.edge-crit, .sw-device-table tr.edge-crit, .sw-rules-table tr.edge-crit, .sw-findings-table tr.edge-crit { box-shadow: inset 3px 0 0 var(--c-crit); }
  .sw-table tr.edge-warn, .sw-device-table tr.edge-warn, .sw-rules-table tr.edge-warn, .sw-findings-table tr.edge-warn { box-shadow: inset 3px 0 0 var(--c-warn); }
  .sw-table .sw-name, .sw-table .sw-actions, .sw-device-table .sw-d-host, .sw-device-table .sw-d-customer, .sw-device-table .sw-d-actions,
  .sw-rules-table .sw-r-name, .sw-rules-table .sw-r-actions, .sw-findings-table .sw-f-name, .sw-findings-table .sw-f-rule,
  .sw-findings-table .sw-f-actions, .sw-exceptions-table td { grid-column: 1 / -1; }
  .sw-table .sw-new { grid-column: 1 / -1; font-size: var(--fs-small); }
  .table-wrap table.sw-table td.sw-actions, .table-wrap table.sw-device-table td.sw-d-actions, .table-wrap table.sw-rules-table td.sw-r-actions,
  .table-wrap table.sw-findings-table td.sw-f-actions { display: flex; flex-wrap: wrap; gap: 6px; }
  .sw-table td.sw-actions .btn, .sw-device-table td.sw-d-actions .btn, .sw-rules-table td.sw-r-actions .btn, .sw-findings-table td.sw-f-actions .btn {
    flex: 1 1 auto; margin: 0;
  }
  .table-wrap table.sw-device-table td.sw-d-actions:empty, .table-wrap table.sw-findings-table td.sw-f-actions:empty { display: none; }
  /* Die aufgeklappte Gruppe trägt die Fläche als ganze Karte, nicht je Zelle. */
  .sw-table tr.sw-row.is-open { background: var(--c-hover); }
  .sw-table tr.is-open > td { background: transparent; }
  .sw-table tr.sw-detail { display: block; border-bottom: 1px solid var(--c-border-soft); }
  .table-wrap table.sw-table tr.sw-detail > td { display: block; padding: var(--sp-2) var(--sp-2) var(--sp-3); }
  .sw-device-table tr { background: var(--c-surface); }
  /* Mit Auswahl steht das Kästchen links neben der ganzen Karte. */
  .sw-device-table.selectable tr { grid-template-columns: 24px repeat(3, minmax(0, 1fr)); }
  .sw-device-table.selectable .sw-d-check { grid-column: 1; grid-row: 1 / span 5; }
  .sw-device-table.selectable .sw-d-host, .sw-device-table.selectable .sw-d-customer, .sw-device-table.selectable .sw-d-finding,
  .sw-device-table.selectable .sw-d-actions { grid-column: 2 / -1; }
  .sw-device-table.selectable .sw-d-version { grid-column: 2; }
  .sw-device-table.selectable .sw-d-source { grid-column: 3; }
  .sw-device-table.selectable .sw-d-seen { grid-column: 4; }
  .sw-device-table .sw-d-customer { font-size: var(--fs-small); }
  .sw-device-table .sw-d-version, .sw-device-table .sw-d-source, .sw-device-table .sw-d-seen { font-size: var(--fs-small); }
  .sw-findings-table .sw-f-kind { grid-column: 1 / -1; }
  .sw-exceptions li { flex-direction: column; align-items: stretch; }
  /* Inventarstand im Software-Reiter des Geräts: Programm und Quelle oben, Version, Hersteller und Datum beschriftet darunter,
     „Deinstallieren“ rechts in eigener Zeile (fehlt bei Programmen im Benutzerprofil). */
  table.software-table.sw-inventory { table-layout: auto; }
  .sw-inventory colgroup, .sw-inventory thead { display: none; }
  .sw-inventory, .sw-inventory tbody { display: block; }
  .sw-inventory tr {
    display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); grid-template-areas: "name name source" "version publisher date" "actions actions actions";
    gap: 4px var(--sp-2); align-items: start; padding: 12px var(--sp-3); border-bottom: 1px solid var(--c-border-soft);
  }
  .sw-inventory tbody tr:last-child { border-bottom: 0; }
  .table-wrap table.sw-inventory td { display: block; padding: 0; border: 0; min-width: 0; max-width: none; overflow: visible; white-space: normal; }
  table.software-table.sw-inventory td .cell-main, table.software-table.sw-inventory td .cell-sub { white-space: normal; overflow-wrap: anywhere; }
  .sw-inventory .sw-i-name { grid-area: name; }
  .sw-inventory .sw-i-source { grid-area: source; text-align: right; }
  .sw-inventory .sw-i-version { grid-area: version; font-size: var(--fs-small); overflow-wrap: anywhere; }
  .sw-inventory .sw-i-version .sw-label { font-family: var(--font); }
  .sw-inventory .sw-i-publisher { grid-area: publisher; font-size: var(--fs-small); overflow-wrap: anywhere; }
  .sw-inventory .sw-i-date { grid-area: date; font-size: var(--fs-small); }
  .table-wrap table.sw-inventory td.sw-i-actions { grid-area: actions; display: flex; justify-content: flex-end; }
  table.software-table.sw-inventory td.sw-i-actions .btn { margin: 0; }
  .table-wrap table.sw-inventory td.sw-i-actions:has(.sw-i-none) { display: none; }
}
/* Ende Software 0.78 */

/* ---------- Isolation 0.78 ---------- */
/* Pille, Banner, Kachel und Dialog der Netzwerk-Isolation an der Geräteseite. */
/* Banner: Text links (Überschrift, Einzelheiten, freigegebene Ziele), Schaltfläche rechts oben. */
.isolation-banner { align-items: flex-start; }
.isolation-banner-text { display: flex; flex-direction: column; gap: 2px; flex: 1 1 320px; min-width: 0; line-height: 1.45; }
.isolation-endpoints { font-family: var(--mono); font-size: var(--fs-label); color: var(--c-muted); overflow-wrap: anywhere; }
/* Dialog: Grund breit, Ablaufzeit schmal; Folgen in zwei Spalten. */
.isolation-form { grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); }
.isolation-facts { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-2) var(--sp-4); }
.isolation-facts section { min-width: 0; }
.isolation-facts ul { margin: 4px 0 0; padding-left: 18px; }
.isolation-facts li { margin: 3px 0; line-height: 1.45; }
/* Hinweise je nach Gerät als eine Liste; der Notweg bricht nicht mitten im Befehl um. */
.isolation-warnings ul { margin: 4px 0 0; padding-left: 18px; }
.isolation-warnings li { margin: 2px 0; line-height: 1.45; }
.isolation-cmd { font-family: var(--mono); font-size: var(--fs-label); white-space: nowrap; }
/* Löschen eines isolierten Geräts ohne Verbindung: Folgen als Warnung über den Punkten des Bestätigungsdialogs. */
.isolation-delete-warn { color: var(--c-warn-ink); line-height: 1.45; }
@media (max-width: 640px) {
  .isolation-form, .isolation-facts { grid-template-columns: 1fr; }
  .isolation-banner .btn { width: 100%; }
}
/* Ende Isolation 0.78 */

/* ---------- Akzentfarbe: Vorschau in den Einstellungen (0.79) ----------
   Je Thema eine Fläche mit Schaltfläche, Link und Reiterlinie in den Farben, die der Server ausgibt (AccentColorPreview.razor setzt
   sie als --pv-*), darunter die gemessenen Kontraste und die Hinweise zu automatischen Anpassungen. */
.accent-setting { display: flex; flex-direction: column; gap: var(--sp-3); width: 100%; max-width: 760px; }
.accent-preview { display: flex; flex-direction: column; gap: var(--sp-2); }
.accent-preview-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-3); }
.accent-sample { padding: 12px 14px; border: 1px solid var(--pv-border); border-radius: var(--radius-sm); background: var(--pv-bg); color: var(--pv-text); }
.accent-sample-title { margin-bottom: var(--sp-2); font-size: var(--fs-label); font-weight: 600; }
.accent-sample-row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2) var(--sp-4); }
.accent-sample-btn {
  display: inline-flex; align-items: center; min-height: var(--control-h-sm); padding: 3px 12px; border-radius: var(--radius-sm);
  background: var(--pv-fill); color: var(--pv-on-fill); font-weight: 600;
}
.accent-sample-link { color: var(--pv-ink); text-decoration: underline; text-underline-offset: 2px; }
.accent-sample-tab { padding: 2px 0; border-bottom: 2px solid var(--pv-line); font-weight: 600; }
.accent-sample-ratios { display: grid; grid-template-columns: auto auto; justify-content: start; gap: 2px var(--sp-3); margin: var(--sp-3) 0 0; font-size: var(--fs-label); }
.accent-sample-ratios dd { margin: 0; font-weight: 600; font-variant-numeric: tabular-nums; }
.accent-preview-notes { margin: 0; padding-left: 18px; font-size: var(--fs-small); color: var(--c-muted); }
.accent-preview-notes.plain { padding-left: 0; }
.accent-preview .notice { margin: 0; }
@media (max-width: 640px) {
  .accent-preview-grid { grid-template-columns: minmax(0, 1fr); }
}
/* Ende Akzentfarbe */

/* ---------- Hoher Kontrast ----------
   Die Werte stehen bei den Themen oben; hier die Regeln, die über Farbe hinausgehen, für „Hoch“ und für „System“ bei
   prefers-contrast: more. Links sind unterstrichen (Namen in Textfarbe und Navigation ausgenommen), Tabellenzeilen trennt der
   Standardrand, Pillen tragen einen Rand in ihrer Textfarbe. Die Fokusbreite (3 px) kommt aus --focus-w. */
html[data-contrast="high"] a:not(.plain, .btn, .tab, .nav-item, .stat-card, .need-row, .lib-tile, .lib-index-item, .search-hit, .pill) {
  text-decoration: underline;
  text-underline-offset: 2px;
}
html[data-contrast="high"] th, html[data-contrast="high"] td { border-bottom-color: var(--c-border); }
html[data-contrast="high"] .pill, html[data-contrast="high"] .badge, html[data-contrast="high"] .tab-badge { box-shadow: inset 0 0 0 1px currentColor; }
@media (prefers-contrast: more) {
  html[data-contrast="system"] a:not(.plain, .btn, .tab, .nav-item, .stat-card, .need-row, .lib-tile, .lib-index-item, .search-hit, .pill) {
    text-decoration: underline;
    text-underline-offset: 2px;
  }
  html[data-contrast="system"] th, html[data-contrast="system"] td { border-bottom-color: var(--c-border); }
  html[data-contrast="system"] .pill, html[data-contrast="system"] .badge, html[data-contrast="system"] .tab-badge { box-shadow: inset 0 0 0 1px currentColor; }
}
/* Ende Hoher Kontrast */

/* ---------- Erzwungene Farben ----------
   Windows-Kontrastdesigns (forced-colors) entfernen Schatten und Hintergründe. Statuskanten werden dann zum linken Rand, dessen
   Stärke und Linie den Zustand trägt (kritisch und ungültig kräftig, Warnung und ungespeichert gestrichelt, sonst schmal); die
   Legende der Einstellungen zeichnet ihre Kanten genauso. Die selbst gezeichneten Kontrollkästchen weichen der Darstellung des
   Systems, Markierungen aktiver Einträge der Systemfarbe Highlight. Gedrückte Umschalter (aria-pressed, etwa Darstellung und
   Kontrast im Benutzermenü) heben sich sonst nur über Fläche und Schatten ab; sie stehen hier auf Highlight, gesperrte auf GrayText.
   Die Richtlinien-Zeilen regelt ihr eigener Block. */
@media (forced-colors: active) {
  .stat-card[class*="edge-"], .card[class*="edge-"], tr[class*="edge-"] > td:first-child, tr.monitored > td:first-child,
  .set-row.custom, .set-legend-edge { border-left: 2px solid CanvasText; }
  .stat-card.edge-warn, .card.edge-warn, tr.edge-warn > td:first-child, .set-row.dirty, .set-legend-edge.dirty { border-left: 3px dashed CanvasText; }
  .stat-card.edge-crit, .card.edge-crit, tr.edge-crit > td:first-child, .set-row.invalid, .set-legend-edge.invalid { border-left: 4px solid CanvasText; }
  .set-legend-edge { width: 4px; height: 20px; border-radius: 0; background: none; }
  /* :root hebt die Regel über die Regeln der einzelnen Umschalter für den gewählten Zustand (Klasse „on“ bzw. aria-pressed). */
  :root button[aria-pressed="true"] {
    forced-color-adjust: none;
    background: Highlight;
    color: HighlightText;
    border-color: Highlight;
    box-shadow: none;
    outline-color: CanvasText;
  }
  :root button[aria-pressed="true"]:disabled { background: GrayText; color: Canvas; border-color: GrayText; }
  input[type=checkbox], input[type=radio], .toggle input[type=checkbox] {
    appearance: auto;
    -webkit-appearance: auto;
    width: auto;
    min-width: 0;
    height: auto;
    min-height: 0;
  }
  input[type=checkbox]::before, input[type=radio]::before, .toggle input[type=checkbox]::before { content: none; }
  .nav-item.active::before, .set-index-group.active::before, .set-index-section[aria-current]::before,
  .lib-index-item.active::before { forced-color-adjust: none; background: Highlight; }
}
/* Ende Erzwungene Farben */

/* ---------- NIS2-Nachweis 0.79 ---------- */
/* Reiter „Berichte“ des Kunden mit Art, Zeitraum und Freigabe, Dialog des NIS2-Nachweisberichts und begründete Ausnahmen. */
/* Dialog: Prüfansicht mit einer Kachel je Maßnahme. Der Statustext steht statt der großen Zahl und darf umbrechen. */
.nis2-invalid { color: var(--c-crit-ink); }
.nis2-check { margin-top: var(--sp-3); }
.nis2-check-head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 4px var(--sp-2); margin-bottom: var(--sp-2); }
.nis2-check-head .muted { font-size: var(--fs-small); }
.nis2-tiles { grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: var(--sp-2); margin-bottom: var(--sp-2); }
.nis2-tiles .stat-card { padding: 10px 12px; }
.nis2-tiles .stat-value.nis2-status { font-family: var(--font); font-size: var(--fs-body); font-weight: 600; line-height: 1.3; }
.nis2-tiles .stat-value.muted { color: var(--c-muted); }
.nis2-notes { margin: 0 0 var(--sp-2); padding-left: 18px; color: var(--c-muted); font-size: var(--fs-small); }
/* Reiter „Berichte“: Filter nach Art, Status mit Kurzbewertung und Prüfsumme dürfen umbrechen. */
.nis2-report-filter { margin-right: var(--sp-1); }
.nis2-reports-table td.nis2-rep-status { white-space: normal; min-width: 190px; }
.nis2-reports-table .nis2-rep-summary { max-width: 280px; }
.nis2-reports-table td.nis2-rep-period { white-space: normal; min-width: 150px; }
/* Begründete Ausnahmen: Überschrift als Schalter zum Ein- und Ausklappen, beendete und abgelaufene gedämpft. */
.nis2-exc-head { margin-top: var(--sp-5); }
.nis2-exc-head .section-title { display: inline-flex; align-items: center; gap: 6px; }
.nis2-exc-toggle { appearance: none; border: 0; background: none; padding: 0; margin: 0; font: inherit; color: inherit; cursor: pointer; }
.nis2-exc-toggle::before { content: "\25B8"; display: inline-block; width: 1em; color: var(--c-muted); transition: transform .15s ease; }
.nis2-exc-toggle[aria-expanded="true"]::before { transform: rotate(90deg); }
.nis2-exc-toggle:focus-visible { outline: var(--focus-w) solid var(--c-focus); outline-offset: 2px; border-radius: 4px; }
.nis2-exc-table td.nis2-exc-reason { white-space: normal; min-width: 200px; max-width: 380px; }
/* Gerät gelöscht oder verschoben: der Hinweis unter dem Namen bricht um, statt die Spalte zu verbreitern. */
.nis2-exc-table td.nis2-exc-target { white-space: normal; min-width: 140px; max-width: 220px; }
.nis2-exc-table tr.nis2-exc-old td { color: var(--c-muted); }
@media (prefers-reduced-motion: reduce) {
  .nis2-exc-toggle::before { transition: none; }
}
/* Telefon: Berichte und Ausnahmen als Karten; oben Zeitraum bzw. Maßnahme und Status, darunter die übrigen Angaben beschriftet. */
@media (max-width: 640px) {
  .nis2-reports-table thead, .nis2-exc-table thead { display: none; }
  .nis2-reports-table, .nis2-reports-table tbody, .nis2-exc-table, .nis2-exc-table tbody { display: block; }
  .nis2-reports-table tr, .nis2-exc-table tr {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 3px var(--sp-2);
    padding: 10px var(--sp-3);
    border-bottom: 1px solid var(--c-border-soft);
  }
  .nis2-reports-table tbody tr:last-child, .nis2-exc-table tbody tr:last-child { border-bottom: 0; }
  .nis2-reports-table td, .nis2-exc-table td { display: block; padding: 0; border: 0; min-width: 0; max-width: none; white-space: normal; text-align: left; }
  .nis2-reports-table td.nis2-rep-period, .nis2-exc-table td.nis2-exc-measure { grid-column: 1; grid-row: 1; }
  .nis2-reports-table td.nis2-rep-kind { grid-column: 2; grid-row: 1; text-align: right; color: var(--c-muted); font-size: var(--fs-small); }
  .nis2-exc-table td.nis2-exc-state { grid-column: 2; grid-row: 1; text-align: right; }
  .nis2-reports-table td.nis2-rep-status, .nis2-reports-table td.nis2-rep-created,
  .nis2-exc-table td.nis2-exc-target, .nis2-exc-table td.nis2-exc-reason, .nis2-exc-table td.nis2-exc-until, .nis2-exc-table td.nis2-exc-by {
    grid-column: 1 / -1; font-size: var(--fs-small); min-width: 0; max-width: none;
  }
  .nis2-reports-table td.nis2-rep-format, .nis2-reports-table td.nis2-rep-size { display: none; }
  .nis2-reports-table td[data-label]::before, .nis2-exc-table td[data-label]::before { content: attr(data-label) " "; color: var(--c-muted); }
  .nis2-reports-table td.row-actions, .nis2-exc-table td.row-actions { grid-column: 1 / -1; text-align: left; margin-top: 4px; }
  .nis2-reports-table td.row-actions .btn:first-child, .nis2-exc-table td.row-actions .btn:first-child { margin-left: 0; }
  .nis2-exc-table td.row-actions:empty { display: none; }
  .nis2-report-filter { order: -1; flex-basis: 100%; }
  .nis2-report-filter .nis2-filter-btn { flex: 1 1 auto; }
}
/* Ende NIS2-Nachweis 0.79 */

/* ---------- Logos 0.79 ---------- */
/* Logo je Darstellung (Tag und Nacht) in Seitenleiste und Anmeldung, Vorschau beider Varianten in den Einstellungen. */

/* BrandMark rendert zwei Bilder, wenn sich Nacht- und Tag-Logo unterscheiden. Nacht ist Vorgabe; Tag gilt bei data-theme="light" und
   bei "system" mit hellem Betriebssystem. Der Wechsel im Benutzermenü setzt nur data-theme, das Logo folgt ohne Neuladen. */
.brand-logo-img.for-light { display: none; }
html[data-theme="light"] .brand-logo-img.for-dark { display: none; }
html[data-theme="light"] .brand-logo-img.for-light { display: block; }
@media (prefers-color-scheme: light) {
  html[data-theme="system"] .brand-logo-img.for-dark { display: none; }
  html[data-theme="system"] .brand-logo-img.for-light { display: block; }
}

/* Einstellungen, Branding, Produkt: zwei Kacheln Nacht und Tag nebeneinander, auf dem Telefon untereinander. Die Bühne zeigt das
   wirksame Logo auf der echten Fläche der Seitenleiste des jeweiligen Themas; Farbe und Rand setzt Settings.razor aus BrandColors. */
.set-control .logo-tiles { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-3); width: 100%; align-items: stretch; }
.logo-tile {
  display: flex; flex-direction: column; gap: 8px; min-width: 0; padding: 12px;
  border: 1px solid var(--c-border-soft); border-radius: var(--radius-sm); background: var(--c-elev);
}
.logo-tile-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.logo-tile-title { font-weight: 600; }
.logo-tile-ground { color: var(--c-muted); font-size: var(--fs-label); }
.logo-tile-head .pill { margin-left: auto; }
.logo-tile-stage {
  display: flex; align-items: center; justify-content: center; gap: 10px; min-height: 76px; padding: 12px 16px;
  border: 1px solid; border-radius: var(--radius-sm);
}
.logo-tile-stage img { height: 40px; width: auto; max-width: 100%; object-fit: contain; display: block; }
.logo-tile-sign { font-family: var(--font-display); font-size: 1.1rem; font-weight: 600; display: flex; align-items: center; gap: 8px; overflow-wrap: anywhere; }
.logo-tile-meta, .logo-tile-use { margin: 0; color: var(--c-muted); font-size: var(--fs-label); overflow-wrap: anywhere; }
.logo-tile-note { margin: 0; color: var(--c-warn-ink); font-size: var(--fs-label); }
.logo-tile-actions { display: flex; align-items: center; gap: 8px 16px; flex-wrap: wrap; margin-top: auto; padding-top: 4px; }
.logo-tile-actions .btn.danger { margin-left: auto; }
@media (max-width: 760px) {
  .set-control .logo-tiles { grid-template-columns: minmax(0, 1fr); }
}
/* Ende Logos 0.79 */

/* ---------- Web-App 0.80 ---------- */
/* Installierte App: Safe Areas (Kopfleiste, Toasts, Vollbild-Dialoge, Detailleiste, Benutzermenü, Speicherleiste), 16 px in Feldern
   auf Touch-Geräten gegen das Zoomen unter iOS, Regeln für display-mode: standalone („Seite neu laden“, kein Hinweis zur Installation),
   „Angemeldet bleiben“ auf der Anmeldeseite, die Karte „Web-App“ unter „Mein Konto“ und die Kachel „App-Symbol“ in den Einstellungen.
   Die Wiederverbindung ohne Aufblitzen steuert wwwroot/js/reconnect.js (die Regeln der Anzeige bleiben im Block „Verbindungsabbruch“). */

/* Safe Areas: Abstand zu Notch, Kamera-Insel und Home-Leiste. App.razor setzt viewport-fit=cover, damit reicht die Seite bis an den Rand;
   ohne solche Ränder sind die Werte 0. Als Tokens, damit sich Telefone in der Sichtprüfung simulieren lassen. */
:root {
  --safe-top: env(safe-area-inset-top, 0px);
  --safe-right: env(safe-area-inset-right, 0px);
  --safe-bottom: env(safe-area-inset-bottom, 0px);
  --safe-left: env(safe-area-inset-left, 0px);
}

/* Toasts und Speicherleiste über der Home-Leiste, die Detailleiste der Alarme mit Abstand oben, rechts und unten. Breite Fenster:
   Seitenleiste und Inhalt halten seitlich Abstand (Telefon quer mit mehr als 900 px). */
.toast-stack { bottom: calc(22px + var(--safe-bottom)); }
body:has(.set-savebar) .toast-stack { bottom: calc(92px + var(--safe-bottom)); }
.set-savebar { bottom: calc(var(--sp-4) + var(--safe-bottom)); }
.ap-head { padding-top: calc(14px + var(--safe-top)); padding-right: calc(14px + var(--safe-right)); }
.ap-body { padding-right: calc(18px + var(--safe-right)); padding-bottom: calc(24px + var(--safe-bottom)); }
.sidebar { padding-left: var(--safe-left); }
.app-header { padding-right: calc(var(--sp-4) + var(--safe-right)); }
.content { padding-right: calc(28px + var(--safe-right)); padding-bottom: calc(40px + var(--safe-bottom)); }

/* Schmal: Die klebende Kopfleiste beginnt unter der Statusleiste, Knopf und Menü rücken mit; --header-h wächst um denselben Betrag. */
@media (max-width: 900px) {
  :root { --header-h: calc(97px + var(--safe-top)); }
  .sidebar { padding-top: var(--safe-top); padding-right: var(--safe-right); }
  .sidebar:has(> .nav-check:checked) { padding-bottom: var(--safe-bottom); }
  .app-header { top: var(--safe-top); right: var(--safe-right); padding-right: 12px; }
  .user-menu[open] > .user-trigger::before { top: calc(var(--bar-h) + var(--safe-top)); }
  .user-panel {
    top: calc(var(--bar-h) + var(--safe-top));
    max-height: calc(100dvh - var(--bar-h) - var(--safe-top));
    padding-bottom: var(--safe-bottom);
  }
  .content { padding-left: calc(16px + var(--safe-left)); padding-right: calc(16px + var(--safe-right)); }
}
@media (max-width: 900px) and (pointer: coarse) {
  :root { --header-h: calc(109px + var(--safe-top)); }
}

/* Telefon: Dialoge als Vollbild mit Kopf unter der Statusleiste und Schaltflächen über der Home-Leiste. */
@media (max-width: 640px) {
  .modal-head { padding-top: calc(14px + var(--safe-top)); }
  .modal-foot { padding-bottom: calc(14px + var(--safe-bottom)); }
  .modal:not(:has(> .modal-foot)) > .modal-body { padding-bottom: calc(14px + var(--safe-bottom)); }
  .toast-stack { bottom: calc(10px + var(--safe-bottom)); }
  body:has(.set-savebar) .toast-stack { bottom: calc(132px + var(--safe-bottom)); }
  .set-savebar { bottom: calc(var(--sp-2) + var(--safe-bottom)); }
  .ap-head { padding: calc(12px + var(--safe-top)) calc(10px + var(--safe-right)) 10px calc(14px + var(--safe-left)); }
  .ap-body { padding-left: calc(14px + var(--safe-left)); padding-right: calc(14px + var(--safe-right)); padding-bottom: calc(28px + var(--safe-bottom)); }
  .content { padding-left: calc(12px + var(--safe-left)); padding-right: calc(12px + var(--safe-right)); padding-bottom: calc(32px + var(--safe-bottom)); }
}

/* iOS vergrößert die Seite beim Tippen in ein Feld mit weniger als 16 px Schrift. Auf Touch-Geräten haben Eingaben deshalb 16 px; die
   Dichte der Oberfläche bleibt, nur die Schrift in Feldern wächst. Die :not()-Kette schlägt auch kleinere Schriften einzelner Bereiche. */
@media (pointer: coarse) {
  input:not([type=checkbox]):not([type=radio]):not([type=range]):not([type=color]):not([type=file]),
  select:not([data-keep-size]),
  textarea:not([data-keep-size]) { font-size: 16px; }
}

/* Installierte App: „Seite neu laden“ im Benutzermenü statt des Hinweises zur Installation. */
.user-panel-top-actions { display: flex; align-items: center; gap: 2px; min-width: 0; }
.user-panel-reload { display: none; }
.user-panel-install { font-size: var(--fs-small); }
@media (display-mode: standalone) {
  .user-panel-reload { display: inline-block; }
  .user-panel-install { display: none; }
}

/* Anmeldeseite: „Angemeldet bleiben“ zwischen Kennwort und Anmelden. */
.login-remember { display: flex; align-items: center; gap: 8px; margin: -2px 0 16px; font-size: .9rem; cursor: pointer; }
.login-remember .muted { font-size: var(--fs-small); }
.login-remember-note { margin: -4px 0 14px; font-size: var(--fs-small); color: var(--c-muted); }

/* Mein Konto, Karte „Web-App“: links der QR-Code mit der Adresse, rechts „Jetzt installieren“ (nur wenn der Browser es anbietet) und
   die Anleitung je Plattform; die Plattform dieses Geräts steht oben und ist markiert (data-app-platform aus app.js). Unten
   „Auf allen Geräten abmelden“. In der installierten App entfällt die Anleitung. */
.webapp-card .card-head-row { justify-content: flex-start; }
.webapp-when-app { display: none; }
.webapp-lead { max-width: 80ch; }
.webapp-layout { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: var(--sp-5); align-items: start; margin-top: var(--sp-4); }
.webapp-qr { width: 184px; }
.webapp-qr .qr-box { width: 184px; margin: 0; }
.webapp-url { margin: 8px 0 0; font-size: var(--fs-label); overflow-wrap: anywhere; color: var(--c-muted); }
.webapp-qr-note { margin: 4px 0 0; font-size: var(--fs-label); color: var(--c-muted); }
.webapp-steps { display: flex; flex-direction: column; gap: var(--sp-2); min-width: 0; }
.webapp-install { order: -2; display: none; align-items: center; flex-wrap: wrap; gap: var(--sp-2) var(--sp-3); margin-bottom: var(--sp-2); }
html[data-app-installable] .webapp-install { display: flex; }
.webapp-step { padding: 10px 12px; border: 1px solid var(--c-border-soft); border-radius: var(--radius-sm); background: var(--c-elev); }
.webapp-step h3 { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 0 0 2px; }
.webapp-step p { margin: 0; font-size: var(--fs-small); color: var(--c-muted); }
.webapp-here { display: none; }
html[data-app-platform="ios"] .webapp-step[data-platform="ios"],
html[data-app-platform="android"] .webapp-step[data-platform="android"],
html[data-app-platform="desktop"] .webapp-step[data-platform="desktop"] { order: -1; border-color: var(--c-accent-line); }
html[data-app-platform="ios"] .webapp-step[data-platform="ios"] .webapp-here,
html[data-app-platform="android"] .webapp-step[data-platform="android"] .webapp-here,
html[data-app-platform="desktop"] .webapp-step[data-platform="desktop"] .webapp-here { display: inline-block; }
.webapp-note { margin: 0; font-size: var(--fs-small); color: var(--c-muted); }
.webapp-sessions {
  display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: var(--sp-3) var(--sp-5);
  margin-top: var(--sp-5); padding-top: var(--sp-4); border-top: 1px solid var(--c-border-soft);
}
.webapp-sessions-text { flex: 1 1 320px; min-width: 0; }
.webapp-sessions h3 { margin: 0 0 2px; }
.webapp-sessions p { margin: 0; max-width: 72ch; font-size: var(--fs-small); }
@media (display-mode: standalone) {
  p.webapp-when-app { display: block; }
  .pill.webapp-when-app { display: inline-block; }
  .webapp-when-browser { display: none; }
}
@media (max-width: 640px) {
  .webapp-layout { grid-template-columns: minmax(0, 1fr); }
  .webapp-qr { width: auto; display: flex; flex-direction: column; align-items: center; text-align: center; }
  .webapp-qr .qr-box { width: 168px; }
  .webapp-install .btn, .webapp-sessions .btn { flex: 1 1 100%; }
}

/* Einstellungen, Branding, Web-App: Kachel „App-Symbol“ wie die Logo-Kacheln, mit Vorschau als iPhone-Symbol (abgerundetes Quadrat),
   Android-Symbol (Kreismaske) und Computer-Symbol (Kachel auf kariertem Grund, der Transparenz zeigt). */
.set-control .app-icon-tile { width: 100%; max-width: 620px; }
.app-icon-previews {
  display: flex; flex-wrap: wrap; justify-content: space-around; gap: var(--sp-4); padding: 14px 12px;
  border: 1px solid var(--c-border-soft); border-radius: var(--radius-sm); background: var(--c-bg);
}
.app-icon-preview { margin: 0; display: flex; flex-direction: column; align-items: center; gap: 6px; font-size: var(--fs-label); color: var(--c-muted); }
.app-icon-stage { display: grid; place-items: center; width: 76px; height: 76px; border-radius: var(--radius); }
.app-icon-stage img { display: block; width: 60px; height: 60px; }
.app-icon-stage.ios img { border-radius: 22.5%; }
.app-icon-stage.android img { border-radius: 50%; }
.app-icon-stage.desktop {
  background: repeating-conic-gradient(var(--c-hover) 0 25%, var(--c-surface) 0 50%) 0 0 / 12px 12px;
  border: 1px solid var(--c-border-soft);
}
/* Ende Web-App 0.80 */

/* ---------- Web-Push 0.80 ---------- */
/* Karte „Push-Benachrichtigungen“ unter „Mein Konto“ mit Zustand des Geräts, „Meine Geräte“ (auf dem Telefon als Karten) und „Meine
   Bereitschaft“, Empfängerauswahl des Kanaltyps Web-Push und die Push-Geräte in der Benutzerverwaltung. */

/* Dieses Gerät: Text links, Schaltfläche rechts; auf dem Telefon untereinander. */
.push-device {
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); flex-wrap: wrap;
  padding: 12px 14px; border: 1px solid var(--c-border-soft); border-radius: var(--radius-sm); background: var(--c-elev);
}
.push-device-text { flex: 1 1 320px; min-width: 0; }
.push-device-title { font-weight: 600; }
.push-device-text p { margin: 4px 0 0; font-size: var(--fs-small); max-width: 72ch; }
.push-device-note { color: var(--c-warn-ink); }
.push-device-actions { display: flex; gap: 8px; flex-wrap: wrap; }
.push-device-actions:empty { display: none; }
.push-section { margin: var(--sp-4) 0 var(--sp-2); font-size: var(--fs-body); font-weight: 600; color: var(--c-text); }
.push-section .count { color: var(--c-muted); font-weight: 500; }
.push-devices-table td.push-dev-state { min-width: 90px; }
.push-devices-table td.push-dev-name { white-space: normal; min-width: 160px; }
.push-dev-error { max-width: 320px; overflow-wrap: anywhere; color: var(--c-warn-ink); }

/* Meine Bereitschaft: Kanäle und feste Bereitschaft als ruhige Liste, Schichten als Tabelle. */
.push-channels, .push-rules { list-style: none; margin: 0 0 var(--sp-2); padding: 0; }
.push-channels li, .push-rules li {
  display: flex; align-items: center; gap: 6px 10px; flex-wrap: wrap; padding: 6px 0;
  border-top: 1px solid var(--c-border-soft); font-size: var(--fs-small);
}
.push-channels li:first-child, .push-rules li:first-child { border-top: 0; }
.push-channel-name { font-weight: 600; }
.push-rules { margin-top: var(--sp-2); }

/* Kanal anlegen: Empfänger mit Zahl der Geräte rechts; ohne Gerät oder Recht in der Warnfarbe. */
.push-recipients { margin: var(--sp-2) 0 0; }
.push-recipient { grid-template-columns: auto minmax(0, 1fr) auto; }
.push-recipient-name { min-width: 0; overflow-wrap: anywhere; }
.push-recipient-name .muted { font-size: var(--fs-label); margin-left: 4px; }
.push-recipient-state { font-size: var(--fs-label); color: var(--c-muted); white-space: nowrap; }
.push-recipient-state.warn { color: var(--c-warn-ink); }
td .cell-sub.push-none { color: var(--c-warn-ink); }

/* Schlüssel der Instanz auf der Seite Benachrichtigungen. */
.push-key-facts { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: 6px var(--sp-3); margin: 0; font-size: var(--fs-small); }
.push-key-facts dt { color: var(--c-muted); }
.push-key-facts dd { margin: 0; overflow-wrap: anywhere; }
.push-key-facts dd a { margin-left: 6px; }
.push-key-missing { color: var(--c-warn-ink); }

/* Hinweis beim Start der App (app.js): im Aussehen der Toasts, über deren Stapel. */
.toast-stack.push-hint { bottom: calc(22px + 64px); }

/* Telefon: Geräte und Schichten als Karten; oben Name bzw. Kanal und Zustand, darunter die übrigen Angaben beschriftet. */
@media (max-width: 640px) {
  .push-devices-table thead, .push-shifts-table thead { display: none; }
  .push-devices-table, .push-devices-table tbody, .push-shifts-table, .push-shifts-table tbody { display: block; }
  .push-devices-table tr, .push-shifts-table tr {
    display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 3px var(--sp-2);
    padding: 10px var(--sp-3); border-bottom: 1px solid var(--c-border-soft);
  }
  .push-devices-table tbody tr:last-child, .push-shifts-table tbody tr:last-child { border-bottom: 0; }
  .push-devices-table td, .push-shifts-table td,
  .card > .table-wrap .push-devices-table td, .card > .table-wrap .push-shifts-table td {
    display: block; padding: 0; border: 0; min-width: 0; max-width: none; white-space: normal; text-align: left;
  }
  .push-devices-table td.push-dev-name, .push-shifts-table td.push-shift-channel { grid-column: 1; grid-row: 1; min-width: 0; }
  .push-devices-table td.push-dev-state { grid-column: 2; grid-row: 1; text-align: right; min-width: 0; }
  .push-devices-table td.push-dev-service, .push-devices-table td.push-dev-created, .push-devices-table td.push-dev-success,
  .push-shifts-table td.push-shift-from, .push-shifts-table td.push-shift-to, .push-shifts-table td.push-shift-note {
    grid-column: 1 / -1; font-size: var(--fs-small);
  }
  .push-devices-table td[data-label]::before, .push-shifts-table td[data-label]::before { content: attr(data-label) " "; color: var(--c-muted); }
  .push-devices-table td.row-actions { grid-column: 1 / -1; text-align: left; margin-top: 4px; }
  .push-devices-table td.row-actions .btn:first-child { margin-left: 0; }
  .push-dev-error { max-width: none; }
  .push-device-actions, .push-device-actions .btn { width: 100%; }

  /* Benachrichtigungen: Kanäle, nicht zugestellte Nachrichten, feste Bereitschaft und Schichten als Karten. Oben Name und Zustand, darunter
     die übrigen Angaben beschriftet, die Schaltflächen zuletzt; der rote Rand eines Kanals mit Fehler steht an der ganzen Karte. */
  .notif-channels-table thead, .notif-outbox-table thead, .notif-duty-table thead, .notif-shifts-table thead { display: none; }
  .notif-channels-table, .notif-channels-table tbody, .notif-outbox-table, .notif-outbox-table tbody,
  .notif-duty-table, .notif-duty-table tbody, .notif-shifts-table, .notif-shifts-table tbody { display: block; }
  .notif-channels-table tr, .notif-outbox-table tr, .notif-duty-table tr, .notif-shifts-table tr {
    display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 3px var(--sp-2);
    padding: 10px var(--sp-3); border-bottom: 1px solid var(--c-border-soft);
  }
  .notif-channels-table td, .notif-outbox-table td, .notif-duty-table td, .notif-shifts-table td,
  .card > .table-wrap .notif-outbox-table td, .card > .table-wrap .notif-duty-table td, .card > .table-wrap .notif-shifts-table td {
    display: block; padding: 0; border: 0; min-width: 0; max-width: none; white-space: normal; text-align: left;
  }
  .notif-channels-table td.notif-ch-name, .notif-outbox-table td.notif-ob-alert, .notif-duty-table td.notif-oc-channel,
  .notif-shifts-table td.notif-oc-channel { grid-column: 1; grid-row: 1; }
  .notif-channels-table td.notif-ch-state, .notif-duty-table td.notif-oc-state, .notif-outbox-table td.notif-ob-since { grid-column: 2; grid-row: 1; text-align: right; }
  .notif-channels-table td.notif-ch-type, .notif-channels-table td.notif-ch-rules, .notif-channels-table td.notif-ch-sent,
  .notif-outbox-table td.notif-ob-customer, .notif-outbox-table td.notif-ob-device, .notif-outbox-table td.notif-ob-check, .notif-outbox-table td.notif-ob-error,
  .notif-duty-table td.notif-oc-times, .notif-duty-table td.notif-oc-note,
  .notif-shifts-table td.notif-oc-from, .notif-shifts-table td.notif-oc-to, .notif-shifts-table td.notif-oc-note {
    grid-column: 1 / -1; font-size: var(--fs-small);
  }
  .notif-channels-table td[data-label]::before, .notif-outbox-table td[data-label]::before, .notif-duty-table td[data-label]::before,
  .notif-shifts-table td[data-label]::before { content: attr(data-label) " "; color: var(--c-muted); }
  .notif-channels-table td.row-actions, .notif-outbox-table td.row-actions, .notif-duty-table td.row-actions, .notif-shifts-table td.row-actions {
    grid-column: 1 / -1; text-align: left; margin-top: 4px; white-space: normal;
  }
  .notif-channels-table td.row-actions .btn, .notif-outbox-table td.row-actions .btn, .notif-duty-table td.row-actions .btn,
  .notif-shifts-table td.row-actions .btn { margin: 0 6px 6px 0; }
  .notif-channels-table tr.edge-crit { box-shadow: inset 3px 0 0 var(--c-crit); }
  .notif-channels-table tr.edge-crit > td:first-child { box-shadow: none; }
  .notif-channels-table tr.notif-ch-error { display: block; padding-top: 0; }
  .notif-channels-table tr.notif-ch-error td { display: block; }
  .push-key-facts { grid-template-columns: minmax(0, 1fr); gap: 2px; }
  .push-key-facts dd { margin-bottom: 6px; }
  .toast-stack.push-hint { bottom: calc(10px + 64px); }
}
/* Ende Web-Push 0.80 */

/* ---------- Telefon 0.80 ---------- */
/* Bereitschaft auf dem Telefon: Alarm-Zahl in der Kopfleiste, Alarme oben im Dashboard, einklappbare Filter der Alarme, Neustart in der
   Detailleiste, Geräteliste und Gerätealarme als Karten, verschlankter Kopf der Geräteseite. */

/* Kopfleiste (bis 900 px): Die Zahl der Alarme, die Aufmerksamkeit brauchen, steht neben dem Menüknopf (Layout/HeaderAlerts.razor),
   mit einer Tippfläche von 40 px. Auf breiten Bildschirmen trägt die Seitenleiste die Zahl, hier ist die Insel verborgen. Marke und
   Produktname weichen bei Platzmangel (Auslassungspunkte), damit Zahl, Menüknopf und Benutzerknopf immer in die Zeile passen. */
.head-alerts { display: none; }
@media (max-width: 900px) {
  .sidebar > .brand { min-width: 0; }
  .sidebar > .brand > .brand-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .sidebar > .brand > .brand-logo-img { min-width: 0; flex-shrink: 1; }
  .head-alerts {
    display: inline-flex; align-items: center; justify-content: center; flex: 0 0 auto;
    min-width: 40px; min-height: 40px; margin-left: auto; border-radius: var(--radius-sm); text-decoration: none;
  }
  .head-alerts + .nav-toggle { margin-left: 4px; }
  .head-alerts .badge.count { margin: 0; padding: 4px 9px; min-width: 30px; font-size: .82rem; line-height: 1.25; }
  .head-alerts:hover .badge.count { box-shadow: inset 0 0 0 1px currentColor; }
  .head-alerts:focus-visible { outline: var(--focus-w) solid var(--c-focus); outline-offset: 2px; }
}

/* Dashboard: Auf dem Telefon rückt die Karte „Offene Alarme“ vor Erreichbarkeit und Handlungsbedarf, „Kürzlich geschlossen“ bleibt
   unten. Auf breiten Bildschirmen ist der Rahmen unsichtbar und die Reihenfolge wie bisher. */
.dash-flow { display: contents; }
@media (max-width: 640px) {
  .dash-flow { display: flex; flex-direction: column; }
  .dash-flow > * { min-width: 0; }
  .dash-flow > .card-grid { order: 1; }
  .dash-flow > .dash-closed { order: 2; }
}

/* Knopf „Filter“ (Alarme, Geräteliste) wie in der Job-Liste: nur auf dem Telefon, mit gesetzten Filtern in der Akzentfarbe samt Zahl.
   Die Suche bleibt stehen, die Auswahlfelder erscheinen erst nach dem Aufklappen. */
.toolbar.alert-filters > .filter-toggle, .toolbar.device-list-filters > .filter-toggle { display: none; }
.toolbar.alert-filters > .filter-toggle.is-set, .toolbar.device-list-filters > .filter-toggle.is-set { border-color: var(--c-accent-line); color: var(--c-accent-ink); }
@media (max-width: 640px) {
  .toolbar.alert-filters > .search { flex: 1 1 55%; min-width: 0; max-width: none; }
  .toolbar.alert-filters > .filter-toggle { display: inline-flex; flex: 0 0 auto; }
  .toolbar.alert-filters:not(.filters-open) > select,
  .toolbar.alert-filters:not(.filters-open) > .filter-chip,
  .toolbar.alert-filters:not(.filters-open) > .filter-reset { display: none; }

  .toolbar.device-list-filters > .filter-search { flex: 1 1 55%; min-width: 0; max-width: none; }
  .toolbar.device-list-filters > .filter-toggle { display: inline-flex; flex: 0 0 auto; }
  .toolbar.device-list-filters:not(.filters-open) > .filter:not(.filter-search),
  .toolbar.device-list-filters:not(.filters-open) > .filter-reset { display: none; }
}

/* Detailleiste: „Neustart“ steht als letzte Schaltfläche im Abschnitt „Gerät“ (gefährlich, deshalb am Ende). Auf dem Touchscreen
   werden die kleinen Schaltflächen der Leiste und des Blätterns 40 px hoch. Der Energie-Dialog nennt oben, was geschieht. */
.power-warn { margin: 0 0 var(--sp-3); }
@media (pointer: coarse) {
  .ap-body .btn.small, .pager .btn.small { min-height: 40px; }
}

/* Geräteliste als Karten (bis 640 px): links das Auswahlfeld mit 40 px Tippfläche, daneben Name und Status, Kunde und Klasse, der
   letzte Kontakt und die Hinweise. Die rechte Spalte trägt nur kurze Werte (Status, Klasse), damit der Name nie umbrechen muss. Betriebssystem, IP-Adresse, Agent und Laufzeit stehen auf der Geräteseite. Über den Karten bleibt
   aus dem Tabellenkopf nur „Alle auf dieser Seite“, damit die Sammelauswahl bedienbar bleibt. */
.device-table .select-page-label { display: none; }
@media (max-width: 640px) {
  .device-table, .device-table thead, .device-table tbody { display: block; }
  .device-table thead tr { display: flex; align-items: center; padding: 2px var(--sp-2); border-bottom: 1px solid var(--c-border-soft); background: var(--c-elev); }
  .device-table thead th { display: none; }
  .device-table thead th.select-col { display: block; width: auto; padding: 0; border: 0; background: none; position: static; text-align: left; }
  .device-table .select-hit { display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2); min-width: 40px; min-height: 40px; cursor: pointer; }
  .device-table thead .select-hit { justify-content: flex-start; padding-left: 12px; }
  .device-table .select-page-label { display: inline; font-size: var(--fs-small); font-weight: 600; color: var(--c-muted); }
  .device-table tbody tr {
    display: grid;
    grid-template-columns: 40px minmax(0, 1fr) auto;
    grid-template-areas: "sel name status" "sel cust class" "sel seen seen" "sel hints hints";
    align-items: center;
    gap: 3px var(--sp-2);
    padding: 8px var(--sp-3) 10px var(--sp-1);
    border-bottom: 1px solid var(--c-border-soft);
  }
  .device-table tbody tr:last-child { border-bottom: 0; }
  .device-table tbody tr.selected { background: var(--c-selected); }
  .table-wrap .device-table td { display: block; padding: 0; border: 0; min-width: 0; white-space: normal; background: none; }
  .device-table td.select-col { grid-area: sel; align-self: start; width: auto; }
  .device-table td.dl-name { grid-area: name; overflow-wrap: anywhere; }
  .device-table td.dl-name .cell-main > .pill { margin-left: 6px; }
  /* Der Name ist der einzige Weg auf die Geräteseite: Tippfläche 40 px hoch, ohne die Karte höher zu machen. */
  .device-table td.dl-name .cell-main > a.plain { display: inline-block; padding: 10px 0; margin: -10px 0; }
  .device-table td.dl-status { grid-area: status; align-self: start; text-align: right; }
  .device-table td.dl-customer { grid-area: cust; font-size: var(--fs-small); color: var(--c-muted); }
  .device-table td.dl-class { grid-area: class; font-size: var(--fs-small); color: var(--c-muted); text-align: right; }
  .device-table td.dl-seen { grid-area: seen; font-size: var(--fs-small); }
  .device-table td.dl-seen::before { content: attr(data-label) " "; }
  .device-table td.dl-hints { grid-area: hints; margin-top: 2px; }
  .device-table td.dl-hints .hints { max-width: none; }
  .device-table td.dl-hints.is-empty, .device-table td.dl-os, .device-table td.dl-ip, .device-table td.dl-agent, .device-table td.dl-uptime { display: none; }
}

/* Gerätealarme als Karten (bis 640 px): Nummer, Schwere und Status oben, darunter Check und Meldung, dann die Zeiten mit Beschriftung.
   Die Statuskante wandert an die ganze Karte. Offene Alarme haben keine Zeile „Geschlossen“. */
@media (max-width: 640px) {
  .device-alerts thead { display: none; }
  .device-alerts, .device-alerts tbody { display: block; }
  .device-alerts tr {
    display: grid;
    grid-template-columns: auto auto minmax(0, 1fr);
    grid-template-areas: "id sev status" "check check check" "msg msg msg" "opened opened opened" "closed closed closed";
    align-items: center;
    gap: 3px var(--sp-2);
    padding: 10px var(--sp-3);
    border-bottom: 1px solid var(--c-border-soft);
  }
  .device-alerts tbody tr:last-child { border-bottom: 0; }
  .table-wrap .device-alerts td { display: block; padding: 0; border: 0; min-width: 0; white-space: normal; box-shadow: none; }
  .device-alerts tr.edge-crit { box-shadow: inset 3px 0 0 var(--c-crit); }
  .device-alerts tr.edge-warn { box-shadow: inset 3px 0 0 var(--c-warn); }
  .device-alerts tr.edge-crit > td:first-child, .device-alerts tr.edge-warn > td:first-child { box-shadow: none; }
  .device-alerts tr.selected { background: var(--c-selected); }
  .device-alerts td.da-id { grid-area: id; }
  .device-alerts td.da-sev { grid-area: sev; }
  .device-alerts td.da-status { grid-area: status; }
  .device-alerts td.da-check { grid-area: check; font-weight: 600; }
  .device-alerts td.da-msg { grid-area: msg; font-size: var(--fs-small); overflow-wrap: anywhere; }
  .device-alerts td.da-opened { grid-area: opened; font-size: var(--fs-small); }
  .device-alerts td.da-closed { grid-area: closed; font-size: var(--fs-small); }
  .device-alerts td.da-opened::before, .device-alerts td.da-closed::before { content: attr(data-label) " "; }
  .device-alerts tr.da-open td.da-closed { display: none; }
}

/* Kopf der Geräteseite: Die Rahmen um die Kopf-Schaltflächen sind unsichtbar (display: contents), der Kopf auf breiten Bildschirmen
   bleibt wie bisher. Auf dem Telefon bleiben „Fernwartung“ und „Aktionen“ nebeneinander; Inventar, Dateien, Registry und Web-Zugriff
   stehen dann im Aktionen-Dialog unter „Zugriff“ (.actions-phone, sonst verborgen). Ohne Aktionen-Dialog (.head-keep) bleibt alles im
   Kopf. Pfad und Untertitel rücken enger zusammen. */
.page-actions > .head-more, .page-actions > .head-keep { display: contents; }
.actions-phone { display: none; }
@media (max-width: 900px) {
  /* Im Spaltenlayout des Seitenkopfs maß Chrome die Höhe der Aktionen ohne feste Breite: zwei Schaltflächen zu je halber Breite ergaben
     zwei Zeilen Höhe bei einer Zeile Inhalt. Mit voller Breite stimmt die Höhe (gilt für jeden Seitenkopf, etwa auch die Geräteliste
     mit Auswahl). */
  .page-head > .page-actions { width: 100%; }
}
@media (max-width: 640px) {
  .page-actions > .head-more { display: none; }
  .actions-phone { display: block; }
  .page-head:has(.head-more) { gap: var(--sp-2); margin-bottom: var(--sp-3); }
  .page-head:has(.head-more) h1 { line-height: 1.35; }
}
/* Ende Telefon 0.80 */

/* ---------- Konten 0.80 ---------- */
/* Kontoeinrichtung: Seite /account/setup mit Schrittkopf, Kennwortregeln unter den Feldern, Block der Wiederherstellungscodes mit
   Kopieren, Herunterladen und Drucken (auch als Druckansicht), einmalige Anzeige des Startkennworts, Karte „Kennwort“ unter „Mein Konto“
   und die Marken „Einrichtung offen“ und „Startkennwort abgelaufen“ in der Benutzerverwaltung. */

/* Einrichtung: dieselbe Karte wie die Anmeldung, breiter für QR-Code und Codes. */
.login-card.setup-card { max-width: 560px; }
.setup-title { font-size: 1.3rem; margin: 14px 0 4px; }
/* Nach dem Laden setzt Blazor den Fokus auf die Überschrift (Bildschirmleser); ein Rahmen darum hilft dort niemandem. */
.setup-title:focus, .setup-title:focus-visible { outline: none; }
.setup-error { margin: var(--sp-3) 0 0; }
.setup-lead { color: var(--c-muted); margin: 0 0 var(--sp-4); font-size: .92rem; line-height: 1.5; }
.setup-lead strong { color: var(--c-text); font-weight: 600; overflow-wrap: anywhere; }

/* Fortschritt: nummerierte Schritte; erledigte mit Haken, der aktuelle hervorgehoben. */
.setup-progress { list-style: none; margin: 0 0 var(--sp-4); padding: 0; display: grid; gap: var(--sp-2); }
.setup-progress li {
  display: flex; align-items: center; gap: var(--sp-3);
  padding: 8px 10px; border-radius: var(--radius-sm); border: 1px solid var(--c-border-soft); background: var(--c-elev);
}
.setup-progress-mark {
  flex: 0 0 auto; width: 26px; height: 26px; border-radius: 50%;
  display: inline-grid; place-items: center; font-size: .82rem; font-weight: 700;
  border: 2px solid var(--c-border-strong); color: var(--c-muted);
}
.setup-progress-text { display: flex; flex-direction: column; min-width: 0; }
.setup-progress-label { font-weight: 600; font-size: .92rem; }
.setup-progress-hint { font-size: var(--fs-label); color: var(--c-muted); }
.setup-progress li.current { border-color: var(--c-accent-border); background: var(--c-accent-wash); }
.setup-progress li.current .setup-progress-mark { border-color: var(--c-accent-line); background: var(--c-accent-fill); color: var(--c-accent-contrast); }
.setup-progress li.done .setup-progress-mark { border-color: var(--c-ok); background: var(--c-ok-bg); color: var(--c-ok-ink); }
.setup-progress li.done .setup-progress-label { color: var(--c-muted); font-weight: 500; }

.setup-step { border-top: 1px solid var(--c-border-soft); padding-top: var(--sp-4); }
.setup-step h2 { font-size: 1.08rem; margin: 0 0 var(--sp-2); }
.setup-step > p { font-size: .92rem; line-height: 1.55; margin: 0 0 var(--sp-3); }
.setup-count { margin: 0 0 2px; font-size: var(--fs-label); font-weight: 600; color: var(--c-accent-ink); }
.setup-form { margin-top: var(--sp-3); }
.setup-form .btn.block { margin-top: var(--sp-2); }
.setup-check { display: flex; align-items: flex-start; gap: 8px; margin: 2px 0 var(--sp-3); font-size: .9rem; cursor: pointer; }
.setup-check input { width: 18px; height: 18px; margin: 1px 0 0; flex: 0 0 auto; }
.setup-check.setup-confirm { padding: 10px 12px; border-radius: var(--radius-sm); border: 1px solid var(--c-warn); background: color-mix(in srgb, var(--c-warn-bg) 50%, var(--c-elev)); font-weight: 600; }
.setup-rule { margin: 0 0 var(--sp-3); font-size: var(--fs-small); color: var(--c-muted); line-height: 1.5; }
.setup-code { font-size: 1.25rem; letter-spacing: .18em; max-width: 220px; }
.setup-foot {
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-2) var(--sp-3); flex-wrap: wrap;
  margin-top: var(--sp-4); padding-top: var(--sp-3); border-top: 1px solid var(--c-border-soft); font-size: var(--fs-small);
}
.setup-foot form { margin: 0; }

/* Einrichtung der Authenticator-App: Schritte, QR-Code links, Alternativen rechts (Telefon: untereinander). */
.enroll-steps { margin: 0 0 var(--sp-2); padding-left: 22px; display: grid; gap: var(--sp-3); font-size: .92rem; }
.enroll-steps li > strong { display: block; }
.enroll-steps li > .muted { display: block; font-size: var(--fs-small); line-height: 1.5; }
.enroll-steps li::marker { color: var(--c-muted); font-weight: 600; }
.enroll-qr { display: flex; gap: var(--sp-4); align-items: flex-start; margin-top: var(--sp-2); }
.enroll-qr .qr-box { flex: 0 0 auto; width: 176px; margin: 0; }
.enroll-alt { display: flex; flex-direction: column; gap: 6px; min-width: 0; font-size: var(--fs-small); }
.enroll-alt .btn { align-self: flex-start; }
.enroll-key { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; }
.enroll-key code { font-size: .95rem; letter-spacing: .06em; overflow-wrap: anywhere; padding: 4px 8px; border-radius: var(--radius-sm); background: var(--c-elev); border: 1px solid var(--c-border-soft); }
.enroll-code { margin-top: var(--sp-3); }
.enroll-code input { max-width: 220px; font-size: 1.1rem; letter-spacing: .14em; }

/* Wiederherstellungscodes: Liste im bestehenden Raster, darunter die drei Knöpfe; der Kopf erscheint nur im Druck. */
ol.recovery-codes { list-style: none; margin: 0; }
ol.recovery-codes li { padding: 2px 0; }
.recovery-sheet-head { display: none; }
.recovery-actions { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin: var(--sp-2) 0 var(--sp-3); }
.print-only-sheet { display: none; }

/* Druckansicht: nur das Blatt mit den Codes (app.js hängt eine Kopie direkt an body und setzt html.print-sheet). */
@media print {
  html.print-sheet body > *:not(.print-only-sheet) { display: none !important; }
  html.print-sheet, html.print-sheet body { background: #fff !important; }
  html.print-sheet .print-only-sheet { display: block; color: #000; background: #fff; padding: 12mm; font-size: 11pt; }
  html.print-sheet .print-only-sheet .recovery-sheet-head { display: flex; flex-direction: column; gap: 3pt; margin-bottom: 8mm; }
  html.print-sheet .print-only-sheet .recovery-sheet-head strong { font-size: 14pt; }
  html.print-sheet .print-only-sheet .recovery-codes {
    display: grid; grid-template-columns: repeat(2, max-content); gap: 4mm 16mm; padding: 6mm; margin: 0;
    background: #fff; color: #000; border: 1px solid #000; font-size: 13pt;
  }
}

/* „Mein Konto“, Karte „Kennwort“: drei Felder nebeneinander, auf schmalen Schirmen untereinander. */
.password-form .form-grid { margin-bottom: var(--sp-2); }
.password-form .form-actions { justify-content: space-between; }
.password-form .setup-check { margin: 0; }

/* Benutzerverwaltung: Anlege-Dialog in Gruppen, Startkennwort einmalig mit Kopieren, Marke unter dem Status. */
.user-create-group { border: 1px solid var(--c-border-soft); border-radius: var(--radius-sm); padding: 10px 12px 4px; margin: var(--sp-3) 0 0; }
.user-create-group legend { padding: 0 6px; font-size: var(--fs-label); font-weight: 600; color: var(--c-muted); }
.user-create-group .hint { margin: 6px 0 8px; }
.user-create-choice { display: flex; flex-wrap: wrap; gap: var(--sp-2) var(--sp-5); margin-bottom: var(--sp-2); }
.user-create-group .form-grid { margin: var(--sp-2) 0 0; }
.start-password {
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); flex-wrap: wrap;
  padding: 12px 14px; margin: var(--sp-3) 0; border-radius: var(--radius-sm); border: 1px solid var(--c-accent-border); background: var(--c-accent-wash);
}
.start-password code { font-size: 1.2rem; letter-spacing: .06em; overflow-wrap: anywhere; }
.start-password-facts { margin: 0; padding-left: 18px; font-size: var(--fs-small); display: grid; gap: 4px; }
.start-password-facts .mono { overflow-wrap: anywhere; }
td > .pill.setup-pill { margin-left: 4px; }

@media (max-width: 640px) {
  .login-card.setup-card { padding: 22px 16px 18px; }
  /* Telefon: Fortschritt kompakt, Codes zweispaltig. */
  .setup-progress { gap: 6px; }
  .setup-progress li { padding: 6px 10px; }
  .setup-progress-hint { display: none; }
  ol.recovery-codes { grid-template-columns: repeat(2, minmax(0, 1fr)); padding: 12px; font-size: .9rem; }
  .enroll-qr { flex-direction: column; }
  .enroll-qr .qr-box { width: 200px; }
  .setup-foot { flex-direction: column; align-items: flex-start; }
  .password-form .form-actions { flex-direction: column; align-items: stretch; }
  td > .pill.setup-pill { margin: 4px 0 0; }
}
/* Benutzerliste als Karten (bis 640 px): E-Mail und „Verwalten“ oben, darunter Name, Status mit Einrichtung und Zwei-Faktor, Rolle und
   Kunden-Zugriff, zuletzt die letzte Anmeldung mit Beschriftung. */
@media (max-width: 640px) {
  .users-table thead { display: none; }
  .users-table, .users-table tbody { display: block; }
  .users-table tr {
    display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    grid-template-areas: "email actions" "name name" "status twofa" "role scope" "login login";
    align-items: center; gap: 6px var(--sp-2); padding: 10px var(--sp-3); border-bottom: 1px solid var(--c-border-soft);
  }
  .users-table tbody tr:last-child { border-bottom: 0; }
  .table-wrap .users-table td { display: block; padding: 0; border: 0; min-width: 0; white-space: normal; }
  .users-table td.ut-email { grid-area: email; overflow-wrap: anywhere; }
  .users-table td.ut-actions { grid-area: actions; justify-self: end; }
  .users-table td.ut-name { grid-area: name; color: var(--c-muted); font-size: var(--fs-small); }
  .users-table td.ut-status { grid-area: status; }
  .users-table td.ut-2fa { grid-area: twofa; justify-self: end; }
  .users-table td.ut-role { grid-area: role; }
  .users-table td.ut-role select { width: 100%; }
  .users-table td.ut-scope { grid-area: scope; justify-self: end; }
  .users-table td.ut-login { grid-area: login; font-size: var(--fs-small); }
  .users-table td.ut-2fa::before, .users-table td.ut-login::before { content: attr(data-label) " "; color: var(--c-muted); font-size: var(--fs-small); }
}
/* Ende Konten 0.80 */

/* ---------- Microsoft-Anmeldung 0.80 ---------- */
/* Statuskarte und Assistent unter Einstellungen, Sicherheit (Schritte, Umleitungs-URI zum Kopieren, Wahl der Anmeldedaten als zwei
   Karten, Fingerabdruck), Banner zum Ablauf, Karte „Microsoft-Konto“ unter „Mein Konto“, Marke „Microsoft“ und Kacheln in der
   Benutzerverwaltung. */

/* Anmeldeseite: Knopf mit dem Zeichen von Microsoft, Hinweise zur Verknüpfung, Bestätigungsseite. */
.btn.ms-login { display: inline-flex; align-items: center; justify-content: center; gap: 10px; font-weight: 600; }
.ms-logo { width: 16px; height: 16px; flex: none; }
.ms-login-notice, .ms-login-link { font-size: var(--fs-small); }
.ms-login-link strong { overflow-wrap: anywhere; }
.login-card.ms-link-card { max-width: 440px; }
.ms-link-facts { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: 6px 14px; margin: 0 0 14px; font-size: var(--fs-small); }
.ms-link-facts dt { color: var(--c-muted); }
.ms-link-facts dd { margin: 0; font-weight: 600; overflow-wrap: anywhere; }
.ms-link-text { font-size: var(--fs-small); color: var(--c-muted); margin: 0 0 14px; }
.ms-link-actions { display: flex; justify-content: flex-end; gap: var(--sp-2); flex-wrap: wrap; margin-top: 4px; }

/* Statuskarte und Assistent unter Einstellungen, Sicherheit, Microsoft-Anmeldung. */
.ms-wizard { display: grid; gap: var(--sp-3); margin-bottom: var(--sp-3); }
.ms-wizard .card { margin-bottom: 0; }
.ms-wizard h3 { margin: 0; font-size: var(--fs-section); }
.ms-wizard h4 { margin: 0 0 var(--sp-2); font-size: var(--fs-section); }
.ms-wizard h5 { margin: 0 0 var(--sp-2); font-size: var(--fs-body); }
.ms-status-grid { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: 6px 18px; margin: 0 0 var(--sp-3); font-size: var(--fs-small); }
.ms-status-grid dt { color: var(--c-muted); }
.ms-status-grid dd { margin: 0; min-width: 0; display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; }
.ms-status-grid dd.mono { display: block; }
.ms-break { overflow-wrap: anywhere; word-break: break-all; }
.ms-status .notice { margin-bottom: var(--sp-2); }
.ms-last-error { margin: 0 0 var(--sp-2); overflow-wrap: anywhere; }
.ms-status-actions { margin-top: var(--sp-2); }
.ms-test.ok { border-left: 3px solid var(--c-ok); }
.ms-test.failed { border-left: 3px solid var(--c-crit); }
.ms-test p { margin: 0 0 var(--sp-2); }

.ms-steps { list-style: none; margin: 0 0 var(--sp-4); padding: 0; display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: var(--sp-2); }
.ms-steps button {
  width: 100%; height: 100%; display: flex; align-items: center; gap: var(--sp-2); text-align: left;
  background: var(--c-elev); border: 1px solid var(--c-border-soft); border-radius: var(--radius-sm); padding: 8px 10px;
  color: var(--c-muted); font: inherit; font-size: var(--fs-small); cursor: pointer;
}
.ms-steps button:hover { border-color: var(--c-border); color: var(--c-text); }
.ms-step-no {
  flex: none; width: 22px; height: 22px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--c-border); font-weight: 600; font-size: var(--fs-label);
}
.ms-step-label { min-width: 0; line-height: 1.25; }
.ms-steps li.done .ms-step-no { background: var(--c-ok-bg); color: var(--c-ok-ink); border-color: transparent; }
.ms-steps li.current button { border-color: var(--c-accent-line); color: var(--c-text); background: var(--c-accent-wash); }
.ms-steps li.current .ms-step-no { background: var(--c-accent-tint-strong); color: var(--c-accent-ink); border-color: var(--c-accent-line); }
.ms-step-body { min-height: 120px; }
.ms-step-body > p { margin: 0 0 var(--sp-3); max-width: 80ch; }
.ms-step-body .form-actions { margin-top: var(--sp-3); }
.ms-step-nav { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-2); margin-top: var(--sp-4); padding-top: var(--sp-3); border-top: 1px solid var(--c-border-soft); }
.ms-step-count { font-size: var(--fs-small); }
/* Prüffehler am Feld (Schritt 2) und Karte „Letzte Prüfung“ (Schritt 4) an fester Stelle. */
.field.ms-invalid input { border-color: var(--c-crit); }
.field > .ms-field-error { font-size: var(--fs-small); font-weight: 600; line-height: 1.4; color: var(--c-crit-ink); overflow-wrap: anywhere; }
.ms-result {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px var(--sp-2); margin: 0 0 var(--sp-3); padding: 10px 12px; font-size: var(--fs-small);
  background: var(--c-elev); border: 1px solid var(--c-border-soft); border-left-width: 3px; border-radius: var(--radius-sm);
}
.ms-result.ok { border-left-color: var(--c-ok); }
.ms-result.failed { border-left-color: var(--c-crit); }
.ms-result-label { color: var(--c-muted); }
.ms-result-text { flex: 1 1 100%; overflow-wrap: anywhere; }
.ms-guide { font-size: var(--fs-small); gap: 8px; margin: var(--sp-3) 0; max-width: 90ch; }
.ms-copy { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; padding: 10px 12px; background: var(--c-elev); border: 1px solid var(--c-border-soft); border-radius: var(--radius-sm); }
.ms-copy-label { color: var(--c-muted); font-size: var(--fs-small); }
.ms-copy code { flex: 1 1 260px; min-width: 0; }
.ms-choices { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-3); margin-bottom: var(--sp-3); }
.ms-choice {
  display: flex; flex-direction: column; align-items: flex-start; gap: 6px; text-align: left; font: inherit; color: var(--c-text); cursor: pointer;
  background: var(--c-surface); border: 1px solid var(--c-border); border-radius: var(--radius); padding: 12px 14px;
}
.ms-choice:hover { border-color: var(--c-border-strong); }
.ms-choice.selected { border-color: var(--c-accent-line); box-shadow: 0 0 0 1px var(--c-accent-line) inset; background: var(--c-accent-wash); }
.ms-choice-title { font-weight: 600; display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; }
.ms-choice-text { color: var(--c-muted); font-size: var(--fs-small); }
.ms-panel { border-top: 1px solid var(--c-border-soft); padding-top: var(--sp-3); }
.ms-cert { margin-bottom: var(--sp-2); }
.ms-cert .ms-status-grid { margin-bottom: var(--sp-2); }
.ms-downloads { display: flex; gap: var(--sp-2); flex-wrap: wrap; }
.ms-next { margin-top: var(--sp-4); padding-top: var(--sp-3); border-top: 1px dashed var(--c-border-soft); }
.ms-create { display: grid; gap: var(--sp-2); }
.ms-create-row { display: flex; align-items: flex-end; gap: var(--sp-2); flex-wrap: wrap; }
.ms-create-row .field { flex: 0 1 220px; }
.ms-create .hint { margin-top: 0; }
.ms-checklist { list-style: none; margin: 0 0 var(--sp-3); padding: 0; display: grid; gap: 8px; font-size: var(--fs-small); }
.ms-checklist li { display: flex; align-items: center; gap: var(--sp-2); }
.ms-checklist .pill { min-width: 78px; justify-content: center; text-align: center; }

/* Mein Konto: Karte „Microsoft-Konto“. */
.ms-account .ms-upn { overflow-wrap: anywhere; }
.ms-facts { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: 6px 18px; margin: var(--sp-3) 0 0; font-size: var(--fs-small); }
.ms-facts dt { color: var(--c-muted); }
.ms-facts dd { margin: 0; }
.ms-account .notice { margin-top: var(--sp-3); }
.ms-account-danger {
  display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: var(--sp-3) var(--sp-5);
  margin-top: var(--sp-4); padding-top: var(--sp-3); border-top: 1px solid var(--c-border-soft);
}
.ms-account-danger > div { flex: 1 1 320px; min-width: 0; }
.ms-account-danger p { margin: 2px 0 0; font-size: var(--fs-small); max-width: 72ch; }

/* Benutzerverwaltung: Marke und Auswahl der Anmeldung mit Kennwort; Rollen: Hinweis auf Anzeigenamen. */
.pill.ms-badge { margin-left: 4px; }
.ms-signin-select { width: auto; max-width: 100%; }
.ms-group-names { overflow-wrap: anywhere; }

/* Banner für Administratoren. */
.notice.ms-banner a { white-space: nowrap; }

@media (max-width: 900px) {
  .ms-step-label { display: none; }
  .ms-steps li.current .ms-step-label { display: inline; }
}
@media (max-width: 640px) {
  .ms-steps { gap: 6px; }
  .ms-steps button { justify-content: center; padding: 8px 4px; }
  .ms-steps li.current .ms-step-label { display: none; }
  .ms-choices { grid-template-columns: minmax(0, 1fr); }
  .ms-status-grid, .ms-facts, .ms-link-facts { grid-template-columns: minmax(0, 1fr); gap: 2px; }
  .ms-status-grid dd, .ms-facts dd, .ms-link-facts dd { margin-bottom: 8px; }
  .ms-create-row .field { flex: 1 1 100%; }
  .ms-step-nav .ms-step-count { display: none; }
}
/* Ende Microsoft-Anmeldung 0.80 */

/* ---------- Agent-Ringe 0.81 ---------- */
/* Zusatzbereich „Verteilung“ unter Einstellungen, Agent-Updates: Stufenfolge, Zähler je Stufe, Liste der Fehlschläge und Verlauf (auf dem
   Telefon als Karten), Zeilen „Ring“ und „Verteilung“ der Agent-Karte am Gerät, Pillen der Geräteliste und Zeilen im Dashboard. */
.rollout-panel {
  background: var(--c-surface); border: 1px solid var(--c-border-soft); border-radius: var(--radius); padding: var(--sp-4);
  display: flex; flex-direction: column; gap: var(--sp-3); min-width: 0;
}
.rollout-panel > .card.empty { margin: 0; }
.rollout-head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--sp-2) var(--sp-3); flex-wrap: wrap; }
.rollout-title { min-width: 0; }
.rollout-title .cell-main { font-weight: 600; display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; }
.rollout-title .mono { overflow-wrap: anywhere; }
.rollout-actions { display: flex; gap: var(--sp-2); flex-wrap: wrap; }
.rollout-panel .notice.rollout-halt { margin: 0; }
.rollout-panel p.rollout-failures { margin: 0; font-size: var(--fs-small); }
.rollout-stages {
  list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--sp-2);
}
.rollout-stage {
  border: 1px solid var(--c-border-soft); border-radius: var(--radius-sm); padding: var(--sp-3); background: var(--c-bg);
  display: flex; flex-direction: column; gap: 6px; min-width: 0;
}
.rollout-stage.is-current { border-color: var(--c-accent-line); box-shadow: inset 3px 0 0 var(--c-accent-line); }
.rollout-stage .rs-head { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-2); }
.rollout-stage .rs-name { font-weight: 600; }
.rollout-stage .rs-time { color: var(--c-muted); font-size: var(--fs-small); }
.rollout-stage .rs-note { font-size: var(--fs-small); }
.rollout-stage .rs-counts { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 2px var(--sp-3); margin: 4px 0 0; }
.rollout-stage .rs-counts > div { display: flex; justify-content: space-between; gap: var(--sp-2); font-size: var(--fs-small); }
.rollout-stage .rs-counts dt { color: var(--c-muted); }
.rollout-stage .rs-counts dd { margin: 0; font-variant-numeric: tabular-nums; font-weight: 600; }
.rollout-stage .rs-counts dd.ok { color: var(--c-ok-ink); }
.rollout-stage .rs-counts dd.warn { color: var(--c-warn-ink); }
.rollout-stage .rs-counts dd.crit { color: var(--c-crit-ink); }
.rollout-panel h4.rollout-sub { margin: var(--sp-2) 0 0; font-size: var(--fs-body); font-weight: 600; color: var(--c-text); }
.rollout-panel .muted.compact { margin: 0; }
.rollout-panel .table-wrap { margin: 0; }
table.rollout-problems td.rp-message { white-space: normal; min-width: 180px; overflow-wrap: anywhere; }
table.rollout-problems td.rp-device { min-width: 160px; }
table.rollout-problems td.rp-device .cell-sub { white-space: normal; }
table.rollout-problems td.rp-device a { font-weight: 600; }
table.rollout-problems td.rp-time { white-space: nowrap; }
table.rollout-problems tr.edge-crit td:first-child { box-shadow: inset 3px 0 0 var(--c-crit); }
table.rollout-problems tr.edge-warn td:first-child { box-shadow: inset 3px 0 0 var(--c-warn); }
table.rollout-history td.rh-version { overflow-wrap: anywhere; }
.rollout-panel .danger-zone.rollout-danger { margin: var(--sp-2) 0 0; }
/* Agent-Karte am Gerät: Grund der Verteilung unter der Pille. Geräteliste: Pille in der Schrift der Oberfläche, nicht in der Versionsschrift. */
dd.agent-rollout-state .cell-sub { white-space: normal; }
.device-table td.dl-agent .pill { font-family: var(--font); margin-left: 4px; }
@media (max-width: 900px) {
  .rollout-stages { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 640px) {
  /* Telefon: Kopf untereinander, Schaltflächen in voller Breite, Tabellen als Karten mit beschrifteten Werten. */
  .rollout-panel { padding: var(--sp-3); }
  .rollout-actions { width: 100%; }
  .rollout-actions .btn { flex: 1 1 auto; }
  .rollout-problems thead, .rollout-history thead { display: none; }
  .rollout-problems, .rollout-problems tbody, .rollout-history, .rollout-history tbody { display: block; }
  .rollout-problems tr, .rollout-history tr {
    display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: start; gap: 4px var(--sp-2);
    padding: 10px var(--sp-3); border-bottom: 1px solid var(--c-border-soft);
  }
  .rollout-problems tbody tr:last-child, .rollout-history tbody tr:last-child { border-bottom: 0; }
  .table-wrap table.rollout-problems td, .table-wrap table.rollout-history td {
    display: block; padding: 0; border: 0; min-width: 0; max-width: none; white-space: normal; text-align: left; box-shadow: none;
  }
  .rollout-problems td[data-label]::before, .rollout-history td[data-label]::before { content: attr(data-label) " "; color: var(--c-muted); }
  .rollout-problems td.rp-device, .rollout-history td.rh-version { grid-column: 1; grid-row: 1; }
  .rollout-problems td.rp-outcome, .rollout-history td.rh-state { grid-column: 2; grid-row: 1; text-align: right; }
  .rollout-problems td.rp-message, .rollout-problems td.rp-time,
  .rollout-history td.rh-start, .rollout-history td.rh-stage, .rollout-history td.rh-results { grid-column: 1 / -1; font-size: var(--fs-small); }
  .table-wrap table.rollout-problems td.rp-actions { grid-column: 1 / -1; display: flex; gap: 6px; margin-top: 4px; }
  .table-wrap table.rollout-problems td.rp-actions:empty { display: none; }
  .table-wrap table.rollout-problems td.rp-actions .btn { flex: 1 1 auto; margin: 0; }
  .rollout-problems tr.edge-crit { box-shadow: inset 3px 0 0 var(--c-crit); }
  .rollout-problems tr.edge-warn { box-shadow: inset 3px 0 0 var(--c-warn); }
}
/* Ende Agent-Ringe 0.81 */

/* ---------- Selbstüberwachung 0.81 ---------- */
/* Zusatzbereich „Zustand des Servers“ mit Prüfungen und Lebenszeichen (auf dem Telefon als Karten), Banner der laufenden Warnungen für
   Administratoren und das Kontrollkästchen „Betriebsmeldungen des Servers“ im Kanal-Dialog. */
.health-panel .card-head-row h2 { display: flex; align-items: center; gap: var(--sp-2); }
.health-panel .card-head-row h2 .pill { font-size: var(--fs-label); }
.health-checks .card-lead span + span { margin-left: 2px; }
.health-table td.health-name { white-space: nowrap; }
.health-table td.health-state { white-space: nowrap; }
.health-table td.health-since { white-space: nowrap; }
.health-table td.health-detail { min-width: 260px; }
.health-pending { display: inline-block; margin-left: 6px; font-size: var(--fs-label); }
.health-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-3); align-items: start; }
.health-grid > .card { margin-bottom: 0; }
.health-facts { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: 6px var(--sp-3); margin: 0; font-size: var(--fs-small); }
.health-facts dt { color: var(--c-muted); }
.health-facts dd { margin: 0; min-width: 0; overflow-wrap: anywhere; }
.health-facts dd .pill { margin-right: 4px; }
.health-ping-answer { margin-top: 3px; font-size: var(--fs-label); overflow-wrap: anywhere; }
.notice.health-unreadable { margin-bottom: var(--sp-3); }
.health-notices p { margin: 0 0 var(--sp-2); }
.health-notices p:last-child { margin-bottom: 0; }
.health-last-notice { font-size: var(--fs-small); overflow-wrap: anywhere; }
.notice.health-banner > span { min-width: 0; overflow-wrap: anywhere; }
.field.channel-system-notices { grid-column: 1 / -1; }
.channel-system-notices .switch { align-items: flex-start; }
.channel-system-notices .switch input { flex: none; margin-top: 1px; }
@media (max-width: 900px) {
  .health-grid { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 640px) {
  /* Prüfungen als Karten: oben Name und Zustand, darunter seit wann und die Einzelheiten. */
  .health-table thead { display: none; }
  .health-table, .health-table tbody { display: block; }
  .health-table tr {
    display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 3px var(--sp-2);
    padding: 10px var(--sp-3); border-bottom: 1px solid var(--c-border-soft);
  }
  .health-table td, .card > .table-wrap .health-table td {
    display: block; padding: 0; border: 0; min-width: 0; max-width: none; white-space: normal; text-align: left;
  }
  .health-table td.health-name { grid-column: 1; grid-row: 1; }
  .health-table td.health-state { grid-column: 2; grid-row: 1; text-align: right; }
  .health-table td.health-since, .health-table td.health-detail { grid-column: 1 / -1; font-size: var(--fs-small); }
  .health-table td[data-label]::before { content: attr(data-label) " "; color: var(--c-muted); }
  .health-table tr.edge-crit { box-shadow: inset 3px 0 0 var(--c-crit); }
  .health-table tr.edge-warn { box-shadow: inset 3px 0 0 var(--c-warn); }
  .health-table tr.edge-crit > td:first-child, .health-table tr.edge-warn > td:first-child { box-shadow: none; }
  .health-facts { grid-template-columns: minmax(0, 1fr); gap: 2px; }
  .health-facts dd { margin-bottom: 6px; }
  .health-panel .card-head-row .btn { width: 100%; }
}
/* Ende Selbstüberwachung 0.81 */

/* ---------- Datensicherung 0.81 ---------- */
/* Zusatzbereich „Sicherungen des Servers“ unter Einstellungen, Datenbank: Zustand des Sicherungsdienstes, Speicherort und Verlauf der Läufe (auf
   dem Telefon als Karten), dazu die Kennzahl „Letzte Sicherung“ im Bereich „Zustand und Wartung“. */
.backup-card .notice { margin-bottom: var(--sp-3); }
.backup-card .notice p { margin: 0; }
.backup-card .notice p + p, .backup-card .notice .steps { margin-top: 8px; }
dl.kv.backup-facts { grid-template-columns: 150px minmax(0, 1fr); }
dl.kv.backup-facts .cell-sub { margin-top: 2px; }
.backup-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: var(--sp-4); }
.backup-card .cell-sub .mono { font-size: inherit; }
.backup-runs-table .br-sha { font-size: var(--fs-small); }
.backup-runs-table td.br-result .cell-sub { max-width: 420px; white-space: normal; }
.backup-restore pre.code-view { margin-top: 6px; user-select: all; }
.kpi-row.db-kpis { grid-template-columns: repeat(4, minmax(0, 1fr)); }
@media (max-width: 900px) {
  .kpi-row.db-kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
/* Telefon: Läufe als Karten. Oben Beginn mit Auslöser und rechts das Ergebnis, darunter die Meldung, dann Dauer und Größe nebeneinander
   und die Prüfsumme mit Datei; die Zelle des Ergebnisses löst sich dafür auf (display: contents). */
@media (max-width: 640px) {
  dl.kv.backup-facts { grid-template-columns: 1fr; }
  .backup-actions .btn { flex: 1 1 calc(50% - 4px); }
  .backup-runs-table thead { display: none; }
  .backup-runs-table, .backup-runs-table tbody { display: block; }
  .backup-runs-table tr {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 4px var(--sp-2);
    padding: 10px var(--card-px);
    border-bottom: 1px solid var(--c-border-soft);
  }
  .backup-runs-table tbody tr:last-child { border-bottom: 0; }
  .card > .table-wrap .backup-runs-table td { display: block; padding: 0; border: 0; min-width: 0; max-width: none; white-space: normal; text-align: left; }
  .card > .table-wrap .backup-runs-table td.br-result { display: contents; }
  .backup-runs-table td.br-start { grid-column: 1; grid-row: 1; }
  .backup-runs-table td.br-result .pill { grid-column: 2; grid-row: 1; justify-self: end; align-self: start; }
  .backup-runs-table td.br-result .cell-sub { grid-column: 1 / -1; grid-row: 2; max-width: none; }
  .backup-runs-table td.br-duration { grid-column: 1; grid-row: 3; font-size: var(--fs-small); }
  .card > .table-wrap .backup-runs-table td.br-size { grid-column: 2; grid-row: 3; font-size: var(--fs-small); text-align: right; }
  .backup-runs-table td.br-hash { grid-column: 1 / -1; grid-row: 4; font-size: var(--fs-small); }
  .backup-runs-table td.br-duration:empty, .backup-runs-table td.br-size:empty, .backup-runs-table td.br-hash:empty { display: none; }
  .backup-runs-table td[data-label]::before { content: attr(data-label) " "; color: var(--c-muted); }
}
/* Ende Datensicherung 0.81 */

/* ---------- Abrechnung 0.81 ---------- */
/* Seite „Abrechnung“ unter Kunden: Monatsauswahl, Tabelle je Kunde mit hervorgehobener Grundlage (auf dem Telefon als Karten), Fußzeile
   und Export. */
.billing-rule {
  display: flex; flex-wrap: wrap; align-items: center; gap: 4px var(--sp-3);
  margin: 0 0 var(--sp-3); font-size: var(--fs-small); color: var(--c-muted);
}
.billing-rule strong { color: var(--c-text); }
/* Köpfe brechen um, damit Kundenfeld, drei Messgrößen, Leistungen und „Geräte als CSV“ auch neben der Seitenleiste ohne Scrollen passen. */
table.billing-table th { white-space: normal; vertical-align: bottom; }
table.billing-table th, table.billing-table td { padding-left: 8px; padding-right: 8px; }
table.billing-table th:first-child, table.billing-table td:first-child { padding-left: 12px; }
table.billing-table th:last-child, table.billing-table td:last-child { padding-right: 12px; }
table.billing-table td.bl-customer { min-width: 150px; white-space: normal; overflow-wrap: anywhere; }
table.billing-table td.bl-extra { white-space: normal; overflow-wrap: anywhere; }
table.billing-table th.num { text-align: right; }
table.billing-table .bl-measure { min-width: 92px; }
table.billing-table .bl-value { display: block; font-weight: 600; font-variant-numeric: tabular-nums; }
table.billing-table .bl-split { display: block; font-size: var(--fs-label); color: var(--c-muted); font-variant-numeric: tabular-nums; }
/* Die Grundlage nach billing.basis trägt die Fläche in der Akzentfarbe, Kopf und Wert in der Textfarbe des Akzents. */
table.billing-table th.is-basis { color: var(--c-accent-ink); background: color-mix(in srgb, var(--c-accent) 10%, var(--c-elev)); }
table.billing-table td.is-basis { background: var(--c-accent-wash); }
table.billing-table td.is-basis .bl-value { color: var(--c-accent-ink); font-size: 1.05rem; }
table.billing-table td.bl-nocontact { color: var(--c-muted); }
table.billing-table tfoot td { border-top: 1px solid var(--c-border); border-bottom: 0; background: var(--c-elev); }
table.billing-table tfoot .bl-value { font-weight: 700; }
.billing-foot { margin-top: var(--sp-3); font-size: var(--fs-small); }
.billing-foot p { margin: 0 0 4px; }

@media (max-width: 640px) {
  /* Telefon: je Kunde eine Karte. Oben Name und Nummer, darunter die drei Messgrößen nebeneinander (die Grundlage hervorgehoben), dann
     Leistungen und „Ohne Kontakt“ mit Beschriftung, zuletzt „Geräte als CSV“ in voller Breite. Die Summe steht als letzte Karte. */
  .billing-table thead { display: none; }
  .billing-table, .billing-table tbody, .billing-table tfoot { display: block; }
  .billing-table tr {
    display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px var(--sp-2); align-items: start;
    padding: 12px var(--sp-3); border-bottom: 1px solid var(--c-border-soft);
  }
  .billing-table tbody tr:last-child { border-bottom: 0; }
  .table-wrap table.billing-table td {
    display: block; padding: 0; border: 0; min-width: 0; white-space: normal; text-align: left; background: none;
  }
  .table-wrap table.billing-table td.bl-customer, .table-wrap table.billing-table td.bl-extra,
  .table-wrap table.billing-table td.bl-actions { grid-column: 1 / -1; }
  .billing-table td[data-label]::before { content: attr(data-label); display: block; font-size: var(--fs-label); color: var(--c-muted); }
  .table-wrap table.billing-table td.is-basis { margin: -4px -6px; padding: 4px 6px; border-radius: var(--radius-sm); background: var(--c-accent-wash); }
  .billing-table td.bl-svc, .billing-table td.bl-nocontact { font-size: var(--fs-small); }
  .table-wrap table.billing-table td.bl-actions { display: flex; }
  .table-wrap table.billing-table td.bl-actions:empty { display: none; }
  .billing-table td.bl-actions .btn { flex: 1 1 auto; margin: 0; }
  .billing-table tfoot tr { background: var(--c-elev); }
  .billing-toolbar > .filter { flex: 1 1 calc(50% - var(--sp-2)); max-width: none; }
  .billing-toolbar .filter select { width: 100%; max-width: none; }
}
/* Ende Abrechnung 0.81 */

/* ---------- Aufräumen 0.81 ---------- */
/* Seite „Aufräumen“ unter Geräte: Filter nach Grund und Kunde, Liste mit Auswahl und Aktionen (auf dem Telefon als Karten) und die
   abgewiesenen Agents ohne Gerät. */
.cleanup-toolbar .cleanup-dismissed-toggle { align-self: flex-end; min-height: 36px; font-size: var(--fs-small); }
.cleanup-limits { margin: 0 0 var(--sp-3); font-size: var(--fs-small); }
.cleanup-table .select-page-label { display: none; }
table.cleanup-table td.cu-device { min-width: 170px; white-space: normal; overflow-wrap: anywhere; }
table.cleanup-table td.cu-device .cell-main > .pill { margin-left: 6px; }
table.cleanup-table td.cu-customer { white-space: normal; min-width: 120px; }
table.cleanup-table td.cu-reasons { white-space: normal; min-width: 260px; }
.cu-reason { display: flex; align-items: baseline; gap: 6px; padding: 2px 0; font-size: var(--fs-small); }
.cu-reason + .cu-reason { border-top: 1px dashed var(--c-border-soft); padding-top: 4px; margin-top: 2px; }
.cu-reason > .pill { flex: 0 0 auto; }
.cu-reason-text { overflow-wrap: anywhere; }
.cleanup-rejected { margin-top: var(--sp-4); }
.cleanup-rejected > p { font-size: var(--fs-small); margin: 0 0 var(--sp-3); }
table.cleanup-rejected-table td.cr-agent { white-space: normal; min-width: 180px; }
table.cleanup-rejected-table th.num { text-align: right; }

@media (max-width: 640px) {
  /* Telefon: je Gerät eine Karte mit dem Auswahlfeld links (40 px Tippfläche), Name und Klasse, Kunde und letzter Kontakt, darunter die
     Gründe in voller Breite und „Älteres löschen“. „Alle auswählen“ bleibt über den Karten stehen. */
  .cleanup-table, .cleanup-table thead, .cleanup-table tbody { display: block; }
  .cleanup-table thead tr { display: flex; align-items: center; padding: 2px var(--sp-2); border-bottom: 1px solid var(--c-border-soft); background: var(--c-elev); }
  .cleanup-table thead th { display: none; }
  .cleanup-table thead th.select-col { display: block; width: auto; padding: 0; border: 0; background: none; position: static; text-align: left; }
  .cleanup-table .select-hit { display: inline-flex; align-items: center; justify-content: flex-start; gap: var(--sp-2); min-width: 40px; min-height: 40px; cursor: pointer; }
  .cleanup-table thead .select-hit { padding-left: 12px; }
  .cleanup-table .select-page-label { display: inline; font-size: var(--fs-small); font-weight: 600; color: var(--c-muted); }
  .cleanup-table tbody tr {
    display: grid; grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas: "device device" "customer seen" "reasons reasons" "actions actions";
    gap: 4px var(--sp-2); align-items: start; padding: 10px var(--sp-3); border-bottom: 1px solid var(--c-border-soft);
  }
  .cleanup-table.selectable tbody tr {
    grid-template-columns: 40px minmax(0, 1fr) auto;
    grid-template-areas: "sel device device" "sel customer seen" "sel reasons reasons" "sel actions actions";
    padding-left: var(--sp-1);
  }
  .cleanup-table tbody tr:last-child { border-bottom: 0; }
  .table-wrap .cleanup-table td { display: block; padding: 0; border: 0; min-width: 0; white-space: normal; background: none; }
  .cleanup-table tbody tr.selected { background: var(--c-selected); }
  .cleanup-table td.select-col { grid-area: sel; align-self: start; width: auto; }
  .cleanup-table td.cu-device { grid-area: device; }
  .cleanup-table td.cu-customer { grid-area: customer; font-size: var(--fs-small); color: var(--c-muted); }
  .cleanup-table td.cu-seen { grid-area: seen; font-size: var(--fs-small); text-align: right; }
  .cleanup-table td.cu-reasons { grid-area: reasons; }
  .table-wrap .cleanup-table td.cu-actions { grid-area: actions; display: flex; gap: 6px; text-align: left; }
  .table-wrap .cleanup-table td.cu-actions:empty { display: none; }
  .cleanup-table td.cu-actions .btn { flex: 1 1 auto; margin: 0; }
  .cu-reason { flex-wrap: wrap; }
  .cleanup-toolbar > .filter { flex: 1 1 calc(50% - var(--sp-2)); max-width: none; }
  .cleanup-toolbar .filter select { width: 100%; max-width: none; }
  /* Abgewiesene Agents als Karten: Agent oben, Adresse, Grund, letzter Versuch und Versuche beschriftet darunter. */
  .cleanup-rejected-table thead { display: none; }
  .cleanup-rejected-table, .cleanup-rejected-table tbody { display: block; }
  .cleanup-rejected-table tr {
    display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 4px var(--sp-2); padding: 10px var(--card-px);
    border-bottom: 1px solid var(--c-border-soft);
  }
  .cleanup-rejected-table tbody tr:last-child { border-bottom: 0; }
  .card > .table-wrap .cleanup-rejected-table td { display: block; padding: 0; border: 0; white-space: normal; text-align: left; }
  .cleanup-rejected-table td.cr-agent { grid-column: 1 / -1; }
  .cleanup-rejected-table td[data-label]::before {
    content: attr(data-label); display: block; font-family: var(--font); font-size: var(--fs-label); color: var(--c-muted);
  }
}
/* Ende Aufräumen 0.81 */

/* ---------- Schnellansicht 0.82 ---------- */
/* Leiste „Schnellansicht“ der Geräteliste im Muster der Alarm-Leiste (side-panel device-panel, ohne transform, ab 1400 px mit Push, bis
   640 px als Blatt), Zeilen mit Klick und Knopf „Vorschau“ sowie Abschnitte, Balken und Aktionen der Leiste. Lage, Breite, Blatt und
   Push stehen als gemeinsame Grundregeln (.side-panel) im Block „Alarm-Arbeitsplatz“; Kopf, Körper und Abschnitte nutzen dieselben
   Klassen (ap-head, ap-body, ap-section). */

/* Zeilen: Die offene Zeile trägt eine Akzentkante. „Vorschau“ ist der Tastaturweg in der letzten Spalte. Die Spalte ist schmal wie
   null und klebt am rechten Rand; der Knopf liegt bei Hover oder Fokus über dem Ende der Zeile, damit die Tabelle nicht breiter wird.
   Für Screenreader ist er immer da (Deckkraft statt Ausblenden). */
.device-table tbody tr.is-previewed td:first-child { box-shadow: inset 3px 0 0 var(--c-accent-line); }
.device-table th.peek-col, .table-wrap .device-table td.dl-peek { position: sticky; right: 0; width: 0; min-width: 0; padding: 0; overflow: visible; }
.device-table .dl-peek-btn { position: absolute; top: 50%; right: 8px; translate: 0 -50%; opacity: 0; box-shadow: var(--shadow); }
.device-table tbody tr:hover .dl-peek-btn, .device-table .dl-peek-btn:focus-visible { opacity: 1; }

/* Leiste: Wechsel zwischen den Geräten der Seite und „Aktualisieren“ in einer Zeile unter dem Kopf. */
.device-panel .dqv-nav {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  padding: 8px 14px 8px 18px;
  border-bottom: 1px solid var(--c-border-soft);
  flex-shrink: 0;
}
.device-panel .dqv-position { font-size: var(--fs-small); font-variant-numeric: tabular-nums; }
.device-panel .dqv-refresh { margin-left: auto; }
.device-panel .ap-head h2 { overflow-wrap: anywhere; }
.device-panel .dqv-display { margin: 0 0 8px; font-size: var(--fs-small); }
.device-panel .dqv-inline-pill { margin-left: 6px; }

/* Listen der Alarme und Jobs: Nummer bzw. Name, Ton, Zeit rechts. */
.device-panel .dqv-list { list-style: none; margin: 0; padding: 0; }
.device-panel .dqv-list li {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 2px 8px;
  padding: 6px 0;
  border-top: 1px solid var(--c-border-soft);
  font-size: var(--fs-small);
}
.device-panel .dqv-list li:first-child { border-top: 0; padding-top: 0; }
.device-panel .dqv-num { min-width: 48px; font-weight: 600; font-variant-numeric: tabular-nums; }
.device-panel .dqv-main { flex: 1 1 140px; min-width: 0; overflow-wrap: anywhere; }
.device-panel .dqv-when { margin-left: auto; white-space: nowrap; }
.device-panel .dqv-more { margin: 8px 0 0; font-size: var(--fs-small); }

/* Datenträger und Virenschutz. */
.device-panel .dqv-vols { gap: 10px; }
.device-panel .dqv-vols .bar { min-width: 60px; }
.device-panel .dqv-av { margin: 0; overflow-wrap: anywhere; }
.device-panel .dqv-av.ok { color: var(--c-ok-ink); }
.device-panel .dqv-av.warn { color: var(--c-warn-ink); font-weight: 600; }
.device-panel .dqv-av.crit { color: var(--c-crit-ink); font-weight: 600; }
.device-panel .dqv-av.muted { color: var(--c-muted); }

@media (max-width: 640px) {
  /* Telefon: Die Karte öffnet die Schnellansicht per Tippen; „Vorschau“ bleibt nur für Screenreader (dieselbe Gewichtung wie die
     Regel der Spalte oben, sonst bliebe die Zelle klebend im Fluss der Karte). */
  .table-wrap .device-table td.dl-peek {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
  }
  .device-table tbody tr.is-previewed td:first-child { box-shadow: none; }
  .device-table tbody tr.is-previewed { box-shadow: inset 3px 0 0 var(--c-accent-line); }
  .device-panel .dqv-nav { padding: 8px 10px 8px 14px; }
}
/* Ende Schnellansicht 0.82 */

/* ---------- Ansichten 0.82 ---------- */
/* Auswahl „Ansicht“ als erstes Feld der Filterleiste mit „(geändert)“, Dialoge „Ansicht speichern“, „Ansichten verwalten“ und „Spalten“,
   dazu die Spalte „Standort“. Abgewählte Spalten der Telefon-Karte (dl-off) blendet nur der Desktop aus. */
.toolbar .view-tools { display: inline-flex; flex-wrap: wrap; gap: var(--sp-2); }
.toolbar.device-filters > .columns-button { margin-left: auto; }
.device-table td.dl-site { white-space: normal; min-width: 110px; }
@media (min-width: 641px) {
  .device-table .dl-off { display: none; }
}

.view-save-mode { margin-top: 0; }
.view-save-switches { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; margin: 14px 0 8px; }
.view-save-switches .hint { margin: 0 0 6px 28px; }
.view-save-note { margin: 8px 0 0; font-size: var(--fs-small); }
dl.kv.view-manage-facts { margin: 14px 0; }
/* Die Zeile mit Eingabe und „Umbenennen“ steht im Feld neben der Bezeichnung; sie übernimmt nicht deren kleine, fette Schrift. */
.field > span.view-rename-row { display: flex; gap: var(--sp-2); font-size: inherit; font-weight: inherit; color: inherit; }
.view-rename-row input { flex: 1 1 auto; min-width: 0; }
.columns-choice { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px 16px; margin: 12px 0 16px; }

@media (max-width: 640px) {
  /* Telefon: Karten statt Spalten, deshalb kein Knopf „Spalten“; die Knöpfe der Ansichten klappen mit den Filtern auf. */
  .toolbar.device-filters > .columns-button { display: none; }
  .toolbar.device-filters:not(.filters-open) > .view-tools { display: none; }
  .toolbar.device-filters > .view-tools { flex: 1 1 100%; }
  .toolbar.device-filters > .view-tools .btn { flex: 1 1 auto; }
  .device-table td.dl-site { display: none; }
  .columns-choice { grid-template-columns: minmax(0, 1fr); }
  .view-rename-row { flex-wrap: wrap; }
}
/* Ende Ansichten 0.82 */

/* ---------- Kunden-Kontext 0.82 ---------- */
/* Knopf in der Kopfzeile links (ruhig ohne Kontext, mit Akzentkante „Arbeiten für …“), Auswahl der Kunden, gedämpft auf Seiten ohne
   Kundenbezug, Abschnitt im Benutzermenü und die schmale Zeile über dem Inhalt auf dem Telefon, dazu die Hinweise auf Dashboard und in
   der Alarmliste und der Knopf „Als Kunden-Kontext“ in der Suche. Bis 900 px hat die Kopfleiste keinen Platz: Dort gelten der Abschnitt
   im Benutzermenü und die Zeile über dem Inhalt. */
.app-header .header-context { display: flex; align-items: center; margin-right: auto; min-width: 0; }
@media (max-width: 900px) {
  .app-header .header-context { display: none; }
}

/* Mit Kontext: eine Leiste mit Akzentkante links, „Arbeiten für“ leise, der Kunde kräftig, „Kontext aufheben“ abgetrennt rechts. */
.work-context-picker.is-set {
  display: inline-flex;
  align-items: stretch;
  min-width: 0;
  max-width: min(560px, 48vw);
  border: 1px solid var(--c-accent-border);
  border-left: 3px solid var(--c-accent-line);
  border-radius: var(--radius-sm);
  background: var(--c-accent-wash);
}
.work-context-picker .wc-current {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  min-width: 0;
  min-height: var(--control-h-sm);
  padding: 3px 10px;
  border: 0;
  background: transparent;
  color: var(--c-text);
  font: inherit;
  font-size: var(--fs-small);
  text-align: left;
  cursor: pointer;
}
.work-context-picker .wc-label { flex: none; color: var(--c-muted); white-space: nowrap; }
.work-context-picker .wc-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.work-context-picker .wc-clear {
  flex: none;
  padding: 3px 10px;
  border: 0;
  border-left: 1px solid var(--c-border-soft);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  background: transparent;
  color: var(--c-muted);
  font: inherit;
  font-size: var(--fs-small);
  white-space: nowrap;
  cursor: pointer;
}
.work-context-picker .wc-current:hover, .work-context-picker .wc-clear:hover { background: var(--c-hover); color: var(--c-text); }
.work-context-picker button:focus-visible { outline: var(--focus-w) solid var(--c-focus); outline-offset: 2px; }
/* Seite ohne Kundenbezug: gedämpft, aber bedienbar; beim Überfahren und mit dem Fokus wieder voll sichtbar. */
.work-context-picker.is-idle { opacity: .55; }
.work-context-picker.is-idle:hover, .work-context-picker.is-idle:focus-visible, .work-context-picker.is-idle:focus-within { opacity: 1; }
.work-context-picker.is-set.is-idle { border-color: var(--c-border-soft); border-left-color: var(--c-border-strong); background: transparent; }

/* Auswahl der Kunden: Zeilen wie die Treffer der Suche, der aktuelle Kunde mit Akzent. */
.wc-intro { margin: 0 0 var(--sp-3); font-size: var(--fs-small); }
.wc-item {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 2px 12px;
  width: 100%;
  padding: 9px 12px;
  border: 0;
  border-bottom: 1px solid var(--c-border-soft);
  background: transparent;
  color: var(--c-text);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.wc-item:last-child { border-bottom: 0; }
.wc-item:hover { background: var(--c-hover); }
.wc-item:focus-visible { outline: var(--focus-w) solid var(--c-focus); outline-offset: -2px; }
.wc-item:disabled { cursor: progress; opacity: .6; }
.wc-item-name { grid-column: 1; font-weight: 600; overflow-wrap: anywhere; }
.wc-item-sub { grid-column: 1; font-size: .8rem; color: var(--c-muted); }
.wc-item .pill { grid-column: 2; grid-row: 1 / span 2; }
.wc-item.is-current { background: var(--c-accent-wash); box-shadow: inset 3px 0 0 var(--c-accent-line); }

/* Abschnitt im Benutzermenü und Zeile über dem Inhalt: nur bis 900 px, darüber steht der Knopf in der Kopfzeile. */
.work-context-menu, .work-context-bar { display: none; }
.wc-menu-state { margin-bottom: 8px; font-size: var(--fs-small); overflow-wrap: anywhere; }
.wc-menu-actions { display: flex; flex-wrap: wrap; gap: 8px; }
@media (max-width: 900px) {
  .work-context-menu { display: block; }
  .work-context-bar {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 2px 6px;
    margin: 0 0 var(--sp-3);
    padding: 6px 12px;
    border: 1px solid var(--c-accent-border);
    border-left: 3px solid var(--c-accent-line);
    border-radius: var(--radius-sm);
    background: var(--c-accent-wash);
    font-size: var(--fs-small);
  }
  .work-context-bar.is-idle { border-color: var(--c-border-soft); border-left-color: var(--c-border-strong); background: var(--c-elev); color: var(--c-muted); }
  .wc-bar-text { min-width: 0; overflow-wrap: anywhere; }
  .work-context-bar .wc-bar-clear { min-height: 32px; }
}
@media (max-width: 900px) and (pointer: coarse) {
  .wc-menu-actions .btn { min-height: 40px; }
  .work-context-bar .wc-bar-clear { min-height: 40px; }
}

/* Hinweise: Dashboard „Gefiltert auf …“, Alarmliste „Weitere … bei anderen Kunden“; Text links, Aktion rechts, auf dem Telefon darunter. */
.work-context-note {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 6px var(--sp-3);
  margin-bottom: var(--sp-3);
  padding: 8px 12px;
  border: 1px solid var(--c-border-soft);
  border-left: 3px solid var(--c-accent-line);
  border-radius: var(--radius-sm);
  background: var(--c-accent-wash);
  font-size: var(--fs-small);
}
.work-context-note.is-all { border-left-color: var(--c-border-strong); background: var(--c-elev); }
.work-context-note.warn { border-left-color: var(--c-warn); background: var(--c-elev); }
.work-context-note.crit { border-left-color: var(--c-crit); background: var(--c-elev); }
.work-context-note .wc-note-text { min-width: 0; overflow-wrap: anywhere; }
.work-context-note .wc-note-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
/* Telefon: Den Kontext nennt schon die Zeile über dem Inhalt; der gleichlautende Hinweis des Dashboards entfällt dort. */
@media (max-width: 900px) {
  .work-context-note.is-context { display: none; }
}

/* Suche: Kundentreffer mit dem Knopf „Als Kunden-Kontext“ rechts neben dem Link. */
.search-list .wc-search-row { display: flex; align-items: center; border-bottom: 1px solid var(--c-border-soft); }
.search-list .wc-search-row:last-child { border-bottom: 0; }
.wc-search-row > .search-hit { flex: 1 1 auto; min-width: 0; border-bottom: 0; }
.wc-search-row > .wc-search-set { flex: none; margin-right: 12px; }
@media (max-width: 640px) {
  .search-list .wc-search-row { flex-wrap: wrap; }
  .wc-search-row > .search-hit { flex-basis: 100%; }
  .wc-search-row > .wc-search-set { margin: 0 12px 9px; }
}
/* Ende Kunden-Kontext 0.82 */

/* ---------- Morgenübersicht 0.82 ---------- */
/* Kundenliste als Lage: Statuskante je Zeile, Stufe als Text, Bereichs-Pillen, Spalten „Seit gestern“ und Erreichbarkeit, Werkzeugleiste
   mit „Nur mit Handlungsbedarf“, Sortierung und „Aktualisieren“, auf dem Telefon als Karten, dazu der Zusatz an der Kachel „Kunden“. */
.co-toolbar .co-refresh { display: inline-flex; align-items: center; gap: var(--sp-2); margin-left: auto; }
.co-toolbar .co-stand { font-size: var(--fs-small); color: var(--c-muted); white-space: nowrap; }
.co-table .select-page-label { display: none; }
/* Neun Spalten auf 1440 px: etwas engere Zellen, Spaltenköpfe dürfen umbrechen, die Breite bestimmt der Inhalt. */
table.co-table th, table.co-table td { padding-left: 10px; padding-right: 10px; }
table.co-table th { white-space: normal; vertical-align: bottom; }
table.co-table td { vertical-align: top; }
table.co-table td.co-name { min-width: 150px; white-space: normal; }
table.co-table td.co-name .cell-main { overflow-wrap: anywhere; }
table.co-table td.co-name .cell-main > .pill { margin-left: 6px; }
table.co-table td.co-state { white-space: normal; min-width: 200px; }
.co-pills { display: flex; flex-wrap: wrap; gap: 4px; max-width: 320px; }
/* Die Stufe steht vorn in fester Breite, damit sie über die Zeilen hinweg eine Spalte bildet. */
.co-pills .co-level { min-width: 76px; text-align: center; }
.co-pills a:hover { text-decoration: none; }
.co-alerts-link { display: inline-flex; flex-direction: column; gap: 1px; }
.co-alerts-link:hover { text-decoration: none; }
.co-alerts-link:hover span { text-decoration: underline; }
.co-table .co-crit { color: var(--c-crit-ink); font-weight: 600; }
.co-table .co-warn { color: var(--c-warn-ink); font-weight: 600; }
table.co-table td.co-patch { white-space: normal; min-width: 80px; }
table.co-table td.co-since { white-space: normal; min-width: 150px; max-width: 240px; font-size: var(--fs-small); }
table.co-table td.co-devices a { display: block; }
table.co-table td.co-contact { white-space: normal; min-width: 130px; }
.co-table .co-phone { font-size: var(--fs-small); font-variant-numeric: tabular-nums; white-space: nowrap; }
/* Zusatz an der Kachel „Kunden“ im Dashboard: Handlungsbedarf in der Farbe der Warnung, ein Klick öffnet die gefilterte Liste. */
.stat-card .co-need-hint { color: var(--c-warn-ink); font-weight: 600; cursor: pointer; }
.stat-card .co-need-hint:hover { text-decoration: underline; }

/* Unter 1366 px weicht die Erreichbarkeit (nur Information, auf der Kundenseite weiter sichtbar), damit die übrigen Spalten ohne seitliches
   Scrollen in die Breite passen. */
@media (max-width: 1366px) {
  table.co-table .co-avail { display: none; }
  table.co-table td.co-state { min-width: 185px; }
  table.co-table td.co-since { min-width: 130px; }
}

@media (max-width: 640px) {
  /* Telefon: je Kunde eine Karte mit dem Auswahlfeld links (40 px Tippfläche), oben Name mit Nummer und Ort, darunter die Lage in voller
     Breite, dann Alarme und Patch-Rückstand, „Seit gestern“, Erreichbarkeit und Geräte, zuletzt der Ansprechpartner mit Telefon. Jede
     Angabe trägt ihre Spalte als Beschriftung; die Statuskante wandert an die ganze Karte. „Alle sichtbaren“ bleibt über den Karten. */
  .co-toolbar > .search { flex: 1 1 100%; max-width: none; }
  .co-toolbar .co-refresh { margin-left: 0; width: 100%; justify-content: space-between; }
  .co-table, .co-table thead, .co-table tbody { display: block; }
  .co-table thead tr { display: flex; align-items: center; padding: 2px var(--sp-2); border-bottom: 1px solid var(--c-border-soft); background: var(--c-elev); }
  .co-table thead th { display: none; }
  .co-table thead th.select-col { display: block; width: auto; padding: 0; border: 0; background: none; position: static; text-align: left; }
  .co-table .select-hit { display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2); min-width: 40px; min-height: 40px; cursor: pointer; }
  .co-table thead .select-hit { justify-content: flex-start; padding-left: 12px; }
  .co-table .select-page-label { display: inline; font-size: var(--fs-small); font-weight: 600; color: var(--c-muted); }
  .co-table tbody tr {
    display: grid;
    grid-template-columns: 40px minmax(0, 1fr) minmax(0, 1fr);
    grid-template-areas: "sel name name" "sel state state" "sel alerts patch" "sel since since" "sel avail devices" "sel contact contact";
    align-items: start;
    gap: 6px var(--sp-2);
    padding: 10px var(--sp-3) 12px var(--sp-1);
    border-bottom: 1px solid var(--c-border-soft);
  }
  .co-table.co-plain tbody tr { grid-template-areas: "sel name name" "sel devices maint" "sel contact contact"; }
  .co-table tbody tr:last-child { border-bottom: 0; }
  .co-table tbody tr.selected { background: var(--c-selected); }
  .co-table tr.edge-crit { box-shadow: inset 3px 0 0 var(--c-crit); }
  .co-table tr.edge-warn { box-shadow: inset 3px 0 0 var(--c-warn); }
  .co-table tr.edge-crit > td:first-child, .co-table tr.edge-warn > td:first-child { box-shadow: none; }
  .table-wrap .co-table td { display: block; padding: 0; border: 0; min-width: 0; max-width: none; white-space: normal; text-align: left; background: none; }
  .co-table td.select-col { grid-area: sel; align-self: start; width: auto; }
  .co-table td.co-name { grid-area: name; }
  /* Der Name führt auf die Kundenseite: Tippfläche 40 px hoch, ohne die Karte höher zu machen. */
  .co-table td.co-name .cell-main > a.plain { display: inline-block; padding: 10px 0; margin: -10px 0; }
  .co-table td.co-state { grid-area: state; }
  .co-table td.co-alerts { grid-area: alerts; }
  .co-table td.co-patch { grid-area: patch; }
  .co-table td.co-since { grid-area: since; }
  .co-table td.co-avail { grid-area: avail; }
  .co-table td.co-devices { grid-area: devices; }
  .co-table td.co-contact { grid-area: contact; }
  .co-table td.co-maint { grid-area: maint; }
  .co-table td.co-alerts, .co-table td.co-patch, .co-table td.co-since, .co-table td.co-avail, .co-table td.co-devices, .co-table td.co-contact,
  .co-table td.co-maint { font-size: var(--fs-small); }
  .co-table td.co-alerts::before, .co-table td.co-patch::before, .co-table td.co-since::before, .co-table td.co-avail::before,
  .co-table td.co-devices::before, .co-table td.co-contact::before, .co-table td.co-maint::before {
    content: attr(data-label); display: block; font-size: var(--fs-label); font-weight: 400; color: var(--c-muted);
  }
  .co-pills { max-width: none; }
  .co-table .co-phone { display: inline-block; padding: 9px 0; margin: -9px 0; }
}
/* Ende Morgenübersicht 0.82 */

/* ---------- Zeitachse 0.82 ---------- */
/* Reiter „Aktivität“ als Zeitachse: Kopf „Seit gestern“, Werkzeugleiste, Liste nach Tagen mit Uhrzeit, Statuskante, Titel, Akteur und
   aufklappbaren Punkten der Inventar-Änderungen, Hinweis zur Aufbewahrung am Ende; ohne Sonderlayout auf dem Telefon. */
.timeline .tl-since { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); margin-bottom: var(--sp-3); }
.timeline .tl-since-label { font-size: var(--fs-label); font-weight: 600; color: var(--c-muted); margin-right: var(--sp-1); }
.timeline .tl-since-chip {
  display: inline-flex; align-items: center; gap: 6px; min-height: var(--control-h-sm); padding: 2px 10px; border: 1px solid var(--c-border);
  border-radius: 999px; background: var(--c-elev); color: var(--c-text); font: inherit; font-size: var(--fs-small); cursor: pointer;
}
.timeline .tl-since-chip strong { font-variant-numeric: tabular-nums; }
.timeline .tl-since-chip:hover { background: var(--c-hover); }
.timeline .tl-since-chip.active { border-color: var(--c-accent-border); background: var(--c-accent-tint); color: var(--c-accent-ink); }
.timeline .tl-filters .tl-switch { min-height: var(--control-h); font-size: var(--fs-small); }
/* Werkzeugleiste ohne Springen (0.84): Die Suche wächst nicht mit dem freien Platz, und „Filter zurücksetzen“ steht ohne gesetzten
   Filter unsichtbar an seinem Platz. Ein Filter oder „Nur Fehler und Befunde“ ändert so weder die Breite der Suche noch die Zeilen. */
.timeline .tl-filters > .filter-search { flex: 0 1 300px; }
.timeline .tl-filters > .filter-reset.is-idle { visibility: hidden; }
.timeline .tl-day + .tl-day { margin-top: var(--sp-4); }
.timeline .tl-day-head {
  margin: 0 0 var(--sp-2); font-size: var(--fs-small); font-weight: 600; color: var(--c-muted);
}
.timeline .tl-list { list-style: none; margin: 0; padding: 0; background: var(--c-surface); border: 1px solid var(--c-border-soft); border-radius: var(--radius); overflow: hidden; }
.timeline .tl-item {
  display: grid; grid-template-columns: 48px minmax(0, 1fr) auto; gap: var(--sp-1) var(--sp-3); align-items: start;
  padding: var(--sp-2) var(--sp-3); border-top: 1px solid var(--c-border-soft);
}
.timeline .tl-item:first-child { border-top: 0; }
.timeline .tl-item.edge-ok { box-shadow: inset 3px 0 0 var(--c-ok); }
.timeline .tl-item.edge-warn { box-shadow: inset 3px 0 0 var(--c-warn); }
.timeline .tl-item.edge-crit { box-shadow: inset 3px 0 0 var(--c-crit); }
.timeline .tl-item.edge-info { box-shadow: inset 3px 0 0 var(--c-info); }
.timeline .tl-item.is-muted .tl-title, .timeline .tl-item.is-muted .tl-time { color: var(--c-muted); }
.timeline .tl-time { font-family: var(--mono); font-size: var(--fs-small); color: var(--c-muted); padding-top: 1px; font-variant-numeric: tabular-nums; }
.timeline .tl-body { min-width: 0; }
.timeline .tl-head { display: flex; flex-wrap: wrap; align-items: center; gap: 4px var(--sp-2); }
.timeline .tl-title { font-weight: 600; overflow-wrap: anywhere; }
.timeline .tl-detail { margin-top: 2px; font-size: var(--fs-small); color: var(--c-muted); overflow-wrap: anywhere; }
.timeline .pill.actor-user { background: var(--c-accent-tint); color: var(--c-accent-ink); }
.timeline .pill.actor-agent { background: var(--c-neutral-bg); color: var(--c-muted); }
.timeline .pill.actor-system { background: var(--c-warn-bg); color: var(--c-warn-ink); }
.timeline .tl-link { font-size: var(--fs-small); white-space: nowrap; padding-top: 1px; }
.timeline .tl-points { list-style: none; margin: var(--sp-1) 0 0; padding: 0; font-size: var(--fs-small); }
.timeline .tl-points li { display: flex; gap: var(--sp-2); align-items: baseline; padding: 1px 0; min-width: 0; }
.timeline .tl-points li.is-finding .tl-point-text { color: var(--c-warn-ink); }
.timeline .tl-point-kind { flex: 0 0 64px; font-size: var(--fs-label); font-weight: 600; color: var(--c-muted); }
.timeline .tl-point-kind.added { color: var(--c-ok-ink); }
.timeline .tl-point-kind.removed { color: var(--c-crit-ink); }
.timeline .tl-point-kind.changed { color: var(--c-info-ink); }
.timeline .tl-point-text { min-width: 0; overflow-wrap: anywhere; }
.timeline .tl-more { margin-top: var(--sp-1); }
.timeline .tl-message { margin-top: var(--sp-2); max-height: 280px; }
.timeline .tl-coverage { margin-top: var(--sp-4); padding-top: var(--sp-3); border-top: 1px dashed var(--c-border); font-size: var(--fs-small); color: var(--c-muted); }
.timeline .tl-coverage p { margin: 0 0 var(--sp-1); }
@media (max-width: 640px) {
  .timeline .tl-item { grid-template-columns: 42px minmax(0, 1fr); padding: var(--sp-2); }
  .timeline .tl-link { grid-column: 2; }
  .timeline .tl-point-kind { flex-basis: 56px; }
  .timeline .tl-filters .tl-switch { flex: 1 1 100%; }
  /* Telefon: Suche über die volle Breite wie in der Geräteliste; ein unsichtbarer Knopf in eigener Zeile wäre nur Leerraum. */
  .timeline .tl-filters > .filter-search { flex: 1 1 100%; }
  .timeline .tl-filters > .filter-reset.is-idle { display: none; }
}
/* Ende Zeitachse 0.82 */

/* ---------- Nachrichten 0.83 ---------- */
/* Nachrichten an angemeldete Benutzer: Dialog mit Empfängern, Zähler, Vorschau und „Zuletzt gesendet“, Kachel im Sammeldialog
   (Strang Nachricht am Server). */
.um-target-row { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-2) var(--sp-3); flex-wrap: wrap; margin-bottom: var(--sp-2); }
.um-target-row + .table-wrap, .um-target-row + .notice { margin-top: var(--sp-2); }
table.um-sessions td { white-space: normal; }
table.um-sessions th.um-pick, table.um-sessions td.um-pick { width: 36px; padding-right: 0; }
table.um-sessions td.um-account { overflow-wrap: anywhere; }
table.um-sessions td.um-state .pill { margin-left: 6px; }
.um-bulk-target { margin: calc(-1 * var(--sp-2)) 0 var(--sp-2); overflow-wrap: anywhere; }
.um-bulk-facts { margin: 0 0 var(--sp-2); padding-left: 1.2em; }
.um-bulk-facts li + li { margin-top: 2px; }
.switch.um-later { margin-top: var(--sp-3); }
.um-recent { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); margin-bottom: var(--sp-3); }
.um-recent .btn { max-width: 100%; white-space: normal; overflow-wrap: anywhere; text-align: left; }
.um-form { display: grid; gap: var(--sp-3); }
.um-form textarea.um-text { width: 100%; min-height: 140px; resize: vertical; line-height: 1.45; }
.um-counter { align-self: flex-end; font-size: var(--fs-label); font-weight: 400; color: var(--c-muted); font-variant-numeric: tabular-nums; }
.field > .um-counter { font-weight: 400; }
.um-counter.over { color: var(--c-crit-ink); font-weight: 600; }
.um-options { display: flex; align-items: flex-end; gap: var(--sp-3) var(--sp-5); flex-wrap: wrap; margin-top: var(--sp-3); }
.um-options select { min-width: 160px; }
/* Dringlichkeit so hoch wie das Auswahlfeld daneben, damit die Beschriftungen auf einer Linie stehen. */
.um-urgency > button { min-height: calc(var(--control-h) - 2px); padding: 2px 16px; }
.um-options .switch.um-ack { min-height: var(--control-h); }
/* Vorschau: verkleinerte Nachbildung des Dialogs der Tray-App, ruhig gerahmt; „Wichtig“ mit Warnkante. */
.um-preview {
  max-width: 440px;
  border: 1px solid var(--c-border);
  border-radius: var(--radius);
  background: var(--c-elev);
  box-shadow: var(--shadow-soft);
  overflow: hidden;
  font-size: var(--fs-small);
}
.um-preview.important { box-shadow: inset 4px 0 0 var(--c-warn), var(--shadow-soft); }
.um-preview-head { padding: 6px 12px; background: var(--c-chrome); color: var(--c-muted); border-bottom: 1px solid var(--c-border-soft); font-weight: 600; }
.um-preview-body { padding: 10px 12px; display: grid; gap: 6px; }
.um-preview-from { color: var(--c-muted); font-size: var(--fs-label); }
.um-preview-title { font-weight: 600; font-size: var(--fs-body); overflow-wrap: anywhere; }
.um-preview-text { white-space: pre-wrap; overflow-wrap: anywhere; max-height: 9.5em; overflow: hidden; }
.um-preview-foot { display: flex; justify-content: flex-end; padding: 8px 12px; border-top: 1px solid var(--c-border-soft); }
.um-preview-ok {
  display: inline-block; min-width: 64px; padding: 3px 12px; border-radius: var(--radius-sm); text-align: center;
  background: var(--c-accent-fill); color: var(--c-accent-contrast); font-weight: 600;
}
/* Zuletzt gesendet: Betreff mit Zustand, je Sitzung eine Pille mit Konto und Zeit des Geräts. */
table.um-history td { white-space: normal; vertical-align: top; }
table.um-history td.um-when { white-space: nowrap; }
table.um-history .um-by { display: block; font-size: var(--fs-label); }
table.um-history td.um-subject { overflow-wrap: anywhere; min-width: 160px; }
table.um-history td.um-subject .pill { margin-left: 6px; }
table.um-history .um-sub { display: block; font-size: var(--fs-label); font-weight: 400; }
table.um-history td.um-receipts .pill { display: inline-block; margin: 0 4px 4px 0; max-width: 100%; white-space: normal; overflow-wrap: anywhere; }
@media (max-width: 640px) {
  /* Telefon: Empfänger und Verlauf als Karten, Umschalter und Auswahl in voller Breite. */
  .um-target { width: 100%; }
  .um-target-row .btn { width: 100%; }
  .um-options { flex-direction: column; align-items: stretch; }
  .um-options select { width: 100%; }
  .um-preview { max-width: none; }
  .um-sessions thead, .um-history thead { display: none; }
  .um-sessions, .um-sessions tbody, .um-history, .um-history tbody { display: block; }
  .um-sessions tr, .um-history tr {
    display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: start; gap: 4px var(--sp-2);
    padding: 10px var(--sp-3); border-bottom: 1px solid var(--c-border-soft);
  }
  .um-sessions tbody tr:last-child, .um-history tbody tr:last-child { border-bottom: 0; }
  .um-sessions tr.selected { background: var(--c-selected); }
  .um-sessions tr.selected td { background: transparent; }
  .table-wrap table.um-sessions td, .table-wrap table.um-history td {
    display: block; padding: 0; border: 0; min-width: 0; max-width: none; white-space: normal; text-align: left; box-shadow: none;
  }
  .um-sessions td[data-label]::before, .um-history td[data-label]::before { content: attr(data-label) " "; color: var(--c-muted); }
  .um-sessions td.um-pick { grid-column: 2; grid-row: 1; width: auto; }
  .um-sessions td.um-account { grid-column: 1; grid-row: 1; }
  .um-sessions td.um-station, .um-sessions td.um-state, .um-sessions td.um-tray { grid-column: 1 / -1; font-size: var(--fs-small); }
  .um-history td.um-subject { grid-column: 1 / -1; grid-row: 1; min-width: 0; }
  .um-history td.um-when, .um-history td.um-receipts { grid-column: 1 / -1; font-size: var(--fs-small); }
  .um-history td.um-when .um-by { display: inline; margin-left: 4px; }
  .table-wrap table.um-history td.um-actions { grid-column: 1 / -1; display: flex; }
  .table-wrap table.um-history td.um-actions:empty { display: none; }
  .table-wrap table.um-history td.um-actions .btn { flex: 1 1 auto; margin: 0; }
}
/* Ende Nachrichten 0.83 */

/* ---------- Journal 0.83 ---------- */
/* Linux-Journal der Ereignisprotokoll-Regeln: Plattform in Bibliothek, Satz- und Regel-Dialog, Reiter „Ereignisse“ am Gerät (Strang
   Journal am Server). Eigene Klassen mit „journal-“, damit die Klassen des Blocks Ereignisprotokoll 0.78 nur dort stehen. */
/* Auswahlchips Alle, Windows, Linux über der Bibliothek, sobald es Linux-Sätze gibt. */
.journal-filter { display: flex; flex-wrap: wrap; gap: 6px; margin: 0 0 var(--sp-3); }
/* Pill „Linux“ am Namen eines Satzes: in Tabelle, Karte auf dem Telefon und beim Kunden dieselbe. */
.journal-pill { margin-left: 6px; vertical-align: middle; }
/* Plattform beim Anlegen eines Satzes; danach nur die Pill. */
.journal-platform { align-self: flex-start; }
.journal-platform > button { min-width: 88px; }
.journal-platform-value { display: flex; align-items: center; min-height: var(--control-h-sm); }
/* MESSAGE_ID mit 32 Hexzeichen: gleichbreite Schrift, auf dem Telefon umbrechen. */
.journal-id { font-family: var(--mono); font-size: var(--fs-small); overflow-wrap: anywhere; }
@media (max-width: 640px) {
  .journal-filter > .chip-button { flex: 1 1 0; text-align: center; }
  .journal-platform { display: flex; width: 100%; }
  .journal-platform > button { flex: 1 1 0; min-width: 0; }
}
/* Ende Journal 0.83 */

/* ---------- Logos 0.84 ---------- */
/* Logos ab Werk für Tag und Nacht, Favicon, App-Symbol, Tray und Mails (Strang Logos). */

/* BrandMark mit der Vorgabe (Klasse factory): Das mitgelieferte Logo hat über und unter dem Motiv transparenten Rand (die Höhe entspricht
   der Breite der Bildmarke, damit die Tray-App im linken Quadrat die ganze Marke zeigt). Mit 34 px steht das Motiv 24 px hoch und der
   Schriftzug 14 px in der Seitenleiste, mit 56 px auf Anmeldung, Kontoeinrichtung und Impressum 39 bzw. 23 px. Der Name daneben entfällt,
   das Logo enthält ihn. Welche Variante sichtbar ist, regelt der Block „Logos 0.79“ (for-dark, for-light). */
.brand-logo-img.factory { height: 34px; max-width: none; }
.brand-logo-img.big.factory { height: 56px; max-width: min(100%, 260px); }
.logo-tile-stage img.factory { height: 48px; }
/* Telefon: Seitenleiste als Kopfleiste mit Logo, Alarmzahl und Menüknopf; das Logo darf schrumpfen, bleibt aber lesbar. */
@media (max-width: 900px) {
  .sidebar > .brand > .brand-logo-img.factory { height: 30px; min-width: 72px; }
}
/* Ende Logos 0.84 */

/* ---------- Monitore 0.84 ---------- */
/* Angeschlossene Monitore im Reiter Hardware eines Geräts (Strang Monitore). */
/* Nicht verbundene Monitore als gedämpfte Zeile (muted-row) ohne Befundfarbe; Größe in cm und „zuletzt gesehen“ unter dem Wert. */
table.monitors-table td.mon-serial { white-space: normal; overflow-wrap: anywhere; min-width: 110px; }
table.monitors-table td.mon-state .cell-sub { white-space: nowrap; }
@media (max-width: 640px) {
  /* Telefon: je Monitor eine Karte; oben Modell und Zustand, darunter die Werte mit ihrer Bezeichnung. */
  .monitors-table thead { display: none; }
  .monitors-table, .monitors-table tbody { display: block; }
  .monitors-table tr {
    display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: start; gap: 4px var(--sp-2);
    padding: 10px var(--sp-3); border-bottom: 1px solid var(--c-border-soft);
  }
  .monitors-table tbody tr:last-child { border-bottom: 0; }
  .table-wrap table.monitors-table td {
    display: block; padding: 0; border: 0; min-width: 0; max-width: none; white-space: normal; text-align: left;
  }
  .monitors-table td.mon-name { grid-column: 1; grid-row: 1; overflow-wrap: anywhere; }
  .table-wrap table.monitors-table td.mon-state { grid-column: 2; grid-row: 1; text-align: right; font-size: var(--fs-small); }
  .monitors-table td.mon-size, .monitors-table td.mon-res, .monitors-table td.mon-conn, .monitors-table td.mon-serial,
  .monitors-table td.mon-year { grid-column: 1 / -1; font-size: var(--fs-small); }
  .monitors-table td[data-label]::before { content: attr(data-label) " "; color: var(--c-muted); }
  .monitors-table td.mon-size .cell-sub { display: inline; margin-left: 4px; }
}
/* Ende Monitore 0.84 */

/* ---------- Erreichbarkeit 0.84 ---------- */
/* Karte Erreichbarkeit in der Übersicht eines Geräts mit Zeitstrahl und Ausfällen (Strang Erreichbarkeit). Shared/DeviceAvailabilityCard:
   Kopf mit Kennzahl und Zeitraum, Zeitstrahl als eigenes SVG (Abschnitte als Klassen, Wartung schraffiert über ein Muster), Tageszeilen
   (7 Tage) und Tagesbalken (30 Tage) als Knöpfe, Legende, Liste der Ausfälle (Telefon als Karten). Farben nur aus den Tokens: verbunden
   grün, Ausfall rot (nur überwachte Geräte), Wartung schraffiert im Info-Ton, aus neutral grau, keine Daten blass. */
.avail-card { position: relative; }
.avail-defs { position: absolute; width: 0; height: 0; overflow: hidden; }
.avail-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--sp-2) var(--sp-4); }
.avail-kpi { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px var(--sp-3); min-width: 0; }
.avail-kpi > .pill { align-self: center; }
.avail-kpi-label { font-size: var(--fs-small); color: var(--c-muted); }
.avail-summary { margin: var(--sp-2) 0 var(--sp-3); font-size: var(--fs-small); }
.avail-summary.muted { color: var(--c-muted); max-width: 90ch; }

/* Abschnitte: Spur (außerhalb des Zeitraums), verbunden, Ausfall, Wartung, aus, keine Daten; Marke für kurze aufgeführte Ausfälle. */
.avail-svg { display: block; width: 100%; overflow: visible; }
.avail-track { fill: color-mix(in srgb, var(--c-muted) 7%, transparent); }
.avail-seg.s-connected { fill: var(--c-ok); }
.avail-seg.s-outage, .avail-mark { fill: var(--c-crit); }
.avail-seg.s-off { fill: color-mix(in srgb, var(--c-muted) 40%, var(--c-surface)); }
.avail-seg.s-nodata { fill: color-mix(in srgb, var(--c-muted) 17%, var(--c-surface)); }
.avail-hatch-bg { fill: var(--c-info-bg); }
.avail-hatch-line { fill: var(--c-info); }

/* 24 Stunden: ein Strahl mit Uhrzeiten alle 6 Stunden und „jetzt“ rechts. */
.avail-window .avail-strip { height: 32px; }
.avail-axis { position: relative; height: 18px; margin-top: 4px; font-size: var(--fs-label); color: var(--c-muted); }
.avail-tick { position: absolute; top: 0; transform: translateX(-50%); white-space: nowrap; font-variant-numeric: tabular-nums; }
.avail-axis .avail-tick.is-now { left: auto; right: 0; transform: none; }

/* 7 Tage: eine Zeile je Ortstag mit Strahl von 0 bis 24 Uhr, rechts die Ausfallzeit des Tages. */
.avail-week { display: grid; gap: 2px; }
.avail-week-axis, .avail-day {
  display: grid;
  grid-template-columns: 72px minmax(0, 1fr) 76px;
  align-items: center;
  gap: var(--sp-3);
  padding: 0 var(--sp-2);
}
.avail-hours { position: relative; height: 16px; font-size: var(--fs-label); color: var(--c-muted); }
.avail-hours .avail-tick.is-start { transform: none; }
.avail-hours .avail-tick.is-end { transform: translateX(-100%); }
.avail-day {
  width: 100%;
  min-height: 30px;
  margin: 0;
  padding-top: 4px;
  padding-bottom: 4px;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--c-text);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.avail-day:hover { background: var(--c-hover); }
.avail-day.on { background: var(--c-selected); }
.avail-day .avail-strip { height: 22px; }
.avail-day-label { font-size: var(--fs-small); font-weight: 400; white-space: nowrap; font-variant-numeric: tabular-nums; }
.avail-day-sum { font-size: var(--fs-small); color: var(--c-muted); text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
.avail-day.t-outage .avail-day-sum { color: var(--c-crit-ink); }
.avail-day:focus-visible, .avail-bar:focus-visible { outline: var(--focus-w) solid var(--c-focus); outline-offset: 1px; }

/* 30 Tage: ein Balken je Ortstag in der Farbe der Tageslage; bei Arbeitsplätzen der Anteil „verbunden“ als Füllhöhe. */
.avail-bars { display: grid; grid-template-columns: repeat(var(--avail-days, 31), minmax(0, 1fr)); grid-auto-rows: 52px; gap: 2px; }
.avail-bar {
  display: block;
  min-width: 0;
  height: 52px;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 2px;
  background: none;
  overflow: hidden;
  cursor: pointer;
}
.avail-bar .avail-svg { height: 100%; }
.avail-bar:hover { opacity: .82; }
.avail-bar.on { outline: 2px solid var(--c-text); outline-offset: 1px; overflow: visible; }
.avail-bars-axis { display: flex; justify-content: space-between; margin-top: 4px; font-size: var(--fs-label); color: var(--c-muted); }

/* Einzelheiten zum gewählten Tag, Legende, Liste der Ausfälle und Fußzeile. */
.avail-detail { min-height: 1.45em; margin: var(--sp-3) 0 var(--sp-2); font-size: var(--fs-small); }
.avail-legend { display: flex; flex-wrap: wrap; gap: 4px var(--sp-4); margin: 0 0 var(--sp-2); padding: 0; list-style: none; font-size: var(--fs-label); color: var(--c-muted); }
.avail-legend li { display: inline-flex; align-items: center; gap: 6px; }
.avail-swatch { display: block; flex: 0 0 auto; border-radius: 2px; }
.avail-subtitle { margin: var(--sp-4) 0 var(--sp-2); font-size: var(--fs-body); font-weight: 600; }
.avail-subtitle .count { color: var(--c-muted); font-weight: 500; }
.avail-outages td.ao-duration .pill, .avail-outages td.ao-end .pill { margin-left: 6px; }
.avail-outages tr.edge-warn > td:first-child { box-shadow: inset 3px 0 0 var(--c-warn); }
.avail-more { margin: var(--sp-2) 0 0; font-size: var(--fs-small); }
.avail-foot { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px var(--sp-4); margin-top: var(--sp-3); font-size: var(--fs-label); color: var(--c-muted); }
.avail-foot a { margin-left: auto; }

/* Telefon: Strahl und Balken volle Breite, Tageszeilen schmaler, die Ausfälle als Karten mit Beschriftung aus data-label. */
@media (max-width: 640px) {
  .avail-head { align-items: stretch; }
  .avail-switch { width: 100%; }
  .avail-week-axis, .avail-day { grid-template-columns: 58px minmax(0, 1fr) 56px; gap: var(--sp-2); padding: 0 2px; }
  .avail-day { min-height: 36px; }
  .avail-bars { gap: 1px; grid-auto-rows: 44px; }
  .avail-bar { height: 44px; }
  .avail-foot a { margin-left: 0; }
  .avail-outages thead { display: none; }
  .avail-outages, .avail-outages tbody { display: block; }
  .avail-outages tr {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas: "start duration" "end end" "alert alert" "maint maint";
    gap: 3px var(--sp-2);
    padding: 10px var(--sp-3);
    border-bottom: 1px solid var(--c-border-soft);
  }
  .avail-outages tbody tr:last-child { border-bottom: 0; }
  .table-wrap .avail-outages td, .card > .table-wrap .avail-outages td { display: block; padding: 0; border: 0; min-width: 0; white-space: normal; box-shadow: none; }
  .avail-outages tr.edge-warn { box-shadow: inset 3px 0 0 var(--c-warn); }
  .avail-outages tr.edge-warn > td:first-child { box-shadow: none; }
  .avail-outages td.ao-start { grid-area: start; font-weight: 600; }
  .avail-outages td.ao-duration { grid-area: duration; text-align: right; }
  .avail-outages td.ao-end { grid-area: end; font-size: var(--fs-small); }
  .avail-outages td.ao-alert { grid-area: alert; font-size: var(--fs-small); }
  .avail-outages td.ao-maintenance { grid-area: maint; font-size: var(--fs-small); }
  .avail-outages td.ao-end::before, .avail-outages td.ao-alert::before, .avail-outages td.ao-maintenance::before {
    content: attr(data-label) " ";
    color: var(--c-muted);
  }
}

/* Erzwungene Farben: Hintergründe und Füllungen weichen sonst dem System; die Abschnitte tragen dann Systemfarben und Muster
   (verbunden Highlight, Ausfall voll in Textfarbe, Wartung schraffiert, aus nur Rahmen, keine Daten GrayText). */
@media (forced-colors: active) {
  .avail-svg, .avail-swatch, .avail-defs { forced-color-adjust: none; }
  .avail-track { fill: Canvas; stroke: GrayText; stroke-width: 1px; }
  .avail-seg.s-connected { fill: Highlight; }
  .avail-seg.s-outage, .avail-mark { fill: CanvasText; }
  .avail-seg.s-off { fill: Canvas; stroke: CanvasText; stroke-width: 1px; }
  .avail-seg.s-nodata { fill: GrayText; }
  .avail-hatch-bg { fill: Canvas; }
  .avail-hatch-line { fill: CanvasText; }
  /* Gewählter Tag: Rahmen statt Fläche, sonst verschwände der Strahl (verbunden ist Highlight) in der Fläche des gedrückten Knopfs. */
  :root .avail-day[aria-pressed="true"], :root .avail-bar[aria-pressed="true"] {
    forced-color-adjust: auto;
    background: Canvas;
    color: CanvasText;
    outline: 2px solid Highlight;
    outline-offset: 1px;
  }
}
/* Ende Erreichbarkeit 0.84 */

/* ---------- Leistung 0.84 ---------- */
/* Leistungsmessung mit Kernen und Datenträgern (Strang Leistung). */
/* Prozessor: Umschalter „Gesamt“ und „Kerne“ neben der Pille; in der Ansicht „Kerne“ nimmt die Karte die ganze Breite. */
.perf-cpu-tools { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; }
.perf-view-btn:disabled { opacity: .45; cursor: not-allowed; }
.perf-view-btn:disabled:hover { background: transparent; color: var(--c-muted); }
.perf-grid.perf-grid-cores { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.perf-grid > .perf-cpu-cores { grid-column: 1 / -1; }
.perf-cores-empty { padding: var(--sp-2) 0; }

/* Bis 16 logische Prozessoren: je eine kleine Kurve mit Beschriftung und Wert. */
.perf-cores { display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: var(--sp-2) var(--sp-3); margin-bottom: var(--sp-2); }
.perf-core { min-width: 0; }
.perf-core-head { display: flex; justify-content: space-between; gap: 6px; font-size: var(--fs-label); line-height: 1.3; }
.perf-core-label { color: var(--c-muted); white-space: nowrap; }
.perf-core-value { font-variant-numeric: tabular-nums; font-weight: 600; white-space: nowrap; }
.perf-chart.perf-core-chart { height: 40px; margin: 2px 0 0; }

/* Ab 17 logischen Prozessoren: Wärmebild, Zeilen sind Prozessoren, Spalten Messwerte. Fünf Stufen in Tönen der Reihenfarbe über der
   Kartenfläche, keine Zustandsfarben; die Höhe setzt die Komponente (rund 5 px je Zeile). */
.perf-heat-wrap { display: grid; grid-template-columns: auto minmax(0, 1fr); column-gap: var(--sp-2); margin-bottom: var(--sp-2); }
.perf-heat-rows { display: flex; flex-direction: column; justify-content: space-between; font-size: var(--fs-label); color: var(--c-muted); white-space: nowrap; line-height: 1.2; }
.perf-heat { display: block; width: 100%; border-radius: var(--radius-sm); shape-rendering: crispEdges; }
.perf-heat-bg { fill: var(--c-elev); }
.perf-heat .h0, .perf-heat-swatch .h0 { fill: color-mix(in srgb, var(--c-series-1) 10%, var(--c-surface)); }
.perf-heat .h1, .perf-heat-swatch .h1 { fill: color-mix(in srgb, var(--c-series-1) 32%, var(--c-surface)); }
.perf-heat .h2, .perf-heat-swatch .h2 { fill: color-mix(in srgb, var(--c-series-1) 54%, var(--c-surface)); }
.perf-heat .h3, .perf-heat-swatch .h3 { fill: color-mix(in srgb, var(--c-series-1) 76%, var(--c-surface)); }
.perf-heat .h4, .perf-heat-swatch .h4 { fill: var(--c-series-1); }
.perf-heat .hoff { fill: var(--c-neutral-bg); }
.perf-heat-axis { grid-column: 2; display: flex; justify-content: space-between; align-items: center; gap: var(--sp-2); flex-wrap: wrap; margin-top: 4px; font-size: var(--fs-label); color: var(--c-muted); }
.perf-heat-legend { display: inline-flex; align-items: center; gap: 3px; }
.perf-heat-legend > span:first-child { margin-right: 3px; }
.perf-heat-legend > span:last-child { margin-left: 3px; }
.perf-heat-swatch { width: 16px; height: 10px; display: block; border-radius: 2px; outline: 1px solid var(--c-border-soft); }
.perf-heat-top { margin: var(--sp-1) 0 0; font-size: var(--fs-small); }

/* Datenträger: je Datenträger eine Karte; der Name darf umbrechen, das Modell steht in einer Zeile (vollständig im title), damit die
   Kurven nebeneinander auf einer Höhe stehen. Die Zahlen stehen als Paare in zwei Spalten. Die Karten stehen im gemeinsamen Kachelraster
   (unvollständige Reihe mittig); mit dem Abstand der Karten darüber stehen drei Datenträger genau unter Prozessor, Speicher und Netzwerk. */
.card-grid.perf-disks { gap: var(--sp-4); }
.perf-old-agent { margin-top: var(--sp-3); }
.perf-disk .card-head-row { align-items: flex-start; flex-wrap: nowrap; }
.perf-disk-name { min-width: 0; flex: 1 1 auto; }
.perf-disk-name h2 { overflow-wrap: anywhere; }
.perf-disk-model { display: block; margin-top: 2px; font-size: var(--fs-small); color: var(--c-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.perf-disk .pill { flex: 0 0 auto; }
.perf-disk-stats { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 4px var(--sp-4); margin: var(--sp-2) 0 0; font-size: var(--fs-small); }
.perf-disk-stats > div { display: flex; justify-content: space-between; gap: var(--sp-2); min-width: 0; }
.perf-disk-stats dt { color: var(--c-muted); }
.perf-disk-stats dd { margin: 0; font-variant-numeric: tabular-nums; white-space: nowrap; }

/* Telefon: Umschalter und Pille teilen sich die Zeile, drei kleine Kurven nebeneinander. */
@media (max-width: 640px) {
  .perf-grid.perf-grid-cores { grid-template-columns: minmax(0, 1fr); }
  .perf-cpu-tools { width: 100%; }
  .perf-cpu-tools .perf-view-switch { width: auto; flex: 1 1 0; }
  .perf-cores { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .perf-disk-stats { gap: 4px var(--sp-3); }
}

/* Erzwungene Farben: Das Wärmebild behält seine Stufen, sonst wären alle Zellen gleich. */
@media (forced-colors: active) {
  .perf-heat, .perf-heat-swatch { forced-color-adjust: none; }
}
/* Ende Leistung 0.84 */

/* ---------- Geräteseite 0.84 ---------- */
/* Alarme der Übersicht mit Seiten und feste Spaltenbreiten der Protokoll- und Listentabellen (Strang Geräteseite). */
/* Feste Spalten (cols-fixed): Die Breiten kommen aus der <colgroup> der Tabelle, nicht aus dem Inhalt der gerade gezeigten Zeilen.
   Filter, Blättern und Nachladen verschieben so keine Spalte. Zu lange Inhalte enden mit „…“ (der volle Text steht im title oder
   hinter „Details“), Zellen mit „wrap“ brechen um. Eine Spalte ohne Klasse (<col />) nimmt den Rest. Die Regeln wirken über :where()
   ohne Gewicht, damit die Regeln der einzelnen Tabellen und ihre Telefon-Karten Vorrang behalten. */
:where(table.cols-fixed) { table-layout: fixed; }
:where(table.cols-fixed) > thead > tr > th,
:where(table.cols-fixed) > tbody > tr > td { overflow: hidden; text-overflow: ellipsis; }
:where(table.cols-fixed) > tbody > tr > td.wrap { overflow-wrap: anywhere; }
:where(table.cols-fixed) > tbody > tr > td:where(.row-actions, .select-col, [colspan]) { overflow: visible; }
/* Zeilen in der Zelle schneiden nur seitlich ab (clip, nicht hidden) und haben links und rechts Platz für den Fokusrahmen
   (:focus-visible: 2 px Abstand, bis 3 px breit); der negative Außenabstand hebt den Innenabstand auf, Breite und „…“ bleiben gleich.
   So bleibt der Rahmen eines Links oder Knopfs am Zellanfang (Gerät, Job, Ziel, Programm) ganz sichtbar. */
:where(table.cols-fixed) > tbody > tr > td:not(.wrap, [colspan]) :where(.cell-main, .cell-sub, .cell-fill-block) {
  overflow-x: clip; overflow-y: visible; text-overflow: ellipsis;
  padding-inline: calc(var(--focus-w) + 2px); margin-inline: calc(-1 * (var(--focus-w) + 2px));
}
:where(table.cols-fixed) > tbody > tr > td:not([colspan]) .pill { max-width: 100%; overflow: hidden; text-overflow: ellipsis; vertical-align: middle; }

/* Aktivitätsprotokoll: Zeit, Akteur, Aktion und Ziel fest, Details nehmen den Rest und stehen auf höchstens zwei Zeilen. Unterhalb
   der Mindestbreite rollt die Tabelle seitlich (wie die Ereignisse). */
table.activity-table { min-width: 56rem; }
table.activity-table col.col-when { width: 10rem; }
table.activity-table col.col-actor { width: 18%; }
table.activity-table col.col-action { width: 21%; }
table.activity-table col.col-target { width: 13%; }
table.activity-table td.msg { max-width: none; }
table.activity-table .msg-text {
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2;
  overflow: hidden; white-space: normal; overflow-wrap: anywhere;
}
/* „Details“ immer dann, wenn der Text gekürzt dargestellt wird: app.js setzt data-cut an die Zeile, sobald der Text über die zwei
   Zeilen hinausreicht (je Breite gemessen, nicht ab einer festen Zeichenzahl); mehrzeilige Meldungen (is-multi) zeigen den Knopf immer. */
table.activity-table .msg-line > .msg-more { display: none; }
table.activity-table .msg-line:is(.is-multi, [data-cut]) > .msg-more { display: inline-flex; }
.toolbar > .activity-failures { white-space: nowrap; }

/* Alarme (Seite „Alarme“ und Dashboard): Nummer, Schwere und Zeiten fest, Gerät, Kunde und Check anteilig, die Meldung nimmt den Rest
   und bricht um. Die Mindestbreite gilt nur oberhalb der Telefon-Karten. */
table.cols-alerts col.col-id { width: 5.5rem; }
table.cols-alerts col.col-sev { width: 7.5rem; }
table.cols-alerts col.col-sev-closed { width: 11.5rem; }
table.cols-alerts col.col-dev { width: 15%; }
table.cols-alerts col.col-cust { width: 13%; }
table.cols-alerts col.col-check { width: 14%; }
table.cols-alerts col.col-fix { width: 18%; }
table.cols-alerts col.col-time, table.cols-alerts col.col-ago { width: 9.5rem; }
table.cols-alerts col.col-until { width: 6.5rem; }
/* Geschlossene Alarme haben eine Spalte mehr (Ausgelöst): Gerät, Kunde und Check werden schmaler, die beiden Zeiten brechen zwischen
   Datum und Uhrzeit um, damit die Meldung lesbar bleibt. */
table.cols-alerts.al-closed col.col-dev, table.cols-alerts.al-closed col.col-check { width: 12%; }
table.cols-alerts.al-closed col.col-cust { width: 10%; }
table.cols-alerts.al-closed col.col-time, table.cols-alerts.al-closed col.col-ago { width: 7.5rem; }
table.cols-alerts.al-closed td.al-opened, table.cols-alerts.al-closed td.al-time { white-space: normal; }

/* Alarme in der Übersicht eines Geräts (DeviceAlertList). Unter 1400 px brechen die Zeiten zwischen Datum und Uhrzeit um. */
table.device-alerts col.col-id { width: 5.5rem; }
table.device-alerts col.col-sev { width: 7rem; }
table.device-alerts col.col-status { width: 9rem; }
table.device-alerts col.col-check { width: 18%; }
table.device-alerts col.col-time { width: 7.5rem; }
table.device-alerts td.da-time { white-space: normal; }
@media (min-width: 1400px) {
  table.device-alerts col.col-status { width: 10.5rem; }
  table.device-alerts col.col-check { width: 20%; }
  table.device-alerts col.col-time { width: 9.5rem; }
}

/* Jobs und Läufe eines Jobs. */
table.cols-jobs col.col-select { width: 3rem; }
table.cols-jobs col.col-shell { width: 10%; }
table.cols-jobs col.col-started { width: 9.5rem; }
table.cols-jobs col.col-count { width: 7%; }
table.cols-jobs col.col-result { width: 17%; }
table.cols-jobs col.col-actions { width: 13.5rem; }
/* Spalte „Job“: Name und Marken (Zeitplan, Check, Behebung, Wiederholung, Benutzer) teilen sich die Zeile; reicht der Platz nicht,
   rutschen die Marken in eine zweite Zeile. Nur ein Name, der allein nicht passt, endet mit „…“ (voller Name im title), die Marken
   bleiben immer sichtbar. Am Telefon bricht der Name in der Karte um wie bisher. */
@media (min-width: 641px) {
  table.cols-jobs td.jl-job .cell-main { display: flex; flex-wrap: wrap; align-items: center; gap: 2px 6px; }
  table.cols-jobs td.jl-job .cell-main > a { min-width: 0; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  table.cols-jobs td.jl-job .cell-main > .pill { flex: 0 0 auto; margin-left: 0; }
}
table.cols-runs col.col-cust { width: 18%; }
table.cols-runs col.col-status { width: 9rem; }
table.cols-runs col.col-started { width: 9.5rem; }
table.cols-runs col.col-duration { width: 7rem; }
table.cols-runs col.col-exit { width: 6rem; }
table.cols-runs col.col-actions { width: 7.5rem; }

/* Software-Übersicht: das Programm nimmt den Rest, die aufgeklappte Gruppe (eine Zelle über alle Spalten) bleibt unbeschnitten. */
table.cols-software col.col-devices { width: 6rem; }
table.cols-software col.col-versions { width: 7rem; }
table.cols-software col.col-customers { width: 6rem; }
table.cols-software col.col-new { width: 8.5rem; }
table.cols-software col.col-actions { width: 12.5rem; }

@media (min-width: 641px) {
  /* Mindestbreiten: darunter rollt die Tabelle seitlich, statt die Spalten unlesbar schmal zu machen. */
  table.cols-alerts.cols-fixed { min-width: 60rem; }
  table.cols-alerts.al-closed.cols-fixed { min-width: 68rem; }
  table.device-alerts.cols-fixed { min-width: 60rem; }
  table.cols-jobs.cols-fixed { min-width: 60rem; }
  table.cols-runs.cols-fixed { min-width: 63rem; }
  table.cols-software.cols-fixed { min-width: 56rem; }
}

@media (max-width: 640px) {
  /* Telefon-Karten bleiben, wie sie sind: keine Spaltenbreiten, kein Abschneiden aus der gemeinsamen Regel. */
  :where(table.cols-fixed.cols-alerts, table.cols-fixed.device-alerts, table.cols-fixed.cols-jobs, table.cols-fixed.cols-runs, table.cols-fixed.cols-software) > colgroup { display: none; }
  :where(table.cols-fixed.cols-alerts, table.cols-fixed.device-alerts, table.cols-fixed.cols-jobs, table.cols-fixed.cols-runs, table.cols-fixed.cols-software) > tbody > tr > td { overflow: visible; text-overflow: clip; }
  :where(table.cols-fixed.cols-alerts, table.cols-fixed.device-alerts, table.cols-fixed.cols-jobs, table.cols-fixed.cols-runs, table.cols-fixed.cols-software) > tbody > tr > td:not(.wrap, [colspan]) :where(.cell-main, .cell-sub, .cell-fill-block) { overflow: visible; text-overflow: clip; padding-inline: 0; margin-inline: 0; }
  :where(table.cols-fixed.cols-alerts, table.cols-fixed.device-alerts, table.cols-fixed.cols-jobs, table.cols-fixed.cols-runs, table.cols-fixed.cols-software) > tbody > tr > td:not([colspan]) .pill { max-width: none; overflow: visible; vertical-align: baseline; }
}

/* Kurzes Blättern „‹ Seite x von y ›“ (PageArrows): Pfeile als kleine Schaltflächen, die Seitenangabe mit fester Breite und Ziffern
   gleicher Breite, damit die Pfeile beim Wechsel nicht wandern. Auf dem Touchscreen sind die Pfeile 40 px groß. */
.page-arrows { display: inline-flex; align-items: center; gap: var(--sp-1); }
.page-arrows .page-arrow { min-width: 34px; justify-content: center; padding-left: 8px; padding-right: 8px; font-size: 1.25rem; font-weight: 600; line-height: 1; }
.page-arrows-label { min-width: 8.5em; text-align: center; color: var(--c-muted); font-size: var(--fs-small); font-variant-numeric: tabular-nums; white-space: nowrap; }
@media (pointer: coarse) {
  .page-arrows .page-arrow { min-width: 40px; min-height: 40px; }
}

/* Alarme in der Übersicht eines Geräts: unter der Tabelle die Seiten, rechts daneben „Alle Alarme des Geräts“. Mit mehreren Seiten
   behält die Liste die Höhe von fünf einzeiligen Alarmen, damit die Pfeile auf der letzten, kürzeren Seite nicht nach oben rutschen. */
.device-alerts-foot { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: var(--sp-2) var(--sp-3); margin-top: var(--sp-2); }
.device-alerts-all { font-size: var(--fs-small); white-space: nowrap; }
@media (min-width: 641px) {
  .device-alerts-list.is-paged > .table-wrap { min-height: 15.5rem; }
}
/* Ende Geräteseite 0.84 */

/* ---------- Lizenz 0.85 ---------- */
/* Banner, Karte „Lizenz“ auf Info und Seite „Lizenz“ der Lizenzsperre (Strang Lizenz in der Instanz). */
/* Banner: Text darf umbrechen, der Verweis bleibt in einer Zeile; der Hinweis auf eine neue Version ist ruhig und kompakt. */
.notice.license-banner > span, .notice.license-update > span { min-width: 0; overflow-wrap: anywhere; }
.notice.license-banner a, .notice.license-update a { white-space: nowrap; }
.notice.license-update { padding: 8px 12px; font-size: var(--fs-small); }

/* Karte „Lizenz“: Stufe neben dem Titel, Grund und nächste Stufe unter der Pille, Hinweise kompakt, Aktionen unten. */
.license-card dl.kv dd .pill { margin-left: 0; margin-right: 6px; }
.license-card .license-reason { font-size: var(--fs-small); }
.license-card dl.kv dd .cell-sub { display: block; }
.notice.license-note { padding: 8px 12px; overflow-wrap: anywhere; }
.license-card .notice.license-note { margin: var(--sp-3) 0 0; }
.license-card .notice.license-note + .notice.license-note { margin-top: var(--sp-2); }
.license-message strong { display: block; margin-bottom: 2px; }
.license-message .linked-text { font-size: var(--fs-small); }
.license-actions { margin-top: var(--sp-4); }
.license-no-trust { margin-top: var(--sp-3); }

/* Dialoge: Schlüssel, Anforderungscode und Antwort in Festbreitenschrift, umbrechend; Schritte des Offline-Wegs nummeriert. */
.license-modal-lead { margin: 0 0 var(--sp-3); font-size: var(--fs-small); line-height: 1.5; }
textarea.license-token, textarea.license-code {
  width: 100%; resize: vertical; font-family: var(--mono); font-size: var(--fs-label); line-height: 1.4; word-break: break-all;
  overflow-wrap: anywhere; white-space: pre-wrap;
}
textarea.license-code { margin-top: var(--sp-2); }
dl.kv.license-key-facts { margin-top: var(--sp-3); }
.license-key-error, .license-key-other { margin: var(--sp-3) 0 0; overflow-wrap: anywhere; }
.license-offline-steps { margin: 0; padding-left: 22px; display: grid; gap: var(--sp-4); }
.license-offline-steps li::marker { color: var(--c-muted); font-weight: 600; }
.license-offline-steps li > strong { display: block; }
.license-offline-steps li > .muted { display: block; font-size: var(--fs-small); line-height: 1.5; }

/* Seite „Lizenz“: Karte wie die Einrichtung, Stufe als Pille vor dem Satz, Fakten, Hinweise und der Ausstieg darunter. */
.login-card.license-page { max-width: 600px; }
.license-page .license-lead .pill { margin-right: 6px; vertical-align: 1px; }
dl.kv.license-page-facts { margin: 0 0 var(--sp-4); }
.license-page .notice.license-note { margin: 0 0 var(--sp-3); }
.license-page .notice.license-always { margin-bottom: var(--sp-4); }
.license-page-key { margin: 0 0 var(--sp-2); font-size: var(--fs-small); overflow-wrap: anywhere; }
.license-page-hint { margin: 0 0 var(--sp-3); font-size: var(--fs-small); line-height: 1.5; }
.license-page .license-actions { margin: 0 0 var(--sp-4); }
.license-page .license-back { margin-top: var(--sp-2); }
.license-exit { border-top: 1px solid var(--c-border-soft); padding-top: var(--sp-4); margin-top: var(--sp-2); }
.license-exit h2 { font-size: 1.08rem; margin: 0 0 var(--sp-2); }
.license-exit h3 { font-size: .95rem; margin: var(--sp-4) 0 var(--sp-2); }
.license-exit > p { font-size: var(--fs-small); line-height: 1.5; margin: 0; }
.license-exit-list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--sp-2); }
.license-exit-list li {
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); flex-wrap: wrap;
  padding: 8px 10px; border: 1px solid var(--c-border-soft); border-radius: var(--radius-sm); background: var(--c-elev);
}
.license-exit-name { display: flex; flex-direction: column; min-width: 0; overflow-wrap: anywhere; }
.license-exit-danger .action-card { margin-bottom: var(--sp-3); }
.license-exit-danger select.license-exit-customer { flex: 1 1 200px; min-width: 0; max-width: 100%; }

@media (max-width: 640px) {
  .license-card .license-actions .btn { flex: 1 1 100%; }
  .license-exit-list li .btn { flex: 1 1 100%; }
  .notice.license-banner a, .notice.license-update a { white-space: normal; }
}
/* Ende Lizenz 0.85 */

/* ---------- Einrichtung 0.85 ---------- */
/* Ersteinrichtung /setup mit Schritten, Einrichtungscode und Lizenzschlüssel (Strang Ersteinrichtung). Karte, Fortschritt, Schritte und
   Fußzeile kommen aus dem Block „Konten 0.80“ (setup-card, setup-progress, setup-step, setup-foot); hier nur, was die Einrichtung dazu
   braucht: Code in Gruppen, eingefügte Dokumente (Lizenzschlüssel, Anforderungscode, Antwort), Vorschau der Lizenz und Zusammenfassung,
   Knopfzeilen und die nächsten Schritte nach dem Abschluss. */
.firstrun-card .setup-code.firstrun-code { max-width: 100%; width: 100%; }
.firstrun-card .setup-code.firstrun-code::placeholder { letter-spacing: .12em; }
.firstrun-card .setup-step code { font-size: .86em; padding: 1px 5px; border-radius: var(--radius-sm); background: var(--c-elev); border: 1px solid var(--c-border-soft); }
.firstrun-document { width: 100%; font-size: var(--fs-small); line-height: 1.4; resize: vertical; overflow-wrap: anywhere; word-break: break-all; }
textarea.firstrun-document[readonly] { background: var(--c-elev); color: var(--c-text); }
.firstrun-summary { margin: 0 0 var(--sp-3); padding: 10px 12px; border-radius: var(--radius-sm); border: 1px solid var(--c-border-soft); background: var(--c-elev); }
.firstrun-summary dd { overflow-wrap: anywhere; }
.firstrun-swatch {
  display: inline-block; width: 14px; height: 14px; margin-right: 8px; vertical-align: -2px;
  border-radius: 4px; border: 1px solid var(--c-border-strong);
}
.firstrun-color input[type=color] { width: 72px; height: var(--control-h, 36px); padding: 3px; cursor: pointer; }
.firstrun-actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); margin: var(--sp-2) 0 0; }
.firstrun-actions form { margin: 0; }
.firstrun-actions-split > form { flex: 1 1 0; }
.firstrun-actions-split > form .btn { width: 100%; }
.firstrun-change { margin: var(--sp-3) 0 0; text-align: center; font-size: var(--fs-small); }
.firstrun-subtitle { font-size: .95rem; margin: var(--sp-4) 0 var(--sp-2); }
.firstrun-steps { margin: 0 0 var(--sp-2); padding-left: 20px; display: grid; gap: 6px; font-size: .9rem; line-height: 1.5; }
.firstrun-steps li::marker { color: var(--c-muted); font-weight: 600; }
.firstrun-next { margin: var(--sp-4) 0 0; font-size: var(--fs-small); color: var(--c-muted); line-height: 1.5; }
@media (max-width: 640px) {
  /* Telefon: Vorschau und Zusammenfassung untereinander, Knöpfe in voller Breite. */
  .firstrun-summary { grid-template-columns: 1fr; gap: 2px; }
  .firstrun-summary dt { margin-top: 6px; }
  .firstrun-summary dt:first-child { margin-top: 0; }
  .firstrun-actions-split { flex-direction: column; align-items: stretch; }
  .firstrun-actions > .btn { flex: 1 1 auto; }
}
/* Ende Einrichtung 0.85 */

/* ---------- Lizenzverwaltung 0.85 ---------- */
/* Lizenzverwaltung der Lizenz-Instanz in den Einstellungen mit Tabelle, Karten und Dialogen (Strang Lizenz-Instanz). */
.lic-panel { display: flex; flex-direction: column; gap: var(--sp-3); min-width: 0; }
.lic-panel > .card, .lic-panel > .table-wrap { margin: 0; }
.lic-head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--sp-2) var(--sp-3); flex-wrap: wrap; }
.lic-title { min-width: 0; }
.lic-title .cell-main { display: flex; align-items: center; gap: var(--sp-2); }
.lic-title .count { color: var(--c-muted); font-weight: 500; }
.lic-actions { display: flex; gap: var(--sp-2); flex-wrap: wrap; }
.lic-hint { margin: 0; font-size: var(--fs-small); }
/* Tabelle der Lizenzen: Lizenznehmer darf umbrechen, Zahlen rechtsbündig mit Grenze darunter, widerrufene Lizenzen gedämpft. */
.lic-notice { margin: 0; }
.lic-nowrap { white-space: nowrap; }
table.lic-table td.lt-name { min-width: 170px; white-space: normal; }
table.lic-table td.lt-until { white-space: nowrap; }
table.lic-table td.lt-name .link-button { overflow-wrap: anywhere; }
table.lic-table td.lt-devices, table.lic-table td.lt-users { white-space: nowrap; font-variant-numeric: tabular-nums; }
table.lic-table td.lt-devices.is-over { color: var(--c-warn-ink); font-weight: 600; }
table.lic-table td.lt-seen { white-space: nowrap; }
table.lic-table td.lt-seen .pill { margin-top: 4px; }
table.lic-table td.lt-version { font-size: var(--fs-small); white-space: nowrap; }
table.lic-table tr.is-revoked td { color: var(--c-muted); }
table.lic-table tr.is-revoked .link-button { color: var(--c-muted); text-decoration: line-through; }
/* Dialog „Lizenz anlegen“: Module als Liste mit Haken, Abweichungen vom Paket markiert; Fristen eingeklappt. */
.lic-modules, .lic-deadlines { margin: 0 0 var(--sp-3); border: 1px solid var(--c-border-soft); border-radius: var(--radius-sm); background: var(--c-elev); }
.lic-modules > summary, .lic-deadlines > summary { padding: 8px 12px; cursor: pointer; font-size: var(--fs-small); font-weight: 600; color: var(--c-text); }
.lic-modules[open] > summary, .lic-deadlines[open] > summary { border-bottom: 1px solid var(--c-border-soft); }
.lic-deadlines > .form-grid { padding: 12px; margin: 0; }
.lic-module-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 2px var(--sp-3); padding: 8px 12px; }
.lic-module { display: flex; align-items: center; gap: 8px; min-width: 0; padding: 4px 0; font-size: var(--fs-small); cursor: pointer; }
.lic-module > span:first-of-type { min-width: 0; overflow-wrap: anywhere; }
.lic-module .pill { margin-left: auto; flex-shrink: 0; }
.lic-module.is-changed > span:first-of-type { font-weight: 600; }
/* Details einer Lizenz: Stammdaten, Fristen mit Herkunft, Tabellen für Installationen, Ausgaben und Nutzung. */
.lic-detail dl.lic-facts { margin-bottom: var(--sp-2); }
.lic-detail dl.lic-facts dd .pill { margin: 0 4px 2px 0; }
.lic-pre { white-space: pre-wrap; }
.lic-deadline-list { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 6px var(--sp-4); }
.lic-deadline { display: flex; align-items: center; gap: 8px; min-width: 0; font-size: var(--fs-small); }
.lic-deadline > span:first-child { flex: 1 1 auto; min-width: 0; color: var(--c-muted); }
.lic-deadline strong { font-variant-numeric: tabular-nums; white-space: nowrap; }
.lic-detail .table-wrap { margin-bottom: var(--sp-2); }
table.lic-inst-table td.li-url { min-width: 200px; white-space: normal; overflow-wrap: anywhere; }
table.lic-inst-table td.li-seen { white-space: nowrap; }
table.lic-inst-table td.li-state { white-space: normal; min-width: 150px; }
table.lic-inst-table td.li-state .pill { margin: 0 4px 2px 0; }
table.lic-inst-table tr.is-released td { color: var(--c-muted); }
table.lic-inst-table td.li-actions, table.lic-key-table td.lk-actions { text-align: right; white-space: nowrap; }
table.lic-key-table td.lk-state .cell-sub { white-space: normal; max-width: 280px; }
table.lic-usage-table td.lu-devices { font-weight: 600; }
.lic-usage-head { margin: var(--sp-4) 0 var(--sp-2); }
.lic-usage-head .modal-section { margin: 0; }
.lic-csv { display: flex; gap: var(--sp-2); }
/* Einmal sichtbarer Schlüssel, Offline-Antwort, Export und Zeile der Vertrauensliste: kopierbar, ohne die Breite zu sprengen. */
.lic-key-value { max-height: 180px; overflow-y: auto; font-size: .85rem; }
.lic-copy-row { display: flex; gap: var(--sp-2); flex-wrap: wrap; margin: 0 0 var(--sp-3); }
pre.lic-armor { white-space: pre; overflow-x: auto; max-height: 260px; margin: 0 0 var(--sp-2); }
textarea.lic-request { min-height: 150px; white-space: pre; }
.lic-signing { margin: 0; }
.lic-signing .card-head-row { margin-bottom: var(--sp-2); }
.lic-signing dl.kv { margin-bottom: var(--sp-3); }
.lic-signing dl.kv dd .cell-sub { margin-top: 2px; white-space: normal; }
.lic-signing .modal-section { margin-top: var(--sp-3); }
.lic-signing-actions { display: flex; gap: var(--sp-2); flex-wrap: wrap; }
.lic-signing > .notice + .lic-signing-actions { margin-top: var(--sp-3); }
pre.lic-trust-line { white-space: pre-wrap; overflow-wrap: anywhere; font-size: .8rem; margin: var(--sp-2) 0; }
.lic-signing-warning { margin: 0; }
@media (max-width: 640px) {
  /* Telefon: Tabellen als Karten mit beschrifteten Werten, Schaltflächen in voller Breite. */
  .lic-actions { width: 100%; }
  .lic-actions .btn { flex: 1 1 auto; }
  .lic-module-grid { grid-template-columns: minmax(0, 1fr); }
  .lic-table thead, .lic-inst-table thead, .lic-key-table thead, .lic-usage-table thead { display: none; }
  .lic-table, .lic-table tbody, .lic-inst-table, .lic-inst-table tbody, .lic-key-table, .lic-key-table tbody,
  .lic-usage-table, .lic-usage-table tbody { display: block; }
  .lic-table tr, .lic-inst-table tr, .lic-key-table tr, .lic-usage-table tr {
    display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); align-items: start; gap: 6px var(--sp-2);
    padding: 10px var(--sp-3); border-bottom: 1px solid var(--c-border-soft);
  }
  .lic-table tbody tr:last-child, .lic-inst-table tbody tr:last-child, .lic-key-table tbody tr:last-child,
  .lic-usage-table tbody tr:last-child { border-bottom: 0; }
  .table-wrap table.lic-table td, .table-wrap table.lic-inst-table td, .table-wrap table.lic-key-table td, .table-wrap table.lic-usage-table td {
    display: block; padding: 0; border: 0; min-width: 0; max-width: none; white-space: normal; text-align: left; box-shadow: none;
  }
  .lic-table td[data-label]::before, .lic-inst-table td[data-label]::before, .lic-key-table td[data-label]::before,
  .lic-usage-table td[data-label]::before {
    content: attr(data-label); display: block; font-size: var(--fs-label); color: var(--c-muted); font-family: var(--font); font-weight: 400;
  }
  .table-wrap table.lic-table td.lt-name, .table-wrap table.lic-inst-table td.li-id, .table-wrap table.lic-key-table td.lk-id,
  .table-wrap table.lic-usage-table td.lu-month { grid-column: 1 / -1; font-weight: 600; }
  .table-wrap table.lic-inst-table td.li-url { grid-column: 1 / -1; }
  .table-wrap table.lic-inst-table td.li-actions, .table-wrap table.lic-key-table td.lk-actions { grid-column: 1 / -1; display: flex; text-align: left; }
  .table-wrap table.lic-inst-table td.li-actions:empty, .table-wrap table.lic-key-table td.lk-actions:empty { display: none; }
  .lic-inst-table td.li-actions .btn, .lic-key-table td.lk-actions .btn { flex: 1 1 auto; margin: 0; }
  .lic-table tr.edge-crit { box-shadow: inset 3px 0 0 var(--c-crit); }
  .lic-table tr.edge-warn { box-shadow: inset 3px 0 0 var(--c-warn); }
  .lic-usage-table tr { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .lic-usage-head { flex-direction: column; align-items: stretch; }
  .lic-csv .btn { flex: 1 1 auto; }
  .lic-copy-row .btn, .lic-signing-actions .btn { flex: 1 1 auto; }
}
/* Ende Lizenzverwaltung 0.85 */

/* ---------- Felder 0.86 ---------- */
/* Eigene Felder mit Typ, Bereich und Werteliste: Einstellungen, Dialoge, Auswahl an Gerät und Kunde (Strang Eigene Felder). */
/* Einstellungen: Liste der Felder; die Beschreibung bricht um, damit die Aktionen sichtbar bleiben. */
.cf-table td.cf-type, .cf-table td.cf-scope { white-space: nowrap; }
.cf-table td.cf-desc { white-space: normal; min-width: 160px; overflow-wrap: anywhere; }
/* Dialog: Felder in zwei Spalten, Werteliste mit Eingabe in einer Zeile, Auswahl der zu übernehmenden Werte. */
.cf-form { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.cf-new-options { width: 100%; resize: vertical; }
.cf-options td.cf-opt-label { white-space: normal; overflow-wrap: anywhere; }
.cf-options td.cf-opt-label .pill { margin-left: 6px; }
.cf-options td.cf-opt-label input { width: 100%; min-width: 160px; }
.cf-options tr.cf-inactive td.cf-opt-label { color: var(--c-muted); }
.cf-options td.cf-opt-usage { white-space: normal; }
.cf-add-row { display: flex; flex-wrap: wrap; gap: var(--sp-2); align-items: center; margin-top: var(--sp-3); }
.cf-add-row input { flex: 1 1 220px; max-width: 360px; }
.cf-adopt-list { display: flex; flex-direction: column; gap: 6px; max-height: 280px; overflow-y: auto; padding: 2px; }
.cf-adopt { display: flex; align-items: baseline; gap: 10px; cursor: pointer; }
.cf-adopt input { flex: none; width: 16px; height: 16px; transform: translateY(2px); }
.cf-adopt-label { font-weight: 600; overflow-wrap: anywhere; }
.cf-adopt-count { font-size: var(--fs-small); }
.cf-merge-pick { display: flex; flex-wrap: wrap; gap: var(--sp-2); align-items: center; margin-top: 10px; }
.cf-merge-pick select { flex: 1 1 180px; max-width: 260px; }
/* Gerät und Kunde: Wert des Kunden mit Pille, Hinweis bei Altwerten unter dem Feld. */
.cf-value-ro { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; }
.cf-legacy-note { display: block; margin-top: 4px; font-size: var(--fs-label); line-height: 1.4; color: var(--c-warn-ink); }
.cf-device-fields select, .cf-customer-fields select { width: 100%; }
.cf-legacy-pill { margin-left: 6px; }

@media (max-width: 640px) {
  .cf-form { grid-template-columns: minmax(0, 1fr); }
  /* Liste der Felder und Werteliste als Karten: oben Name, darunter die Angaben, unten die Aktionen. */
  .cf-table thead, .cf-options thead { display: none; }
  .cf-table, .cf-table tbody, .cf-options, .cf-options tbody { display: block; }
  .cf-table tr, .cf-options tr { display: block; padding: 10px 12px; border-top: 1px solid var(--c-border-soft); }
  .cf-table tr:first-child, .cf-options tr:first-child { border-top: 0; }
  .cf-table td, .cf-options td { display: block; padding: 0; border: 0; min-width: 0; white-space: normal; text-align: left; }
  .cf-table td + td, .cf-options td + td { margin-top: 2px; }
  .cf-table td.cf-type, .cf-table td.cf-scope, .cf-table td.cf-desc, .cf-options td.cf-opt-usage { font-size: var(--fs-small); }
  .cf-table td[data-label]::before, .cf-options td[data-label]::before { content: attr(data-label) " "; color: var(--c-muted); }
  .cf-table td.row-actions, .cf-options td.row-actions { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
  .cf-table td.row-actions .btn, .cf-options td.row-actions .btn { margin: 0; flex: 1 1 auto; }
  .cf-add-row input { max-width: none; }
  .cf-add-row .btn, .cf-merge-pick select { flex: 1 1 100%; max-width: none; }
  /* Felder an Gerät und Kunde: Name über dem Wert, freie Zeilen mit Entfernen darunter. */
  .cf-device-fields thead, .cf-customer-fields thead { display: none; }
  .cf-device-fields, .cf-device-fields tbody, .cf-customer-fields, .cf-customer-fields tbody { display: block; width: 100%; }
  .cf-device-fields tr, .cf-customer-fields tr { display: block; padding: 10px 0; border-top: 1px solid var(--c-border-soft); }
  .cf-device-fields tr:first-child, .cf-customer-fields tr:first-child { border-top: 0; }
  .table-wrap .cf-customer-fields tr { padding: 10px 12px; }
  .cf-device-fields td, .cf-customer-fields td { display: block; padding: 0; border: 0; min-width: 0; }
  .cf-device-fields td + td, .cf-customer-fields td + td { margin-top: 6px; }
  .cf-device-fields td:empty, .cf-customer-fields td:empty { display: none; }
  .cf-device-fields td.row-actions, .cf-customer-fields td.row-actions { text-align: left; }
}
/* Ende Felder 0.86 */

/* ---------- Symbole 0.86 ---------- */
/* Zeilenaktionen der Dienste und VMs als Symbole mit Hinweis (IconButton mit ActionIcon; bewusste Ausnahme zu D52). Feste quadratische
   Fläche: 28 px am Schreibtisch, auf Touch-Geräten 40 px. Den Hinweis zeichnet app.js aus data-tip in der Blase der Erklärungen.
   Gesperrte Aktionen tragen aria-disabled statt disabled, damit Fokus, Hinweis und Toast mit dem Grund bleiben; sie sehen aus wie
   .btn:disabled. Gedrückt (aria-pressed) bzw. eingeschaltet (is-on) steht der Knopf in der Akzentfarbe. */
.icon-row { display: inline-flex; flex-wrap: nowrap; align-items: center; gap: 4px; vertical-align: middle; }
.btn.icon-btn {
  position: relative;
  flex-direction: column;
  gap: 2px;
  width: var(--control-h-sm);
  min-width: var(--control-h-sm);
  height: var(--control-h-sm);
  min-height: var(--control-h-sm);
  padding: 0;
  color: var(--c-text);
}
.row-actions .icon-row .btn.icon-btn + .btn.icon-btn { margin-left: 0; }
.btn.icon-btn .action-icon { flex: 0 0 auto; width: 18px; height: 18px; }
.btn.icon-btn .icon-btn-text { display: none; }
.btn.icon-btn[aria-pressed="true"], .btn.icon-btn.is-on {
  color: var(--c-accent-ink);
  border-color: var(--c-accent-line);
  background: color-mix(in srgb, var(--c-accent-fill) 12%, transparent);
}
.btn.icon-btn[aria-disabled="true"] { opacity: .45; cursor: not-allowed; }
.btn.icon-btn[aria-disabled="true"]:hover { background: transparent; border-color: var(--c-border); }
.btn.icon-btn[aria-pressed="true"][aria-disabled="true"]:hover, .btn.icon-btn.is-on[aria-disabled="true"]:hover {
  background: color-mix(in srgb, var(--c-accent-fill) 12%, transparent);
  border-color: var(--c-accent-line);
}
/* Arbeitet: Kringel der Ladeknöpfe mittig statt des Symbols, die Fläche bleibt gleich groß. */
.btn.icon-btn.is-busy { opacity: 1; cursor: progress; }
.btn.icon-btn.is-busy::before { position: absolute; top: 50%; left: 50%; width: 12px; height: 12px; margin: -6px 0 0 -6px; }
.btn.icon-btn.is-busy .action-icon { visibility: hidden; }
@media (pointer: coarse) {
  .btn.icon-btn { width: 40px; min-width: 40px; height: 40px; min-height: 40px; }
  .icon-row { gap: 6px; }
}

/* Dienste: Die Spalte der Aktionen ist so schmal wie die Symbolreihe; der Starttyp darf umbrechen („Automatisch (verzögert)“), damit
   die Symbole auch neben der Navigation öfter ohne seitliches Scrollen sichtbar bleiben. */
.services-table td.svc-act { width: 1%; white-space: nowrap; }
.services-table td.svc-mode { white-space: normal; }
.svc-stop-hold { margin-top: var(--sp-2); }

/* VMs: Die Symbole stehen nebeneinander statt der untereinander gestapelten Textknöpfe (schlägt die Regel der Liste). */
td.vm-act .icon-row .btn.icon-btn { display: inline-flex; width: var(--control-h-sm); margin: 0; }
@media (pointer: coarse) {
  td.vm-act .icon-row .btn.icon-btn { width: 40px; }
}

@media (max-width: 640px) {
  /* Telefon: jeder Dienst als Karte wie bei den VMs. Name und Zustand oben, Starttyp und PID darunter, das Konto klein, die Symbole
     in voller Breite mit kurzem Text darunter (kein Überfahren, der Text ersetzt den Hinweis). */
  .services-table thead { display: none; }
  .services-table, .services-table tbody { display: block; }
  .services-table tr {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas: "name state" "mode pid" "account account" "act act";
    align-items: start;
    gap: 4px var(--sp-2);
    padding: 12px var(--sp-3);
    border-bottom: 1px solid var(--c-border-soft);
  }
  .services-table tbody tr:last-child { border-bottom: 0; }
  .table-wrap table.services-table td { display: block; padding: 0; border: 0; min-width: 0; white-space: normal; box-shadow: none; }
  .services-table tr.monitored { box-shadow: inset 3px 0 0 var(--c-accent-line); }
  .services-table td.svc-name { grid-area: name; overflow-wrap: anywhere; }
  .services-table td.svc-state { grid-area: state; text-align: right; }
  .services-table td.svc-mode { grid-area: mode; font-size: var(--fs-small); }
  .services-table td.svc-pid { grid-area: pid; font-size: var(--fs-small); text-align: right; }
  .services-table td.svc-account { grid-area: account; font-size: var(--fs-small); }
  .services-table td.svc-mode::before, .services-table td.svc-pid::before, .services-table td.svc-account::before {
    content: attr(data-label); display: block; font-size: var(--fs-label); color: var(--c-muted);
  }
  .table-wrap table.services-table td.svc-act { grid-area: act; width: auto; margin-top: 6px; text-align: left; }

  /* Symbolreihe der Dienste und VMs über die volle Breite, Knöpfe mit mindestens 40 px und dem Text unter dem Symbol; ein längerer
     Text („Überwachen“) bekommt etwas mehr Breite. */
  .services-table .icon-row, td.vm-act .icon-row { display: flex; width: 100%; gap: 5px; }
  .table-wrap td.svc-act .icon-row .btn.icon-btn, .table-wrap td.vm-act .icon-row .btn.icon-btn {
    flex: 1 1 auto;
    width: auto;
    min-width: 40px;
    height: auto;
    min-height: 52px;
    padding: 6px 3px 5px;
  }
  .btn.icon-btn .icon-btn-text {
    display: block;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    font-size: var(--fs-label);
    font-weight: 600;
    line-height: 1.15;
  }
}

/* Erzwungene Farben: Gesperrte Symbole in GrayText; gedrückte (Überwachen der Dienste) und eingeschaltete (Überwachung einer VM, is-on)
   auf Highlight wie die gedrückten Umschalter im Block „Erzwungene Farben“, die Akzentfarbe oben schlüge diese Regel sonst; gedrückt und
   gesperrt wie dort in GrayText. */
@media (forced-colors: active) {
  .btn.icon-btn[aria-disabled="true"] { opacity: 1; color: GrayText; border-color: GrayText; }
  :root button.icon-btn[aria-pressed="true"], :root button.icon-btn.is-on {
    forced-color-adjust: none;
    background: Highlight;
    color: HighlightText;
    border-color: Highlight;
  }
  :root button.icon-btn[aria-pressed="true"][aria-disabled="true"], :root button.icon-btn.is-on[aria-disabled="true"] {
    background: GrayText;
    color: Canvas;
    border-color: GrayText;
  }
}
/* Ende Symbole 0.86 */

/* ---------- Dienst-Neustart 0.86 ---------- */
/* Karte „Überwachte Dienste“ mit Neustart vor dem Alarm, Dialog der Überwachung (Strang Dienst-Neustart). */
/* Zustände nebeneinander (Zustand, laufender Versuch, gezielt gestoppt); Bei Ausfall und letzter Versuch dürfen umbrechen. */
table.svcmon-table td.svcm-state .pill + .pill { margin-left: 4px; }
table.svcmon-table td.svcm-mode { min-width: 140px; }
table.svcmon-table td.svcm-last { white-space: normal; min-width: 150px; max-width: 260px; }
table.svcmon-table td.svcm-scope { white-space: normal; min-width: 170px; max-width: 280px; }
/* Lange Fehlertexte des letzten Versuchs: zwei Zeilen, der ganze Text im Hinweis. */
table.svcmon-table .svcm-result { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden; }
table.svcmon-table td.svcm-act { width: 1%; white-space: nowrap; }
/* Kundenweite Überwachung, die auf diesem Gerät von der eigenen überdeckt wird: zurückgenommen. */
table.svcmon-table tr.shadowed td.svcm-name, table.svcmon-table tr.shadowed td.svcm-mode { color: var(--c-muted); }
.svcmon-choice { margin-top: var(--sp-3); }
.svcmon-choice select { max-width: 100%; }
.svcmon-notice { margin-top: var(--sp-2); }

@media (max-width: 640px) {
  /* Telefon: jede Überwachung als Karte. Dienst und Zustand oben, Bei Ausfall und letzter Versuch darunter, Geltung und Eingerichtet
     klein, die Aktionen in voller Breite. */
  .svcmon-table thead { display: none; }
  .svcmon-table, .svcmon-table tbody { display: block; }
  .svcmon-table tr {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas: "name state" "mode mode" "last last" "scope scope" "act act";
    gap: 4px var(--sp-2);
    padding: 10px var(--sp-3);
    border-bottom: 1px solid var(--c-border-soft);
  }
  .svcmon-table tbody tr:last-child { border-bottom: 0; }
  .svcmon-table tr.edge-crit { box-shadow: inset 3px 0 0 var(--c-crit); }
  .table-wrap table.svcmon-table td { display: block; padding: 0; border: 0; min-width: 0; max-width: none; white-space: normal; }
  .svcmon-table .svcm-name { grid-area: name; }
  .svcmon-table .svcm-state { grid-area: state; text-align: right; }
  .svcmon-table td.svcm-state .pill { margin: 0 0 2px 4px; }
  .svcmon-table .svcm-mode { grid-area: mode; font-size: var(--fs-small); }
  .svcmon-table .svcm-last { grid-area: last; font-size: var(--fs-small); }
  .svcmon-table .svcm-scope { grid-area: scope; font-size: var(--fs-small); }
  .svcmon-table td.svcm-mode::before, .svcmon-table td.svcm-last::before, .svcmon-table td.svcm-scope::before {
    content: attr(data-label) " "; color: var(--c-muted);
  }
  .svcmon-table td.svcm-mode .cell-sub { display: inline; margin-left: 4px; }
  .table-wrap table.svcmon-table td.svcm-act { grid-area: act; display: flex; gap: 6px; width: auto; margin-top: 4px; text-align: left; }
  .table-wrap table.svcmon-table td.svcm-act .btn { flex: 1 1 auto; margin: 0; min-height: 40px; }
  .svcmon-table td.svcm-act:empty { display: none; }
}
/* Ende Dienst-Neustart 0.86 */

/* ---------- Deinstallation 0.86 ---------- */
/* Dialoge zum Deinstallieren und Löschen, Hinweise zu Windows-Update-Einstellungen und Funktionsupdates (Strang Deinstallation am Server). */
.exit-restore { margin: var(--sp-2) 0; color: var(--c-muted); font-size: var(--fs-small); line-height: 1.45; }
.exit-option { margin: var(--sp-3) 0 var(--sp-2); padding: var(--sp-2) var(--sp-3); border: 1px solid var(--c-border-soft); border-radius: var(--radius-sm); background: var(--c-elev); }
.exit-option .switch { align-items: flex-start; }
.exit-option .switch input { flex: none; margin-top: 2px; }
.exit-option .switch.is-disabled { cursor: not-allowed; color: var(--c-muted); }
.exit-option-note { margin: var(--sp-1) 0 0 28px; color: var(--c-muted); font-size: var(--fs-small); line-height: 1.4; }
.exit-points { margin-top: var(--sp-2); }
.select-col input.feature-locked { cursor: not-allowed; opacity: .45; }
.feature-hint { max-width: 72ch; }
.agent-changes dl.kv { grid-template-columns: 170px minmax(0, 1fr); }
.agent-changes .hint { margin-bottom: 0; }
@media (max-width: 640px) {
  .exit-option { padding: var(--sp-2); }
  .exit-option-note { margin-left: 0; }
  .agent-changes dl.kv { grid-template-columns: minmax(0, 1fr); gap: 2px 0; }
  .agent-changes dl.kv dd { margin-bottom: var(--sp-2); }
}
/* Ende Deinstallation 0.86 */

/* ---------- Funktionsupdates 0.87 ---------- */
/* Reiter „Funktionsupdates“ im Patchmanagement, Karte „Windows-Version“ am Gerät, Dialoge und Bestätigung beim Einschalten (Strang Funktionsupdates in Oberfläche und REST). */
/* Kennzahlen als Filter wie bei den Freigaben, vier gleich breite Kacheln. */
.fu-kpis { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.fu-kpis .stat-card { display: flex; flex-direction: column; align-items: flex-start; text-align: left; font: inherit; color: inherit; cursor: pointer; }
.fu-kpis .stat-card:hover { border-color: var(--c-border); }
.fu-kpis .stat-card.active { border-color: var(--c-accent-line); box-shadow: 0 0 0 1px var(--c-accent-line) inset; }
.fu-kpis .stat-card.active.edge-crit { box-shadow: inset 3px 0 0 var(--c-crit), 0 0 0 1px var(--c-accent-line) inset; }
.fu-kpis .stat-card.active.edge-warn { box-shadow: inset 3px 0 0 var(--c-warn), 0 0 0 1px var(--c-accent-line) inset; }
.fu-kpis .stat-card.active.edge-info { box-shadow: inset 3px 0 0 var(--c-info), 0 0 0 1px var(--c-accent-line) inset; }
.fu-panel > .card { margin-bottom: var(--sp-4); }
.fu-panel .card-head-row .search { max-width: 260px; }
/* Freigaben je Zielversion: Aktionen nebeneinander, der letzte Fehlschlag in Kritisch. */
.fu-release-table td.fu-rel-name { min-width: 200px; }
.fu-release-table td.fu-rel-state { min-width: 170px; max-width: 320px; }
.fu-release-table .fu-rel-failure { color: var(--c-crit-ink); }
.fu-release-table td.fu-rel-actions { white-space: nowrap; }
.fu-release-facts { margin-bottom: var(--sp-3); }
/* Kunden: schmaler gestapelter Balken der Versionen (2 px Abstand zwischen den Abschnitten, runde Enden) mit Legende darunter. */
.fu-customer-table td.fu-cu-name { min-width: 170px; }
.fu-customer-table td.fu-cu-dist { min-width: 240px; width: 34%; }
.fu-customer-table td.fu-cu-open, .fu-customer-table td.fu-cu-noteligible, .fu-customer-table td.fu-cu-failed { font-variant-numeric: tabular-nums; }
.fu-customer-table tr.is-context > td:first-child { box-shadow: inset 3px 0 0 var(--c-accent-line); }
.fu-customer-table tr.is-context.edge-crit > td:first-child { box-shadow: inset 3px 0 0 var(--c-crit); }
.fu-bar { display: flex; gap: 2px; height: 8px; min-width: 120px; border-radius: 4px; overflow: hidden; background: var(--c-surface); }
.fu-seg { display: block; height: 100%; min-width: 3px; }
.fu-seg:first-child { border-radius: 4px 0 0 4px; }
.fu-seg:last-child { border-radius: 0 4px 4px 0; }
.fu-seg:only-child { border-radius: 4px; }
.fu-tone-supported { background: var(--c-series-1); }
.fu-tone-ending { background: var(--c-warn); }
.fu-tone-unsupported { background: var(--c-crit); }
.fu-tone-unknown { background: var(--c-border-strong); }
.fu-legend { display: flex; flex-wrap: wrap; gap: 2px var(--sp-3); margin: 6px 0 0; padding: 0; list-style: none; font-size: var(--fs-label); color: var(--c-muted); }
.fu-legend li { display: inline-flex; align-items: center; gap: 5px; white-space: nowrap; }
.fu-legend strong { color: var(--c-text); font-weight: 600; font-variant-numeric: tabular-nums; }
.fu-swatch { display: inline-block; flex: 0 0 auto; width: 8px; height: 8px; border-radius: 2px; }
/* Geräte im Dialog: Filter über der Tabelle, Zustand mit Grund, Aktionen rechts. */
.fu-devices-lead { margin: 0 0 var(--sp-2); }
.fu-devices-toolbar select { width: auto; max-width: 100%; }
.fu-device-table td.fu-dev-state { min-width: 170px; max-width: 300px; }
.fu-device-table td.fu-dev-end .pill { margin-left: 6px; }
.fu-device-table td.fu-dev-actions { white-space: nowrap; }
/* Dialoge „Zielversion ändern“ und „Jetzt anstoßen“. */
.fu-target-form { margin-bottom: var(--sp-2); }
.fu-win11-switch { margin-top: var(--sp-1); }
/* Herkunft des Schalters unter ihm, „Wieder erben“ als Link daneben (wie die Herkunft in den Richtlinien). */
.fu-win11-origin { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px var(--sp-2); margin-top: 4px; font-size: var(--fs-label); color: var(--c-muted); overflow-wrap: anywhere; }
.fu-target-facts { margin: var(--sp-3) 0; }
.fu-target-summary { margin: 0 0 var(--sp-2); }
.fu-preview-table td.fu-pv-after { min-width: 200px; }
.fu-preview-table td.fu-pv-after .pill { white-space: normal; }
.fu-trigger-points li { line-height: 1.45; }
/* Karte „Windows-Version“ oben im Reiter Updates: zwei Spalten, darunter die Eignung für Windows 11 und die Aktion. */
.fu-version-card { margin-bottom: var(--sp-4); }
.fu-version-card .card-head-row .pill { font-size: var(--fs-label); }
.fu-version-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-2) var(--sp-6); }
.fu-version-grid dl.kv { grid-template-columns: 172px minmax(0, 1fr); align-content: start; }
.fu-version-grid dl.kv dd .pill { margin-left: 6px; }
.fu-run-error { color: var(--c-crit-ink); }
.fu-win11 { margin-top: var(--sp-3); padding-top: var(--sp-3); border-top: 1px solid var(--c-border-soft); }
.fu-win11-head { display: flex; align-items: center; gap: var(--sp-2); margin-bottom: var(--sp-2); }
.fu-win11-title { font-weight: 600; }
.fu-criteria { display: flex; flex-wrap: wrap; gap: 4px var(--sp-4); margin: 0; padding: 0; list-style: none; font-size: var(--fs-small); }
.fu-criteria li { display: inline-block; }
.fu-criteria .fu-crit-label { font-weight: 600; }
.fu-criteria li.met .fu-crit-mark { color: var(--c-ok-ink); }
.fu-criteria li.unmet .fu-crit-mark { color: var(--c-crit-ink); }
.fu-criteria li.unknown .fu-crit-mark { color: var(--c-muted); }
.fu-version-actions { display: flex; align-items: center; flex-wrap: wrap; gap: var(--sp-2) var(--sp-3); margin-top: var(--sp-3); padding-top: var(--sp-3); border-top: 1px solid var(--c-border-soft); }
.fu-version-actions .muted { font-size: var(--fs-small); }
/* Reiter Updates und Freigaben: Pille „Eigener Lauf“ und „Zielversion“ unter dem Titel. */
.fu-own-run, .fu-approval-pill { margin-top: 4px; }
.fu-approval-hint { margin-top: var(--sp-2); }
/* Freigaben der Windows-Updates: sechs Kennzahlen mit „Über Zielversion gesteuert“ (eine Reihe, mittelbreit 3 + 3, Telefon 2 + 2 + 2), der Link
   zum Reiter „Funktionsupdates“ unter dem Stand. */
.approval-filter.fu-approval-states { grid-template-columns: repeat(6, minmax(0, 1fr)); }
.fu-approval-link { display: block; margin-top: 2px; font-size: var(--fs-small); }
/* Erzwungene Farben: Balken und Legende behalten ihre Farben, die Legende nennt Version, Zahl und Zustand ohnehin als Text. */
@media (forced-colors: active) {
  .fu-bar, .fu-swatch { forced-color-adjust: none; }
}
@media (max-width: 1180px) {
  .approval-filter.fu-approval-states { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (max-width: 900px) {
  .fu-kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .fu-version-grid { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 640px) {
  /* Telefon: Kennzahlen zweispaltig, Tabellen als Karten mit beschrifteten Werten, der Balken bleibt in voller Breite. */
  .approval-filter.fu-approval-states { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .fu-panel .card-head-row .search { max-width: none; width: 100%; }
  .fu-release-table thead, .fu-customer-table thead, .fu-device-table thead, .fu-preview-table thead, .fu-trigger-table thead { display: none; }
  .fu-release-table, .fu-release-table tbody, .fu-customer-table, .fu-customer-table tbody, .fu-device-table, .fu-device-table tbody,
  .fu-preview-table, .fu-preview-table tbody, .fu-trigger-table, .fu-trigger-table tbody { display: block; }
  .fu-release-table tr, .fu-customer-table tr, .fu-device-table tr, .fu-preview-table tr, .fu-trigger-table tr {
    display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: start; gap: 4px var(--sp-2);
    padding: 10px var(--sp-3); border-bottom: 1px solid var(--c-border-soft);
  }
  .fu-release-table tbody tr:last-child, .fu-customer-table tbody tr:last-child, .fu-device-table tbody tr:last-child,
  .fu-preview-table tbody tr:last-child, .fu-trigger-table tbody tr:last-child { border-bottom: 0; }
  .table-wrap table.fu-release-table td, .table-wrap table.fu-customer-table td, .table-wrap table.fu-device-table td,
  .table-wrap table.fu-preview-table td, .table-wrap table.fu-trigger-table td {
    display: block; padding: 0; border: 0; min-width: 0; max-width: none; width: auto; white-space: normal; text-align: left; box-shadow: none;
  }
  .fu-release-table td[data-label]::before, .fu-customer-table td[data-label]::before, .fu-device-table td[data-label]::before,
  .fu-preview-table td[data-label]::before, .fu-trigger-table td[data-label]::before { content: attr(data-label) " "; color: var(--c-muted); }
  .fu-release-table td.fu-rel-name::before, .fu-customer-table td.fu-cu-name::before, .fu-customer-table td.fu-cu-dist::before,
  .fu-device-table td.fu-dev-name::before, .fu-preview-table td.fu-pv-name::before, .fu-trigger-table td.fu-tr-name::before { content: none; }
  .fu-release-table td, .fu-customer-table td, .fu-device-table td, .fu-preview-table td, .fu-trigger-table td { grid-column: 1 / -1; font-size: var(--fs-small); }
  .fu-release-table td.fu-rel-name, .fu-customer-table td.fu-cu-name, .fu-device-table td.fu-dev-name { grid-column: 1; grid-row: 1; font-size: var(--fs-body); }
  .fu-customer-table td.fu-cu-failed { grid-column: 2; grid-row: 1; text-align: right; }
  .table-wrap table.fu-customer-table td.fu-cu-failed.fu-none { visibility: hidden; }
  .fu-customer-table td.fu-cu-failed::before, .fu-device-table td.fu-dev-state::before { content: none; }
  .fu-device-table td.fu-dev-state .cell-sub { white-space: normal; }
  .fu-customer-table td.fu-cu-open, .fu-customer-table td.fu-cu-noteligible, .fu-customer-table td.fu-cu-target, .fu-customer-table td.fu-cu-win11 { grid-column: auto; }
  .fu-customer-table td.fu-cu-dist { margin: 2px 0; }
  .table-wrap table.fu-release-table td.fu-rel-actions, .table-wrap table.fu-customer-table td.fu-cu-actions, .table-wrap table.fu-device-table td.fu-dev-actions {
    grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: 6px; margin-top: 4px;
  }
  .table-wrap table.fu-release-table td.fu-rel-actions:empty, .table-wrap table.fu-device-table td.fu-dev-actions:empty { display: none; }
  .fu-release-table td.fu-rel-actions .btn, .fu-customer-table td.fu-cu-actions .btn, .fu-device-table td.fu-dev-actions .btn { flex: 1 1 auto; margin: 0; }
  .fu-release-table tr.edge-crit, .fu-customer-table tr.edge-crit, .fu-device-table tr.edge-crit { box-shadow: inset 3px 0 0 var(--c-crit); }
  .fu-device-table tr.edge-warn { box-shadow: inset 3px 0 0 var(--c-warn); }
  .fu-customer-table tr.selected { background: var(--c-selected); }
  .table-wrap table.fu-customer-table tr.selected td { background: none; }
  .fu-customer-table tr.is-context { box-shadow: inset 3px 0 0 var(--c-accent-line); }
  .fu-customer-table tr.is-context.edge-crit { box-shadow: inset 3px 0 0 var(--c-crit); }
  .fu-customer-table tr > td:first-child, .fu-release-table tr > td:first-child, .fu-device-table tr > td:first-child,
  .fu-customer-table tr.is-context > td:first-child, .fu-customer-table tr.is-context.edge-crit > td:first-child { box-shadow: none; }
  .fu-version-grid dl.kv { grid-template-columns: minmax(0, 1fr); gap: 2px 0; }
  .fu-version-grid dl.kv dd { margin-bottom: var(--sp-2); }
  .fu-version-actions .btn { width: 100%; }
}
/* Ende Funktionsupdates 0.87 */

/* ---------- Lizenz-Instanz 0.87 ---------- */
/* Schritt „Signaturschlüssel“ der Ersteinrichtung, Grundlage „Lizenz-Instanz“ auf den Karten Lizenz und Signaturschlüssel (Strang Lizenz bei der Installation). */
.setup-signing-expected { margin: 0 0 var(--sp-3); padding: var(--sp-2) var(--sp-3); border: 1px solid var(--c-border-soft); border-radius: var(--radius-sm); background: var(--c-accent-wash); }
.setup-signing-label { display: block; font-size: var(--fs-label); color: var(--c-muted); margin-bottom: var(--sp-1); }
.setup-signing-keys { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--sp-1); }
.setup-signing-keys li { overflow-wrap: anywhere; letter-spacing: .02em; }
.setup-step > p.setup-signing-other { margin-top: var(--sp-4); }
.setup-signing-form input[type="file"] { cursor: pointer; }
.setup-signing-form input[type="file"]::file-selector-button {
  font: inherit; font-size: var(--fs-small); color: var(--c-text); background: var(--c-elev); border: 1px solid var(--c-border);
  border-radius: var(--radius-sm); padding: 3px 10px; margin-right: var(--sp-2); cursor: pointer;
}
.setup-signing-form input[type="file"]::file-selector-button:hover { background: var(--c-hover); }
.license-authority-key { margin-right: var(--sp-2); overflow-wrap: anywhere; }
.license-authority-pill, .lic-proves { margin-left: var(--sp-1); }
@media (max-width: 600px) {
  .license-authority-pill, .lic-proves { margin-left: 0; margin-top: var(--sp-1); }
  .license-authority-key { display: block; margin-right: 0; }
}
/* Ende Lizenz-Instanz 0.87 */

/* ---------- Proxy 0.87 ---------- */
/* Zustandszeile im Bereich „Reverse-Proxy“ der Einstellungen (Strang Doku und vertrauenswürdige Proxys). */
.proxy-status-list { list-style: none; margin: var(--sp-2) 0 0; padding: 0; display: grid; gap: 6px; font-size: var(--fs-small); line-height: 1.45; }
.proxy-status-list li { display: grid; grid-template-columns: 110px minmax(0, 1fr) auto; gap: 2px var(--sp-3); align-items: baseline; }
.proxy-status-key { color: var(--c-muted); font-size: var(--fs-label); }
.proxy-status-text { min-width: 0; overflow-wrap: anywhere; }
.proxy-status-text .mono { font-size: var(--fs-small); }
.proxy-status-text.muted, .proxy-status-text .muted { color: var(--c-muted); }
.proxy-status-list li.is-warn .proxy-status-key { color: var(--c-warn-ink); font-weight: 600; }
.proxy-status-action, .proxy-status-note { justify-self: end; white-space: nowrap; font-size: var(--fs-small); }
.proxy-status-note { color: var(--c-muted); }
.proxy-status-action.linklike, .proxy-status-action.linklike:hover { color: var(--c-accent-ink); }
@media (max-width: 640px) {
  .proxy-status-list { gap: var(--sp-2); }
  .proxy-status-list li { grid-template-columns: minmax(0, 1fr); gap: 2px; }
  .proxy-status-action, .proxy-status-note { justify-self: start; min-height: 40px; display: inline-flex; align-items: center; }
}
/* Ende Proxy 0.87 */

/* ---------- Schlanke Lizenz-Instanz 0.87 ---------- */
/* Navigation, Übersicht, Lizenzen und Lizenznehmer der schlanken Lizenz-Instanz (D189, Strang B). */
/* Navigation (Layout/AuthorityNav.razor): die Gruppe „Lizenzverwaltung“ klappt ein wie die Gruppen des RMM. */
html[data-nav-collapsed~="licensing"] [data-nav-items="licensing"] { display: none; }
html[data-nav-collapsed~="licensing"] [data-nav-group="licensing"]::after { transform: rotate(-90deg); }
/* Übersicht (Shared/LicenseOverview.razor): Kacheln wie das Dashboard, Listen mit Lizenznehmer und Grund in zwei Zeilen. */
.lo-first-steps .card-head-row { margin-bottom: var(--sp-2); }
.lo-steps { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 6px var(--sp-5); }
.lo-steps li { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); min-width: 0; padding: 6px 0; border-bottom: 1px solid var(--c-border-soft); }
.lo-steps li > :first-child { min-width: 0; overflow-wrap: anywhere; }
.lo-steps li > .pill { flex-shrink: 0; }
.lo-steps li.is-done > :first-child { color: var(--c-muted); }
.lo-need { align-items: flex-start; }
.lo-need-main { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.lo-need-who { font-weight: 600; overflow-wrap: anywhere; }
.lo-need-who .mono { font-weight: 400; font-size: var(--fs-small); margin-left: 4px; }
.lo-need > .pill, .lo-need > .lo-date { flex-shrink: 0; margin-top: 2px; }
.lo-date { font-variant-numeric: tabular-nums; white-space: nowrap; }
.lo-more { display: inline-block; margin-top: var(--sp-2); font-size: var(--fs-small); font-weight: 600; }
.lo-hints { margin-top: var(--sp-3); border-top: 1px solid var(--c-border-soft); padding-top: var(--sp-2); }
.lo-hints > summary { cursor: pointer; font-size: var(--fs-small); color: var(--c-muted); padding: 4px 0; }
.lo-hints[open] > summary { margin-bottom: var(--sp-2); }
.lo-sub { margin: var(--sp-3) 0 var(--sp-2); font-size: var(--fs-small); font-weight: 600; color: var(--c-muted); }
.lo-versions > h2 + .lo-sub { margin-top: 0; }
.lo-versions .need-row .pill { margin-left: 6px; }
.lo-event-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.lo-event-list li { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--sp-3); min-width: 0; }
.lo-event-what { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 6px; min-width: 0; }
.lo-event-what .mono { font-size: var(--fs-small); overflow-wrap: anywhere; }
.lo-event-what .cell-sub { flex-basis: 100%; overflow-wrap: anywhere; }
.lo-event-list li.is-failed .lo-event-action { color: var(--c-crit-ink); }
.lo-event-when { flex-shrink: 0; font-size: var(--fs-small); white-space: nowrap; }
.lo-signing dl.kv { margin-bottom: var(--sp-3); }
.lo-key-id, .lo-url { overflow-wrap: anywhere; }
.lo-signing-text { margin: 0 0 var(--sp-3); font-size: var(--fs-small); }
.lo-signing-links { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin-top: auto; }
/* Verlauf der Geräte je Monat (Shared/LicensePortfolioChart.razor): Balken im SVG, Beschriftungen als Text daneben. */
.lpc { margin: 0; }
.lpc-plot { position: relative; height: 170px; margin-left: 44px; }
.lpc-ticks { position: absolute; inset: 0 auto 0 -44px; width: 38px; }
.lpc-tick { position: absolute; right: 0; transform: translateY(50%); font-size: var(--fs-label); color: var(--c-muted); font-variant-numeric: tabular-nums; line-height: 1; }
.lpc-svg { display: block; width: 100%; height: 100%; overflow: visible; }
.lpc-grid { stroke: var(--c-border-soft); stroke-width: 1; }
.lpc-bar { fill: var(--c-series-2); opacity: .55; }
.lpc-bar.is-current { fill: var(--c-series-1); opacity: 1; }
.lpc-bar:hover { opacity: .85; }
.lpc-months { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); margin: 6px 0 0 44px; }
.lpc-months span { text-align: center; font-size: var(--fs-label); color: var(--c-muted); white-space: nowrap; overflow: hidden; }
.lpc-months span.is-current { color: var(--c-text); font-weight: 600; }
.lpc-caption { margin-top: var(--sp-3); font-size: var(--fs-small); color: var(--c-muted); }
.lsd-chart, .lsd-events { margin-bottom: var(--sp-3); }
/* Seite „Lizenzen“: Filter, Suche und Lizenznehmer als Chip über der Tabelle. */
.lic-tools { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); }
.lic-tools .lic-filter { width: auto; max-width: 280px; }
.lic-tools .lic-search { flex: 1 1 240px; max-width: 420px; }
.lic-licensee-chip { display: inline-flex; align-items: center; gap: 6px; padding: 3px 10px; font-size: var(--fs-small); }
.lic-chip-clear { color: var(--c-muted); }
.lic-new-licensee { font-size: inherit; }
.lic-assign-rename { margin-top: var(--sp-3); align-items: flex-start; }
.lic-assign-rename input { margin-top: 2px; flex-shrink: 0; }
/* Lizenznehmer (Pages/Licensees.razor, Pages/LicenseeDetail.razor). */
.lsn-tools { margin-bottom: var(--sp-3); }
table.lsn-table td.ln-name { min-width: 180px; white-space: normal; }
table.lsn-table td.ln-name .cell-main { overflow-wrap: anywhere; }
table.lsn-table td.ln-contact { white-space: normal; min-width: 150px; }
table.lsn-table td.ln-contact .cell-sub { overflow-wrap: anywhere; }
table.lsn-table td.ln-licenses { white-space: normal; }
table.lsn-table td.ln-installations, table.lsn-table td.ln-devices { white-space: nowrap; font-variant-numeric: tabular-nums; }
table.lsn-table td.ln-seen { white-space: nowrap; }
table.lsn-table td.ln-actions { text-align: right; white-space: nowrap; }
table.lsn-table td.ln-actions .btn { margin: 2px 0 2px 4px; }
table.lsn-table tr.is-revoked td { color: var(--c-muted); }
.lsn-unassigned-title { scroll-margin-top: calc(var(--header-h) + var(--sp-3)); }
.lsd-stats .stat-value.lsd-date { font-size: 1.4rem; }
@media (max-width: 640px) {
  /* Telefon: Lizenznehmer als Karten mit beschrifteten Werten; Werkzeuge und Kennzahlen untereinander. */
  .lic-tools .lic-filter, .lic-tools .lic-search { flex: 1 1 100%; max-width: none; }
  .lo-steps { grid-template-columns: minmax(0, 1fr); }
  .lpc-plot { height: 140px; margin-left: 36px; }
  .lpc-ticks { left: -36px; width: 30px; }
  .lpc-months { margin-left: 36px; }
  .lpc-months span { overflow: visible; }
  .lpc-months span:nth-child(even):not(.is-current) { visibility: hidden; }
  .lo-signing-links .btn { flex: 1 1 auto; }
  .lsn-table thead { display: none; }
  .lsn-table, .lsn-table tbody { display: block; }
  .lsn-table tr {
    display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); align-items: start; gap: 6px var(--sp-2);
    padding: 10px var(--sp-3); border-bottom: 1px solid var(--c-border-soft);
  }
  .lsn-table tbody tr:last-child { border-bottom: 0; }
  .table-wrap table.lsn-table td { display: block; padding: 0; border: 0; min-width: 0; max-width: none; white-space: normal; text-align: left; box-shadow: none; }
  .lsn-table td[data-label]::before { content: attr(data-label); display: block; font-size: var(--fs-label); color: var(--c-muted); font-weight: 400; }
  .table-wrap table.lsn-table td.ln-name { grid-column: 1 / -1; }
  .table-wrap table.lsn-table td.ln-actions { grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: var(--sp-2); }
  .table-wrap table.lsn-table td.ln-actions:empty { display: none; }
  .lsn-table td.ln-actions .btn { flex: 1 1 auto; margin: 0; }
  .lsn-table tr.edge-crit { box-shadow: inset 3px 0 0 var(--c-crit); }
  .lsn-table tr.edge-warn { box-shadow: inset 3px 0 0 var(--c-warn); }
}
/* Ende Schlanke Lizenz-Instanz 0.87 */

/* ---------- Lagebild 0.88 ---------- */
/* Gemeinsame Bausteine der Neugestaltung: Symbole (Icon.razor), Lampen (StatusLamp.razor), Lagezeile mit Lampen und Band (Lage.razor,
   LageStat.razor, HourBand.razor, DayBand.razor), Kacheln mit Verlauf (StatTile.razor, Sparkline.razor), Zähler, Anteilsbalken und
   Listen aus Zeilen. Der Block steht am Ende und gewinnt gegen ältere Regeln gleicher Spezifität. */

/* Symbole: Größe aus dem Attribut, Farbe aus dem Text; in Schaltflächen und Menüeinträgen mit kleinem Abstand zum Wort. */
.ico { display: inline-block; flex: 0 0 auto; vertical-align: -3px; }
.btn > .ico, .nav-item > .ico, .chip-button > .ico { vertical-align: middle; }
.btn > .ico:first-child { margin-right: 2px; }

/* Lampen: Form und Farbe je Zustand, Text daneben in derselben Farbe. */
.lamp { display: inline-flex; align-items: center; gap: 6px; vertical-align: middle; line-height: 1.2; }
.lamp.ok { color: var(--c-ok-ink); }
.lamp.warn { color: var(--c-warn-ink); }
.lamp.crit { color: var(--c-crit-ink); }
.lamp.info { color: var(--c-info-ink); }
.lamp.off { color: var(--c-faint); }
.lamp-text { font-size: var(--fs-small); }
td > .lamp:only-child, .cell-main > .lamp:first-child { vertical-align: baseline; }

/* Zähler: runde Zahl, neutral grau, bei Handlungsbedarf in der Zustandsfarbe mit dunkler Schrift (wie die kleine rote Zahl am Reiter). */
.cnt {
  display: inline-block; min-width: 20px; height: 18px; padding: 0 6px; border-radius: 999px;
  font: 600 .8rem/18px var(--font-display); text-align: center; font-variant-numeric: tabular-nums;
  background: var(--c-neutral-bg); color: var(--c-text); vertical-align: middle;
}
.cnt.crit { background: var(--c-crit); color: var(--c-on-crit); }
.cnt.warn { background: var(--c-warn); color: var(--c-on-warn); }
.cnt.info { background: var(--c-info-bg); color: var(--c-info-ink); }
.cnt.ok { background: var(--c-ok-bg); color: var(--c-ok-ink); }

/* Lagezeile: links die Lampen mit Zahl, rechts das Band; eine Karte, die jede Ebene gleich eröffnet. */
.lage {
  display: grid; grid-template-columns: minmax(280px, 44%) minmax(0, 1fr); gap: 18px 28px; align-items: center;
  padding: 14px 18px; margin-bottom: var(--sp-4);
  background: var(--c-surface); border: 1px solid var(--c-border-soft); border-radius: var(--radius-lg);
}
.lage.no-band { grid-template-columns: minmax(0, 1fr); }
.lamps { display: flex; flex-wrap: wrap; gap: 6px 22px; }
.lstat { display: flex; align-items: center; gap: 9px; min-width: 0; color: var(--c-text); text-decoration: none; }
.lstat:hover { text-decoration: none; color: var(--c-text); }
.lstat > .ico { flex: 0 0 auto; }
.lstat b { display: block; font: 600 1.55rem/1 var(--font-display); }
.lstat span { display: block; font-size: var(--fs-label); color: var(--c-muted); line-height: 1.2; margin-top: 2px; }
.lstat.ok > .ico { color: var(--c-ok); }
.lstat.warn > .ico { color: var(--c-warn); }
.lstat.crit > .ico { color: var(--c-crit); }
.lstat.info > .ico { color: var(--c-info); }
.lstat.off > .ico { color: var(--c-faint); }
.lstat.crit b { color: var(--c-crit-ink); }
a.lstat:hover b { text-decoration: underline; text-decoration-color: var(--c-accent-line); text-underline-offset: 4px; }

/* Bänder: 7 Tage je Stunde (168 Zellen) in der Lagezeile, 7 Zellen in Listenzeilen. Zellen „ok“ halb durchsichtig, Ausfälle deckend. */
.band-wrap { min-width: 0; }
.band-head { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 4px 10px; margin-bottom: 6px; font-size: var(--fs-label); color: var(--c-muted); }
.band-legend { display: flex; flex-wrap: wrap; gap: 4px 12px; }
.band-legend span { white-space: nowrap; }
.band-legend i { display: inline-block; width: 9px; height: 9px; margin-right: 5px; border-radius: 2px; vertical-align: -1px; }
.band168 { display: block; width: 100%; height: 26px; border-radius: 4px; overflow: hidden; }
.band-axis { display: grid; grid-template-columns: repeat(7, 1fr); margin-top: 4px; font-size: .76rem; color: var(--c-faint); }
.band7 { display: inline-block; width: 84px; height: 10px; border-radius: 2px; overflow: hidden; vertical-align: middle; }

/* Kacheln: Beschriftung mit Symbol, Wert in der Anzeigeschrift, Richtung rechts daneben, Verlauf darunter. Vier je Reihe, zwei auf
   Tablets und Telefonen. */
.tiles { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--sp-3); margin-bottom: var(--sp-4); }
.tiles.cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.tiles.cols-5 { grid-template-columns: repeat(5, minmax(0, 1fr)); }
.tile {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 2px 10px; min-width: 0;
  padding: 12px 14px 10px; background: var(--c-surface); border: 1px solid var(--c-border-soft); border-radius: var(--radius);
  color: var(--c-text); text-decoration: none;
}
a.tile:hover { border-color: var(--c-border-strong); text-decoration: none; color: var(--c-text); }
.tile .t-label { grid-column: 1 / 3; display: flex; align-items: center; gap: 6px; font-size: var(--fs-label); color: var(--c-muted); }
.tile .t-label > .ico { color: var(--c-faint); }
.tile .t-value { font: 600 1.9rem/1.1 var(--font-display); white-space: nowrap; }
.tile .t-value small { font-size: 1rem; font-weight: 500; color: var(--c-muted); }
.tile .t-value.ok { color: var(--c-ok-ink); }
.tile .t-value.warn { color: var(--c-warn-ink); }
.tile .t-value.crit { color: var(--c-crit-ink); }
.tile .t-value.info { color: var(--c-info-ink); }
.tile .t-delta { align-self: end; font-size: var(--fs-label); color: var(--c-muted); text-align: right; }
.tile .t-delta.up { color: var(--c-ok-ink); }
.tile .t-delta.down { color: var(--c-crit-ink); }
.tile > .spark { grid-column: 1 / 3; width: 100%; height: 30px; margin-top: 4px; }
.tile > .meter { grid-column: 1 / 3; margin-top: 8px; }
.spark { display: block; }

/* Anteilsbalken: Segmente in den Zustandsfarben mit 2 px Lücke in der Flächenfarbe; die leere Spur bleibt leise. */
.meter { display: flex; gap: 2px; height: 6px; border-radius: 3px; background: var(--c-track); overflow: hidden; }
.meter > i { display: block; height: 100%; background: var(--c-accent); }
.meter > i.ok { background: var(--c-ok); }
.meter > i.warn { background: var(--c-warn); }
.meter > i.crit { background: var(--c-crit); }
.meter > i.info { background: var(--c-info); }
.meter > i.ord1 { background: var(--c-ord-1); }
.meter > i.ord2 { background: var(--c-ord-2); }
.meter > i.ord3 { background: var(--c-ord-3); }
.meter.thick { height: 12px; border-radius: 4px; }
.meter-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 2px 8px; align-items: center; font-size: var(--fs-label); }
.meter-row > .meter { grid-column: 1 / 3; }

/* Pillen mit Paketstufe (eine Farbe hell nach dunkel) und Symbol in Pillen. */
.pill.ord1 { background: var(--c-ord-1); color: var(--c-on-ord-1); }
.pill.ord2 { background: var(--c-ord-2); color: var(--c-on-ord-2); }
.pill.ord3 { background: var(--c-ord-3); color: var(--c-on-ord-3); }
.pill > .ico { vertical-align: -2px; margin-right: 2px; }

/* Listen aus Zeilen mit Symbol: Symbol links, Text, rechts Zahl oder Pfeil; jede Zeile ein Verweis. */
.ico-list { display: flex; flex-direction: column; }
.ico-list > a, .ico-list > div { display: flex; align-items: center; gap: 10px; padding: 8px 2px; border-top: 1px solid var(--c-border-soft); color: var(--c-text); text-decoration: none; }
.ico-list > a:first-child, .ico-list > div:first-child { border-top: 0; }
.ico-list > a:hover { color: var(--c-accent-ink); text-decoration: none; }
.ico-list > a > .ico, .ico-list > div > .ico { color: var(--c-muted); }
.ico-list .grow { flex: 1 1 auto; min-width: 0; }
.ico-list .cnt { margin-left: auto; }
.ico-list .cnt + .ico { margin-left: 4px; color: var(--c-faint); }
.ico-list .end { margin-left: auto; flex: 0 0 auto; color: var(--c-muted); font-size: var(--fs-label); }

/* Diagrammflächen: Text in Tokens, Raster und Achsen als Haarlinien eine Stufe von der Fläche entfernt. */
.chart { display: block; width: 100%; }
.chart text { fill: var(--c-faint); font: .76rem var(--font); }
.chart text.strong { fill: var(--c-text); font-weight: 600; }
.chart .grid-l { stroke: var(--c-grid); stroke-width: 1; }
.chart .axis { stroke: var(--c-border); stroke-width: 1; }
.lg { display: flex; flex-wrap: wrap; gap: 14px; font-size: var(--fs-label); color: var(--c-muted); }
.lg i { display: inline-block; width: 9px; height: 9px; margin-right: 5px; border-radius: 2px; vertical-align: -1px; }

/* Messuhr: Ring mit Wert, daneben Beschriftung und Verlauf. */
.gauge { display: grid; grid-template-columns: 54px minmax(0, 1fr); gap: 0 12px; align-items: center; }
.gauge > svg { width: 54px; height: 54px; }
.gauge .g-val { font: 600 1.3rem/1 var(--font-display); }
.gauge .g-label { font-size: var(--fs-label); color: var(--c-muted); }
.gauge .spark { width: 100%; height: 22px; margin-top: 3px; }
.g-row { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--sp-4); }

/* Seitentitel in der Anzeigeschrift etwas größer; Pillen im Titel in der Textschrift. */
h1 { font-size: var(--fs-title); }
h1 > .pill, h1 > .lamp { font-family: var(--font); }

@media (max-width: 1100px) {
  .lage { grid-template-columns: minmax(0, 1fr); }
  .tiles, .tiles.cols-5 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .g-row { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 640px) {
  .lamps { gap: 6px 16px; }
  .lstat b { font-size: 1.3rem; }
  .tiles, .tiles.cols-3, .tiles.cols-5 { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
  .tile { grid-template-columns: minmax(0, 1fr); }
  .tile .t-label, .tile > .spark, .tile > .meter { grid-column: 1; }
  .tile .t-value { font-size: 1.5rem; }
  .tile .t-delta { align-self: auto; text-align: left; }
  .band7 { width: 70px; }
  .g-row { grid-template-columns: minmax(0, 1fr); }
  .lage { padding: 12px 14px; }
}
/* Ende Lagebild 0.88 */

/* ---------- Schiene 0.88 ---------- */
/* Seitenleiste als Schiene (Lagebild 0.88): jeder Eintrag mit Symbol, die aktive Seite getönt mit Akzentkante, Gruppen weiter einklappbar.
   Die ganze Leiste lässt sich auf die Symbole zusammenschieben (html[data-rail="collapsed"], Knopf unten, wwwroot/js/app.js); dann tragen
   die Einträge ihren Namen als title. Auf dem Telefon (bis 900 px) kommt die Tab-Leiste unten dazu (Layout/TabBar.razor). */

.brand { gap: 10px; }
.brand-name { font-family: var(--font-display); font-size: 1.1rem; letter-spacing: .01em; }

/* Einträge: Symbol in einer festen Spalte, Text daneben, Zahl rechts. Die Einrückung unter dem Gruppenkopf entfällt, das Symbol
   gliedert. */
.nav-item { gap: 10px; min-height: 34px; padding: 5px 9px; color: var(--c-muted); }
.nav-items .nav-item { padding-left: 9px; }
.nav-item > .ico { color: inherit; flex: 0 0 auto; }
.nav-item > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nav-item:hover { color: var(--c-text); }
.nav-item.active, .nav-item.active:hover { color: var(--c-text); font-weight: 500; }
.nav-item.active::before { left: -8px; top: 7px; bottom: 7px; border-radius: 0 3px 3px 0; }
.nav-item.locked { color: var(--c-faint); }
.nav-item .badge.count, .nav-item .feature-badge { margin-left: auto; }
.nav-item .badge.count { min-width: 20px; height: 18px; padding: 0 6px; font: 600 .8rem/18px var(--font-display); color: var(--c-text); }
.nav-item .badge.count.crit { background: var(--c-crit); color: var(--c-on-crit); }
.nav-item .badge.count.warn { background: var(--c-warn); color: var(--c-on-warn); }
button.nav-group { padding-left: 9px; font-weight: 500; color: var(--c-faint); }
button.nav-group .nav-icon { display: none; }
.nav-action { display: flex; gap: 8px; justify-content: flex-start; width: calc(100% - 16px); margin: 0 8px 8px; font-weight: 500; }
.nav-action > .ico { color: var(--c-muted); }
.nav-recent-item { padding-left: 9px; }
.nav-recent-item .nav-dot { position: static; margin: 0 2px 0 4px; flex: 0 0 auto; }

/* Suche als Feld unter der Marke: Lupe, Beschriftung, Kürzel. */
.nav-search { gap: 8px; width: calc(100% - 16px); margin: 0 8px 8px; min-height: 34px; border-color: var(--c-border); background: var(--c-input); }
.nav-search > .ico { flex: 0 0 auto; color: var(--c-faint); }
.nav-search > .nav-search-label { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Knopf zum Zusammenschieben am Ende der Leiste; auf schmalen Bildschirmen ohne Sinn und deshalb verborgen. */
.rail-foot { flex: 0 0 auto; padding: 6px 8px 10px; border-top: 1px solid var(--c-border-soft); }
.rail-toggle { width: 100%; background: transparent; border: 0; font: inherit; cursor: pointer; text-align: left; }
.rail-toggle:hover { background: var(--c-hover); }

/* Zusammengeschoben: nur die Symbole, zentriert; Beschriftungen, Gruppenköpfe, Zahlen und zuletzt angesehene Geräte verschwinden,
   Alarme und Patchmanagement behalten einen Punkt in der Zustandsfarbe. Suche und „Agent installieren“ werden zu Symbolknöpfen. */
@media (min-width: 901px) {
  html[data-rail="collapsed"] .app-shell { grid-template-columns: var(--sidebar-w-collapsed) 1fr; }
  html[data-rail="collapsed"] .sidebar > .brand { padding: 0 0 0 19px; }
  html[data-rail="collapsed"] .brand-name, html[data-rail="collapsed"] .brand-logo-img.factory, html[data-rail="collapsed"] .brand-logo-img.wide { display: none; }
  html[data-rail="collapsed"] .brand-logo-img { max-width: 26px; height: 26px; }
  html[data-rail="collapsed"] .nav { padding: 0 8px 12px; }
  html[data-rail="collapsed"] button.nav-group { display: none; }
  html[data-rail="collapsed"] .nav-items .nav-item, html[data-rail="collapsed"] .nav-item { justify-content: center; padding: 0; width: 48px; height: 38px; margin: 2px 0; }
  html[data-rail="collapsed"] .nav-item > span, html[data-rail="collapsed"] .nav-item .badge.count, html[data-rail="collapsed"] .nav-item .feature-badge,
  html[data-rail="collapsed"] .nav-recent, html[data-rail="collapsed"] button.nav-group[data-nav-group="recent"],
  html[data-rail="collapsed"] .nav-search > .nav-search-label, html[data-rail="collapsed"] .nav-search > .kbd,
  html[data-rail="collapsed"] .nav-action > span { display: none; }
  html[data-rail="collapsed"] .nav-item.active::before { left: -8px; }
  html[data-rail="collapsed"] .nav-item:has(> .badge.count) { position: relative; }
  html[data-rail="collapsed"] .nav-item:has(> .badge.count)::after { content: ""; position: absolute; top: 7px; right: 9px; width: 7px; height: 7px; border-radius: 50%; background: var(--c-crit); }
  html[data-rail="collapsed"] .nav-item:has(> .badge.count.warn)::after { background: var(--c-warn); }
  html[data-rail="collapsed"] .nav-search { justify-content: center; width: 48px; margin: 0 8px 8px; padding: 0; }
  html[data-rail="collapsed"] .nav-action { justify-content: center; width: 48px; padding: 0; }
  html[data-rail="collapsed"] .rail-toggle { justify-content: center; }
  html[data-rail="collapsed"] .rail-toggle > .ico { transform: scaleX(-1); }
  html[data-rail="collapsed"] .app-header { padding-left: 20px; }
}

/* Tab-Leiste: fest am unteren Rand, fünf gleich breite Reiter; der aktive in der Akzentfarbe. Der Inhalt bekommt unten Platz. Über dem
   geöffneten Menü bleibt sie stehen, damit „Menü“ auch wieder schließt. */
.tabbar { display: none; }
@media (max-width: 900px) {
  .rail-foot { display: none; }
  .tabbar {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 202;
    display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr);
    padding: 6px 4px calc(8px + env(safe-area-inset-bottom, 0px));
    background: var(--c-chrome); border-top: 1px solid var(--c-border);
  }
  .tab-item {
    position: relative; display: flex; flex-direction: column; align-items: center; gap: 3px; padding: 4px 0; min-height: 44px;
    border-radius: var(--radius); color: var(--c-muted); font-size: .72rem; line-height: 1.1; text-decoration: none; cursor: pointer;
  }
  .tab-item:hover { text-decoration: none; color: var(--c-text); }
  .tab-item.active { color: var(--c-accent-ink); }
  .tab-item > .ico { flex: 0 0 auto; }
  .tab-item > .cnt { position: absolute; top: 0; left: calc(50% + 6px); height: 16px; line-height: 16px; min-width: 16px; padding: 0 4px; font-size: .7rem; }
  .content { padding-bottom: calc(84px + env(safe-area-inset-bottom, 0px)); }
  .toast-stack { bottom: calc(76px + env(safe-area-inset-bottom, 0px)); }
  /* Das geöffnete Menü lässt unten Platz für die Tab-Leiste. */
  .sidebar:has(> .nav-check:checked) { padding-bottom: calc(76px + env(safe-area-inset-bottom, 0px)); }
  /* Ein offener Dialog liegt über allem außer Hilfe und Toasts, Schnellansicht und Alarmdetails liegen als Blatt über der Seite
     (Korrektur 0.89): Die Tab-Leiste weicht, sonst verdeckte sie auf dem Telefon die Fußzeile mit den Schaltflächen bzw. das Ende der
     Leiste. Erkennungszeichen ist aria-modal, das genau diese drei tragen (Dialog „true“, Leisten „false“); geschlossen stehen sie nicht
     im Dokument. */
  body:has([aria-modal]) .tabbar { display: none; }
}
/* Ende Schiene 0.88 */

/* ---------- Geräteliste 0.88 ---------- */
/* Filter als Chips in einer Zeile (Bezeichnung als Vorsatz im Chip, das Auswahlfeld ohne eigenen Rahmen), Zeilen mit Lampe und
   Klassensymbol vor dem Namen, Status als Lampe mit Wort, das 7-Zellen-Band je Zeile. Gilt für jede Werkzeugleiste mit FilterSelect. */
.toolbar .filter {
  display: inline-flex; flex-direction: row; align-items: center; gap: 4px; height: var(--control-h); padding: 0 6px 0 10px;
  border: 1px solid var(--c-border); border-radius: var(--radius); background: var(--c-surface); font-size: var(--fs-small);
}
.toolbar .filter.is-set { border-color: var(--c-accent-line); background: var(--c-accent-wash); }
.toolbar .filter > .filter-label { font-size: var(--fs-small); font-weight: 400; color: var(--c-muted); margin: 0; white-space: nowrap; }
.toolbar .filter > .filter-label::after { content: ":"; }
.toolbar .filter > select { width: auto; max-width: 240px; height: auto; min-height: 0; padding: 0 2px; border: 0; background: transparent; box-shadow: none; font-weight: 500; }
.toolbar .filter > select:focus-visible { outline-offset: 0; }
.toolbar .filter.filter-search { padding: 0; border: 0; background: transparent; flex: 1 1 240px; max-width: 420px; }
.toolbar .filter.filter-search > .filter-label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
.toolbar .filter.filter-search > .search { width: 100%; max-width: none; }
.toolbar .view-tools { display: inline-flex; gap: 6px; }
.toolbar .columns-button { margin-left: auto; }

.device-table .cell-main { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }
.device-table .cell-main > .lamp > .ico { width: 15px; height: 15px; }
.device-table .cell-main > .class-ico { color: var(--c-muted); }
.device-table td.dl-status .lamp-text { font-size: inherit; }
.device-table td.dl-band { width: 96px; }
.device-table td.dl-band:empty::after { content: "-"; color: var(--c-faint); }

@media (max-width: 640px) {
  .toolbar .filter.filter-search { flex-basis: 55%; }
  .device-table tbody tr { grid-template-areas: "sel name status" "sel cust class" "sel seen band" "sel hints hints"; }
  .device-table td.dl-band { grid-area: band; justify-self: end; }
  .device-table td.dl-band:empty { display: none; }
}
/* Ende Geräteliste 0.88 */

/* ---------- Geräteseite 0.88 ---------- */
/* Lagezeile unter dem Kopf, Reiter in Gruppen mit Symbol und zweiter Zeile für die Reiter der aktiven Gruppe. */
.tabs > .tab > .ico { margin-right: 6px; vertical-align: -3px; color: var(--c-muted); }
.tabs > .tab.active > .ico { color: var(--c-accent-ink); }
.tabs.sub { margin-top: -10px; margin-bottom: var(--sp-4); padding-left: 4px; border-bottom: 0; gap: 4px; }
.tabs.sub > .tab { padding: 6px 10px; border-radius: var(--radius-sm); border-bottom: 0; font-size: var(--fs-small); background: var(--c-elev); }
.tabs.sub > .tab.active { background: var(--c-accent-tint); color: var(--c-text); }
.tabs.sub > .tab.active::after { display: none; }
@media (max-width: 640px) {
  .tabs > .tab > .ico { display: none; }
}
/* Ende Geräteseite 0.88 */

/* ---------- Einstellungen 0.88 ---------- */
/* Verzeichnis in Bereichen mit Symbol je Gruppe, Kopf der Gruppe mit Symbol und Stand, Vermerke je Zeile mit der Herkunft als Pille zuerst. */
.set-index-area { padding: 12px 10px 4px; font-size: var(--fs-label); color: var(--c-faint); list-style: none; }
.set-index-area:first-child { padding-top: 4px; }
.set-index-group { gap: 8px; }
.set-index-group > .ico { flex: 0 0 auto; color: var(--c-muted); }
.set-index-group.active > .ico { color: var(--c-accent-ink); }
.set-index-sections { padding-left: 24px; }
.set-group-title { display: flex; align-items: center; gap: 10px; }
.set-group-title > .ico { color: var(--c-muted); }
.set-group-sum { margin: 6px 0 0; font-size: var(--fs-small); color: var(--c-muted); }
.set-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 12px; }
.set-meta > .pill { font-size: .72rem; padding: 0 7px; line-height: 1.6; }
.set-meta > .pill.info { background: var(--c-neutral-bg); color: var(--c-text); }
.set-row.custom { box-shadow: none; }
.set-row.dirty { background: var(--c-accent-wash); }
@media (max-width: 900px) {
  .set-index-area { display: none; }
}
/* Mittlere Breite: Das Verzeichnis braucht für Verweise mit Symbol und Pfeil (etwa „Benachrichtigungen“) etwas mehr Platz als 188 px.
   Erst ab 901 px (Korrektur 0.89): Darunter steht das Verzeichnis als Auswahl über dem Inhalt in einer Spalte; ohne die Untergrenze
   teilte diese Regel auch das Telefon in zwei Spalten. */
@media (min-width: 901px) and (max-width: 1240px) {
  .set-layout { grid-template-columns: 208px minmax(0, 1fr); }
}
/* Ende Einstellungen 0.88 */


/* ---------- Seiten 0.88 ---------- */
/* Alarme, Kunden, Patchmanagement und die Übersicht der Lizenz-Instanz in der Sprache des Lagebilds: Lagezeile oben, Lampen statt
   Schwere-Pillen, das 7-Zellen-Band je Kunde, Kacheln mit Symbol auf der Lizenz-Instanz. */
.lage .lage-chart { min-width: 0; }
.lage .lage-chart > .chart { height: 72px; }
.alert-table td.al-sev .lamp-text { font-size: inherit; }
.co-table td.co-band { width: 100px; }
.co-table td.co-band:empty::after { content: "-"; color: var(--c-faint); }
.lo-stats .tile .t-delta { text-align: left; grid-column: 1 / 3; }
@media (max-width: 640px) {
  .co-table td.co-band { display: none; }
}
/* Ende Seiten 0.88 */

/* ---------- Aktionen 0.88 ---------- */
/* Aktionen-Dialoge der Geräte und Kunden (ActionCard): statt Kacheln zu zweit eine Liste von Zeilen mit Symbol links, Titel und
   Erklärung in der Mitte, Zustand und genau eine Schaltfläche rechts. Abschnitte als ruhige Zwischentitel, gefährliche Aktionen
   unten in einer rot getönten Gruppe mit roten Schaltflächen. Das Verzeichnis der Einstellungen bekommt Verweise mit Pfeil. */
.modal .action-grid { display: flex; flex-direction: column; gap: 0; margin: 0 0 var(--sp-4); border: 1px solid var(--c-border-soft); border-radius: var(--radius); overflow: hidden; }
.modal .action-grid > .action-card { display: grid; grid-template-columns: 34px minmax(0, 1fr) auto; gap: 2px 12px; align-items: center; padding: 10px 14px; border: 0; border-top: 1px solid var(--c-border-soft); border-radius: 0; background: var(--c-surface); }
.modal .action-grid > .action-card:first-child { border-top: 0; }
.modal .action-grid > .action-card:hover { background: var(--c-elev); }
.modal .action-grid > .action-card > .action-ico { display: grid; place-items: center; width: 34px; height: 34px; border-radius: var(--radius-sm); background: var(--c-elev); color: var(--c-muted); grid-row: 1 / span 2; }
.modal .action-grid > .action-card:hover > .action-ico { background: var(--c-hover); color: var(--c-text); }
.modal .action-grid > .action-card > .action-card-text { grid-column: 2; min-width: 0; }
.modal .action-grid > .action-card > .action-card-text:first-child { grid-column: 1 / span 2; }
.modal .action-grid > .action-card .action-title { font-weight: 500; }
.modal .action-grid > .action-card .action-desc { max-width: 60ch; }
.modal .action-grid > .action-card > .action-card-foot { grid-column: 3; display: flex; flex-direction: column; align-items: flex-end; gap: 4px; margin: 0; padding: 0; border: 0; }
.modal .action-grid > .action-card > .action-card-foot .action-state { text-align: right; max-width: 220px; }
.modal .action-grid > .action-card > .action-card-foot > .action-input, .modal .action-grid > .action-card > .action-card-foot > input.action-input, .modal .action-grid > .action-card > .action-card-foot > .switch { flex: 0 0 auto; width: 220px; max-width: 220px; }
.modal .action-grid > .action-card.is-danger > .action-ico { background: var(--c-crit-bg); color: var(--c-crit-ink); }
.modal .modal-section { margin: var(--sp-4) 0 var(--sp-2); font: 600 var(--fs-section)/1.3 var(--font-display); color: var(--c-text); }
.modal .modal-section:first-child { margin-top: 0; }
.modal .danger-zone { margin-top: var(--sp-5); padding: var(--sp-3) var(--sp-3) var(--sp-2); border: 1px solid color-mix(in srgb, var(--c-crit) 35%, var(--c-border)); border-radius: var(--radius); background: color-mix(in srgb, var(--c-crit-bg) 45%, var(--c-surface)); }
.modal .danger-zone .danger-zone-title { margin: 0 0 var(--sp-2); font: 600 var(--fs-section)/1.3 var(--font-display); color: var(--c-crit-ink); }
.modal .danger-zone .action-grid { margin-bottom: 0; border-color: color-mix(in srgb, var(--c-crit) 25%, var(--c-border-soft)); }
.modal .danger-zone .action-grid > .action-card { background: transparent; border-top-color: color-mix(in srgb, var(--c-crit) 25%, var(--c-border-soft)); }
.modal .danger-zone .action-grid > .action-card:hover { background: color-mix(in srgb, var(--c-crit) 8%, transparent); }
.set-index-link { color: var(--c-muted); text-decoration: none; }
.set-index-link:hover { color: var(--c-text); text-decoration: none; }
.set-index-link > .set-index-name { hyphens: auto; }
.set-index-link > .set-index-go { margin-left: auto; color: var(--c-faint); }
.set-index-link > .set-index-go { flex: 0 0 auto; }
@media (max-width: 640px) {
  .modal .action-grid > .action-card { grid-template-columns: 34px minmax(0, 1fr); }
  .modal .action-grid > .action-card > .action-card-foot { grid-column: 2; align-items: stretch; }
  .modal .action-grid > .action-card > .action-card-foot .action-state { text-align: left; max-width: none; }
  .modal .action-grid > .action-card > .action-card-foot .btn, .modal .action-grid > .action-card > .action-card-foot > .action-input, .modal .action-grid > .action-card > .action-card-foot > .switch { width: 100%; max-width: none; }
}
/* Ende Aktionen 0.88 */

/* ---------- Wandanzeige 0.89 ---------- */
/* Wandanzeige (0.89, Strang A): eigenes Dokument unter /wall für Fernseher und Monitore, Verwaltung unter /wall-displays. */
/* Dokument: Die Schrift wächst mit der Breite, damit ein Fernseher aus einigen Metern lesbar bleibt (rund 16 px bei 1920 Pixeln Breite;
   bis 0.91.1 rund 20 px, dann passten Checks und Befunde nicht in die Spalten); Ziffern gleich breit, keine Rollleiste. Mit wall.js
   (Klasse wall-js) füllt die Anzeige ab 900 px genau den Bildschirm, lange Listen blättert das Skript; ohne Skript und auf schmalen
   Bildschirmen fließt die Seite und rollt. */
html.wall-doc { font-size: clamp(13px, .82vw, 21px); scrollbar-gutter: auto; }
html.wall-doc body.wall-body { font-size: 1rem; line-height: 1.35; font-variant-numeric: tabular-nums; background: var(--c-bg); }
.wall { display: flex; flex-direction: column; gap: .75rem; min-height: 100vh; padding: .9rem 1.1rem; }

/* Kopf: Marke, Name der Anzeige, Uhr mit Datum, Verbindungslampe mit „Stand“. */
.wall-head {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto auto; align-items: center; gap: .5rem 1.6rem;
  padding: .55rem 1rem; background: var(--c-surface); border: 1px solid var(--c-border-soft); border-radius: var(--radius-lg);
}
.wall-brand, .wall-notice-brand { display: flex; align-items: center; gap: .6rem; min-width: 0; }
.wall-brand .brand-logo-img.wall-logo, .wall-notice-brand .brand-logo-img.wall-logo { height: 2rem; max-width: 12rem; }
.wall-brand .brand-logo-img.wall-logo.wide, .wall-notice-brand .brand-logo-img.wall-logo.wide { height: 2.2rem; max-width: 14rem; }
.wall-brand .brand-logo-img.wall-logo.factory, .wall-notice-brand .brand-logo-img.wall-logo.factory { height: 2.5rem; max-width: none; }
.wall-brand .brand-logo, .wall-notice-brand .brand-logo { font-size: 1.6rem; }
.wall-brand .brand-name, .wall-notice-brand .brand-name { font-size: 1.15rem; color: var(--c-muted); white-space: nowrap; }
.wall-name { margin: 0; min-width: 0; font: 600 1.7rem/1.15 var(--font-display); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wall-time { text-align: right; }
.wall-clock { font: 600 2.2rem/1 var(--font-display); letter-spacing: .02em; }
.wall-date { margin-top: .25rem; font-size: .85rem; color: var(--c-muted); white-space: nowrap; }
.wall-conn { display: flex; flex-direction: column; align-items: flex-end; gap: .3rem; min-width: 11rem; }
.wall-conn [hidden] { display: none; }
.wall-conn .lamp > .ico { width: 1.25rem; height: 1.25rem; }
.wall-conn .lamp-text { font-size: .95rem; font-weight: 600; }
.wall-stand { font-size: .8rem; color: var(--c-muted); white-space: nowrap; }

/* Inhalt: Lagezeile mit vier großen Lampen, darunter links die Alarme, rechts Fehler und Geräte offline. */
.wall-board { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
.wall-content { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; gap: .75rem; }
.wall .lage.wall-lage { margin: 0; padding: .7rem 1.1rem; border-radius: var(--radius-lg); }
.wall .lage.wall-lage .lamps { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: .5rem 1.5rem; }
.wall .lstat { gap: .75rem; }
.wall .lstat > .ico { width: 2.5rem; height: 2.5rem; }
.wall .lstat b { font-size: 2.5rem; }
.wall .lstat span { font-size: .95rem; }
.wall-grid { flex: 1 1 auto; min-height: 0; display: grid; grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr); gap: .75rem; }
.wall-side { min-height: 0; display: grid; grid-template-rows: minmax(0, 3fr) minmax(0, 2fr); gap: .75rem; }
.wall-panel {
  min-height: 0; display: flex; flex-direction: column; overflow: hidden;
  background: var(--c-surface); border: 1px solid var(--c-border-soft); border-radius: var(--radius-lg);
}
.wall-panel-head { display: flex; align-items: center; justify-content: space-between; gap: .5rem 1rem; padding: .55rem 1rem; border-bottom: 1px solid var(--c-border-soft); }
.wall-panel-head h2 { display: flex; align-items: center; gap: .55rem; min-width: 0; margin: 0; font: 600 1.15rem/1.2 var(--font-display); }
.wall-panel-head h2 > .ico { width: 1.3rem; height: 1.3rem; color: var(--c-muted); }
.wall-panel-head .cnt { height: 1.45rem; min-width: 1.8rem; padding: 0 .5rem; font-size: .9rem; line-height: 1.45rem; }
.wall-page { font-size: .85rem; color: var(--c-muted); white-space: nowrap; }
.wall-rows { flex: 1 1 auto; min-height: 0; overflow: hidden; }
.wall-empty { margin: 0; padding: .9rem 1rem; }
.wall-empty .lamp > .ico { width: 1.3rem; height: 1.3rem; }
.wall-empty .lamp-text { font-size: 1rem; }
.wall-more { margin: 0; padding: .35rem 1rem .45rem; font-size: .8rem; color: var(--c-muted); border-top: 1px solid var(--c-border-soft); }

/* Listen als feste Zeilen gleicher Höhe (das Skript blättert nach Höhe), lange Texte enden mit „…“. */
.wall-table th, .wall-table td { height: 2.55rem; padding: 0 .7rem; font-size: .95rem; border-bottom-color: var(--c-border-soft); }
.wall-table th { position: static; height: 2rem; font-size: .8rem; }
.wall-table tbody tr:hover { background: transparent; }
.wall-table tr[hidden] { display: none; }
.wall-table td .lamp > .ico { width: 1.2rem; height: 1.2rem; }
.wall-table td.wf-result .lamp-text { font-size: inherit; }
.wall-table td.wa-dev, .wall-table td.wf-dev, .wall-table td.wo-dev { font-weight: 600; }
.wall-table td.wa-since, .wall-table td.wo-since, .wall-table td.wf-time { color: var(--c-muted); }
.wall-table td.wa-msg .pill { margin-right: .35rem; font-size: .75rem; vertical-align: middle; }
.wall-table tr.is-handled td { color: var(--c-faint); }
.wall-table tr.is-handled td .lamp { opacity: .6; }
.wall-alert-table col.col-lamp, .wall-offline-table col.col-lamp { width: 2.6rem; }
.wall-alert-table col.col-cust { width: 15%; }
.wall-alert-table col.col-dev { width: 14%; }
.wall-alert-table col.col-check { width: 24%; }
.wall-alert-table col.col-since { width: 6.5rem; }
.wall-side .wall-table td { font-size: .9rem; }
.wall-failure-table col.col-time { width: 7.2rem; }
.wall-failure-table col.col-dev { width: 18%; }
.wall-failure-table col.col-cust { width: 16%; }
.wall-failure-table col.col-result { width: 10.5rem; }
.wall-table td.wf-result .lamp { display: flex; max-width: 100%; }
.wall-table td.wf-result .lamp-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wall-offline-table col.col-cust { width: 34%; }
.wall-offline-table col.col-since { width: 7.2rem; }
/* Herkunft eines Fehlers als Symbol (Skript, Zeitplan, Software, Updates); das Wort steht für Bildschirmleser und auf dem Telefon dabei. */
.wall-src { display: inline-flex; align-items: center; gap: .3rem; margin-right: .4rem; color: var(--c-muted); vertical-align: -.2em; }
.wall-src > .ico { width: 1.05rem; height: 1.05rem; }
.wall-src-label { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }
.wall-class-ico { margin-right: .35rem; color: var(--c-muted); vertical-align: -.15em; }
.wall-table td.wo-dev .pill { margin-left: .4rem; font-size: .72rem; vertical-align: middle; }

/* Ruhe: große Lampe in der Mitte; Hinweise (gesperrte Lizenz, keine Kunden, Zugang widerrufen) in derselben Fläche. */
.wall-calm, .wall-message {
  flex: 1 1 auto; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: .7rem; padding: 2rem 1rem;
  text-align: center; background: var(--c-surface); border: 1px solid var(--c-border-soft); border-radius: var(--radius-lg);
}
.wall-calm .wall-calm-lamp > .ico { width: min(34vh, 22rem); height: min(34vh, 22rem); }
.wall-calm-title { margin: 0; font: 600 2.7rem/1.1 var(--font-display); color: var(--c-ok-ink); }
.wall-calm-sub { margin: 0; font-size: 1.3rem; color: var(--c-muted); }
.wall-message h2 { margin: 0; font: 600 2rem/1.2 var(--font-display); }
.wall-message p { max-width: 46rem; margin: 0; font-size: 1.1rem; color: var(--c-muted); }
.wall-message-lamp > .ico { width: 4.5rem; height: 4.5rem; }

/* Hinweisseiten (Link ungültig, nicht angemeldet, Server nicht bereit): eine Karte in der Mitte. */
.wall-notice { min-height: 100vh; display: grid; place-items: center; padding: 1rem; }
.wall-notice-card {
  width: min(100%, 36rem); display: flex; flex-direction: column; align-items: center; gap: .75rem; padding: 2rem 1.5rem; text-align: center;
  background: var(--c-surface); border: 1px solid var(--c-border-soft); border-radius: var(--radius-lg);
}
.wall-notice-brand { margin-bottom: .4rem; }
.wall-notice-card h1 { font-size: 1.6rem; }
.wall-notice-card p { margin: 0; color: var(--c-muted); }

@media (min-width: 901px) {
  html.wall-js .wall { height: 100vh; overflow: hidden; }
}
@media (max-width: 900px) {
  .wall-grid { grid-template-columns: minmax(0, 1fr); }
  .wall-side { grid-template-rows: none; }
  .wall-rows { overflow: visible; }
  .wall .lage.wall-lage .lamps { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .wall-head { grid-template-columns: auto minmax(0, 1fr) auto; }
  .wall-conn { grid-column: 1 / -1; flex-direction: row; flex-wrap: wrap; align-items: center; justify-content: space-between; min-width: 0; }
}

/* Telefon: Kopf in zwei Zeilen, Listen als Karten mit Beschriftung je Feld (data-label). */
@media (max-width: 640px) {
  html.wall-doc { font-size: 15px; }
  .wall { padding: .6rem; gap: .6rem; }
  .wall-head { grid-template-columns: minmax(0, 1fr) auto; padding: .6rem .8rem; gap: .4rem .8rem; }
  .wall-name { grid-column: 1 / -1; grid-row: 2; font-size: 1.3rem; white-space: normal; }
  .wall-clock { font-size: 1.5rem; }
  .wall .lage.wall-lage { padding: .6rem .8rem; }
  .wall .lstat > .ico { width: 1.7rem; height: 1.7rem; }
  .wall .lstat b { font-size: 1.6rem; }
  .wall .lstat span { font-size: .85rem; }
  .wall-calm-title { font-size: 1.8rem; }
  .wall-calm-sub { font-size: 1.05rem; }
  .wall-table thead, .wall-table colgroup { display: none; }
  .wall-table, .wall-table tbody { display: block; }
  .wall-table tbody tr { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: .15rem .6rem; padding: .6rem .8rem; border-bottom: 1px solid var(--c-border-soft); }
  .wall-table tbody tr:last-child { border-bottom: 0; }
  .wall-table td { display: block; height: auto; padding: 0; border: 0; min-width: 0; white-space: normal; overflow: visible; text-overflow: clip; }
  .wall-alert-table tbody tr { grid-template-areas: "sev dev since" "sev check check" "sev msg msg" "sev cust cust"; }
  .wall-alert-table td.wa-sev { grid-area: sev; }
  .wall-alert-table td.wa-dev { grid-area: dev; }
  .wall-alert-table td.wa-since { grid-area: since; text-align: right; }
  .wall-alert-table td.wa-check { grid-area: check; }
  .wall-alert-table td.wa-msg { grid-area: msg; overflow-wrap: anywhere; }
  .wall-alert-table td.wa-cust { grid-area: cust; }
  .wall-failure-table tbody tr { grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "job time" "dev dev" "cust cust" "result result"; }
  .wall-failure-table td.wf-job { grid-area: job; font-weight: 600; }
  .wall-failure-table td.wf-time { grid-area: time; text-align: right; }
  .wall-failure-table td.wf-dev { grid-area: dev; }
  .wall-failure-table td.wf-cust { grid-area: cust; }
  .wall-failure-table td.wf-result { grid-area: result; }
  .wall-table td.wf-result .lamp-text { white-space: normal; }
  .wall-src { display: flex; margin: 0 0 .1rem; font-size: .8rem; font-weight: 400; }
  .wall-src-label { position: static; width: auto; height: auto; margin: 0; overflow: visible; clip: auto; }
  .wall-offline-table tbody tr { grid-template-areas: "lamp dev since" "lamp cust cust"; }
  .wall-offline-table td.wo-lamp { grid-area: lamp; }
  .wall-offline-table td.wo-dev { grid-area: dev; }
  .wall-offline-table td.wo-since { grid-area: since; text-align: right; }
  .wall-offline-table td.wo-cust { grid-area: cust; }
  .wall-table td:is(.wa-cust, .wa-check, .wf-dev, .wf-cust, .wo-cust)::before { content: attr(data-label) ": "; color: var(--c-muted); font-size: .85rem; }
}

/* Hoher Kontrast: Ränder und gedämpfte Zeilen eine Stufe kräftiger. */
html[data-contrast="high"] .wall-head, html[data-contrast="high"] .wall-panel, html[data-contrast="high"] .wall-calm,
html[data-contrast="high"] .wall-message, html[data-contrast="high"] .wall-notice-card { border-color: var(--c-border); }
html[data-contrast="high"] .wall-table td, html[data-contrast="high"] .wall-panel-head { border-bottom-color: var(--c-border); }
html[data-contrast="high"] .wall-table tr.is-handled td { color: var(--c-muted); }
@media (prefers-contrast: more) {
  html[data-contrast="system"] .wall-head, html[data-contrast="system"] .wall-panel, html[data-contrast="system"] .wall-calm,
  html[data-contrast="system"] .wall-message, html[data-contrast="system"] .wall-notice-card { border-color: var(--c-border); }
  html[data-contrast="system"] .wall-table td, html[data-contrast="system"] .wall-panel-head { border-bottom-color: var(--c-border); }
  html[data-contrast="system"] .wall-table tr.is-handled td { color: var(--c-muted); }
}

/* Erzwungene Farben: Flächen mit Rand, Zähler und Herkunft mit Rahmen; die Lampen behalten ihre Form. */
@media (forced-colors: active) {
  .wall-head, .wall-panel, .wall-calm, .wall-message, .wall-notice-card { border: 1px solid CanvasText; }
  .wall-src, .wall-panel-head .cnt { border: 1px solid CanvasText; }
  .wall-table tr.is-handled td .lamp { opacity: 1; }
}

/* Verwaltung (/wall-displays): Liste mit festen Spalten, auf dem Telefon Karten; Link und QR-Code im Einmal-Dialog. */
.wd-table col.col-cust { width: 18%; }
.wd-table col.col-net { width: 15%; }
.wd-table col.col-theme { width: 7.5rem; }
.wd-table col.col-used { width: 10.5rem; }
.wd-table col.col-expires { width: 7.5rem; }
.wd-table col.col-state { width: 8.5rem; }
.wd-table col.col-actions { width: 7.5rem; }
.wd-table td.wd-theme .ico { color: var(--c-muted); }
.wd-table tr.is-expired td.wd-name .cell-main { color: var(--c-muted); }
.wd-table td.wd-state .lamp-text { font-size: inherit; }
.card.empty.wd-empty p { max-width: 72ch; margin: 0 auto var(--sp-3); }
.wd-lead { margin: 0 0 var(--sp-3); }
.wd-group { margin: 0 0 var(--sp-3); padding: var(--sp-2) var(--sp-3) var(--sp-3); border: 1px solid var(--c-border-soft); border-radius: var(--radius); }
.wd-group legend { padding: 0 6px; font-weight: 600; }
.wd-choice { display: flex; flex-wrap: wrap; gap: var(--sp-2) var(--sp-4); }
.wd-group .hint { margin: var(--sp-2) 0; }
.wd-picker { max-height: 240px; }
.wd-error { margin-top: var(--sp-3); }
.wd-kv { margin-bottom: var(--sp-3); }
.wd-link-row { display: flex; align-items: center; gap: var(--sp-2); }
.wd-link-row .wd-link { flex: 1 1 auto; min-width: 0; margin: 0; font-size: var(--fs-small); overflow-wrap: anywhere; word-break: break-all; }
.wd-qr-row { display: flex; align-items: center; gap: var(--sp-4); margin: var(--sp-3) 0; }
.wd-qr { flex: 0 0 auto; width: 168px; height: 168px; border-radius: var(--radius-sm); overflow: hidden; }
.wd-qr > svg { display: block; width: 100%; height: 100%; }
.wd-qr-hint { margin: 0; font-size: var(--fs-small); }
.wd-security { margin-top: var(--sp-3); }
@media (min-width: 641px) {
  table.wd-table.cols-fixed { min-width: 60rem; }
}
@media (max-width: 640px) {
  .wd-table thead, .wd-table colgroup { display: none; }
  .wd-table, .wd-table tbody { display: block; }
  .wd-table tbody tr {
    display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 4px var(--sp-2); padding: 10px var(--sp-3); border-bottom: 1px solid var(--c-border-soft);
    grid-template-areas: "name state" "cust cust" "net net" "used used" "expires expires" "theme actions";
  }
  .wd-table tbody tr:last-child { border-bottom: 0; }
  .table-wrap .wd-table td { display: block; min-width: 0; padding: 0; border: 0; white-space: normal; overflow: visible; text-overflow: clip; }
  .wd-table td .cell-main, .wd-table td .cell-sub { padding-inline: 0; margin-inline: 0; overflow: visible; }
  .wd-table td.wd-name { grid-area: name; }
  .wd-table td.wd-state { grid-area: state; text-align: right; }
  .wd-table td.wd-cust { grid-area: cust; }
  .wd-table td.wd-net { grid-area: net; }
  .wd-table td.wd-used { grid-area: used; }
  .wd-table td.wd-expires { grid-area: expires; }
  .wd-table td.wd-theme { grid-area: theme; align-self: center; }
  .wd-table td.wd-actions { grid-area: actions; text-align: right; }
  .wd-table td.wd-actions .btn { min-height: 40px; }
  .wd-table td:is(.wd-cust, .wd-net, .wd-used, .wd-expires)::before { content: attr(data-label) ": "; color: var(--c-muted); font-size: var(--fs-label); }
  .wd-table td.wd-used .cell-main, .wd-table td.wd-used .cell-sub { display: inline; }
  .wd-link-row { flex-direction: column; align-items: stretch; }
  .wd-link-row .btn { min-height: 40px; }
  .wd-qr-row { flex-direction: column; align-items: flex-start; }
}
@media (forced-colors: active) {
  .wd-group { border: 1px solid CanvasText; }
}
/* Ende Wandanzeige 0.89 */

/* ---------- L2-Scan 0.89 ---------- */
/* L2-Scan (0.89, Strang B): Reiter „L2-Scan“ am Gerät, Haken im Dialog „Agent installieren“. */
/* Lagezeile des Reiters: links Stand, Netze und Geräte, rechts die gescannten Netze und „Jetzt scannen“. */
.ns-lage { grid-template-columns: minmax(280px, 40%) minmax(0, 1fr); }
.ns-side { display: flex; flex-direction: column; gap: var(--sp-2); min-width: 0; }
.ns-networks { display: flex; flex-direction: column; gap: 4px; margin: 0; padding: 0; list-style: none; font-size: var(--fs-small); }
.ns-networks li { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 8px; min-width: 0; }
.ns-network-text { color: var(--c-muted); }
.ns-note { margin: 0; font-size: var(--fs-small); color: var(--c-muted); }
.ns-note.warn { color: var(--c-warn-ink); }
.ns-actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2) var(--sp-3); }
.ns-actions:empty { display: none; }
.ns-actions > .notice { margin: 0; }
.ns-offline { font-size: var(--fs-small); }

/* Werkzeugleiste: Filter-Chips mit Zählern, daneben die Suche. */
.ns-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2) var(--sp-3); margin-bottom: var(--sp-3); }
.ns-toolbar .ns-search { flex: 1 1 220px; max-width: 360px; }

/* Zeilen mit festen Spalten: IP mit Lampe, MAC, Hersteller, Name (Rest), Netz, zuerst und zuletzt gesehen. */
table.ns-table col.ns-c-ip { width: 11.25rem; }
table.ns-table col.ns-c-mac { width: 11rem; }
table.ns-table col.ns-c-vendor { width: 15%; }
table.ns-table col.ns-c-net { width: 10.5rem; }
table.ns-table col.ns-c-seen { width: 8.25rem; }
.ns-table td.ns-ip { white-space: nowrap; }
.ns-table td.ns-ip > .lamp { margin-right: 6px; }
.ns-table td.mono, .ns-table td .mono { font-size: var(--fs-small); }
.ns-table td.ns-first, .ns-table td.ns-last { color: var(--c-muted); font-size: var(--fs-small); }
.ns-table tr.is-gone td { color: var(--c-muted); }

/* Dialog „Agent installieren“: Haken mit Erklärung; Hinweis beim erzeugten Token ohne L2-Scan. Token-Details: Zeile L2-Scan. */
.install-netscan .switch { align-items: flex-start; }
.install-netscan .switch > .badge { margin-left: 4px; }
.install-netscan-off { margin: 0 0 var(--sp-2); font-size: var(--fs-small); }

/* Einstellungen, Bereich L2-Scan: Stand der Herstellerliste mit letztem Fehler. */
.mac-vendor-status .mac-vendor-error { color: var(--c-warn-ink); }

@media (max-width: 900px) {
  .ns-lage { grid-template-columns: minmax(0, 1fr); }
}
/* Telefon: Zeilen als Karten. Oben Lampe und IP, rechts zuletzt gesehen; darunter Name, Hersteller, MAC, Netz und zuerst gesehen mit
   Beschriftung. Chips und Knopf mit Tippflächen von 40 px. */
@media (max-width: 640px) {
  .ns-toolbar .ns-search { flex-basis: 100%; max-width: none; }
  .ns-filter .chip-button { min-height: 40px; }
  .ns-actions .btn { width: 100%; min-height: 40px; }
  .ns-table thead { display: none; }
  .ns-table, .ns-table tbody { display: block; }
  .ns-table tr {
    display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 4px var(--sp-2);
    grid-template-areas: "ip last" "name name" "vendor vendor" "mac mac" "net first";
    padding: 10px var(--sp-3); border-bottom: 1px solid var(--c-border-soft);
  }
  .ns-table tbody tr:last-child { border-bottom: 0; }
  .table-wrap table.ns-table td {
    display: block; padding: 0; border: 0; min-width: 0; max-width: none; width: auto; white-space: normal; text-align: left; box-shadow: none;
    overflow: visible;
  }
  .ns-table td.ns-ip { grid-area: ip; font-weight: 600; }
  .table-wrap table.ns-table td.ns-last { grid-area: last; justify-self: end; text-align: right; }
  .ns-table td.ns-name { grid-area: name; }
  .ns-table td.ns-vendor { grid-area: vendor; font-size: var(--fs-small); }
  .ns-table td.ns-mac { grid-area: mac; }
  .ns-table td.ns-net { grid-area: net; }
  .table-wrap table.ns-table td.ns-first { grid-area: first; justify-self: end; text-align: right; }
  .ns-table td[data-label]::before { content: attr(data-label) " "; color: var(--c-muted); font-family: var(--font); }
  .ns-table td.ns-ip::before, .ns-table td.ns-name::before, .ns-table td.ns-last::before { content: none; }
  .ns-table td.ns-name a { display: inline-block; min-height: 40px; line-height: 40px; }
}
/* Hoher Kontrast: Zeilen nicht mehr gesehener Geräte in der vollen Textfarbe; den Zustand trägt die Lampe mit ihrer Form. */
html[data-contrast="high"] .ns-table tr.is-gone td { color: var(--c-text); }
@media (prefers-contrast: more) {
  html[data-contrast="system"] .ns-table tr.is-gone td { color: var(--c-text); }
}
/* Erzwungene Farben: Der gewählte Filter bleibt als markiert erkennbar, nicht mehr gesehene Zeilen in GrayText. */
@media (forced-colors: active) {
  .ns-filter .chip-button.on { forced-color-adjust: none; background: Highlight; color: HighlightText; border-color: Highlight; }
  .ns-table tr.is-gone td { color: GrayText; }
  .ns-note.warn, .mac-vendor-status .mac-vendor-error { color: CanvasText; }
}
/* Ende L2-Scan 0.89 */

/* ---------- Virenschutz 0.89 ---------- */
/* Virenschutz (0.89, Strang C): Reiter „Virenschutz“ am Gerät mit Produkten, Funden und Scans. */
/* Werkzeugleiste: Stand links, „Scan starten“ rechts, davor in Worten, warum es gerade nicht geht. */
.av-toolbar { flex-wrap: wrap; }
.av-start { display: inline-flex; align-items: center; justify-content: flex-end; flex-wrap: wrap; gap: var(--sp-2); }
.av-start-hint { font-size: var(--fs-small); }
.av-title-icon { margin-right: 6px; color: var(--c-muted); vertical-align: -2px; }
/* Produkte: der Name nimmt den Rest, Lampe und Name in einer Zeile, Version und Hinweise darunter. */
table.av-products col.col-source { width: 11rem; }
table.av-products col.col-mode { width: 11.5rem; }
table.av-products col.col-rt { width: 9rem; }
table.av-products col.col-sig { width: 16%; }
table.av-products col.col-when { width: 10.5rem; }
table.av-products td.av-name .cell-main { display: flex; align-items: center; gap: 7px; }
table.av-products td.av-name .cell-main > .lamp { flex: 0 0 auto; }
.av-scan-note { color: var(--c-faint); }
/* Scans: Auftrag, Art, Funde und Auslöser fest, das Ergebnis nimmt den Rest; ein laufender Scan trägt die Kante im Info-Ton. */
table.av-scans col.col-when { width: 10.5rem; }
table.av-scans col.col-product { width: 18%; }
table.av-scans col.col-type { width: 15%; }
table.av-scans col.col-count { width: 8rem; }
table.av-scans col.col-by { width: 14%; }
table.av-scans tr.av-running > td:first-child { box-shadow: inset 3px 0 0 var(--c-info); }
.av-result-button { display: inline-flex; align-items: center; min-height: 24px; color: var(--c-text); font-weight: 500; }
.av-result-button .lamp-text { font-size: inherit; }
.av-result-button:hover .lamp-text { text-decoration: underline; text-underline-offset: 3px; }
/* Meldung eines Fehlschlags höchstens zwei Zeilen; vollständig im Dialog „Scan vom …“. */
.av-result .cell-sub { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden; overflow-wrap: anywhere; }
/* Funde: Pfad bricht um, Zustand als Lampe. */
table.av-threats col.col-when { width: 10.5rem; }
table.av-threats col.col-threat { width: 22%; }
table.av-threats col.col-action { width: 14%; }
table.av-threats col.col-state { width: 9.5rem; }
table.av-threats col.col-origin { width: 12rem; }
.av-path { font-size: var(--fs-small); }
/* Dialoge „Virenscan starten“ und „Scan vom …“. */
.av-scan-form { margin-bottom: var(--sp-2); }
.av-scan-product { display: block; padding: 6px 0; font-weight: 600; }
.av-scan-path { display: block; margin-top: var(--sp-2); }
.av-scan-path input { width: 100%; }
.av-server-warning { margin-top: var(--sp-3); }
.av-detail { margin-bottom: var(--sp-3); }
/* Funde im Dialog: feste Breiten in der Breite des Dialogs, lange Pfade brechen um statt seitlich zu rollen. */
table.av-detail-threats { table-layout: fixed; width: 100%; }
table.av-detail-threats th:nth-child(1) { width: 30%; }
table.av-detail-threats th:nth-child(3) { width: 20%; }
table.av-detail-threats th:nth-child(4) { width: 9.5rem; }
table.av-detail-threats td { white-space: normal; overflow-wrap: anywhere; }
/* Übersicht des Geräts: Virenschutz als eine Zeile mit Lampe und Verweis auf den Reiter. */
.av-sec-row .lamp-text { font-size: inherit; }
.av-sec-link { flex: 0 0 auto; font-size: var(--fs-small); white-space: nowrap; }
@media (min-width: 641px) {
  /* Mindestbreiten: darunter rollt die Tabelle seitlich, statt die Spalten unlesbar schmal zu machen. */
  table.av-products.cols-fixed { min-width: 58rem; }
  table.av-scans.cols-fixed { min-width: 52rem; }
  table.av-threats.cols-fixed { min-width: 56rem; }
}
/* Hoher Kontrast: Ergebnis als Verweis erkennbar, laufender Scan mit kräftigerer Kante. */
html[data-contrast="high"] .av-result-button .lamp-text { text-decoration: underline; text-underline-offset: 2px; }
html[data-contrast="high"] table.av-scans tr.av-running > td:first-child { box-shadow: inset 4px 0 0 var(--c-info); }
@media (prefers-contrast: more) {
  html[data-contrast="system"] .av-result-button .lamp-text { text-decoration: underline; text-underline-offset: 2px; }
  html[data-contrast="system"] table.av-scans tr.av-running > td:first-child { box-shadow: inset 4px 0 0 var(--c-info); }
}
/* Erzwungene Farben: Die Kante eines laufenden Scans wird zum Rand; Lampen tragen den Zustand ohnehin über ihre Form. */
@media (forced-colors: active) {
  table.av-scans tr.av-running > td:first-child { border-left: 3px dotted CanvasText; }
  .av-result-button { color: LinkText; }
}
@media (max-width: 640px) {
  /* Telefon: „Scan starten“ in voller Breite unter dem Stand, die Tabellen als Karten mit beschrifteten Werten. */
  .av-start { width: 100%; justify-content: space-between; }
  .av-start .btn { min-height: 40px; }
  :where(table.cols-fixed.av-products, table.cols-fixed.av-scans, table.cols-fixed.av-threats) > colgroup { display: none; }
  :where(table.cols-fixed.av-products, table.cols-fixed.av-scans, table.cols-fixed.av-threats) > tbody > tr > td:not(.wrap, [colspan]) :where(.cell-main, .cell-sub) {
    overflow: visible; text-overflow: clip; padding-inline: 0; margin-inline: 0;
  }
  table.av-products thead, table.av-scans thead, table.av-threats thead { display: none; }
  table.av-products, table.av-products tbody, table.av-scans, table.av-scans tbody, table.av-threats, table.av-threats tbody { display: block; }
  table.av-products tr, table.av-scans tr, table.av-threats tr {
    display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: start; gap: 4px var(--sp-2);
    padding: 10px var(--sp-3); border-bottom: 1px solid var(--c-border-soft);
  }
  table.av-products tbody tr:last-child, table.av-scans tbody tr:last-child, table.av-threats tbody tr:last-child { border-bottom: 0; }
  .table-wrap table.av-products td, .table-wrap table.av-scans td, .table-wrap table.av-threats td {
    display: block; grid-column: 1 / -1; padding: 0; border: 0; min-width: 0; max-width: none; width: auto;
    overflow: visible; text-overflow: clip; white-space: normal; text-align: left; font-size: var(--fs-small);
  }
  .av-products td[data-label]::before, .av-scans td[data-label]::before, .av-threats td[data-label]::before { content: attr(data-label) " "; color: var(--c-muted); }
  .av-products td.av-name::before, .av-scans td.av-result::before, .av-threats td.av-threat::before { content: none; }
  .table-wrap table.av-products td.av-name, .table-wrap table.av-threats td.av-threat { grid-row: 1; font-size: var(--fs-body); }
  .table-wrap table.av-scans td.av-result { grid-row: 1; font-size: var(--fs-body); }
  .av-result-button { min-height: 40px; }
  table.av-scans tr.av-running { box-shadow: inset 3px 0 0 var(--c-info); }
  table.av-threats tr.edge-crit { box-shadow: inset 3px 0 0 var(--c-crit); }
  table.av-scans tr.av-running > td:first-child, table.av-threats tr.edge-crit > td:first-child { box-shadow: none; }
  .av-sec-row { flex-wrap: wrap; }
}
/* Ende Virenschutz 0.89 */

/* ---------- Lizenz-Anmeldung 0.89 ---------- */
/* Lizenz-Anmeldung (0.89, Strang D): Hinweise zur Anmeldung bei der Lizenz-Instanz auf Karte, Einrichtung und Dashboard. */
/* Ende Lizenz-Anmeldung 0.89 */

/* ---------- Gerätegruppen 0.90 ---------- */
/* Gerätegruppen (0.90, Strang A): Liste unter /device-groups (feste Spalten, auf dem Telefon Karten), Verwalten mit Mitgliedern, Dialog mit
   Bedingungen, festen Geräten und Vorschau, Zeile „Gerätegruppen“ am Gerät, Chip des Gruppenfilters in der Geräteliste und der Hinweis
   „Abweichend in der Gerätegruppe“ im Richtlinien-Dialog des Kunden. */
.card.empty.dg-empty p { max-width: 72ch; margin: 0 auto var(--sp-3); }
.dg-toolbar { flex-wrap: wrap; align-items: flex-end; }
.dg-table col.col-scope { width: 15%; }
.dg-table col.col-cond { width: 34%; }
.dg-table col.col-members { width: 8.5rem; }
.dg-table col.col-rank { width: 4.5rem; }
.dg-table col.col-actions { width: 7.5rem; }
.dg-table td.dg-name .cell-main { display: flex; align-items: center; gap: 6px; min-width: 0; }
.dg-table td.dg-name .cell-main > span:not(.pill) { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; }
.dg-table td.dg-name .pill { flex: 0 0 auto; }
.dg-table .dg-ico { flex: 0 0 auto; color: var(--c-muted); }
.dg-table td.dg-cond .cell-main { white-space: normal; overflow-wrap: anywhere; font-weight: 400; }
.dg-table td.dg-rank { color: var(--c-muted); }
.dg-table td.dg-members .lamp-text { font-size: inherit; }
.dg-table tr.is-empty td.dg-name .cell-main > span:not(.pill) { color: var(--c-muted); }
.dg-kv { margin-bottom: var(--sp-3); }
.dg-member-table col.col-cust { width: 28%; }
.dg-member-table col.col-class { width: 7.5rem; }
.dg-member-table col.col-since { width: 8.5rem; }
.dg-member-table td.dgm-name .cell-main { display: flex; align-items: center; gap: 6px; min-width: 0; }
.dg-member-table td.dgm-since { color: var(--c-muted); }
@media (min-width: 641px) {
  table.dg-table.cols-fixed { min-width: 52rem; }
}

/* Dialog: Bedingungen als Zeilen (Art, Vergleich, Entfernen; darunter die Werte), feste Geräte mit Begründung, Trefferliste, Vorschau. */
.dg-lead { margin: 0 0 var(--sp-3); }
.dg-hint { margin: 0 0 var(--sp-2); font-size: var(--fs-small); }
.dg-conditions, .dg-fixed { display: flex; flex-direction: column; gap: var(--sp-2); margin: 0 0 var(--sp-2); padding: 0; list-style: none; }
.dg-condition, .dg-fixed-row {
  padding: var(--sp-2) var(--sp-3); border: 1px solid var(--c-border-soft); border-radius: var(--radius-sm); background: var(--c-surface);
}
.dg-condition-head { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); }
.dg-condition-head select { min-width: 0; }
.dg-condition-head .dg-kind { flex: 0 1 15rem; }
.dg-condition-head .dg-op { flex: 0 1 13rem; }
.dg-remove {
  flex: 0 0 auto; width: 28px; height: 28px; margin-left: auto; padding: 0; border: 0; border-radius: 50%;
  background: transparent; color: var(--c-muted); font: inherit; font-size: 1.15rem; line-height: 1; cursor: pointer;
}
.dg-remove:hover { background: var(--c-hover); color: var(--c-text); }
.dg-remove:focus-visible { outline: var(--focus-w) solid var(--c-focus); outline-offset: 1px; }
.dg-condition-values { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); margin-top: var(--sp-2); }
.dg-condition-values .dg-values { flex: 1 1 16rem; min-width: 0; }
.dg-condition-values .dg-publisher { flex: 1 1 12rem; min-width: 0; }
.dg-chips { flex-wrap: wrap; gap: 6px; }
.dg-condition-hint { display: block; margin-top: 6px; font-size: var(--fs-small); font-weight: 400; color: var(--c-muted); }
.dg-add { margin-bottom: var(--sp-2); }
.dg-fixed-row.is-excluded { border-left: 3px solid var(--c-warn); }
.dg-fixed-head { display: flex; flex-wrap: wrap; align-items: center; gap: 6px var(--sp-2); }
.dg-fixed-name { font-weight: 600; overflow-wrap: anywhere; }
.dg-fixed-row .dg-reason { width: 100%; margin-top: 6px; }
.dg-search { margin-top: var(--sp-2); }
.dg-hits {
  display: flex; flex-direction: column; max-height: 260px; overflow-y: auto; overscroll-behavior: contain;
  margin: var(--sp-2) 0; border: 1px solid var(--c-border-soft); border-radius: var(--radius-sm);
}
.dg-hit {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "name actions" "cust actions";
  align-items: center; gap: 0 var(--sp-3); padding: 7px 12px; border-bottom: 1px solid var(--c-border-soft);
}
.dg-hit:last-child { border-bottom: 0; }
.dg-hit-name { grid-area: name; font-weight: 600; overflow-wrap: anywhere; }
.dg-hit .cell-sub { grid-area: cust; }
.dg-hit-actions, .dg-hit-state { grid-area: actions; display: flex; gap: 6px; justify-content: flex-end; }
.dg-hit-state { font-size: var(--fs-small); }
.dg-preview {
  padding: var(--sp-2) var(--sp-3); border: 1px solid var(--c-border-soft); border-radius: var(--radius-sm); background: var(--c-neutral-bg);
}
.dg-preview .lamp { align-items: flex-start; }
.dg-preview .lamp-text { font-size: var(--fs-small); color: var(--c-text); white-space: normal; overflow-wrap: anywhere; }
.dg-error { margin-top: var(--sp-3); }

/* Zeile „Gerätegruppen“ in der Karte „Gerät“: Namen als Links in Rangfolge. */
dl.kv dd.dg-line { display: flex; flex-wrap: wrap; gap: 4px 10px; }
.dg-line-link { color: var(--c-accent-ink); text-decoration: none; }
.dg-line-link:hover { text-decoration: underline; }

/* Geräteliste: Filter auf eine Gruppe als Chip neben der Suche, × entfernt ihn. */
.dg-filter-chip {
  display: inline-flex; align-items: center; gap: 6px; align-self: flex-end; max-width: 100%; min-width: 0; min-height: 34px;
  padding: 2px 3px 2px 10px; border: 1px solid var(--c-accent-line); border-radius: 999px;
  background: var(--c-accent-tint); color: var(--c-accent-ink); font-size: var(--fs-small);
}
.dg-filter-chip > .ico { flex: 0 0 auto; }
.dg-filter-chip-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dg-filter-chip-remove {
  flex: 0 0 auto; width: 26px; height: 26px; padding: 0; border: 0; border-radius: 50%;
  background: transparent; color: inherit; font: inherit; font-size: 1.05rem; line-height: 1; cursor: pointer;
}
.dg-filter-chip-remove:hover { background: var(--c-hover); }
.dg-filter-chip-remove:focus-visible { outline: var(--focus-w) solid var(--c-focus); outline-offset: 1px; }

/* Richtlinien-Dialog des Kunden: Gruppen mit eigenem Wert unter der Herkunft. */
.dg-pol-groups { display: flex; align-items: center; gap: 6px; color: var(--c-info-ink); }
.dg-pol-groups > .ico { flex: 0 0 auto; }

/* Touch: Tippflächen mindestens 40 px. */
@media (pointer: coarse) {
  .dg-remove, .dg-filter-chip-remove { width: 40px; height: 40px; }
  .dg-filter-chip { min-height: 40px; }
  .dg-hit-actions .btn, .dg-actions .btn, .dg-add { min-height: 40px; }
}

/* Telefon: Liste und Mitglieder als Karten mit Beschriftung je Feld (data-label), Bedingungen und Treffer untereinander. */
@media (max-width: 640px) {
  .dg-table thead, .dg-table colgroup, .dg-member-table thead, .dg-member-table colgroup { display: none; }
  .dg-table, .dg-table tbody, .dg-member-table, .dg-member-table tbody { display: block; }
  .dg-table tbody tr {
    display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 4px var(--sp-2); padding: 10px var(--sp-3); border-bottom: 1px solid var(--c-border-soft);
    grid-template-areas: "name rank" "scope scope" "cond cond" "members actions";
  }
  .dg-member-table tbody tr {
    display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 4px var(--sp-2); padding: 10px var(--sp-3); border-bottom: 1px solid var(--c-border-soft);
    grid-template-areas: "name since" "cust class";
  }
  .dg-table tbody tr:last-child, .dg-member-table tbody tr:last-child { border-bottom: 0; }
  .table-wrap .dg-table td, .table-wrap .dg-member-table td {
    display: block; min-width: 0; padding: 0; border: 0; white-space: normal; overflow: visible; text-overflow: clip;
  }
  .dg-table td .cell-main, .dg-table td .cell-sub, .dg-member-table td .cell-main, .dg-member-table td .cell-sub { padding-inline: 0; margin-inline: 0; overflow: visible; }
  .dg-table td.dg-name { grid-area: name; }
  .dg-table td.dg-rank { grid-area: rank; text-align: right; }
  .dg-table td.dg-scope { grid-area: scope; }
  .dg-table td.dg-cond { grid-area: cond; }
  .dg-table td.dg-members { grid-area: members; align-self: center; }
  .dg-table td.dg-actions { grid-area: actions; text-align: right; }
  .dg-table td.dg-actions .btn { min-height: 40px; }
  .dg-table td:is(.dg-scope, .dg-cond, .dg-members, .dg-rank)::before { content: attr(data-label) ": "; color: var(--c-muted); font-size: var(--fs-label); }
  .dg-member-table td.dgm-name { grid-area: name; }
  .dg-member-table td.dgm-since { grid-area: since; text-align: right; }
  .dg-member-table td.dgm-cust { grid-area: cust; }
  .dg-member-table td.dgm-class { grid-area: class; text-align: right; }
  .dg-member-table td:is(.dgm-cust, .dgm-class)::before { content: attr(data-label) ": "; color: var(--c-muted); font-size: var(--fs-label); }
  .dg-condition-head .dg-kind, .dg-condition-head .dg-op { flex: 1 1 100%; }
  .dg-condition-head .dg-remove { position: absolute; right: 6px; top: 6px; }
  .dg-condition { position: relative; padding-right: 48px; }
  .dg-hit { grid-template-columns: minmax(0, 1fr); grid-template-areas: "name" "cust" "actions"; gap: 4px; }
  .dg-hit-actions, .dg-hit-state { justify-content: flex-start; }
  .dg-hit-actions .btn { min-height: 40px; }
  .dg-filter-chip { align-self: stretch; }
}

/* Hoher Kontrast: Ränder der Zeilen und Karten eine Stufe kräftiger. */
html[data-contrast="high"] .dg-condition, html[data-contrast="high"] .dg-fixed-row, html[data-contrast="high"] .dg-hits,
html[data-contrast="high"] .dg-preview, html[data-contrast="high"] .dg-filter-chip { border-color: var(--c-border); }
@media (prefers-contrast: more) {
  html[data-contrast="system"] .dg-condition, html[data-contrast="system"] .dg-fixed-row, html[data-contrast="system"] .dg-hits,
  html[data-contrast="system"] .dg-preview, html[data-contrast="system"] .dg-filter-chip { border-color: var(--c-border); }
}

/* Erzwungene Farben: Zeilen, Vorschau und Chip mit Rand; die Ausnahme behält ihre Kante. */
@media (forced-colors: active) {
  .dg-condition, .dg-fixed-row, .dg-hits, .dg-preview, .dg-filter-chip { border: 1px solid CanvasText; }
  .dg-fixed-row.is-excluded { border-left: 3px solid CanvasText; }
  .dg-remove, .dg-filter-chip-remove { border: 1px solid ButtonText; }
}
/* Ende Gerätegruppen 0.90 */

/* ---------- Skripte 0.90 ---------- */
/* Skripte (0.90, Strang B): Parameter mit Typ, Rückgabewerte im Editor, Prüfen einer Beispielausgabe, Verwendung des Skripts. */
/* Bibliothek: Lagezeile über der Übersicht in der rechten Spalte, Verwendungen in der Zeile eines Skripts. */
.lib-main > .lage.lib-lage { margin: 0 0 var(--sp-4); }
.lib-row-meta .lib-row-used { color: var(--c-text); }

/* Editor: Erklärungen sichtbar unter den Abschnitten, Schreibweisen in Schreibmaschinenschrift. */
.sp-content { margin-bottom: var(--sp-2); }
code.sp-code { padding: 1px 5px; font-family: var(--mono); font-size: .82rem; color: var(--c-code-text); background: var(--c-code-bg); border-radius: var(--radius-sm); overflow-wrap: anywhere; }
.sp-param-lead, .sp-out-lead p { margin: 0 0 var(--sp-3); max-width: 96ch; font-size: var(--fs-small); line-height: 1.55; color: var(--c-muted); }
.sp-out-lead p + p { margin-top: calc(-1 * var(--sp-2)); }
.sp-head-actions { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.sp-out-empty, .sp-usage-none { margin: 0 0 var(--sp-3); font-size: var(--fs-small); }

/* Parameter und Rückgabewerte als Zeilen mit Eingaben; je Zelle bis zu zwei Felder untereinander (Bezeichnung und Hilfe, Typ und Auswahl). */
.sp-param-wrap, .sp-out-wrap { margin-bottom: var(--sp-3); overflow: visible; }
table.sp-params td, table.sp-outputs td { white-space: normal; vertical-align: top; padding: 8px 10px; }
table.sp-params th, table.sp-outputs th { position: static; }
table.sp-params tbody tr:hover, table.sp-outputs tbody tr:hover { background: transparent; }
table.sp-params td.sp-p-type select { min-width: 8rem; }
table.sp-outputs td.sp-out-type select { min-width: 8.5rem; }
table.sp-outputs td.sp-out-unit input { min-width: 4.5rem; }
table.sp-params td > input + input, table.sp-params td > select + textarea { margin-top: 6px; }
table.sp-params th:nth-child(1), table.sp-outputs th:nth-child(1) { width: 15%; }
table.sp-params th:nth-child(2) { width: 30%; }
table.sp-params th:nth-child(3) { width: 17%; }
table.sp-params th:nth-child(5) { width: 4.5rem; }
table.sp-params th:last-child, table.sp-outputs th:last-child { width: 6.5rem; }
table.sp-outputs th:nth-child(3) { width: 7.5rem; }
table.sp-outputs th:nth-child(4) { width: 6rem; }
table.sp-outputs th:nth-child(5), table.sp-outputs th:nth-child(6) { width: 19%; }
.sp-p-choices { min-height: 64px; resize: vertical; font-size: var(--fs-small); }
.sp-p-help { font-size: var(--fs-small); }
td.sp-p-required { text-align: center; }
td.sp-p-required .switch { min-height: var(--control-h); justify-content: center; }
.sp-cond { display: flex; flex-direction: column; gap: 6px; }

/* Verwendet in: eine ruhige Liste mit Symbol, Art, Name als Link und Zustand. */
.sp-usage { display: flex; flex-direction: column; margin: 0 0 var(--sp-3); padding: 0; list-style: none; border: 1px solid var(--c-border-soft); border-radius: var(--radius); }
.sp-usage-item { display: grid; grid-template-columns: 20px 11rem minmax(0, 1fr) auto; align-items: center; gap: 4px 10px; padding: 8px 12px; border-top: 1px solid var(--c-border-soft); }
.sp-usage-item:first-child { border-top: 0; }
.sp-usage-item > .ico { color: var(--c-muted); }
.sp-usage-kind { font-size: var(--fs-label); color: var(--c-muted); white-space: nowrap; }
.sp-usage-name { min-width: 0; overflow-wrap: anywhere; }
.sp-usage-detail { font-size: var(--fs-small); text-align: right; }
.sp-usage-hidden { margin: calc(-1 * var(--sp-2)) 0 var(--sp-3); font-size: var(--fs-small); }

/* Eingabe der Parameter in den Dialogen von Aufgaben und Checks: Schalter, Kennwort „gesetzt“ mit „Ändern“, Hinweis bei Benutzerkontext. */
.sp-input .switch.sp-switch { min-height: var(--control-h); }
.sp-secret-set { display: flex; align-items: center; gap: var(--sp-2); min-height: var(--control-h); }
.sp-input-secret > .sp-input-warn { color: var(--c-warn-ink); }

/* Ausgabe prüfen: Beispielausgabe und Exit-Code nebeneinander, Bewertung als Lampe, Werte als Zeilen mit festen Spalten. */
.sp-check-lead { margin: 0 0 var(--sp-3); font-size: var(--fs-small); line-height: 1.55; }
.form-grid.sp-check-form { grid-template-columns: minmax(0, 1fr) 11rem; align-items: start; }
.form-grid.sp-check-form > .span-all { grid-column: 1; }
.sp-check-sample { min-height: 150px; }
.sp-check-result { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2) var(--sp-5); margin-bottom: var(--sp-2); }
.sp-check-result .lamp-text { font-weight: 600; }
.sp-check-task { font-size: var(--fs-small); color: var(--c-muted); }
.sp-check-message { margin: 0 0 var(--sp-3); overflow-wrap: anywhere; }
.sp-check-unknown { margin: var(--sp-2) 0 0; font-size: var(--fs-small); overflow-wrap: anywhere; }
table.sp-check-values col.col-value { width: 26%; }
table.sp-check-values col.col-state { width: 44%; }
table.sp-check-values td.sp-cv-state .lamp-text { white-space: normal; }
table.sp-check-values td.sp-cv-state { white-space: normal; }

/* Schmal: Bezeichnung und Typ der Parameter brauchen Platz, die Liste der Verwendungen bricht um. */
@media (max-width: 900px) {
  .sp-usage-item { grid-template-columns: 20px minmax(0, 1fr) auto; }
  .sp-usage-kind { grid-column: 2; }
  .sp-usage-name { grid-column: 2 / -1; }
  .sp-usage-detail { grid-column: 2 / -1; text-align: left; }
}

/* Telefon: Parameter, Rückgabewerte und Werte der Prüfung als Karten mit Beschriftung je Feld (data-label), Tippflächen 40 px. */
@media (max-width: 640px) {
  table.sp-params thead, table.sp-outputs thead, table.sp-check-values thead, table.sp-check-values colgroup { display: none; }
  table.sp-params, table.sp-params tbody, table.sp-outputs, table.sp-outputs tbody, table.sp-check-values, table.sp-check-values tbody { display: block; }
  table.sp-params tbody tr, table.sp-outputs tbody tr, table.sp-check-values tbody tr {
    display: grid; grid-template-columns: minmax(0, 1fr); gap: 8px; padding: 12px; border-bottom: 1px solid var(--c-border-soft);
  }
  table.sp-params tbody tr:last-child, table.sp-outputs tbody tr:last-child, table.sp-check-values tbody tr:last-child { border-bottom: 0; }
  .table-wrap table.sp-params td, .table-wrap table.sp-outputs td, .table-wrap table.sp-check-values td {
    display: block; width: auto; min-width: 0; padding: 0; border: 0; white-space: normal; overflow: visible; text-overflow: clip;
  }
  table.sp-params td[data-label]::before, table.sp-outputs td[data-label]::before, table.sp-check-values td[data-label]::before {
    content: attr(data-label); display: block; margin-bottom: 4px; font-size: var(--fs-label); font-weight: 600; color: var(--c-muted);
  }
  table.sp-check-values td.sp-cv-name::before { content: none; }
  td.sp-p-required { text-align: left; }
  td.sp-p-required .switch { justify-content: flex-start; }
  table.sp-params td.row-actions, table.sp-outputs td.row-actions { text-align: left; }
  table.sp-params td.row-actions .btn, table.sp-outputs td.row-actions .btn, .sp-head-actions .btn, .sp-secret-set .btn, .btn.sp-check-insert { min-height: 40px; }
  .sp-head-actions { width: 100%; }
  .sp-head-actions .btn { flex: 1 1 0; }
  .form-grid.sp-check-form { grid-template-columns: minmax(0, 1fr); }
  .sp-usage-item { grid-template-columns: 20px minmax(0, 1fr); padding: 10px 12px; }
  .sp-usage-item > .ico { grid-row: 1 / span 3; align-self: start; margin-top: 2px; }
  .sp-usage-kind, .sp-usage-name, .sp-usage-detail { grid-column: 2; }
  .sp-usage-name a { display: inline-block; min-height: 40px; line-height: 40px; }
}

/* Hoher Kontrast: Rahmen der Listen und Zeilen eine Stufe kräftiger, Schreibweisen umrandet. */
html[data-contrast="high"] .sp-usage, html[data-contrast="high"] .sp-usage-item { border-color: var(--c-border); }
html[data-contrast="high"] code.sp-code { box-shadow: inset 0 0 0 1px var(--c-border); }
html[data-contrast="high"] .sp-param-lead, html[data-contrast="high"] .sp-out-lead p, html[data-contrast="high"] .sp-usage-kind { color: var(--c-text); }
@media (prefers-contrast: more) {
  html[data-contrast="system"] .sp-usage, html[data-contrast="system"] .sp-usage-item { border-color: var(--c-border); }
  html[data-contrast="system"] code.sp-code { box-shadow: inset 0 0 0 1px var(--c-border); }
  html[data-contrast="system"] .sp-param-lead, html[data-contrast="system"] .sp-out-lead p, html[data-contrast="system"] .sp-usage-kind { color: var(--c-text); }
}

/* Erzwungene Farben: Listen und Schreibweisen mit Systemrahmen; die Lampen behalten ihre Form. */
@media (forced-colors: active) {
  .sp-usage, .sp-usage-item { border-color: CanvasText; }
  code.sp-code { border: 1px solid CanvasText; }
}
/* Ende Skripte 0.90 */

/* ---------- Aufgaben 0.90 ---------- */
/* Aufgaben (0.90, Strang C): Seite mit Verlauf und Geplant, Dialog für sofort, einmalig und wiederkehrend, Werte je Lauf. */

/* Dialog „Aufgabe anlegen“ (TaskModal): Ausführung als Chips mit Symbol, eine große Auswahl der Geräteliste als feste Zeile, der Hinweis
   auf Checks unter den Feldern. Die Raster der Felder und die Vorschau kommen aus dem Block „Zeitpläne 0.76“ (schedule-modal). */
.task-modal > .tabs.tabs-tight { margin-bottom: var(--sp-3); }
.task-modes { display: flex; flex-wrap: wrap; gap: 6px; margin: 0 0 var(--sp-2); }
.task-modes .chip-button { display: inline-flex; align-items: center; gap: 6px; min-height: 34px; font-size: var(--fs-small); }
.task-modes .chip-button:disabled { opacity: .55; cursor: not-allowed; }
.task-fixed {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--sp-2);
  padding: 8px 12px; margin-bottom: var(--sp-2);
  background: var(--c-neutral-bg); border: 1px solid var(--c-border-soft); border-radius: var(--radius-sm);
}
.task-fixed-text { display: inline-flex; align-items: center; gap: 6px; font-weight: 600; }
.task-fixed-text > .ico { color: var(--c-muted); }
.task-check-hint { margin-top: var(--sp-3); }

/* Lagezeilen der Seite und einer Aufgabe: Lampen ohne Band nehmen die ganze Breite. */
.lage.tasks-lage .lamps, .lage.task-run-lage .lamps { gap: 8px 28px; }

/* Geplant: Zustand als Chips über der Liste, Zeilen mit festen Spalten; der Grund eines Fehlers steht breit im title der Pille. */
.task-plan-tools { margin-bottom: var(--sp-3); }
.task-plan-table col.col-state { width: 10rem; }
.task-plan-table col.col-rhythm { width: 16%; }
.task-plan-table col.col-target { width: 19%; }
.task-plan-table col.col-last { width: 10.5rem; }
.task-plan-table col.col-next { width: 10.5rem; }
.task-plan-table col.col-actions { width: 7.5rem; }
.task-plan-table td.tp-state .lamp-text { font-size: inherit; }
.task-plan-table td.tp-state .tp-error-pill { margin-top: 2px; }
.task-plan-table td.tp-error { display: none; }
.task-legacy-title { margin-top: var(--sp-5); }
.task-plan-kv { margin-bottom: var(--sp-3); }
.task-plan-kv .tp-error-text { color: var(--c-crit-ink); overflow-wrap: anywhere; }
@media (min-width: 641px) {
  table.task-plan-table.cols-fixed { min-width: 58rem; }
}

/* Werte je Lauf (Rückgabewerte): kleine Liste unter dem Gerät; in der Tabelle eine Zeile mit „…“, der volle Text steht im title. */
ul.task-values { display: flex; flex-wrap: wrap; gap: 0 12px; margin: 2px 0 0; padding: 0; list-style: none; font-size: var(--fs-small); color: var(--c-muted); }
ul.task-values li { min-width: 0; white-space: nowrap; }
.task-value { color: var(--c-text); font-variant-numeric: tabular-nums; }
table.cols-runs.cols-fixed td.jr-dev ul.task-values { flex-wrap: nowrap; overflow: hidden; text-overflow: ellipsis; }
ul.task-values.task-values-group { gap: 2px var(--sp-4); margin: 0; }
.task-run-message { margin: 0 0 var(--sp-2); overflow-wrap: anywhere; }
/* Läufe einer Aufgabe: „Gestartet“ mit Datum und Uhrzeit ohne Kürzung, Status mit Platz für „Nicht anwendbar“ (Läufe der Checks). */
table.cols-runs col.col-started { width: 10.5rem; }
table.cols-runs col.col-status { width: 10.5rem; }

/* Telefon: Warnungen mit gelber Kante auf der ganzen Karte (wie die rote der Fehler im Block „Jobs-Liste 0.76“), Werte umbrechend, Geplant
   als Karten mit Beschriftung je Feld, Chips und Knöpfe mit Tippflächen von 40 px. */
@media (max-width: 640px) {
  table.cols-jobs.cols-fixed tr.edge-warn, table.cols-runs.cols-fixed tr.edge-warn { box-shadow: inset 3px 0 0 var(--c-warn); }
  table.cols-jobs.cols-fixed tr.edge-warn > td:first-child, table.cols-runs.cols-fixed tr.edge-warn > td:first-child { box-shadow: none; }
  table.cols-runs.cols-fixed td.jr-dev ul.task-values { flex-wrap: wrap; overflow: visible; }
  .toolbar.job-run-tools > .filter { flex: 1 1 100%; min-width: 0; }
  ul.task-values li { white-space: normal; }

  .task-modes .chip-button { flex: 1 1 auto; justify-content: center; min-height: 40px; }
  .task-fixed { flex-direction: column; align-items: stretch; }
  .task-fixed .btn { min-height: 40px; }
  .task-plan-filter .chip-button { min-height: 40px; }

  .task-plan-table thead, .task-plan-table colgroup { display: none; }
  .task-plan-table, .task-plan-table tbody { display: block; }
  .task-plan-table tbody tr {
    display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 4px var(--sp-2); padding: 10px var(--sp-3);
    grid-template-areas: "name state" "rhythm rhythm" "target target" "last next" "error error" "actions actions";
    border-bottom: 1px solid var(--c-border-soft);
  }
  .task-plan-table tbody tr:last-child { border-bottom: 0; }
  .table-wrap .task-plan-table td { display: block; min-width: 0; padding: 0; border: 0; white-space: normal; overflow: visible; text-overflow: clip; box-shadow: none; }
  .task-plan-table td .cell-main, .task-plan-table td .cell-sub { padding-inline: 0; margin-inline: 0; overflow: visible; white-space: normal; }
  .task-plan-table tr.edge-crit { box-shadow: inset 3px 0 0 var(--c-crit); }
  .task-plan-table tr.edge-crit > td:first-child { box-shadow: none; }
  .task-plan-table td.tp-name { grid-area: name; }
  .task-plan-table td.tp-state { grid-area: state; text-align: right; }
  .task-plan-table td.tp-state .tp-error-pill { display: none; }
  .task-plan-table td.tp-rhythm { grid-area: rhythm; }
  .task-plan-table td.tp-target { grid-area: target; }
  .task-plan-table td.tp-last { grid-area: last; font-size: var(--fs-small); }
  .task-plan-table td.tp-next { grid-area: next; font-size: var(--fs-small); text-align: right; }
  .table-wrap .task-plan-table td.tp-error { display: block; grid-area: error; font-size: var(--fs-small); color: var(--c-crit-ink); overflow-wrap: anywhere; }
  .task-plan-table td.tp-actions { grid-area: actions; text-align: left; }
  .task-plan-table td.tp-actions .btn { min-height: 40px; }
  .task-plan-table td:is(.tp-rhythm, .tp-target, .tp-last, .tp-next)::before { content: attr(data-label) ": "; color: var(--c-muted); font-size: var(--fs-label); }
}

/* Hoher Kontrast: Ränder der festen Auswahl und der Karten eine Stufe kräftiger, Werte in der vollen Textfarbe. */
html[data-contrast="high"] .task-fixed { border-color: var(--c-border); }
html[data-contrast="high"] ul.task-values { color: var(--c-text); }
@media (prefers-contrast: more) {
  html[data-contrast="system"] .task-fixed { border-color: var(--c-border); }
  html[data-contrast="system"] ul.task-values { color: var(--c-text); }
}

/* Erzwungene Farben: Die gewählte Ausführung und der gewählte Zustand bleiben markiert, Kanten der Zeilen als Rahmen. */
@media (forced-colors: active) {
  .task-modes .chip-button.on, .task-plan-filter .chip-button.on { forced-color-adjust: none; background: Highlight; color: HighlightText; border-color: Highlight; }
  .task-fixed { border: 1px solid CanvasText; }
  table.cols-jobs tr.edge-warn > td:first-child, table.cols-runs tr.edge-warn > td:first-child, .task-plan-table tr.edge-crit > td:first-child {
    border-left: 3px solid CanvasText;
  }
}
/* Ende Aufgaben 0.90 */

/* ---------- Checks 0.90 ---------- */
/* Checks (0.90, Strang D): Seite mit Paketen und Ergebnissen, Dialoge für Paket und Check, Reiter am Gerät mit Verlauf. */
/* Hinweiszeile auf die eingebauten Checks unter der Lagezeile (kein Banner), Werkzeugleiste mit Chips nach Zustand, Suche und Filtern. */
.ck-builtin { margin: 0 0 var(--sp-3); font-size: var(--fs-small); }
.ck-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2) var(--sp-3); margin-bottom: var(--sp-3); }
.ck-toolbar .search { flex: 1 1 220px; max-width: 360px; }
.ck-filter .chip-button { display: inline-flex; align-items: center; gap: 5px; }
.card.empty.ck-empty p { max-width: 72ch; margin: 0 auto var(--sp-3); }

/* Pakete: der Name nimmt den Rest; Ziele, Checks, Geräte, Zustand als Lampen mit Zahl, letzter Lauf und „Verwalten“ fest. */
table.ck-packages col.col-targets { width: 22%; }
table.ck-packages col.col-checks { width: 16%; }
table.ck-packages col.col-devices { width: 6rem; }
table.ck-packages col.col-states { width: 13rem; }
table.ck-packages col.col-last { width: 8.5rem; }
table.ck-packages col.col-actions { width: 7.5rem; }
table.ck-packages td.ck-name .pill { margin-left: 6px; }
table.ck-packages tr.is-paused td.ck-name .cell-main { color: var(--c-muted); }
.ck-lamps { display: inline-flex; flex-wrap: wrap; gap: 4px 10px; }
.ck-lamp { display: inline-flex; align-items: center; min-height: 24px; }
.ck-lamp .lamp-text, .ck-state .lamp-text, .ck-pkg-counts .lamp-text { font-size: inherit; }

/* Ergebnisse und Reiter am Gerät: Zustand, Gerät und Check fest, die Meldung nimmt den Rest, Werte als kleine Marken mit Zustand. */
table.ck-results col.col-state { width: 11rem; }
table.ck-results col.col-device { width: 14%; }
table.ck-results col.col-check { width: 16%; }
table.ck-results col.col-values { width: 19%; }
table.ck-results col.col-since { width: 10.5rem; }
table.ck-device-checks col.col-state { width: 11rem; }
table.ck-device-checks col.col-check { width: 20%; }
table.ck-device-checks col.col-values { width: 20%; }
table.ck-device-checks col.col-last { width: 9.5rem; }
table.ck-device-checks col.col-actions { width: 14.5rem; }
.ck-stale, .ck-alert-link { margin-left: 6px; }
.ck-value-list { display: flex; flex-wrap: wrap; gap: 4px; }
.ck-value {
  display: inline-block; max-width: 100%; padding: 1px 6px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: var(--fs-small); border: 1px solid var(--c-border-soft); border-radius: var(--radius-sm);
}
.ck-value-label { color: var(--c-muted); }
.ck-value.is-warn { border-color: var(--c-warn); background: var(--c-warn-bg); color: var(--c-warn-ink); }
.ck-value.is-crit { border-color: var(--c-crit); background: var(--c-crit-bg); color: var(--c-crit-ink); }
.ck-value.is-warn .ck-value-label, .ck-value.is-crit .ck-value-label { color: inherit; }
td.ck-row-actions { white-space: nowrap; text-align: right; }
td.ck-row-actions .btn + .btn { margin-left: 4px; }
.ck-history-toggle { display: inline-flex; align-items: center; gap: 4px; }
.ck-device-toolbar { flex-wrap: wrap; }

/* Verlauf beim Aufklappen: je Zahlenwert eine Karte mit letztem Wert, Sparkline der letzten Messungen und dem Mittel je Tag über 30 Tage. */
tr.ck-history-row > td { padding: var(--sp-3); background: var(--c-elev); }
.ck-history { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-3); }
.ck-series { min-width: 0; padding: var(--sp-2) var(--sp-3); background: var(--c-surface); border: 1px solid var(--c-border-soft); border-radius: var(--radius); }
.ck-series-head { display: grid; grid-template-columns: minmax(0, 1fr) auto 6rem; align-items: center; gap: var(--sp-2); margin-bottom: var(--sp-2); }
.ck-series-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; }
.ck-series-last { font-variant-numeric: tabular-nums; }
.ck-spark { width: 6rem; height: 24px; }

/* Dialog des Pakets: Kopf mit Zustand, Ausnahmen und Checks als Zeilen mit Aktion rechts. */
.ck-pkg-kv { margin-bottom: var(--sp-3); }
.ck-pkg-counts { display: flex; flex-wrap: wrap; gap: 4px 12px; }
.ck-exclusions, .ck-def-list { margin: 0 0 var(--sp-2); padding: 0; list-style: none; border: 1px solid var(--c-border-soft); border-radius: var(--radius-sm); }
.ck-exclusion { display: grid; grid-template-columns: minmax(0, 14rem) minmax(0, 1fr) auto; align-items: center; gap: var(--sp-2); padding: 6px var(--sp-3); border-bottom: 1px solid var(--c-border-soft); }
.ck-exclusion:last-child, .ck-def-row:last-child { border-bottom: 0; }
.ck-exclusion-dev, .ck-def-text { display: flex; flex-direction: column; min-width: 0; }
.ck-exclusion-reason { min-width: 0; font-size: var(--fs-small); color: var(--c-muted); overflow-wrap: anywhere; }
.ck-exclusion-add { margin-top: var(--sp-2); }
.ck-def-row { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: var(--sp-3); padding: 8px var(--sp-3); border-bottom: 1px solid var(--c-border-soft); }
.ck-def-row.is-off .ck-def-text .cell-main { color: var(--c-muted); }
.ck-def-ico { display: inline-flex; color: var(--c-muted); }
.ck-def-text .cell-main .pill { margin-left: 6px; }
.ck-def-actions { display: inline-flex; flex-wrap: wrap; justify-content: flex-end; gap: 4px; }
.ck-pkg-error, .ck-def-error { margin-top: var(--sp-3); }

/* Dialog des Checks: Erklärung der Bewertung, Schwellen je Rückgabewert mit dem Namen als Kopf und Warnung und Kritisch darunter nebeneinander
   (so bleibt der Vergleich „kleiner als“ in der Auswahl lesbar). */
.ck-def-rule { margin: var(--sp-2) 0 0; }
.ck-thresholds { display: flex; flex-direction: column; border: 1px solid var(--c-border-soft); border-radius: var(--radius-sm); }
.ck-threshold {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-items: center; gap: var(--sp-2) var(--sp-3);
  padding: 8px var(--sp-3); border-bottom: 1px solid var(--c-border-soft);
}
.ck-threshold:last-child { border-bottom: 0; }
.ck-threshold-name { grid-column: 1 / -1; display: flex; flex-direction: column; min-width: 0; }
.ck-threshold-cond { display: grid; grid-template-columns: 6.5rem minmax(0, 1fr) minmax(0, 5.5rem); align-items: center; gap: 6px; min-width: 0; }
.ck-threshold-cond select, .ck-threshold-cond input { width: 100%; min-width: 0; }
.ck-threshold-label .lamp-text { font-size: var(--fs-small); }
.ck-defaults { margin-top: var(--sp-2); }

@media (min-width: 641px) {
  /* Mindestbreiten: darunter rollt die Tabelle seitlich, statt die Spalten unlesbar schmal zu machen. */
  table.ck-packages.cols-fixed { min-width: 58rem; }
  table.ck-results.cols-fixed { min-width: 62rem; }
  table.ck-device-checks.cols-fixed { min-width: 58rem; }
}
@media (max-width: 900px) {
  .ck-history { grid-template-columns: minmax(0, 1fr); }
}
/* Telefon: Tabellen als Karten mit beschrifteten Werten, Chips, Suche und Knöpfe mit Tippflächen von 40 px, Zeilen der Dialoge gestapelt. */
@media (max-width: 640px) {
  .ck-toolbar .search { flex-basis: 100%; max-width: none; }
  .ck-filter .chip-button, .ck-toolbar .btn, .ck-toolbar .search, .ck-device-toolbar .btn, .ck-def-actions .btn, .btn.ck-def-add, .ck-exclusion .btn,
  td.ck-row-actions .btn { min-height: 40px; }
  :where(table.cols-fixed.ck-packages, table.cols-fixed.ck-results, table.cols-fixed.ck-device-checks) > colgroup { display: none; }
  :where(table.cols-fixed.ck-packages, table.cols-fixed.ck-results, table.cols-fixed.ck-device-checks) > tbody > tr > td:not(.wrap, [colspan]) :where(.cell-main, .cell-sub) {
    overflow: visible; text-overflow: clip; padding-inline: 0; margin-inline: 0;
  }
  table.ck-packages thead, table.ck-results thead, table.ck-device-checks thead { display: none; }
  table.ck-packages, table.ck-packages tbody, table.ck-results, table.ck-results tbody, table.ck-device-checks, table.ck-device-checks tbody { display: block; }
  table.ck-packages tr, table.ck-results tr, table.ck-device-checks tr {
    display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: start; gap: 4px var(--sp-2);
    padding: 10px var(--sp-3); border-bottom: 1px solid var(--c-border-soft);
  }
  table.ck-packages tbody tr:last-child, table.ck-results tbody tr:last-child, table.ck-device-checks tbody tr:last-child { border-bottom: 0; }
  .table-wrap table.ck-packages td, .table-wrap table.ck-results td, .table-wrap table.ck-device-checks td {
    display: block; padding: 0; border: 0; min-width: 0; max-width: none; width: auto; overflow: visible; text-overflow: clip; white-space: normal;
    text-align: left; font-size: var(--fs-small);
  }
  table.ck-packages tr { grid-template-areas: "name actions" "targets targets" "checks checks" "states states" "devices last"; }
  .table-wrap table.ck-packages td.ck-name { grid-area: name; font-size: var(--fs-body); }
  .table-wrap table.ck-packages td.ck-actions { grid-area: actions; text-align: right; }
  table.ck-packages td.ck-targets { grid-area: targets; }
  table.ck-packages td.ck-checks { grid-area: checks; }
  table.ck-packages td.ck-states { grid-area: states; }
  table.ck-packages td.ck-devices { grid-area: devices; }
  .table-wrap table.ck-packages td.ck-last { grid-area: last; text-align: right; }
  table.ck-packages td.ck-actions .btn { min-height: 40px; }
  table.ck-results tr { grid-template-areas: "state since" "device device" "check check" "msg msg" "values values"; }
  table.ck-results td.ck-state, table.ck-device-checks td.ck-state { grid-area: state; }
  .table-wrap table.ck-results td.ck-since { grid-area: since; text-align: right; }
  table.ck-results td.ck-device { grid-area: device; }
  table.ck-results td.ck-check, table.ck-device-checks td.ck-check { grid-area: check; }
  table.ck-results td.ck-msg, table.ck-device-checks td.ck-msg { grid-area: msg; }
  table.ck-results td.ck-values, table.ck-device-checks td.ck-values { grid-area: values; }
  table.ck-device-checks tr { grid-template-areas: "state last" "check check" "msg msg" "values values" "actions actions"; }
  .table-wrap table.ck-device-checks td.ck-last { grid-area: last; text-align: right; }
  .table-wrap table.ck-device-checks td.ck-row-actions { grid-area: actions; display: flex; flex-wrap: wrap; gap: 6px; text-align: left; }
  td.ck-row-actions .btn + .btn { margin-left: 0; }
  table.ck-device-checks tr.ck-history-row { display: block; padding: var(--sp-2); }
  table.ck-device-checks tr.ck-history-row > td { padding: 0; background: transparent; }
  :where(.ck-packages, .ck-results, .ck-device-checks) td:is(.ck-targets, .ck-checks, .ck-devices, .ck-device, .ck-check, .ck-values)[data-label]::before {
    content: attr(data-label) " "; color: var(--c-muted); font-size: var(--fs-label);
  }
  table.ck-results tr.edge-crit, table.ck-device-checks tr.edge-crit { box-shadow: inset 3px 0 0 var(--c-crit); }
  table.ck-results tr.edge-warn, table.ck-device-checks tr.edge-warn { box-shadow: inset 3px 0 0 var(--c-warn); }
  table.ck-results tr.edge-crit > td:first-child, table.ck-results tr.edge-warn > td:first-child,
  table.ck-device-checks tr.edge-crit > td:first-child, table.ck-device-checks tr.edge-warn > td:first-child { box-shadow: none; }
  .ck-exclusion { grid-template-columns: minmax(0, 1fr) auto; }
  .ck-exclusion-reason { grid-column: 1 / -1; grid-row: 2; }
  .ck-def-row { grid-template-columns: auto minmax(0, 1fr); }
  .ck-def-actions { grid-column: 1 / -1; justify-content: flex-start; }
  .ck-threshold, .ck-threshold-cond { grid-template-columns: minmax(0, 1fr); }
  .ck-threshold-cond select, .ck-threshold-cond input { min-height: 40px; }
  .ck-series-head { grid-template-columns: minmax(0, 1fr) auto; }
  .ck-spark { grid-column: 1 / -1; width: 100%; }
}
/* Hoher Kontrast: Ränder der Marken, Listen und Karten eine Stufe kräftiger, gedämpfte Zeilen in voller Textfarbe. */
html[data-contrast="high"] :is(.ck-value, .ck-exclusions, .ck-def-list, .ck-thresholds, .ck-series) { border-color: var(--c-border); }
html[data-contrast="high"] :is(.ck-exclusion, .ck-def-row, .ck-threshold) { border-bottom-color: var(--c-border); }
html[data-contrast="high"] table.ck-packages tr.is-paused td.ck-name .cell-main, html[data-contrast="high"] .ck-def-row.is-off .ck-def-text .cell-main { color: var(--c-text); }
@media (prefers-contrast: more) {
  html[data-contrast="system"] :is(.ck-value, .ck-exclusions, .ck-def-list, .ck-thresholds, .ck-series) { border-color: var(--c-border); }
  html[data-contrast="system"] :is(.ck-exclusion, .ck-def-row, .ck-threshold) { border-bottom-color: var(--c-border); }
  html[data-contrast="system"] table.ck-packages tr.is-paused td.ck-name .cell-main, html[data-contrast="system"] .ck-def-row.is-off .ck-def-text .cell-main { color: var(--c-text); }
}
/* Erzwungene Farben: Marken mit Rand; Warnung gestrichelt, kritisch doppelt, damit der Zustand ohne Farbe lesbar bleibt; gewählter Filter markiert. */
@media (forced-colors: active) {
  .ck-value, .ck-exclusions, .ck-def-list, .ck-thresholds, .ck-series { border: 1px solid CanvasText; }
  .ck-value.is-warn { border-style: dashed; }
  .ck-value.is-crit { border-width: 3px; border-style: double; }
  .ck-filter .chip-button.on { forced-color-adjust: none; background: Highlight; color: HighlightText; border-color: Highlight; }
  table.ck-packages tr.is-paused td.ck-name .cell-main { color: GrayText; }
}
/* Ende Checks 0.90 */

/* ---------- Check-Vorlagen 0.91 ---------- */
/* Reiter „Vorlagen“ der Checks (0.91): Vorlagen als Zeilen mit festen Spalten für Checks, Ziel und Aktion; die Texte brechen um, weil man sie liest.
   Im Dialog des Pakets stehen Vorschlag und Hinweis der Vorlage als ruhige Zeile unter der Überschrift des Abschnitts. */
.ck-template-intro { max-width: 90ch; margin: 0 0 var(--sp-3); font-size: var(--fs-small); }
table.ck-templates col.col-checks { width: 26%; }
table.ck-templates col.col-target { width: 24%; }
table.ck-templates col.col-actions { width: 9.5rem; }
table.ck-templates td.ck-name .cell-sub + .cell-sub { margin-top: 4px; }
table.ck-templates td.ck-actions { white-space: nowrap; text-align: right; }
.ck-template-note { color: var(--c-text); }
.ck-template-hint { margin: 0 0 var(--sp-2); }

@media (min-width: 641px) {
  /* Mindestbreite: darunter rollt die Tabelle seitlich, statt die Spalten unlesbar schmal zu machen. */
  table.ck-templates.cols-fixed { min-width: 52rem; }
}
/* Telefon: jede Vorlage als Karte mit Name und Knopf oben, Checks und Ziel beschriftet darunter; Tippfläche 40 px. */
@media (max-width: 640px) {
  table.cols-fixed.ck-templates > colgroup { display: none; }
  table.ck-templates thead { display: none; }
  table.ck-templates, table.ck-templates tbody { display: block; }
  table.ck-templates tr {
    display: grid; grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "name actions" "checks checks" "target target";
    align-items: start; gap: 4px var(--sp-2); padding: 10px var(--sp-3); border-bottom: 1px solid var(--c-border-soft);
  }
  table.ck-templates tbody tr:last-child { border-bottom: 0; }
  .table-wrap table.ck-templates td {
    display: block; padding: 0; border: 0; min-width: 0; max-width: none; width: auto; overflow: visible; text-overflow: clip; white-space: normal;
    text-align: left; font-size: var(--fs-small);
  }
  .table-wrap table.ck-templates td.ck-name { grid-area: name; font-size: var(--fs-body); }
  .table-wrap table.ck-templates td.ck-actions { grid-area: actions; text-align: right; }
  table.ck-templates td.ck-checks { grid-area: checks; }
  table.ck-templates td.ck-target { grid-area: target; }
  table.ck-templates td.ck-checks > div:first-child { display: inline; }
  table.ck-templates td.ck-actions .btn { min-height: 40px; }
  table.ck-templates td:is(.ck-checks, .ck-target)[data-label]::before { content: attr(data-label) " "; color: var(--c-muted); font-size: var(--fs-label); }
}
/* Hoher Kontrast: Trennlinien der Karten eine Stufe kräftiger. */
html[data-contrast="high"] table.ck-templates tr { border-bottom-color: var(--c-border); }
@media (prefers-contrast: more) {
  html[data-contrast="system"] table.ck-templates tr { border-bottom-color: var(--c-border); }
}
/* Erzwungene Farben: Trennlinien der Karten in Systemfarbe, der Hinweis bleibt als Text lesbar. */
@media (forced-colors: active) {
  table.ck-templates tr { border-bottom-color: CanvasText; }
  .ck-template-note { color: CanvasText; }
}
/* Ende Check-Vorlagen 0.91 */
/* ---------- Symbole 0.91.1 ---------- */
/* Einstellungen › Branding (0.91.1): Zeilen „Favicon“ und „Tray-Symbol“ mit Kacheln wie die Logos. Die Vorschau zeigt das Symbol in 32 und
   16 px (Browser-Tab und Taskleiste bei doppelter und einfacher Pixeldichte), ohne Tray-Symbol den Statuspunkt der Tray-App. */
.logo-tile-stage.brand-icon-stage { gap: 16px; }
.logo-tile-stage.brand-icon-stage img { width: 32px; height: 32px; max-width: none; }
.logo-tile-stage.brand-icon-stage img.is-small { width: 16px; height: 16px; }
.brand-icon-dot { display: block; width: 22px; height: 22px; border-radius: 50%; background: var(--c-muted); border: 2px solid var(--c-border); }
/* Telefon: Knöpfe der Kacheln mit Tippfläche 40 px. */
@media (max-width: 640px) {
  .brand-icon-tile .logo-tile-actions .btn { min-height: 40px; }
}
/* Hoher Kontrast: Rand des Statuspunkts in Textfarbe. */
html[data-contrast="high"] .brand-icon-dot { border-color: var(--c-text); }
@media (prefers-contrast: more) {
  html[data-contrast="system"] .brand-icon-dot { border-color: var(--c-text); }
}
/* Erzwungene Farben: Der Statuspunkt bleibt als Fläche sichtbar. */
@media (forced-colors: active) {
  .brand-icon-dot { forced-color-adjust: none; background: CanvasText; border-color: Canvas; }
}
/* Ende Symbole 0.91.1 */
/* ---------- Lesbarkeit 0.91.1 ---------- */
/* Balken je Zeile (HBarChart, etwa „Patch-Stand je Kunde“ im Dashboard) als Raster statt SVG: Die Schrift bleibt in der Größe des übrigen
   Textes, nur die Balken folgen der Breite der Karte. Spalten: Name (höchstens 16rem, sonst „…“), Balken, Wert. */
.hbar { display: grid; grid-template-columns: minmax(0, max-content) minmax(6rem, 1fr) auto; align-items: center; gap: 8px 12px; }
.hbar-label { max-width: 16rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--fs-small); font-weight: 600; color: var(--c-text); }
.hbar-track { display: flex; gap: 2px; min-width: 0; height: 14px; }
.hbar-seg { display: block; flex: 0 1 auto; min-width: 2px; height: 100%; }
.hbar-seg:last-child { border-radius: 0 3px 3px 0; }
.hbar-value { font-size: var(--fs-small); color: var(--c-muted); font-variant-numeric: tabular-nums; white-space: nowrap; }
/* Wandanzeige: Hinweis im Kopf der Alarme, dass die Anzeige nur eine Auswahl der Checks oder keine quittierten Alarme zeigt. */
.wall-scope { margin-right: auto; font-size: .8rem; color: var(--c-muted); white-space: nowrap; }
.wd-group .wd-handled { margin-top: var(--sp-2); }
/* Telefon: Namen schmaler, damit der Balken Platz behält; Tippfläche des Schalters 40 px. */
@media (max-width: 640px) {
  .hbar { grid-template-columns: minmax(0, 9rem) minmax(4rem, 1fr) auto; gap: 6px 8px; }
  .hbar-label { max-width: 9rem; }
  .wd-group .wd-handled { min-height: 40px; }
}
/* Hoher Kontrast: Balken mit Rand in Textfarbe, damit sie sich von der Fläche abheben. */
html[data-contrast="high"] .hbar-seg { outline: 1px solid var(--c-text); }
@media (prefers-contrast: more) {
  html[data-contrast="system"] .hbar-seg { outline: 1px solid var(--c-text); }
}
/* Erzwungene Farben: Die Anteile behalten ihre Zustandsfarben und bekommen einen Rand in Systemfarbe. */
@media (forced-colors: active) {
  .hbar-seg { forced-color-adjust: none; outline: 1px solid CanvasText; }
}
/* Ende Lesbarkeit 0.91.1 */
/* ---------- Korrekturen 0.92 ---------- */
/* Auswahllisten: Seit 0.88 sind Auswahlfelder in Filterleisten durchsichtig (Chip). Chrome und Edge unter Windows zeichnen die geöffnete
   Liste dann weiß, die Schrift bleibt hell: im Nachtmodus unlesbar. Optionen tragen deshalb die Farben der Eingabefelder, überall. */
select option, select optgroup { background-color: var(--c-input); color: var(--c-text); }
/* Listen mit Mehrfachauswahl (select multiple, size): Die Farbe der Optionen oben überdeckt dort die Markierung des Browsers. Gewählte
   Optionen tragen deshalb die Farbe gewählter Zeilen und bleiben im Nachtmodus wie am Tag erkennbar. */
select[multiple] option:checked, select[size] option:checked { background-color: var(--c-selected); color: var(--c-text); }
/* Telefon: Auswahlfelder der Filterleisten mit Tippfläche 40 px; der Chip wächst mit. */
@media (max-width: 640px) {
  .toolbar .filter:not(.filter-search) { height: auto; }
  .toolbar .filter > select { min-height: 40px; }
}
/* Hoher Kontrast: Die gewählte Option ist fett, damit sie in der geöffneten Liste erkennbar bleibt. */
html[data-contrast="high"] select option:checked { font-weight: 700; }
@media (prefers-contrast: more) {
  html[data-contrast="system"] select option:checked { font-weight: 700; }
}
/* Erzwungene Farben: Optionen in den Systemfarben, gewählte Optionen einer Liste in der Farbe der Markierung. */
@media (forced-colors: active) {
  select option, select optgroup { background-color: Canvas; color: CanvasText; }
  select[multiple] option:checked, select[size] option:checked { background-color: Highlight; color: HighlightText; }
}
/* Ende Korrekturen 0.92 */
/* ---------- Filter 0.92 ---------- */
/* Baustein „Filter“ (DeviceFilterEditor): Gruppen mit Umschalter „und“/„oder“, Untergruppen eingerückt mit einer Linie in der Rahmenfarbe,
   Regeln als Karte: oben Merkmal, (eigenes Feld,) Vergleich und Entfernen, darunter die Werte (Chips, Umschalter, Auswahl), darunter der
   Hinweis bzw. die Prüfmeldung. Eine ungültige Regel trägt links eine Kante in der Warnfarbe. */
.df-editor { display: grid; gap: var(--sp-2); min-width: 0; }
.df-group { display: grid; gap: var(--sp-2); min-width: 0; }
.df-group.df-sub { margin-left: var(--sp-4); padding: var(--sp-2) 0 var(--sp-2) var(--sp-3); border-left: 2px solid var(--c-border); }
.df-group-head { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; }
.df-logic-label { font-size: var(--fs-small); font-weight: 600; color: var(--c-muted); }
.df-logic .chip-button { min-width: 3.5rem; }
.df-logic-hint { margin: 0; }
.df-group-head > .df-remove { margin-left: auto; }
.df-items { display: grid; gap: var(--sp-2); margin: 0; padding: 0; list-style: none; }
.df-item { min-width: 0; }
.df-rule {
  display: grid; grid-template-columns: minmax(0, 13rem) minmax(0, 11rem) minmax(0, 1fr) auto; align-items: center; gap: var(--sp-2);
  grid-template-areas: "kind op . remove" "values values values values" "note note note note";
  padding: var(--sp-2) var(--sp-3); border: 1px solid var(--c-border-soft); border-radius: var(--radius-sm); background: var(--c-surface);
}
.df-rule:has(> .df-field) {
  grid-template-columns: minmax(0, 13rem) minmax(0, 1fr) minmax(0, 11rem) auto;
  grid-template-areas: "kind field op remove" "values values values values" "note note note note";
}
.df-rule.is-invalid { border-left: 3px solid var(--c-warn); }
.df-rule > .df-kind { grid-area: kind; }
.df-rule > .df-field { grid-area: field; }
.df-rule > .df-op { grid-area: op; }
.df-rule > .df-values { grid-area: values; }
.df-rule > .df-remove { grid-area: remove; justify-self: end; }
.df-rule > .df-note { grid-area: note; }
.df-rule select { min-width: 0; }
.df-values { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); min-width: 0; }
.df-values > select, .df-values > input:not([type=date]), .df-values > .df-chips { flex: 1 1 14rem; min-width: 0; }
.df-values > input[type=date] { flex: 0 1 12rem; }
.df-values > .df-publisher { flex: 1 1 12rem; }
.df-text { min-width: 0; }
/* Hersteller der Anwendung: leer erklärt der Platzhalter das Feld, ausgefüllt steht die Beschriftung davor. */
.df-publisher { display: flex; align-items: center; gap: var(--sp-2); min-width: 0; margin: 0; }
.df-publisher > input { flex: 1 1 auto; width: auto; min-width: 0; }
.df-publisher-label { flex: 0 0 auto; font-size: var(--fs-label); color: var(--c-muted); white-space: nowrap; }
.df-publisher:has(> input:placeholder-shown) > .df-publisher-label { display: none; }
.df-note { display: block; font-size: var(--fs-label); line-height: 1.4; color: var(--c-muted); }
.df-note.is-error { color: var(--c-warn-ink); font-weight: 600; }
/* Werte als Chips: Texte in einem Feld mit Eingabe (df-tags), gewählte Kunden, Standorte und Gruppen neben dem Auswahlfeld. */
.df-chips { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; min-width: 0; }
.df-tags { padding: 3px 4px; border: 1px solid var(--c-border-input); border-radius: var(--radius-sm); background: var(--c-input); }
.df-tags:focus-within { outline: var(--focus-w) solid var(--c-focus); outline-offset: 2px; border-color: var(--c-accent-line); }
.df-chip {
  display: inline-flex; align-items: center; gap: 2px; max-width: 100%; min-height: 26px; padding: 0 2px 0 9px;
  border: 1px solid var(--c-accent-border); border-radius: 999px; background: var(--c-accent-tint); color: var(--c-accent-ink); font-size: var(--fs-small);
}
.df-chip-text { min-width: 0; overflow-wrap: anywhere; }
.df-chip-remove {
  flex: 0 0 auto; width: 22px; height: 22px; padding: 0; border: 0; border-radius: 50%;
  background: transparent; color: inherit; font: inherit; font-size: 1rem; line-height: 1; cursor: pointer;
}
.df-chip-remove:hover { background: var(--c-hover); }
.df-chip-remove:focus-visible { outline: var(--focus-w) solid var(--c-focus); outline-offset: 1px; }
.df-tags > .df-chip-input { flex: 1 1 9rem; width: auto; min-width: 7rem; min-height: 26px; padding: 2px 4px; border: 0; background: transparent; }
.df-tags > .df-chip-input:focus { outline: none; }
.df-chips > .df-picker { flex: 1 1 12rem; width: auto; min-width: 0; }
.df-choices { flex: 1 1 auto; }
.df-empty, .df-none, .df-negative { margin: 0; font-size: var(--fs-small); }
.df-error { margin: 0; font-size: var(--fs-small); font-weight: 600; color: var(--c-warn-ink); }
.df-add { display: flex; gap: var(--sp-2); flex-wrap: wrap; }
.df-lead { margin: 0 0 var(--sp-2); font-size: var(--fs-small); }
/* Check-Paket: die Vorschau der Ziele mit Abstand unter der Feinauswahl. */
p.df-target-preview { margin-top: var(--sp-3); }
/* Vorschau (DeviceFilterPreview): Zahl als Pille mit Lampe, „Neu berechnen“ rechts, darunter die ersten Geräte als Zeilen. */
.df-preview {
  display: grid; gap: var(--sp-2); min-width: 0; padding: var(--sp-2) var(--sp-3);
  border: 1px solid var(--c-border-soft); border-radius: var(--radius-sm); background: var(--c-neutral-bg);
}
.df-preview-head { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); }
.df-preview-head .lamp-text { font-size: var(--fs-small); color: var(--c-text); white-space: normal; overflow-wrap: anywhere; }
.df-preview-status { display: inline-flex; align-items: center; min-width: 0; }
.df-preview-count { display: inline-flex; align-items: center; gap: 6px; font-size: var(--fs-small); }
.df-preview-count .lamp { color: inherit; }
.df-preview-refresh { margin-left: auto; }
.df-preview-list { display: grid; margin: 0; padding: 0; list-style: none; border: 1px solid var(--c-border-soft); border-radius: var(--radius-sm); background: var(--c-surface); }
.df-preview-row {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 14rem) auto; grid-template-areas: "name cust class";
  align-items: center; gap: 2px var(--sp-2); padding: 6px 10px; border-bottom: 1px solid var(--c-border-soft);
}
.df-preview-row:last-child { border-bottom: 0; }
.df-preview-name { grid-area: name; font-weight: 600; overflow-wrap: anywhere; }
.df-preview-customer { grid-area: cust; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.df-preview-class { grid-area: class; justify-self: end; }
.df-preview-none, .df-preview-more { margin: 0; font-size: var(--fs-small); }
/* Touch: Tippflächen der Chips mindestens 40 px. */
@media (pointer: coarse) {
  .df-chip-remove { width: 40px; height: 40px; }
  .df-chip { min-height: 40px; }
}
/* Telefon: Merkmal und Entfernen oben, darunter Feld, Vergleich, Werte und Hinweis untereinander; Tippflächen 40 px; Untergruppen weniger
   eingerückt; die Geräte der Vorschau zweizeilig (Name und Klasse, darunter der Kunde). */
@media (max-width: 640px) {
  .df-rule, .df-rule:has(> .df-field) {
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas: "kind remove" "field field" "op op" "values values" "note note";
    padding: var(--sp-2);
  }
  .df-values > select, .df-values > input, .df-values > .df-chips, .df-values > .df-publisher { flex: 1 1 100%; }
  .df-rule select, .df-rule input, .df-add .btn, .df-logic .chip-button, .df-choices .chip-button, .df-preview-refresh { min-height: 40px; }
  .df-chip-remove { width: 40px; height: 40px; }
  .df-chip { min-height: 40px; }
  .df-tags > .df-chip-input { flex: 1 1 100%; min-height: 40px; }
  /* Entfernen mit dem kurzen Text unter dem Symbol (wie die Symbolknöpfe in den Karten der Tabellen), die Fläche wächst mit. */
  :is(.df-rule, .df-group-head) > .df-remove.btn { width: auto; min-width: 40px; height: auto; min-height: 40px; padding: 4px 6px; }
  .df-group.df-sub { margin-left: var(--sp-2); padding-left: var(--sp-2); }
  .df-preview-row { grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "name class" "cust cust"; }
  .df-preview-customer { white-space: normal; overflow-wrap: anywhere; }
}
/* Hoher Kontrast: Linie der Untergruppen, Rand der Regeln, Chips und Vorschau in Textfarbe. */
html[data-contrast="high"] .df-group.df-sub { border-left-color: var(--c-text); }
html[data-contrast="high"] :is(.df-rule, .df-chip, .df-preview, .df-preview-list) { border-color: var(--c-text); }
@media (prefers-contrast: more) {
  html[data-contrast="system"] .df-group.df-sub { border-left-color: var(--c-text); }
  html[data-contrast="system"] :is(.df-rule, .df-chip, .df-preview, .df-preview-list) { border-color: var(--c-text); }
}
/* Erzwungene Farben: Linien und Ränder in Systemfarben; eine ungültige Regel bleibt an der gestrichelten Kante erkennbar. */
@media (forced-colors: active) {
  .df-group.df-sub { border-left-color: CanvasText; }
  :is(.df-rule, .df-chip, .df-preview, .df-preview-list, .df-tags) { border-color: CanvasText; }
  .df-rule.is-invalid { border-left: 3px dashed CanvasText; }
  .df-chip { forced-color-adjust: none; background: Canvas; color: CanvasText; }
  .df-chip-remove { forced-color-adjust: none; color: ButtonText; }
  .df-note.is-error, .df-error { color: CanvasText; }
}
/* Ende Filter 0.92 */
/* ---------- Patch-Richtlinien 0.92 ---------- */
/* Strang B: Reiter „Richtlinien“ im Patchmanagement (Liste der Patch-Richtlinien mit festen Spalten, auf dem Telefon Karten; Neustarts, die
   der Server hält), Dialog der Patch-Richtlinie (Kunden und Standorte als Chips, Filter, Vorschau, eigene Werte), Zeile „Patch-Richtlinie“ im
   Reiter Updates des Geräts und der Grund eines gehaltenen Neustarts am Lauf. */
.pp-section { margin-bottom: var(--sp-4); }
.pp-intro { max-width: 92ch; margin: 0 0 var(--sp-3); }
.pp-toolbar { flex-wrap: wrap; align-items: center; }
.pp-toolbar .pp-create { margin-left: auto; }
.card.empty.pp-empty p { max-width: 72ch; margin: 0 auto var(--sp-3); }
/* Name bricht um (er ist das Merkmal der Zeile), darunter die Zahl der Werte und die Beschreibung; Treffer mit „davon wirksam“ darunter. */
.pp-table col.col-scope { width: 13%; }
.pp-table col.col-assign { width: 26%; }
.pp-table col.col-hits { width: 8.5rem; }
.pp-table col.col-rank { width: 4.5rem; }
.pp-table col.col-active { width: 7rem; }
.pp-table col.col-actions { width: 7.5rem; }
.pp-table td.pp-name .cell-main { display: flex; align-items: flex-start; gap: 6px; min-width: 0; white-space: normal; }
.pp-table td.pp-name .pp-name-text { min-width: 0; overflow-wrap: anywhere; font-weight: 600; }
.pp-table td.pp-name .pp-name-sub { display: flex; align-items: center; gap: 6px; min-width: 0; margin-top: 2px; }
.pp-table td.pp-name .pp-name-sub .pill { flex: 0 0 auto; }
.pp-table td.pp-name .pp-desc { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pp-table .pp-ico { flex: 0 0 auto; margin-top: 2px; color: var(--c-muted); }
.pp-table td.pp-scope { white-space: normal; overflow-wrap: anywhere; }
.pp-table td.pp-assign .cell-main { white-space: normal; overflow-wrap: anywhere; font-weight: 400; }
.pp-table td.pp-hits .cell-main { font-weight: 400; }
.pp-table td.pp-rank { color: var(--c-muted); }
.pp-table tr.is-off td.pp-name .pp-name-text, .pp-table tr.is-off td.pp-assign .cell-main { color: var(--c-muted); }
.pp-table td.pp-active { overflow: visible; text-overflow: clip; }
.pp-table td.pp-active .switch { margin: 0; }
@media (min-width: 641px) {
  table.pp-table.cols-fixed { min-width: 56rem; }
}
.pp-standard-title { margin-top: var(--sp-6); }
.pp-held { margin-bottom: var(--sp-4); }
.pp-held-table col.col-state { width: 12rem; }
.pp-held-table col.col-since { width: 8.5rem; }
.pp-held-table td.pph-since { color: var(--c-muted); }
.pp-severity-title { margin: var(--sp-4) 0 var(--sp-2); font-size: var(--fs-section); }

/* Dialog: Kopf mit Zustand, Zuweisung mit Chips und Auswahl zum Hinzufügen, Filter, Vorschau, eigene Werte als Zeilen. */
.pp-lead { margin: 0 0 var(--sp-3); }
.pp-kv { margin-bottom: var(--sp-3); }
.pp-hint { margin: 0 0 var(--sp-2); font-size: var(--fs-small); }
.pp-form .pp-enabled { display: flex; flex-direction: column; gap: var(--sp-1); }
.pp-pick { display: flex; flex-wrap: wrap; align-items: center; gap: 6px var(--sp-2); margin: 0 0 var(--sp-2); }
.pp-pick-label { flex: 0 0 6.5rem; font-size: var(--fs-small); font-weight: 600; color: var(--c-muted); }
.pp-pick-all { font-size: var(--fs-small); }
.pp-chips { display: flex; flex-wrap: wrap; gap: 6px; margin: 0; padding: 0; list-style: none; }
.pp-chips:empty { display: none; }
.pp-chip {
  display: inline-flex; align-items: center; gap: var(--sp-1); max-width: 100%; min-height: 30px; padding: 2px 3px 2px 10px;
  border: 1px solid var(--c-accent-line); border-radius: 999px; background: var(--c-accent-tint); color: var(--c-accent-ink); font-size: var(--fs-small);
}
.pp-chip-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pp-chip-remove {
  flex: 0 0 auto; width: 24px; height: 24px; padding: 0; border: 0; border-radius: 50%;
  background: transparent; color: inherit; font: inherit; font-size: 1rem; line-height: 1; cursor: pointer;
}
.pp-chip-remove:hover { background: var(--c-hover); }
.pp-chip-remove:focus-visible { outline: var(--focus-w) solid var(--c-focus); outline-offset: 1px; }
.pp-add { width: auto; max-width: 16rem; }
.pp-filter { display: grid; gap: var(--sp-2); margin: var(--sp-3) 0 var(--sp-2); }
.pp-values { display: grid; margin: 0 0 var(--sp-3); padding: 0; list-style: none; border: 1px solid var(--c-border-soft); border-radius: var(--radius-sm); }
.pp-value {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "name own" "inherited inherited";
  gap: 2px var(--sp-3); padding: 7px 12px; border-bottom: 1px solid var(--c-border-soft);
}
.pp-value:last-child { border-bottom: 0; }
.pp-value-name { grid-area: name; font-weight: 600; overflow-wrap: anywhere; }
.pp-value-own { grid-area: own; text-align: right; }
.pp-value-inherited { grid-area: inherited; font-size: var(--fs-small); }
.pp-error { margin-top: var(--sp-3); }

/* Gerät: Zeile „Patch-Richtlinie“ im Reiter Updates, Grund des gehaltenen Neustarts im Verlauf, Regel je Schweregrad in den Freigaben. */
.pp-device-line { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; margin: 0 0 var(--sp-3); font-size: var(--fs-small); color: var(--c-muted); }
.pp-device-line > .ico { flex: 0 0 auto; }
.pp-device-line a { color: var(--c-accent-ink); }
/* break-word statt anywhere: Die Spalte des Verlaufs (Tabelle ohne feste Spalten) wird sonst bis auf ein Zeichen schmal. */
.pp-reboot-detail, .pp-severity-rule { white-space: normal; overflow-wrap: break-word; }

/* Touch: Tippflächen mindestens 40 px. */
@media (pointer: coarse) {
  .pp-chip-remove { width: 40px; height: 40px; }
  .pp-chip, .pp-add { min-height: 40px; }
}

/* Telefon: Listen als Karten mit Beschriftung je Feld (data-label), Werkzeugleiste und Auswahl untereinander, Tippflächen 40 px. */
@media (max-width: 640px) {
  .pp-table thead, .pp-table colgroup, .pp-held-table thead, .pp-held-table colgroup { display: none; }
  .pp-table, .pp-table tbody, .pp-held-table, .pp-held-table tbody { display: block; }
  .pp-table tbody tr {
    display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: var(--sp-1) var(--sp-2); padding: 10px var(--sp-3);
    border-bottom: 1px solid var(--c-border-soft);
    grid-template-areas: "name active" "scope rank" "assign assign" "hits actions";
  }
  .pp-held-table tbody tr {
    display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: var(--sp-1) var(--sp-2); padding: 10px var(--sp-3);
    border-bottom: 1px solid var(--c-border-soft);
    grid-template-areas: "device since" "state state" "reason reason";
  }
  .pp-table tbody tr:last-child, .pp-held-table tbody tr:last-child { border-bottom: 0; }
  .table-wrap .pp-table td, .table-wrap .pp-held-table td {
    display: block; min-width: 0; padding: 0; border: 0; white-space: normal; overflow: visible; text-overflow: clip;
  }
  .pp-table td .cell-main, .pp-table td .cell-sub, .pp-held-table td .cell-main, .pp-held-table td .cell-sub { padding-inline: 0; margin-inline: 0; overflow: visible; }
  .pp-table td.pp-name { grid-area: name; }
  .pp-table td.pp-active { grid-area: active; text-align: right; }
  .pp-table td.pp-scope { grid-area: scope; }
  .pp-table td.pp-rank { grid-area: rank; text-align: right; }
  .pp-table td.pp-assign { grid-area: assign; }
  .pp-table td.pp-hits { grid-area: hits; }
  .pp-table td.pp-hits .cell-main { display: inline; }
  .pp-table td.pp-actions { grid-area: actions; align-self: end; text-align: right; }
  .pp-table td:is(.pp-scope, .pp-assign, .pp-hits, .pp-rank)::before,
  .pp-held-table td:is(.pph-state, .pph-reason)::before,
  .pp-rules-table td:not(:first-child)::before { content: attr(data-label) ": "; color: var(--c-muted); font-size: var(--fs-label); }
  .pp-held-table td.pph-device { grid-area: device; }
  .pp-held-table td.pph-since { grid-area: since; text-align: right; }
  .pp-held-table td.pph-state { grid-area: state; }
  .pp-held-table td.pph-reason { grid-area: reason; }
  /* Freigaberegeln und Regeln je Schweregrad: je Zeile eine Karte mit Gruppe bzw. Schweregrad als Titel. */
  .pp-rules-table thead { display: none; }
  .pp-rules-table, .pp-rules-table tbody { display: block; }
  .pp-rules-table tbody tr { display: grid; gap: 2px; padding: 8px var(--sp-3); border-bottom: 1px solid var(--c-border-soft); }
  .pp-rules-table tbody tr:last-child { border-bottom: 0; }
  .table-wrap .pp-rules-table td { display: block; min-width: 0; padding: 0; border: 0; white-space: normal; }
  .card > .table-wrap :is(.pp-held-table, .pp-rules-table) td:first-child { padding-left: 0; }
  .pp-table td.pp-actions .btn, .pp-toolbar .btn, .pp-order .chip-button, .pp-add, .pp-table td.pp-active .switch { min-height: 40px; }
  .pp-toolbar .pp-create { margin-left: 0; }
  .pp-pick-label { flex-basis: 100%; }
  .pp-add { max-width: 100%; flex: 1 1 100%; }
  .pp-value { grid-template-columns: minmax(0, 1fr); grid-template-areas: "name" "own" "inherited"; }
  .pp-reboot-detail { min-width: 12rem; }
  .pp-value-own { text-align: left; }
}

/* Hoher Kontrast: Ränder der Werte und der Chips eine Stufe kräftiger. */
html[data-contrast="high"] .pp-values, html[data-contrast="high"] .pp-value, html[data-contrast="high"] .pp-chip { border-color: var(--c-border); }
@media (prefers-contrast: more) {
  html[data-contrast="system"] .pp-values, html[data-contrast="system"] .pp-value, html[data-contrast="system"] .pp-chip { border-color: var(--c-border); }
}
/* Erzwungene Farben: Chips in Systemfarben mit sichtbarem Rand. */
@media (forced-colors: active) {
  .pp-chip { border-color: CanvasText; background: Canvas; color: CanvasText; }
  .pp-chip-remove { color: ButtonText; }
  .pp-values, .pp-value { border-color: CanvasText; }
}
/* Ende Patch-Richtlinien 0.92 */
/* ---------- Checks 0.92 ---------- */
/* Strang C: eingebaute Checks in Paketen und Selbstheilung (Modus, Vorschlag im Alarm). Im Check-Dialog zuerst die Art als Liste zum Wählen
   (Symbol, Name, Plattform), die gewählte mit Akzentrand; nach dem Speichern steht die Art fest. Regelsätze der Ereignisprotokolle als Liste
   mit Haken. Die Selbstheilung mit den drei Modi als Chips, dem Vorschlag der Art als Zeile mit „Vorschlag übernehmen“ und den Parametern
   der Behebung. In der Liste der Checks eines Pakets die Selbstheilung als Pille; im Alarm die Behebung als eine Aktion über die volle Breite. */
.ck-kind-list { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-2); margin: 0 0 var(--sp-2); }
.ck-kind {
  display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: center; gap: var(--sp-3); width: 100%; min-height: 40px;
  padding: 8px var(--sp-3); border: 1px solid var(--c-border-soft); border-radius: var(--radius-sm); background: var(--c-elev);
  color: var(--c-text); font: inherit; text-align: left; cursor: pointer;
}
.ck-kind:hover:not(:disabled) { background: var(--c-hover); }
.ck-kind.on { border-color: var(--c-accent-line); background: var(--c-accent-wash); box-shadow: inset 3px 0 0 var(--c-accent-line); }
.ck-kind:disabled { cursor: not-allowed; opacity: .6; }
.ck-kind-ico { display: inline-flex; color: var(--c-muted); }
.ck-kind.on .ck-kind-ico { color: var(--c-accent-ink); }
.ck-kind-text { display: flex; flex-direction: column; min-width: 0; }
.ck-kind-text .cell-main { font-weight: 600; }
.ck-kind-script { grid-column: 1 / -1; }
.ck-kind-fixed { margin: 0 0 var(--sp-2); }
.ck-kind-fixed .muted { display: block; font-size: var(--fs-small); margin-top: 2px; }
.ck-kind-desc { margin: 0 0 var(--sp-3); }
.ck-sets { display: grid; margin: 0; border: 1px solid var(--c-border-soft); border-radius: var(--radius-sm); max-height: 15rem; overflow-y: auto; }
.ck-set { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: var(--sp-2); padding: 6px var(--sp-3);
  border-bottom: 1px solid var(--c-border-soft); cursor: pointer; }
.ck-set:last-child { border-bottom: 0; }
.ck-set:hover { background: var(--c-hover); }
.ck-heal { display: grid; gap: var(--sp-2); }
.ck-heal-modes { display: flex; flex-wrap: wrap; gap: 6px; }
.ck-heal-hint { margin: 0; }
.ck-heal-suggest { display: grid; margin: 0; border: 1px solid var(--c-border-soft); border-radius: var(--radius-sm); }
.ck-heal-suggestion { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: var(--sp-3); padding: 8px var(--sp-3);
  border-bottom: 1px solid var(--c-border-soft); }
.ck-heal-suggestion:last-child { border-bottom: 0; }
.ck-heal-suggestion-text { display: flex; flex-direction: column; min-width: 0; }
.ck-heal-params { margin-top: var(--sp-1); }
.ck-def-pills { display: inline-flex; flex-wrap: wrap; gap: 4px; margin-top: 2px; }
.ck-heal-pill { white-space: nowrap; }
.ap-remediation .action-grid { grid-template-columns: minmax(0, 1fr); margin-bottom: 0; }
/* Telefon: Arten untereinander, Tippflächen 40 px, Vorschlag mit Knopf darunter. */
@media (max-width: 640px) {
  .ck-kind-list { grid-template-columns: minmax(0, 1fr); }
  .ck-set { min-height: 40px; }
  .ck-heal-modes .chip-button { min-height: 40px; }
  .ck-heal-suggestion { grid-template-columns: minmax(0, 1fr); }
  .ck-heal-suggestion .btn { justify-self: start; min-height: 40px; }
}
/* Hoher Kontrast: Ränder der Listen in voller Rahmenfarbe, die gewählte Art mit Rand in Textfarbe. */
html[data-contrast="high"] :is(.ck-kind, .ck-sets, .ck-heal-suggest) { border-color: var(--c-border); }
html[data-contrast="high"] :is(.ck-set, .ck-heal-suggestion) { border-bottom-color: var(--c-border); }
html[data-contrast="high"] .ck-kind.on { border-color: var(--c-text); }
@media (prefers-contrast: more) {
  html[data-contrast="system"] :is(.ck-kind, .ck-sets, .ck-heal-suggest) { border-color: var(--c-border); }
  html[data-contrast="system"] :is(.ck-set, .ck-heal-suggestion) { border-bottom-color: var(--c-border); }
  html[data-contrast="system"] .ck-kind.on { border-color: var(--c-text); }
}
/* Erzwungene Farben: Arten mit Rand in Systemfarbe, die gewählte hervorgehoben, gesperrte grau. */
@media (forced-colors: active) {
  .ck-kind, .ck-sets, .ck-heal-suggest { border: 1px solid CanvasText; }
  .ck-kind.on { forced-color-adjust: none; border: 2px solid Highlight; box-shadow: none; }
  .ck-kind:disabled { color: GrayText; }
  .ck-heal-modes .chip-button.on { forced-color-adjust: none; background: Highlight; color: HighlightText; border-color: Highlight; }
}
/* Ende Checks 0.92 */
/* ---------- Betriebssystem 0.92 ---------- */
/* Strang D: Betriebssystem als Name mit Zusatz in Liste, Schnellansicht, Kundenseite und Übersicht. */
/* Ende Betriebssystem 0.92 */
/* ---------- Skript-Editor 0.93 ---------- */
/* Code-Editor (CodeEditor) mit Syntaxfarben und Zeilennummern: Das Feld (textarea.ce-input) bleibt die Eingabe und bestimmt die Größe,
   app.js (Abschnitt „Skript-Editor 0.93“) zeichnet denselben Text in Farben in die Ebene dahinter (pre.ce-highlight) und zählt die Zeilen
   (.ce-lines). Ebene und Nummern liegen absolut über bzw. neben dem Feld, damit ein langes Skript das Feld nicht verlängert. Erst mit
   data-ce-ready am Rahmen wird der Text des Felds durchsichtig; ohne Skript bleibt es ein gewöhnliches Feld. Ebene, Feld und Nummern teilen
   Schrift, Größe, Zeilenhöhe, oberen Innenabstand und Tabulatorweite, sonst liefen Farben, Cursor und Nummern auseinander. Zeilen brechen
   nicht um, längere scrollen waagrecht im Feld; Ebene und Nummern haben unten und rechts Reserve für die Bildlaufleisten des Felds. Farben
   nur über die Tokens --c-syn-* (je Thema und Kontrast oben bei den Tokens). */
.ce-wrap { position: relative; }
.ce-area { position: relative; }
.ce-lines, .ce-highlight { display: none; }

.ce-wrap[data-ce-ready] {
  padding-left: 3.6em;
  border: 1px solid var(--c-border-input);
  border-radius: var(--radius-sm);
  background: var(--c-input);
  overflow: hidden;
}
.ce-wrap[data-ce-ready]:focus-within { outline: var(--focus-w) solid var(--c-focus); outline-offset: 1px; }
.ce-wrap[data-ce-ready] .ce-lines,
.ce-wrap[data-ce-ready] .ce-highlight,
.ce-wrap[data-ce-ready] .ce-input {
  font-family: var(--mono);
  font-size: .85rem;
  line-height: 1.45;
  tab-size: 4;
  font-variant-ligatures: none;
  white-space: pre;
  overflow-wrap: normal;
  word-break: normal;
}
.ce-wrap[data-ce-ready] .ce-lines {
  display: block;
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 3.6em;
  margin: 0;
  padding: 6px 8px 26px 4px;
  overflow: hidden;
  text-align: right;
  color: var(--c-faint);
  background: var(--c-elev);
  border-right: 1px solid var(--c-border-soft);
  font-variant-numeric: tabular-nums;
  user-select: none;
}
.ce-wrap[data-ce-ready] .ce-highlight {
  display: block;
  position: absolute;
  inset: 0;
  margin: 0;
  padding: 6px 26px 26px 10px;
  overflow: hidden;
  border: 0;
  border-radius: 0;
  background: transparent;
  color: var(--c-text);
  pointer-events: none;
}
.ce-wrap[data-ce-ready] .ce-input {
  position: relative;
  display: block;
  width: 100%;
  padding: 6px 10px;
  border: 0;
  border-radius: 0;
  background: transparent;
  color: transparent;
  caret-color: var(--c-text);
  overflow: auto;
}
.ce-wrap[data-ce-ready] .ce-input:focus { outline: none; }
.ce-wrap[data-ce-ready] .ce-input::selection { color: transparent; background: var(--c-selected); }
.ce-wrap[data-ce-ready] .ce-input::placeholder { color: var(--c-faint); }
.ce-wrap[data-ce-ready] .ce-input[readonly] { cursor: text; }

/* Farben der Bestandteile; nur Farbe, damit Breiten und Zeilen gleich bleiben. */
.ce-highlight .tk-com { color: var(--c-syn-comment); }
.ce-highlight .tk-kw { color: var(--c-syn-keyword); }
.ce-highlight .tk-cmd, .ce-highlight .tk-fn { color: var(--c-syn-call); }
.ce-highlight .tk-str { color: var(--c-syn-string); }
.ce-highlight .tk-var { color: var(--c-syn-variable); }
.ce-highlight .tk-type { color: var(--c-syn-type); }
.ce-highlight .tk-num { color: var(--c-syn-number); }
.ce-highlight .tk-param { color: var(--c-syn-param); }
.ce-highlight .tk-op { color: var(--c-syn-operator); }
.ce-highlight .tk-tpl { color: var(--c-syn-template); }

@media (max-width: 640px) {
  /* Telefon: schmalere Spalte der Zeilennummern, damit mehr Code in die Breite passt. */
  .ce-wrap[data-ce-ready] { padding-left: 2.8em; }
  .ce-wrap[data-ce-ready] .ce-lines { width: 2.8em; padding-right: 5px; }
}

/* Hoher Kontrast: Zeilennummern in der gedämpften statt der schwachen Schrift, kräftiger Rahmen (die Farben selbst kommen aus den Tokens). */
html[data-contrast="high"] .ce-wrap[data-ce-ready] { border-color: var(--c-border-strong); }
html[data-contrast="high"] .ce-wrap[data-ce-ready] .ce-lines { color: var(--c-muted); }
@media (prefers-contrast: more) {
  html[data-contrast="system"] .ce-wrap[data-ce-ready] { border-color: var(--c-border-strong); }
  html[data-contrast="system"] .ce-wrap[data-ce-ready] .ce-lines { color: var(--c-muted); }
}

/* Erzwungene Farben und Druck: ohne Ebene und Nummern, das Feld zeigt seinen Text selbst. */
@media (forced-colors: active) {
  .ce-wrap[data-ce-ready] { padding-left: 0; border-color: CanvasText; }
  .ce-wrap[data-ce-ready] .ce-lines, .ce-wrap[data-ce-ready] .ce-highlight { display: none; }
  .ce-wrap[data-ce-ready] .ce-input { color: CanvasText; caret-color: CanvasText; }
}
@media print {
  .ce-wrap[data-ce-ready] { padding-left: 0; }
  .ce-wrap[data-ce-ready] .ce-lines, .ce-wrap[data-ce-ready] .ce-highlight { display: none; }
  .ce-wrap[data-ce-ready] .ce-input { color: inherit; }
}
/* Ende Skript-Editor 0.93 */
/* ---------- Erreichbarkeit 0.93 ---------- */
/* Reiter „Erreichbarkeit“ der Geräteseite (DeviceAvailabilityCard): Einzelheiten des gewählten Tags bzw. der letzten 24 Stunden als Kasten
   mit Kopf (Tag und Summen je Zustand mit dem Farbfeld der Legende), beim Tag einem Zeitstrahl von 0 bis 24 Uhr mit Marken alle drei
   Stunden und den Abschnitten als Liste in festen Spalten (Zustand, Zeitspanne, Dauer); auf dem Telefon Zustand und Dauer oben, die
   Zeitspanne darunter, und nur jede zweite Marke. Dazu der Titel des 7-Tage-Bands als Verweis auf den Reiter. */
.avd { margin: var(--sp-3) 0 var(--sp-2); padding: var(--sp-3); border: 1px solid var(--c-border-soft); border-radius: var(--radius-sm); background: var(--c-elev); }
.avd-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--sp-2) var(--sp-4); margin-bottom: var(--sp-2); }
.avd-title { font-weight: 600; font-variant-numeric: tabular-nums; }
.avd-sums { display: flex; flex-wrap: wrap; gap: var(--sp-1) var(--sp-4); margin: 0; padding: 0; list-style: none; font-size: var(--fs-small); }
.avd-sum { display: inline-flex; align-items: center; gap: 6px; }
.avd-sum strong { font-weight: 600; font-variant-numeric: tabular-nums; }
.avd-strip { margin: var(--sp-2) 0 var(--sp-3); }
.avd-strip > svg { height: 28px; }
.avd-axis { position: relative; height: 16px; margin-top: 4px; font-size: var(--fs-label); color: var(--c-muted); }
.avd-tick { position: absolute; top: 0; transform: translateX(-50%); white-space: nowrap; font-variant-numeric: tabular-nums; }
.avd-tick.is-start { transform: none; }
.avd-tick.is-end { transform: translateX(-100%); }
.avd-parts { margin: 0; padding: 0; list-style: none; max-height: 360px; overflow-y: auto; }
.avd-part {
  display: grid;
  grid-template-columns: minmax(150px, 1fr) minmax(0, 1.4fr) 96px;
  align-items: center;
  gap: var(--sp-3);
  padding: 5px 0;
  border-top: 1px solid var(--c-border-soft);
  font-size: var(--fs-small);
}
.avd-part:first-child { border-top: 0; }
.avd-state { display: inline-flex; align-items: center; gap: 8px; }
.avd-span { font-variant-numeric: tabular-nums; }
.avd-dur { text-align: right; color: var(--c-muted); font-variant-numeric: tabular-nums; white-space: nowrap; }
.avd-more, .avd-hint { margin: var(--sp-2) 0 0; font-size: var(--fs-small); }
.band-head .band-link { color: inherit; text-decoration: underline; text-decoration-color: var(--c-border-strong); text-underline-offset: 3px; }
.band-head .band-link:hover { color: var(--c-accent-ink); text-decoration-color: currentColor; }

@media (max-width: 640px) {
  .avd { padding: var(--sp-2); }
  .avd-part { grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "state dur" "span span"; gap: 2px var(--sp-2); }
  .avd-state { grid-area: state; }
  .avd-span { grid-area: span; color: var(--c-muted); }
  .avd-dur { grid-area: dur; }
  .avd-axis .avd-tick:nth-child(even) { display: none; }
  /* Tippfläche des Verweises im Kopf des Bands. */
  .band-head .band-link { display: inline-flex; align-items: center; min-height: 40px; }
}

html[data-contrast="high"] .avd { border-color: var(--c-border); }
html[data-contrast="high"] .avd-part { border-top-color: var(--c-border); }
@media (prefers-contrast: more) {
  html[data-contrast="system"] .avd { border-color: var(--c-border); }
  html[data-contrast="system"] .avd-part { border-top-color: var(--c-border); }
}

@media (forced-colors: active) {
  .avd { border-color: CanvasText; }
  .avd-part { border-top-color: GrayText; }
}
/* Ende Erreichbarkeit 0.93 */
/* ---------- Filter 0.93 ---------- */
/* Vorschläge aus dem Inventar im Baustein „Filter“ (0.93): Auswahl aus dem Bestand mit Knopf „Eigener Wert“ daneben (bzw. „Aus dem Bestand
   wählen“ zurück), Werte ohne Gerät im Bestand als gestrichelt umrandeter Chip in der Warnfarbe und eine Zeile darunter, die sie nennt. Die
   Klassen tragen das Präfix dfs-, damit die Regeln des Blocks „Filter 0.92“ unverändert für sich stehen. */
.dfs-pick { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); flex: 1 1 14rem; min-width: 0; }
.dfs-select { flex: 1 1 12rem; width: auto; min-width: 0; }
.dfs-mode { flex: 0 0 auto; white-space: nowrap; }
.dfs-unknown { border-style: dashed; border-color: var(--c-warn); color: var(--c-warn-ink); }
.dfs-warn { display: block; flex: 1 1 100%; font-size: var(--fs-label); line-height: 1.4; color: var(--c-warn-ink); font-weight: 600; }

@media (max-width: 640px) {
  /* Telefon: Auswahl über die ganze Breite, der Knopf darunter mit voller Tippfläche. */
  .dfs-pick, .dfs-select { flex: 1 1 100%; }
  .dfs-mode { min-height: 40px; }
}

html[data-contrast="high"] .dfs-unknown { border-width: 2px; border-color: var(--c-warn-ink); }
@media (prefers-contrast: more) {
  html[data-contrast="system"] .dfs-unknown { border-width: 2px; border-color: var(--c-warn-ink); }
}
@media (forced-colors: active) {
  .dfs-unknown { border: 2px dashed CanvasText; }
  .dfs-warn { color: CanvasText; }
}
/* Ende Filter 0.93 */
/* ---------- Schnellansicht 0.93 ---------- */
/* Schnellansicht der Geräteliste als Überlagerung (0.93): Die Liste rückt nicht mehr zur Seite (kein Push, die Seite springt nicht), die
   Leiste liegt mit ihrem Schatten darüber und ist breiter als die Alarm-Leiste. Breite über die Variable der gemeinsamen Grundregel
   (.side-panel im Block „Alarm-Arbeitsplatz“); bis 640 px bleibt sie ein Blatt über die ganze Fläche. */
.device-panel { --ap-w: 620px; }

@media (max-width: 640px) {
  /* Telefon: Blatt über die ganze Fläche (Grundregel); die Knöpfe der Leiste behalten ihre Tippfläche. */
  .device-panel .dqv-nav .btn { min-height: 40px; }
}

/* Hoher Kontrast und erzwungene Farben: eine klare Kante zur Liste darunter, weil die Leiste jetzt darüberliegt. */
html[data-contrast="high"] .device-panel { border-left-width: 2px; border-left-color: var(--c-border-strong); }
@media (prefers-contrast: more) {
  html[data-contrast="system"] .device-panel { border-left-width: 2px; border-left-color: var(--c-border-strong); }
}
@media (forced-colors: active) {
  .device-panel { border-left: 2px solid CanvasText; }
}
/* Ende Schnellansicht 0.93 */
/* ---------- Sicherung 0.93 ---------- */
/* Reiter „Sicherung“ (BackupTab): Verlauf der letzten Läufe je Job als Kästchen unter dem Namen (Farbe des Ergebnisses wie die Pille,
   Zeitpunkt und Ergebnis im title, Zusammenfassung für Screenreader), dazu der Hinweis, wenn kein Check der Art „Sicherung“ gilt. */
.bkh-runs { display: flex; flex-wrap: wrap; gap: 2px; margin-top: 6px; max-width: 160px; }
.bkh-run { width: 8px; height: 13px; border-radius: 2px; background: var(--c-neutral-bg); box-shadow: inset 0 0 0 1px var(--c-border-soft); }
.bkh-run.ok { background: var(--c-ok); box-shadow: none; }
.bkh-run.warn { background: var(--c-warn); box-shadow: none; }
.bkh-run.crit { background: var(--c-crit); box-shadow: none; }
.bkh-run.info { background: var(--c-info); box-shadow: none; }
.bkh-unchecked { margin: var(--sp-2) 0 var(--sp-3); }
.bkh-unchecked a { margin-left: 4px; white-space: nowrap; }

@media (max-width: 640px) {
  /* Telefon: etwas größere Kästchen, der Verweis als eigene Zeile mit Tippfläche. */
  .bkh-run { width: 12px; height: 16px; }
  .bkh-unchecked a { display: inline-flex; align-items: center; min-height: 40px; margin-left: 0; }
}

html[data-contrast="high"] .bkh-run { box-shadow: inset 0 0 0 1px var(--c-text); }
@media (prefers-contrast: more) {
  html[data-contrast="system"] .bkh-run { box-shadow: inset 0 0 0 1px var(--c-text); }
}

/* Erzwungene Farben: Ergebnis als Form, erfolgreich gefüllt in Highlight, Fehlschlag in der Textfarbe, Warnung schraffiert. */
@media (forced-colors: active) {
  .bkh-run { forced-color-adjust: none; background: Canvas; box-shadow: inset 0 0 0 1px CanvasText; }
  .bkh-run.ok { background: Highlight; }
  .bkh-run.crit { background: CanvasText; }
  .bkh-run.warn { background: repeating-linear-gradient(45deg, CanvasText 0 2px, Canvas 2px 4px); }
}
/* Ende Sicherung 0.93 */
/* ---------- Sicherungen 0.94 ---------- */
/* Strang A: Seite „Sicherungen“ mit Lage, Filtern und Liste der Sicherungsjobs aller Geräte; Präfix .bko-. Lagezeile mit sechs Lampen und dem
   Band der Läufe, Werkzeugleiste mit Chips nach Zustand, Suche, Produkt und Kunde, Liste mit festen Spalten (der Job nimmt den Rest). Der
   Verlauf der letzten Läufe steht unter dem Namen wie im Reiter am Gerät (Kästchen aus „Sicherung 0.93“). */
.bko-lage .lamps { gap: 8px 26px; }
.bko-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2) var(--sp-3); margin-bottom: var(--sp-3); }
.bko-toolbar .search { flex: 1 1 220px; max-width: 360px; }
.bko-filter .chip-button { display: inline-flex; align-items: center; gap: 5px; }
.card.empty.bko-empty p { max-width: 72ch; margin: 0 auto; }
table.bko-table col.col-state { width: 11rem; }
table.bko-table col.col-device { width: 12%; }
table.bko-table col.col-customer { width: 12%; }
table.bko-table col.col-product { width: 7.5rem; }
table.bko-table col.col-last { width: 8.5rem; }
table.bko-table col.col-success { width: 8.5rem; }
table.bko-table col.col-next { width: 8rem; }
table.bko-table td.bko-state .lamp-text { font-size: inherit; }
.bko-unchecked { display: inline-block; margin-top: 4px; }
table.bko-table td.bko-product { font-size: var(--fs-small); color: var(--c-muted); }
table.bko-table td.bko-last .pill { margin-top: 3px; }
.bko-runs { margin-top: 4px; }

@media (min-width: 641px) {
  /* Mindestbreite: darunter rollt die Tabelle seitlich, statt die Spalten unlesbar schmal zu machen. */
  table.bko-table.cols-fixed { min-width: 64rem; }
}
/* Telefon: jede Zeile eine Karte (Zustand und letzter Lauf oben, der Job darunter, dann Gerät und Kunde, Produkt und letzter Erfolg, nächster
   Lauf), Chips, Suche, Knöpfe und der Verweis auf das Gerät mit Tippflächen von 40 px. */
@media (max-width: 640px) {
  .bko-toolbar .search { flex-basis: 100%; max-width: none; }
  .bko-filter .chip-button, .bko-toolbar .btn, .bko-toolbar .search { min-height: 40px; }
  table.cols-fixed.bko-table > colgroup { display: none; }
  table.cols-fixed.bko-table > tbody > tr > td:not(.wrap, [colspan]) :where(.cell-main, .cell-sub) {
    overflow: visible; text-overflow: clip; padding-inline: 0; margin-inline: 0; white-space: normal;
  }
  table.bko-table thead { display: none; }
  table.bko-table, table.bko-table tbody { display: block; }
  table.bko-table tr {
    display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-items: start; gap: 6px var(--sp-2);
    grid-template-areas: "state last" "job job" "device customer" "product success" "next next";
    padding: 10px var(--sp-3); border-bottom: 1px solid var(--c-border-soft);
  }
  table.bko-table tbody tr:last-child { border-bottom: 0; }
  .table-wrap table.bko-table td {
    display: block; padding: 0; border: 0; min-width: 0; max-width: none; width: auto; overflow: visible; text-overflow: clip; white-space: normal;
    text-align: left; font-size: var(--fs-small);
  }
  table.bko-table td.bko-state { grid-area: state; }
  .table-wrap table.bko-table td.bko-last { grid-area: last; text-align: right; }
  .table-wrap table.bko-table td.bko-job { grid-area: job; font-size: var(--fs-body); }
  table.bko-table td.bko-device { grid-area: device; }
  table.bko-table td.bko-customer { grid-area: customer; }
  table.bko-table td.bko-product { grid-area: product; }
  table.bko-table td.bko-success { grid-area: success; }
  table.bko-table td.bko-next { grid-area: next; }
  table.bko-table td:is(.bko-device, .bko-customer, .bko-product, .bko-success, .bko-next)[data-label]::before {
    content: attr(data-label) " "; display: block; color: var(--c-muted); font-size: var(--fs-label);
  }
  table.bko-table td.bko-device a { display: inline-flex; align-items: center; min-height: 40px; }
  table.bko-table tr.edge-crit { box-shadow: inset 3px 0 0 var(--c-crit); }
  table.bko-table tr.edge-warn { box-shadow: inset 3px 0 0 var(--c-warn); }
  table.bko-table tr.edge-crit > td:first-child, table.bko-table tr.edge-warn > td:first-child { box-shadow: none; }
}
/* Hoher Kontrast: Trennlinien der Karten und der gedämpfte Produktname eine Stufe kräftiger. */
html[data-contrast="high"] table.bko-table td.bko-product { color: var(--c-text); }
html[data-contrast="high"] .bko-unchecked { border-color: var(--c-border); }
@media (prefers-contrast: more) {
  html[data-contrast="system"] table.bko-table td.bko-product { color: var(--c-text); }
  html[data-contrast="system"] .bko-unchecked { border-color: var(--c-border); }
}
@media (max-width: 640px) {
  html[data-contrast="high"] table.bko-table tr { border-bottom-color: var(--c-border); }
}
/* Erzwungene Farben: gewählter Filter markiert, Kanten der Zeilen als Rahmen, damit der Befund ohne Farbe sichtbar bleibt. */
@media (forced-colors: active) {
  .bko-filter .chip-button.on { forced-color-adjust: none; background: Highlight; color: HighlightText; border-color: Highlight; }
  table.bko-table tr.edge-crit > td:first-child { border-left: 3px double CanvasText; }
  table.bko-table tr.edge-warn > td:first-child { border-left: 3px dashed CanvasText; }
  .bko-unchecked { border: 1px dashed CanvasText; }
}
/* Ende Sicherungen 0.94 */
/* ---------- Supremo-Abfrage 0.94 ---------- */
/* Strang A: Abfrage vor Supremo und Einmal-Kennwort im Dialog „Fernwartung“; Präfix .sac-. Stand des Zugangs als Lampe mit Text, die Restzeit
   der Frage als schmaler Balken, das Einmal-Kennwort als Kasten mit ID, Kennwort, Kopieren, Ablaufzeit und „Supremo öffnen“, der Notfall ohne
   Abfrage mit Begründung in der Gefahrenzone. */
.sac-panel { display: flex; flex-direction: column; gap: var(--sp-2); margin-bottom: var(--sp-3); }
.sac-state { margin: 0; }
.sac-state .lamp-text { font-size: inherit; color: var(--c-text); }
.sac-intro { margin: 0; max-width: 70ch; color: var(--c-muted); }
.sac-countdown { width: 100%; height: 6px; accent-color: var(--c-info); }
.sac-otp {
  display: flex; flex-direction: column; gap: var(--sp-2); padding: var(--sp-3); border: 1px solid var(--c-border-soft);
  border-radius: var(--radius); background: var(--c-elev);
}
.sac-otp-row { display: grid; grid-template-columns: 6rem minmax(0, 1fr) auto; align-items: center; gap: var(--sp-2); }
.sac-label { color: var(--c-muted); font-size: var(--fs-label); }
.sac-value { min-width: 0; font-size: 1.05rem; letter-spacing: .04em; }
input.sac-value { width: 100%; }
.sac-otp-foot { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--sp-2); }
.sac-until { font-weight: 600; }
.sac-bypass { margin-top: var(--sp-2); }
.sac-bypass-text { margin: 0 0 var(--sp-2); max-width: 70ch; }
.sac-reason { display: flex; flex-direction: column; gap: 4px; margin-bottom: var(--sp-2); }
.sac-reason textarea { width: 100%; min-height: 3.2rem; resize: vertical; }
.sac-fixed { margin-top: var(--sp-2); }

/* Telefon: Programme als Karten, Zeilen des Kennwort-Kastens gestapelt, Knöpfe und Eingaben mit Tippflächen von 40 px. */
@media (max-width: 640px) {
  table.sac-tools thead { display: none; }
  table.sac-tools, table.sac-tools tbody { display: block; }
  table.sac-tools tr {
    display: grid; grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "name actions" "id id" "version version"; gap: 4px var(--sp-2);
    padding: 10px 0; border-bottom: 1px solid var(--c-border-soft);
  }
  table.sac-tools tbody tr:last-child { border-bottom: 0; }
  .table-wrap table.sac-tools td { display: block; padding: 0; border: 0; white-space: normal; text-align: left; }
  table.sac-tools td:nth-child(1) { grid-area: name; }
  table.sac-tools td:nth-child(2) { grid-area: id; }
  table.sac-tools td:nth-child(3) { grid-area: version; }
  table.sac-tools td:nth-child(4) { grid-area: actions; }
  table.sac-tools td:is(:nth-child(2), :nth-child(3))[data-label]::before { content: attr(data-label) " "; color: var(--c-muted); font-size: var(--fs-label); }
  table.sac-tools td .btn, .sac-otp .btn, .sac-bypass .btn { min-height: 40px; }
  .sac-otp-row { grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "label label" "value copy"; }
  .sac-otp-row .sac-label { grid-area: label; }
  .sac-otp-row .sac-value { grid-area: value; }
  .sac-otp-row .btn { grid-area: copy; }
  input.sac-value, .sac-reason textarea { min-height: 40px; }
}
/* Hoher Kontrast: Rahmen des Kennwort-Kastens und gedämpfte Texte eine Stufe kräftiger. */
html[data-contrast="high"] .sac-otp { border-color: var(--c-border); }
html[data-contrast="high"] :is(.sac-intro, .sac-label) { color: var(--c-text); }
@media (prefers-contrast: more) {
  html[data-contrast="system"] .sac-otp { border-color: var(--c-border); }
  html[data-contrast="system"] :is(.sac-intro, .sac-label) { color: var(--c-text); }
}
/* Erzwungene Farben: Kasten mit Rahmen, Balken der Restzeit in den Systemfarben. */
@media (forced-colors: active) {
  .sac-otp { border: 1px solid CanvasText; }
  .sac-countdown { accent-color: Highlight; border: 1px solid CanvasText; }
}
/* Ende Supremo-Abfrage 0.94 */
/* ---------- Garantie 0.94 ---------- */
/* Strang B: Zeile und Dialog der Garantie am Gerät, Import und Anzeige in Listen; Präfix .wty-. Die Zeile „Garantie“ der Karte „Gerät“ trägt
   Lampe, Ende mit Service-Level, eine Pille bei baldigem oder überschrittenem Ende, die Herkunft klein und rechts den Knopf. Im Dialog Fakten,
   Aktionen und die Ansprüche des Herstellers als Tabelle; der Import zeigt ein Beispiel, die Vorschau als Tabelle und die Listen der
   unbekannten Seriennummern und fehlerhaften Zeilen. Dazu die Spalte „Garantie bis“ der Geräteliste. Auf dem Telefon werden die Tabellen
   Karten, Knöpfe haben 40 px Tippfläche, die Spalte der Liste entfällt wie die übrigen wählbaren Spalten. */
dl.kv dd.wty-line { display: flex; flex-wrap: wrap; align-items: center; gap: 4px var(--sp-2); }
/* Lampe und Ende als eine Zeile über die ganze Breite: Bricht der Text um, bleibt die Lampe vorn; der Text in der Schriftfarbe, nur die Lampe
   trägt den Zustand. Darunter Zustand und Herkunft, rechts der Knopf. */
.wty-line .wty-lamp { flex: 1 1 100%; align-items: flex-start; min-width: 0; }
.wty-line .wty-lamp > .ico { flex: none; margin-top: 2px; }
.wty-lamp .wty-summary { color: var(--c-text); }
.wty-meta { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 4px var(--sp-2); }
.wty-summary { font-variant-numeric: tabular-nums; }
.wty-src { font-size: var(--fs-small); color: var(--c-muted); }
.wty-stale { color: var(--c-warn-ink); }
.wty-none { color: var(--c-muted); }
.wty-edit { margin-left: auto; }

dl.kv.wty-facts { margin: 0 0 var(--sp-3); }
.wty-facts .wty-src { margin-left: 6px; }
.wty-serial { display: flex; flex-wrap: wrap; align-items: center; gap: 4px var(--sp-2); }
.wty-state { display: flex; flex-wrap: wrap; align-items: center; gap: 4px var(--sp-2); font-variant-numeric: tabular-nums; }
.wty-error { color: var(--c-warn-ink); }
.wty-note { white-space: pre-wrap; }
.wty-actions { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin: var(--sp-2) 0; }
.wty-hint { margin-top: 0; }
.wty-form-error { margin-top: var(--sp-2); }
table.wty-claims td, table.wty-preview td { vertical-align: top; }
table.wty-claims td:nth-child(2), table.wty-claims td:nth-child(3) { white-space: nowrap; font-variant-numeric: tabular-nums; }

.wty-example {
  margin: var(--sp-2) 0 var(--sp-3);
  padding: var(--sp-2) var(--sp-3);
  border: 1px solid var(--c-border-soft);
  border-radius: var(--radius-sm);
  background: var(--c-elev);
  font-family: var(--mono);
  font-size: var(--fs-small);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.wty-file input[type="file"] { max-width: 100%; }
.wty-preview-sum { margin: 0 0 var(--sp-2); }
.wty-list { margin: 0 0 var(--sp-3); padding: 0; list-style: none; max-height: 220px; overflow-y: auto; font-size: var(--fs-small); }
.wty-list li { padding: 3px 0; border-top: 1px solid var(--c-border-soft); }
.wty-list li:first-child { border-top: 0; }
.wty-list-errors li { color: var(--c-warn-ink); }
.wty-line-no { display: inline-block; min-width: 5.5em; color: var(--c-muted); font-variant-numeric: tabular-nums; }
.device-table td.wty-col { white-space: nowrap; font-variant-numeric: tabular-nums; }

@media (max-width: 640px) {
  /* Telefon: Knöpfe mit voller Tippfläche, die Zeile bricht unter dem Wert um; Tabellen als Karten mit beschrifteten Werten. */
  .wty-edit, .wty-copy, .wty-actions .btn, .wty-import-open { min-height: 40px; }
  .wty-edit { margin-left: 0; }
  .wty-actions .btn { flex: 1 1 auto; }
  table.wty-claims thead, table.wty-preview thead { display: none; }
  table.wty-claims, table.wty-claims tbody, table.wty-preview, table.wty-preview tbody { display: block; }
  table.wty-claims tr, table.wty-preview tr { display: block; padding: 8px var(--sp-3); border-bottom: 1px solid var(--c-border-soft); }
  table.wty-claims tbody tr:last-child, table.wty-preview tbody tr:last-child { border-bottom: 0; }
  .table-wrap table.wty-claims td, .table-wrap table.wty-preview td {
    display: block; padding: 0; border: 0; min-width: 0; width: auto; white-space: normal; font-size: var(--fs-small);
  }
  table.wty-claims td[data-label]::before, table.wty-preview td[data-label]::before {
    content: attr(data-label) " "; color: var(--c-muted); font-family: var(--font); font-size: var(--fs-small);
  }
  table.wty-claims td.wty-claim-name, table.wty-preview td.wty-pv-device { font-size: var(--fs-body); font-weight: 600; }
  table.wty-claims td.wty-claim-name::before, table.wty-preview td.wty-pv-device::before { content: none; }
  .device-table td.wty-col { display: none; }
  .wty-line-no { min-width: 0; margin-right: 6px; }
}

/* Hoher Kontrast: kräftige Kanten an Beispiel und Listen, der Hinweis auf eine Abfrage ohne Ergebnis in der Textfarbe mit Unterstreichung. */
html[data-contrast="high"] .wty-example { border-color: var(--c-border-strong); }
html[data-contrast="high"] .wty-list li { border-top-color: var(--c-border); }
html[data-contrast="high"] .wty-stale, html[data-contrast="high"] .wty-error { color: var(--c-text); text-decoration: underline; }
@media (prefers-contrast: more) {
  html[data-contrast="system"] .wty-example { border-color: var(--c-border-strong); }
  html[data-contrast="system"] .wty-list li { border-top-color: var(--c-border); }
  html[data-contrast="system"] .wty-stale, html[data-contrast="system"] .wty-error { color: var(--c-text); text-decoration: underline; }
}

/* Erzwungene Farben: Kanten in der Textfarbe, Hinweise unterstrichen statt farbig. */
@media (forced-colors: active) {
  .wty-example { border-color: CanvasText; }
  .wty-list li { border-top-color: GrayText; }
  .wty-stale, .wty-error, .wty-list-errors li { color: CanvasText; text-decoration: underline; }
}
/* Ende Garantie 0.94 */
/* ---------- Onboarding 0.94 ---------- */
/* Strang C: Onboarding im Dialog des Installations-Tokens und der verwaltete lokale Administrator am Gerät; Präfix .onb-. */
/* Dialog „Agent installieren“: Abschnitt unter dem L2-Scan, zwei Auswahlfelder nebeneinander (Telefon untereinander), Hinweise darunter. */
.onb-section { display: flex; flex-direction: column; gap: var(--sp-1); padding-top: var(--sp-3); border-top: 1px solid var(--c-border-soft); }
.onb-section .switch { align-items: flex-start; }
.onb-section .switch > .badge { margin-left: 4px; }
.onb-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-3); margin-top: var(--sp-2); }
.onb-grid select { width: 100%; }
.onb-admin { margin-top: var(--sp-2); }
.onb-note { color: var(--c-warn-ink); }
.onb-locked { color: var(--c-muted); }
.onb-created { margin: 0 0 var(--sp-2); font-size: var(--fs-small); }

/* Detail des Tokens: Schritte als Liste mit kleiner Beschriftung. */
.onb-steps { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }
.onb-step-label { display: inline-block; min-width: 9ch; color: var(--c-muted); font-size: var(--fs-small); }

/* Zeile „Lokaler Admin“ in der Karte „Gerät“: Name und Stand, darunter ein Fehler, rechts bzw. darunter die Knöpfe. */
dl.kv dd.onb-line { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; }
.onb-line-text { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; min-width: 0; }
dl.kv dd.onb-line .onb-line-text .pill { margin-left: 0; }
.onb-name { font-weight: 600; }
.onb-since { font-size: var(--fs-small); }
.onb-error { flex: 1 1 100%; display: inline-flex; align-items: flex-start; gap: 6px; font-size: var(--fs-small); line-height: 1.4; }
.onb-error.crit { color: var(--c-crit-ink); }
.onb-error.warn { color: var(--c-warn-ink); }
.onb-error.muted { color: var(--c-muted); }
.onb-error .ico { flex: 0 0 auto; margin-top: 2px; }
.onb-actions { display: flex; flex-wrap: wrap; gap: 6px; flex: 1 1 100%; }
/* Hinweis „Agent zu alt“ als eigene Zeile über beide Spalten der Karte. */
dl.kv dd.onb-agent-row { grid-column: 1 / -1; }

/* Dialog „Kennwort anzeigen“: Kennwort groß und einzeilig, Kopieren und Verbergen daneben, Ablauf darunter. */
.onb-kv { margin-bottom: var(--sp-3); }
.onb-secret input { min-width: 0; }
.onb-countdown { margin-top: var(--sp-2); }
.onb-hidden { margin: var(--sp-3) 0; }

@media (max-width: 640px) {
  /* Telefon: Auswahlfelder untereinander, Knöpfe der Zeile als volle Tippflächen, Kennwort über den Knöpfen. */
  .onb-grid { grid-template-columns: 1fr; }
  .onb-actions .btn { flex: 1 1 auto; min-height: 40px; }
  .onb-secret { flex-wrap: wrap; }
  .onb-secret input { flex: 1 1 100%; }
  .onb-secret .btn { flex: 1 1 auto; min-height: 40px; }
  .onb-section .switch { min-height: 40px; }
}

html[data-contrast="high"] .onb-error { font-weight: 600; }
html[data-contrast="high"] .onb-section { border-top-color: var(--c-text); }
@media (prefers-contrast: more) {
  html[data-contrast="system"] .onb-error { font-weight: 600; }
  html[data-contrast="system"] .onb-section { border-top-color: var(--c-text); }
}

/* Erzwungene Farben: Fehler und Hinweise in der Systemfarbe des Texts, die Trennlinie als Rahmen. */
@media (forced-colors: active) {
  .onb-error, .onb-note { color: CanvasText; }
  .onb-section { border-top-color: CanvasText; }
}
/* Ende Onboarding 0.94 */
/* ---------- Fernsteuerung 0.94 ---------- */
/* Strang E: Fenster der Fernsteuerung mit Leiste (Präfix .rcv-), Knopf und Dialog am Gerät (Präfix .rcl-). Farben nur über die Tokens des
   Designsystems „Lagebild“; das Fenster ist immer dunkel (data-theme="dark" im Dokument). */

/* Auswahl und Dialog am Gerät (.rcl-). */
.rcl-intro { margin: 0 0 var(--sp-3); }
.rcl-choices { grid-template-columns: 1fr; gap: var(--sp-3); }
.rcl-running { display: flex; align-items: center; gap: var(--sp-3); padding: var(--sp-3); margin-bottom: var(--sp-3);
  border: 1px solid var(--c-accent-border); border-radius: var(--radius-sm); background: var(--c-accent-tint); }
.rcl-running-text { display: flex; flex-direction: column; gap: 2px; flex: 1 1 auto; min-width: 0; }
.rcl-running-actions { display: flex; flex-wrap: wrap; gap: var(--sp-2); justify-content: flex-end; }
.rcl-head { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-2); }
.rcl-pick { display: flex; flex-direction: column; gap: var(--sp-2); margin: var(--sp-2) 0 var(--sp-3); }
.rcl-select { width: 100%; }
.rcl-single, .rcl-blocked, .rcl-hint { margin: 0; }
.rcl-ready { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--sp-2); padding: var(--sp-3);
  margin-bottom: var(--sp-3); border: 1px solid var(--c-accent-border); border-radius: var(--radius-sm); background: var(--c-accent-tint); }
.rcl-reason { width: 100%; resize: vertical; min-height: 64px; }
.rcl-recent { width: 100%; margin-bottom: var(--sp-2); }
.rcl-recent col.rcl-col-when { width: 124px; }
.rcl-recent col.rcl-col-who { width: 22%; }
.rcl-recent col.rcl-col-dur { width: 96px; }
.rcl-recent col.rcl-col-mode { width: 116px; }

/* Fenster (.rcv-): dunkle Fläche, Leiste oben mittig, Bereiche mit Kacheln, Zustand über dem Bild. */
html.rcv-doc, .rcv-body { height: 100%; margin: 0; }
.rcv-body { background: var(--c-bg); color: var(--c-text); overflow: hidden; }
.rcv { position: fixed; inset: 0; display: flex; flex-direction: column; background: var(--c-bg); }
.rcv-stage { flex: 1 1 auto; display: flex; overflow: auto; padding: 60px var(--sp-2) var(--sp-2); min-height: 0; }
.rcv-screen { display: block; margin: auto; flex: none; max-width: none; background: var(--c-bg); touch-action: none; outline: none;
  cursor: default; box-shadow: var(--shadow); }
.rcv-screen:focus-visible { outline: 2px solid var(--c-focus); outline-offset: 2px; }
.rcv-suspended .rcv-screen { cursor: not-allowed; opacity: .85; }

.rcv-overlay { position: fixed; inset: 0; display: flex; align-items: center; justify-content: center; padding: var(--sp-4);
  pointer-events: none; z-index: 20; }
.rcv-overlay[hidden] { display: none; }
.rcv.rcv-covered .rcv-overlay { background: var(--c-backdrop); pointer-events: auto; }
.rcv-overlay-card { pointer-events: auto; background: var(--c-surface); border: 1px solid var(--c-border); border-radius: var(--radius-lg);
  padding: var(--sp-5) var(--sp-6); text-align: center; width: min(440px, 100%); box-shadow: var(--shadow); }
.rcv-overlay-title { margin: var(--sp-3) 0 var(--sp-1); font-weight: 600; font-size: 1.05rem; color: var(--c-text); }
.rcv-overlay-text { margin: 0 0 var(--sp-4); color: var(--c-muted); overflow-wrap: anywhere; }
.rcv-overlay-actions { display: flex; gap: var(--sp-2); justify-content: center; flex-wrap: wrap; }
.rcv-overlay-actions .btn[hidden] { display: none; }
.rcv-spinner { width: 34px; height: 34px; margin: 0 auto; border-radius: 50%; border: 3px solid var(--c-border); border-top-color: var(--c-accent);
  animation: rcv-spin .9s linear infinite; }
.rcv-spinner[hidden] { display: none; }
@keyframes rcv-spin { to { transform: rotate(360deg); } }

.rcv-bar { position: fixed; top: var(--sp-2); left: 50%; transform: translateX(-50%); z-index: 30; display: flex; flex-direction: column;
  background: var(--c-chrome); border: 1px solid var(--c-border); border-radius: var(--radius-lg); box-shadow: var(--shadow);
  width: max-content; max-width: calc(100vw - var(--sp-4)); max-height: calc(100vh - var(--sp-4)); }
.rcv-bar-main { display: flex; align-items: center; gap: var(--sp-1); padding: var(--sp-1) var(--sp-2); }
.rcv-bar-device { font-weight: 600; margin: 0 var(--sp-2) 0 var(--sp-1); max-width: 22ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rcv-tab { display: inline-flex; align-items: center; gap: 6px; background: transparent; color: var(--c-text); border: 1px solid transparent;
  border-radius: var(--radius-sm); padding: 4px 10px; cursor: pointer; min-height: 36px; font: inherit; }
.rcv-tab:hover { background: var(--c-hover); }
.rcv-tab[aria-expanded="true"], .rcv-tab[aria-pressed="true"] { background: var(--c-elev); border-color: var(--c-border); }
.rcv-tab:focus-visible, .rcv-chip:focus-visible, .rcv-tile:focus-visible { outline: 2px solid var(--c-focus); outline-offset: 1px; }
.rcv-kbd-toggle { display: none; }
.rcv-runtime { margin: 0 var(--sp-2); color: var(--c-muted); font-variant-numeric: tabular-nums; min-width: 7ch; text-align: right; }
.rcv-end { display: inline-flex; align-items: center; gap: 6px; }
/* Bereiche klappen als Karte unter der Leiste auf (Telefon: über der Leiste). */
.rcv-panel { position: absolute; top: calc(100% + 6px); left: 50%; transform: translateX(-50%); width: min(600px, calc(100vw - var(--sp-4)));
  max-height: calc(100vh - 90px); overflow: auto; box-sizing: border-box; padding: var(--sp-3); display: flex; flex-direction: column;
  gap: var(--sp-3); background: var(--c-chrome); border: 1px solid var(--c-border); border-radius: var(--radius-lg); box-shadow: var(--shadow); }
.rcv-panel[hidden] { display: none; }
.rcv-panel .btn.danger { align-self: flex-start; }
.rcv-ended .rcv-bar, .rcv-ended .rcv-kbd { display: none; }
.rcv-tiles { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--sp-2); }
.rcv-tile { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px; text-align: center; min-height: 76px;
  padding: var(--sp-2); background: var(--c-elev); color: var(--c-text); border: 1px solid var(--c-border); border-radius: var(--radius-sm);
  cursor: pointer; font: inherit; font-size: .88rem; line-height: 1.25; }
.rcv-tile[hidden] { display: none; }
.rcv-chip { background: var(--c-elev); color: var(--c-text); border: 1px solid var(--c-border); border-radius: var(--radius-sm);
  padding: 6px 10px; cursor: pointer; min-height: 34px; font: inherit; font-size: .9rem; }
.rcv-chip:hover, .rcv-tile:hover { background: var(--c-hover); }
.rcv-chip.is-active, .rcv-tile.is-active, .rcv-tile[aria-pressed="true"] { background: var(--c-accent-tint); border-color: var(--c-accent-border);
  color: var(--c-accent-ink); }
.rcv-field { display: flex; flex-direction: column; gap: 6px; }
.rcv-field-label { color: var(--c-muted); font-size: .85rem; }
.rcv-select { background: var(--c-input); color: var(--c-text); border: 1px solid var(--c-border-input); border-radius: var(--radius-sm);
  padding: 6px 8px; min-height: 34px; font: inherit; }
.rcv-group { display: flex; flex-wrap: wrap; gap: 6px; }
.rcv-kv { display: grid; grid-template-columns: auto 1fr; gap: 6px var(--sp-3); margin: 0; }
.rcv-kv dt { color: var(--c-muted); }
.rcv-kv dd { margin: 0; overflow-wrap: anywhere; }

.rcv-flash { position: fixed; left: 50%; bottom: var(--sp-5); transform: translateX(-50%); z-index: 35; padding: var(--sp-2) var(--sp-4);
  background: var(--c-surface); color: var(--c-text); border: 1px solid var(--c-border); border-radius: var(--radius-sm); box-shadow: var(--shadow);
  max-width: calc(100vw - var(--sp-6)); }
.rcv-flash[hidden] { display: none; }

.rcv-kbd { position: fixed; left: var(--sp-2); right: var(--sp-2); bottom: 76px; z-index: 31; display: flex; flex-direction: column; gap: 4px;
  padding: var(--sp-2) var(--sp-3); background: var(--c-chrome); border: 1px solid var(--c-border); border-radius: var(--radius-sm); }
.rcv-kbd[hidden] { display: none; }
.rcv-kbd-input { min-height: 44px; font: inherit; font-size: 16px; background: var(--c-input); color: var(--c-text);
  border: 1px solid var(--c-border-input); border-radius: var(--radius-sm); padding: 0 var(--sp-2); }

.rcv-textbox { position: fixed; inset: 0; z-index: 40; display: flex; align-items: center; justify-content: center; padding: var(--sp-4);
  background: var(--c-backdrop); }
.rcv-textbox[hidden] { display: none; }
.rcv-textbox-card { background: var(--c-surface); border: 1px solid var(--c-border); border-radius: var(--radius-lg); padding: var(--sp-5);
  width: min(560px, 100%); display: flex; flex-direction: column; gap: var(--sp-3); box-shadow: var(--shadow); }
.rcv-textbox-title { margin: 0; font-weight: 600; font-size: 1.05rem; }
.rcv-textbox-hint { margin: 0; color: var(--c-muted); font-size: .9rem; }
.rcv-textarea { width: 100%; box-sizing: border-box; resize: vertical; min-height: 120px; background: var(--c-input); color: var(--c-text);
  border: 1px solid var(--c-border-input); border-radius: var(--radius-sm); padding: var(--sp-2); font: inherit; }
.rcv-textbox-actions { display: flex; gap: var(--sp-2); justify-content: flex-end; }

/* Fingerbedienung (auch Tablets): Knopf „Tastatur“ in der Leiste. */
@media (pointer: coarse) {
  .rcv-kbd-toggle { display: inline-flex; }
}

@media (max-width: 900px) {
  .rcv-tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* Telefon: Leiste als Zeile unten, Bereiche öffnen nach oben, große Tippflächen, Tabelle der letzten Sitzungen als Karten. */
@media (max-width: 640px) {
  .rcv-stage { padding: var(--sp-1) var(--sp-1) 72px; }
  .rcv-bar { top: auto; bottom: 0; left: 0; right: 0; transform: none; width: auto; max-width: none; max-height: none;
    border-radius: var(--radius-lg) var(--radius-lg) 0 0; padding-bottom: env(safe-area-inset-bottom); }
  .rcv-bar-main { justify-content: space-between; gap: 2px; padding: var(--sp-1); }
  .rcv-bar-device, .rcv-runtime { display: none; }
  .rcv-tab, .rcv-bar .rcv-end, .rcv-kbd-toggle { display: inline-flex; flex-direction: column; justify-content: center; gap: 2px; min-height: 52px;
    min-width: 52px; padding: 4px 6px; font-size: .72rem; }
  .rcv-chip, .rcv-tile, .rcv-select { min-height: 44px; }
  .rcv-panel { top: auto; bottom: calc(100% + 6px); left: var(--sp-1); right: var(--sp-1); transform: none; width: auto; max-height: 62vh; }
  .rcv-tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .rcv-flash { bottom: 84px; }
  .rcv-kbd { bottom: 68px; }
  .rcv-overlay-card { padding: var(--sp-4); }
  .rcv-overlay-actions .btn, .rcv-textbox-actions .btn { min-height: 44px; flex: 1 1 auto; }
  .rcv-textbox { align-items: flex-end; padding: 0; }
  .rcv-textbox-card { width: 100%; border-radius: var(--radius-lg) var(--radius-lg) 0 0; }

  .rcl-running { flex-wrap: wrap; }
  .rcl-running-actions { width: 100%; justify-content: stretch; }
  .rcl-running-actions .btn, .rcl-ready .btn { min-height: 40px; flex: 1 1 auto; }
  .rcl-head .btn { min-height: 40px; }
  .rcl-recent colgroup { display: none; }
  .rcl-recent thead { display: none; }
  .rcl-recent, .rcl-recent tbody, .rcl-recent tr, .rcl-recent td { display: block; width: auto; }
  .rcl-recent tr { padding: var(--sp-2) 0; border-bottom: 1px solid var(--c-border); }
  .rcl-recent td { border: 0; padding: 2px 0; white-space: normal; }
  .rcl-recent td[data-label]::before { content: attr(data-label) " "; color: var(--c-muted); }
}

@media (prefers-reduced-motion: reduce) {
  .rcv-spinner { animation: none; border-top-color: var(--c-border); }
}

/* Hoher Kontrast: kräftigere Ränder an den bedienbaren Flächen und am Bild. */
html[data-contrast="high"] .rcv-tab, html[data-contrast="high"] .rcv-chip, html[data-contrast="high"] .rcv-tile,
html[data-contrast="high"] .rcv-bar, html[data-contrast="high"] .rcl-running, html[data-contrast="high"] .rcl-ready { border-color: var(--c-border-strong); }
@media (prefers-contrast: more) {
  html[data-contrast="system"] .rcv-tab, html[data-contrast="system"] .rcv-chip, html[data-contrast="system"] .rcv-tile,
  html[data-contrast="system"] .rcv-bar, html[data-contrast="system"] .rcl-running, html[data-contrast="system"] .rcl-ready { border-color: var(--c-border-strong); }
}

/* Erzwungene Farben: sichtbare Ränder, aktive Flächen als Auswahl. */
@media (forced-colors: active) {
  .rcv-bar, .rcv-overlay-card, .rcv-textbox-card, .rcv-flash, .rcv-kbd, .rcl-running, .rcl-ready { border: 1px solid CanvasText; }
  .rcv-tab, .rcv-chip, .rcv-tile { forced-color-adjust: none; border: 1px solid CanvasText; background: Canvas; color: CanvasText; }
  .rcv-chip.is-active, .rcv-tile.is-active, .rcv-tile[aria-pressed="true"], .rcv-tab[aria-expanded="true"] { background: Highlight; color: HighlightText; }
  .rcv-spinner { border-color: CanvasText; border-top-color: Highlight; }
  .rcv-screen:focus-visible { outline-color: Highlight; }
}
/* Ende Fernsteuerung 0.94 */
