/* ── Inter Font — SELF-HOSTED (DSGVO, PIN-58-Paket B3) ──────────────────────
   Vorher: @import von fonts.googleapis.com = IP-Übermittlung an Google bei jedem
   Seitenaufruf (Abmahnrisiko LG München 2022). Jetzt: Variable Font (wght 400–700)
   aus /static/fonts/, ein File je Subset. Lizenz: OFL (static/fonts/OFL-LICENSE).
   ✅ PIN-290: Auch die öffentlichen Marketing-/Status-/Tools-Seiten sind jetzt
   self-hosted (inline @font-face, dieselben /static/fonts/-Dateien) — kein direkter
   Google-Fonts-Abruf mehr auf öffentlichen Seiten. (Dort wght 100–900 deklariert,
   da einige Hero-H1 echtes 800 nutzen; hier bleibt 400–700, App nutzt kein 800-Hero.) */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('/static/fonts/inter-var-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: 'Inter';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('/static/fonts/inter-var-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-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ── Variablen ─────────────────────────────── */
:root {
  --bg:               #0a0a0a;
  --surface:          #161616;
  --surface-2:        #1e1e1e;
  --surface-3:        #262626;
  --border:           #2a2a2a;
  --border-2:         #3a3a3a;
  --text:             #f0f0f0;
  --text-2:           #a0a0a0;
  --text-muted:       #606060;
  --green:            #2fd18a;
  /* PIN-458: Textgrün. Im Dunkelmodus identisch mit --green, im Hellmodus eine
     dunklere Stufe (siehe body.light). BEWUSST ein Literal und NICHT
     `var(--green)`: eine var()-Kette auf :root wird DORT aufgelöst und vererbt
     danach nur noch das Ergebnis — body.light überschriebe --green, nicht die
     Kette. Genau daran ist --accent schon einmal gescheitert (PIN-458-Befund). */
  --green-text:       #2fd18a;
  --green-dim:        rgba(47,209,138,.1);
  /* Paket 2 Craft: --accent war NIE definiert, wurde aber an 4 Stellen mit
     widersprüchlichen Fallbacks benutzt (#2fd18a vs. #0b7a3c). Alias auf
     --green → folgt automatisch allen Modi (light/CVD/HC via --green-Kaskade). */
  --accent:           var(--green);
  --red:              #e0655b;
  --red-dim:          rgba(224,101,91,.1);
  --yellow:           #e3a445;
  --yellow-dim:       rgba(227,164,69,.1);
  --blue:             #5ea6da;
  --blue-dim:         rgba(94,166,218,.1);
  /* PIN-198 (A2): semantische Status-Ebene (Endpunkt up/down/degraded). Zeigt per
     Default auf die Marken-Vars → Standard-Look byte-identisch. NUR die Farbenblind-
     und Hoher-Kontrast-Modi überschreiben DIESE Familie; Marke/Buttons/Focus/Stern
     (die --green/--red/--yellow direkt nutzen) bleiben unberührt. */
  /* PIN-458: LITERAL, nicht var(--green). `var()` wird hier auf :root aufgeloest
     und vererbt danach nur noch das Ergebnis — body.light ueberschrieb --green,
     nicht --st-up. Folge (im Browser gemessen): jeder "up"-Text stand im
     Hellmodus mit Dunkelmodus-Gruen auf hellem Papier, 1,75:1. */
  --st-up:            #2fd18a;
  --st-up-dim:        var(--green-dim);
  --st-up-glow:       rgba(47,209,138,.45);
  --st-down:          var(--red);
  --st-down-dim:      var(--red-dim);
  --st-down-glow:     rgba(224,101,91,.5);
  --st-degraded:      var(--yellow);
  --st-degraded-dim:  var(--yellow-dim);
  --st-degraded-glow: rgba(227,164,69,.45);
  /* PIN-198 Nachbesserung: RGB-Kanäle (Space-Syntax für rgb(R G B / a)) für die
     DEKORATIVE Karten-Tönung + den farbigen Glow — damit die GANZE Endpunkt-Status-
     Karte (nicht nur Punkt/Badge/Rand) der CVD-/HC-Palette folgt (kein Grün-Rest).
     Default = exakt die bisherigen Literale → Standard-Look byte-identisch. :root ist
     der Dark-Kontext, body.light setzt die Hell-Kanäle, CVD/HC überschreiben beide. */
  --st-up-rgb:        47 209 138;   /* Paket 2 Craft: Redesign-Grün (war Tailwind-Alt 34 197 94 — Drift zu redesign.css:44) */
  --st-down-rgb:      239 68 68;
  --st-degraded-rgb:  245 158 11;
  /* Solide Akzentlinie oben (::before) — bewusst themen-invariant wie bisher, daher
     eigene Vars (nicht --st-up/-down, die sind hell/dunkel verschieden). */
  --st-up-line:       #3ee0a0;
  --st-down-line:     #e0655b;
  --st-degraded-line: #e3a445;
  --radius:           8px;
  --radius-lg:        12px;
  --shadow:           0 1px 3px rgba(0,0,0,.6), 0 4px 16px rgba(0,0,0,.3);
  --shadow-card:      0 1px 3px rgba(0,0,0,.5), 0 0 0 1px rgba(255,255,255,.03);
  --shadow-card-hover:0 8px 28px rgba(0,0,0,.65), 0 0 0 1px rgba(255,255,255,.06);
  --shadow-panel:     -16px 0 48px rgba(0,0,0,.6);
}

/* ── Light Mode ────────────────────────────── */
body.light {
  --bg:               #f6f8fa;
  --surface:          #ffffff;
  --surface-2:        #f1f5f9;
  --surface-3:        #e2e8f0;
  --border:           #e2e8f0;
  --border-2:         #cbd5e1;
  --text:             #0f172a;
  --text-2:           #475569;
  --text-muted:       #94a3b8;
  --green:            #16a34a;
  --green-text:       #0a6b42;   /* PIN-458: 4,95:1 auf --bg, 6,22:1 auf --surface */
  --st-up:            #0a6b42;   /* PIN-458: stand hell auf 1,75:1 (siehe :root) */
  --green-dim:        rgba(22,163,74,.08);
  --red:              #dc2626;
  --red-dim:          rgba(220,38,38,.08);
  --yellow:           #d97706;
  --yellow-dim:       rgba(217,119,6,.08);
  --blue:             #2563eb;
  --blue-dim:         rgba(37,99,235,.08);
  /* Hell-Kanäle der Karten-Tönung (Light-Mode-Literale des Status-Karten-Blocks). */
  --st-up-rgb:        22 163 74;
  --st-down-rgb:      220 38 38;
  --st-degraded-rgb:  217 119 6;
  --shadow:           0 1px 3px rgba(0,0,0,.06), 0 4px 16px rgba(0,0,0,.05);
  --shadow-card:      0 1px 4px rgba(0,0,0,.07), 0 0 0 1px rgba(0,0,0,.04);
  --shadow-card-hover:0 6px 20px rgba(0,0,0,.10), 0 0 0 1px rgba(0,0,0,.06);
  --shadow-panel:     -8px 0 24px rgba(0,0,0,.08);
}
body.light {
  background: linear-gradient(180deg, rgba(22,163,74,.06) 0%, transparent 300px), #f6f8fa;
}

/* ═══ PIN-198 (A2): Hoher-Kontrast-Theme + Farbenblind-Modi ═══════════════════
   Reihenfolge kritisch: erst body.contrast, DANN die CVD-Modi — bei Kombination
   HC+Farbenblind gewinnt so die CVD-Status-Palette (gleiche Spezifität → Quelltext-
   Reihenfolge). CVD-Werte sind LITERAL-Hex nach dem Single-Hex-Prinzip (erfüllen
   ≥3:1 gegen hellen UND dunklen Grund) → EIN Block je Modus deckt Hell+Dunkel ab
   und schlägt die :root-var(--green)-Indirektion. Überschreiben NUR die --st-*-
   Familie (+ bei HC die Grund-Vars); Marke/Buttons/Focus bleiben unberührt. */

/* Hoher Kontrast: dunkelbasiert (behält .dark → alle Komponenten-Styles bleiben),
   reiner Schwarz-Grund, Text/Rahmen maximal, Status-Marker weit über 3:1. Behält
   bewusst Grün/Gelb/Rot (Hoher Kontrast ≠ Farbenblind-Modus). */
body.contrast {
  --bg:               #000000;
  --surface:          #0a0a0a;
  --surface-2:        #161616;
  --surface-3:        #222222;
  --border:           #8a8a8a;
  --border-2:         #d4d4d4;
  --text:             #ffffff;
  --text-2:           #e6e6e6;
  --text-muted:       #b4b4b4;
  --st-up:            #00E676;  --st-up-dim:       rgba(0,230,118,.18);  --st-up-glow:       rgba(0,230,118,.6);
  --st-down:          #FF5252;  --st-down-dim:     rgba(255,82,82,.18);  --st-down-glow:     rgba(255,82,82,.6);
  --st-degraded:      #FFD400;  --st-degraded-dim: rgba(255,212,0,.18);  --st-degraded-glow: rgba(255,212,0,.6);
  --st-up-rgb: 0 230 118;  --st-down-rgb: 255 82 82;  --st-degraded-rgb: 255 212 0;
  --st-up-line: #00E676;   --st-down-line: #FF5252;   --st-degraded-line: #FFD400;
}

/* Rot-Grün-Modi (Protanopie/Deuteranopie): Rot-Grün-Kanal verloren → up=Blau,
   down=Rot (bleiben trennbar), degraded=tiefes Orange. Zusätzlich A1 Form+Label. */
body.cvd-protan {
  --st-up:            #0072B2;  --st-up-dim:       rgba(0,114,178,.13);  --st-up-glow:       rgba(0,114,178,.5);
  --st-down:          #D02F2F;  --st-down-dim:     rgba(208,47,47,.13);  --st-down-glow:     rgba(208,47,47,.55);
  --st-degraded:      #C77700;  --st-degraded-dim: rgba(199,119,0,.13);  --st-degraded-glow: rgba(199,119,0,.5);
  --st-up-rgb: 0 114 178;  --st-down-rgb: 208 47 47;  --st-degraded-rgb: 199 119 0;
  --st-up-line: #0072B2;   --st-down-line: #D02F2F;   --st-degraded-line: #C77700;
}
body.cvd-deutan {
  --st-up:            #1A6FB0;  --st-up-dim:       rgba(26,111,176,.13); --st-up-glow:       rgba(26,111,176,.5);
  --st-down:          #CC3311;  --st-down-dim:     rgba(204,51,17,.13);  --st-down-glow:     rgba(204,51,17,.55);
  --st-degraded:      #C77700;  --st-degraded-dim: rgba(199,119,0,.13);  --st-degraded-glow: rgba(199,119,0,.5);
  --st-up-rgb: 26 111 176;  --st-down-rgb: 204 51 17;  --st-degraded-rgb: 199 119 0;
  --st-up-line: #1A6FB0;    --st-down-line: #CC3311;   --st-degraded-line: #C77700;
}
/* Tritanopie (Blau-Gelb-Kanal verloren): Rot-Grün intakt → up=Grün, down=Rot
   behalten; Blau/Gelb gemieden, degraded=tiefes Orange. */
body.cvd-tritan {
  --st-up:            #0F7A3D;  --st-up-dim:       rgba(15,122,61,.13);  --st-up-glow:       rgba(15,122,61,.5);
  --st-down:          #C42020;  --st-down-dim:     rgba(196,32,32,.13);  --st-down-glow:     rgba(196,32,32,.55);
  --st-degraded:      #B85C00;  --st-degraded-dim: rgba(184,92,0,.13);   --st-degraded-glow: rgba(184,92,0,.5);
  --st-up-rgb: 15 122 61;  --st-down-rgb: 196 32 32;  --st-degraded-rgb: 184 92 0;
  --st-up-line: #0F7A3D;   --st-down-line: #C42020;   --st-degraded-line: #B85C00;
}

body.light header {
  background: rgba(255,255,255,.95);
  border-bottom-color: #e2e8f0;
  box-shadow: 0 1px 0 rgba(0,0,0,.04), 0 2px 8px rgba(0,0,0,.04);
}
body.light .panel { background: #ffffff; }
body.light .panel-header { background: #ffffff; }
body.light .stat { background: #ffffff; }
body.light .modal-box { background: #ffffff; }
body.light label input, body.light label select { background: #f8fafc; color: #0f172a; }
body.light .card {
  background: #ffffff;
  border: 1px solid #e2e8f0;
  box-shadow: 0 1px 3px rgba(0,0,0,0.05);
  border-radius: 10px;
}
body.light .card.is-down { background: linear-gradient(135deg, rgba(220,38,38,.05) 0%, #ffffff 55%); }
body.light .card.is-slow { background: linear-gradient(135deg, rgba(217,119,6,.04) 0%, #ffffff 55%); }
body.light .card.is-up   { background: linear-gradient(180deg, rgba(22,163,74,.03) 0%, #ffffff 40%); }
body.light .card:hover { box-shadow: var(--shadow-card-hover); }
body.light .sp-card,
body.light .hb-card {
  background: linear-gradient(180deg, var(--surface-2) 0%, var(--surface) 55%);
  border: 1px solid #e2e8f0;
  box-shadow: 0 1px 3px rgba(0,0,0,0.05);
  border-radius: 10px;
}
body.dark .card {
  background: #1a1a1a;
  border: none;
  border-top: 1px solid rgba(47,209,138,0.12);
  box-shadow: 0 2px 8px rgba(0,0,0,0.35);
}
body.dark .sp-card,
body.dark .hb-card {
  background: linear-gradient(180deg, var(--surface-2) 0%, var(--surface) 55%);
}

/* ── Reset & Base ──────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

body {
  background:
    radial-gradient(ellipse 80% 35% at 50% 0%, rgba(47,209,138,.05) 0%, transparent 60%),
    #0a0a0a;
  color: var(--text);
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  font-size: 14px;
  line-height: 1.6;
  min-height: 100vh;
  -webkit-font-smoothing: antialiased;
}

a { color: var(--text-muted); text-decoration: none; transition: color .15s; }
a:hover { color: var(--text); }

/* ── Header ────────────────────────────────── */
header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 24px;
  border-bottom: 1px solid rgba(255,255,255,.06);
  gap: 16px;
  flex-wrap: wrap;
  position: sticky;
  top: 0;
  background: rgba(10,10,10,.9);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  z-index: 5;
  box-shadow: 0 1px 0 rgba(47,209,138,.04), 0 4px 16px rgba(0,0,0,.3);
}

/* ── Nav 3-Spalten ─────────────────────────── */
.nav-left  { display: flex; align-items: center; }
.nav-center { display: flex; align-items: center; gap: 2px; margin: 0 16px; }
.nav-right  { display: flex; align-items: center; gap: 8px; margin-left: auto; }

.logo-wrap {
  display: flex;
  align-items: center;
  gap: 9px;
  text-decoration: none;
}
.logo-icon  { width: 35px; height: 35px; flex-shrink: 0; }
.logo-text  { font-size: 21px; font-weight: 700; letter-spacing: -.2px; color: var(--text); white-space: nowrap; }

.nav-link {
  font-size: 13px; font-weight: 500;
  color: var(--text-muted);
  padding: 5px 10px; border-radius: 6px;
  text-decoration: none;
  transition: color .15s, background .15s;
  white-space: nowrap;
}
.nav-link:hover    { color: var(--text); background: var(--surface-2); }
.nav-link.is-active{ color: var(--text); background: var(--surface-2); }

/* ── Tier Chip ─────────────────────────────── */
.tier-chip {
  font-size: 11px; font-weight: 600; letter-spacing: .3px; text-transform: uppercase;
  padding: 3px 9px; border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--surface-2); color: var(--text-muted);
  white-space: nowrap;
}
.tier-chip.tier-starter { background: rgba(94,166,218,.1); color: #60a5fa; border-color: rgba(94,166,218,.25); }
.tier-chip.tier-pro     { background: rgba(168,85,247,.1); color: #c084fc; border-color: rgba(168,85,247,.25); }
.tier-chip.tier-business{ background: rgba(227,164,69,.1); color: #fbbf24; border-color: rgba(227,164,69,.25); }

.badge {
  padding: 3px 9px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: .1px;
}
.badge-up      { background: var(--st-up-dim); color: var(--st-up); box-shadow: 0 0 0 1px rgba(47,209,138,.2); }
.badge-down    { background: var(--st-down-dim);   color: var(--st-down);   box-shadow: 0 0 0 1px rgba(224,101,91,.2); }
.badge-neutral { background: var(--surface-2); color: var(--text-muted); }

.last-updated { font-size: 11px; color: var(--text-muted); white-space: nowrap; }

/* ── Buttons ───────────────────────────────── */
button { cursor: pointer; border: none; font-family: inherit; font-size: 13px; transition: background .15s, color .15s, box-shadow .15s, transform .1s; }
button:focus-visible { outline: 2px solid var(--green); outline-offset: 2px; }
a:focus-visible      { outline: 2px solid var(--green); outline-offset: 2px; }

.btn-primary {
  background: var(--green);
  color: #000;
  padding: 7px 14px;
  border-radius: var(--radius);
  font-weight: 600;
  font-size: 13px;
  letter-spacing: -.1px;
}
.btn-primary:hover { background: #28b978; }
.btn-primary:active  { transform: scale(.97); }
.btn-primary:disabled { opacity: .35; cursor: not-allowed; }
.btn-sm { padding: 6px 14px; font-size: 12px; }

.btn-secondary {
  background: var(--surface-2);
  color: var(--text-2);
  padding: 7px 14px;
  border-radius: var(--radius);
  border: 1px solid var(--border);
  font-weight: 500;
}
.btn-secondary:hover  { background: var(--surface-3); border-color: var(--border-2); color: var(--text); }
.btn-secondary:active { transform: scale(.97); }

.btn-danger {
  background: var(--red-dim);
  color: var(--red);
  padding: 8px 16px;
  border-radius: var(--radius);
  font-weight: 500;
  width: 100%;
  border: 1px solid rgba(224,101,91,.2);
}
.btn-danger:hover { background: rgba(224,101,91,.18); }

.btn-icon {
  background: transparent;
  color: var(--text-muted);
  font-size: 16px;
  padding: 5px 8px;
  border-radius: var(--radius);
}
.btn-icon:hover  { background: var(--surface-2); color: var(--text); }
.btn-icon:active { transform: scale(.9); }

/* ── Metric Cards ──────────────────────────── */
.metrics-row {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 12px;
  margin-bottom: 8px;
}
.metric-card {
  background: linear-gradient(180deg, var(--surface-2) 0%, var(--surface) 100%);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 16px 20px;
  box-shadow: var(--shadow-card);
  display: flex;
  flex-direction: column;
  gap: 5px;
}
body.dark .metric-card {
  border: none;
  border-top: 1px solid rgba(47,209,138,0.12);
  box-shadow: 0 2px 8px rgba(0,0,0,0.35);
}
body.light .metric-card {
  border: 1px solid #e2e8f0;
  box-shadow: 0 1px 3px rgba(0,0,0,0.05);
}
.metric-value {
  font-size: 28px;
  font-weight: 700;
  letter-spacing: -.5px;
  line-height: 1;
  color: var(--text);
}
.metric-label { font-size: 11px; color: var(--text-muted); font-weight: 500; text-transform: uppercase; letter-spacing: .4px; }
#metric-up   .metric-value { color: var(--st-up); }
#metric-down .metric-value { color: var(--st-down); }

.metrics-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 20px;
}

/* ── PIN-146: Dashboard anpassen (Segmente aus-/einblenden + anordnen) ── */
.dash-cust-trigger {
  background: none; border: none; cursor: pointer; color: var(--text-muted);
  font: inherit; font-size: 12px; padding: 3px 8px; border-radius: 6px; white-space: nowrap;
}
.dash-cust-trigger:hover { color: var(--text-2); background: var(--surface-2); }
.dash-cust {
  background: var(--surface); border: 1px solid var(--border); border-radius: 10px;
  padding: 14px 16px; margin: -8px 0 20px auto; max-width: 460px;
}
.dash-cust.hidden { display: none; }
.dash-cust-head { display: flex; align-items: center; justify-content: space-between; font-weight: 700; font-size: 14px; }
.dash-cust-x { background: none; border: none; cursor: pointer; color: var(--text-muted); font-size: 15px; line-height: 1; }
.dash-cust-x:hover { color: var(--text-2); }
.dash-cust-sub { font-size: 12px; color: var(--text-muted); margin: 6px 0 10px; line-height: 1.5; }
.dash-cust-list { list-style: none; margin: 0; padding: 0; }
.dash-cust-item { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 9px 0; border-top: 1px solid var(--border); }
.dash-cust-item:first-child { border-top: none; }
.dash-cust-toggle { display: flex; align-items: center; gap: 9px; cursor: pointer; font-size: 13.5px; }
.dash-cust-toggle input { cursor: pointer; }
.dash-cust-move { display: inline-flex; gap: 4px; flex-shrink: 0; }
.dash-cust-move button {
  background: var(--surface-2); border: 1px solid var(--border); color: var(--text-2);
  cursor: pointer; border-radius: 6px; width: 26px; height: 26px; font-size: 11px; line-height: 1;
}
.dash-cust-move button:hover:not(:disabled) { background: var(--surface-3); color: var(--text); }
.dash-cust-move button:disabled { opacity: .35; cursor: default; }
.dash-cust-foot { margin-top: 10px; text-align: right; }

/* Ausgeblendetes Segment → dezenter, klickbarer Hinweis an seiner Stelle. */
.dash-seg-hint { display: none; }
.dash-seg.seg-collapsed > .dash-seg-body { display: none; }
.dash-seg.seg-collapsed > .dash-seg-hint {
  display: flex; align-items: center; gap: 8px; width: 100%;
  margin: 6px 0 18px; padding: 9px 14px; cursor: pointer; text-align: left;
  background: var(--surface); border: 1px dashed var(--border-2); border-radius: 8px;
  color: var(--text-muted); font: inherit; font-size: 12.5px;
}
.dash-seg.seg-collapsed > .dash-seg-hint:hover { border-color: var(--text-muted); color: var(--text-2); }
.dash-seg-hint-lbl { font-weight: 600; }
.dash-seg-hint-cta { margin-left: auto; color: var(--green-text); font-weight: 600; }

/* ── Skeleton Loading ──────────────────────── */
@keyframes skeleton-shimmer {
  0%   { background-position: -200% 0; }
  100% { background-position:  200% 0; }
}
.skeleton-block {
  background: linear-gradient(90deg, var(--surface-2) 25%, var(--surface-3) 50%, var(--surface-2) 75%);
  background-size: 200% 100%;
  animation: skeleton-shimmer 1.4s ease-in-out infinite;
  border-radius: var(--radius);
  display: block;
}
.skeleton-metric {
  height: 32px;
  width: 60%;
  margin-bottom: 6px;
}
.skeleton-section {
  height: 16px;
  width: 35%;
  margin: 24px 0 16px;
}

/* ── Section Header ────────────────────────── */
.section-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 24px 0 16px;
  margin-top: 32px;
  position: relative;
}
.section-header::before {
  content: '';
  position: absolute;
  top: 0; left: 0; right: 0; height: 1px;
  background: linear-gradient(90deg, transparent, var(--border-2), transparent);
}
.section-title {
  display: flex;
  align-items: center;
  gap: 8px;
  font-weight: 600;
  font-size: 14px;
  color: var(--text);
}
.section-hint { font-size: 12px; color: var(--text-muted); font-weight: 400; }

/* ── Heartbeat Pulse Animation ─────────────── */
@keyframes heartbeat-pulse {
  0%, 100% { transform: scale(1); opacity: .7; }
  50%      { transform: scale(1.25); opacity: 1; }
}
.heartbeat-icon {
  display: inline-block;
  animation: heartbeat-pulse 2s ease-in-out infinite;
  transform-origin: center;
}
.hb-card[data-status="up"] .heartbeat-icon {
  animation-duration: 1s;
  filter: drop-shadow(0 0 6px rgba(47,209,138,.4));
}

/* ── Heartbeat Empty State ─────────────────── */
.hb-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: 40px 24px;
  color: var(--text-muted);
  font-size: 13px;
  line-height: 1.7;
  background: var(--surface);
  border: 1px dashed var(--border);
  border-radius: var(--radius-lg);
}
.hb-empty-icon {
  font-size: 32px;
  margin-bottom: 12px;
  opacity: .5;
}
.hb-empty-title {
  font-size: 14px;
  font-weight: 600;
  color: var(--text-2);
  margin-bottom: 6px;
}

/* ── Status Page Section ───────────────────── */
.sp-card {
  cursor: default;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 24px;
}
.sp-card:hover { transform: none; box-shadow: var(--shadow-card); }
body.dark .sp-card {
  border: none;
  border-top: 1px solid rgba(47,209,138,0.12);
  box-shadow: 0 2px 8px rgba(0,0,0,0.35);
}
body.light .sp-card {
  border: 1px solid #e2e8f0;
  box-shadow: 0 1px 3px rgba(0,0,0,0.05);
}
.sp-state { display: flex; flex-direction: column; gap: 16px; }
.sp-desc { font-size: 13px; color: var(--text-2); line-height: 1.6; margin: 0; }
.sp-url-row { display: flex; flex-direction: column; gap: 8px; }
.sp-url-label {
  font-size: 11px;
  color: var(--text-muted);
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: .4px;
}
.sp-url-wrap {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}
.sp-url {
  font-size: 13px;
  color: var(--green-text);
  text-decoration: none;
  word-break: break-all;
  font-family: 'SF Mono', 'Fira Code', monospace;
}
.sp-url:hover { text-decoration: underline; }
.sp-disable-btn { margin-top: 8px; width: fit-content; }

/* ── Main & Card-Grid ──────────────────────── */
main {
  padding: 32px 32px 48px;
  max-width: 1200px;
  margin: 0 auto;
  background: linear-gradient(180deg, rgba(255,255,255,.012) 0%, transparent 120px);
}

.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(264px, 1fr));
  gap: 16px;
}

.card {
  background: linear-gradient(180deg, var(--surface-2) 0%, var(--surface) 100%);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 18px 20px;
  cursor: pointer;
  transition: border-color .18s, box-shadow .18s, transform .12s;
  position: relative;
  box-shadow: var(--shadow-card);
}
.card:hover {
  border-color: var(--border-2);
  box-shadow: var(--shadow-card-hover);
  transform: translateY(-2px);
}
.card.is-up {
  border-left: 3px solid var(--st-up);
  background: linear-gradient(180deg, rgba(47,209,138,.04) 0%, var(--surface) 45%);
}
.card.is-down {
  border-left: 3px solid var(--st-down);
  background: linear-gradient(135deg, rgba(224,101,91,.09) 0%, var(--surface) 55%);
  box-shadow: var(--shadow-card), inset 0 0 0 1px rgba(224,101,91,.07);
}
.card.is-slow {
  border-left: 3px solid var(--st-degraded);
  background: linear-gradient(135deg, rgba(227,164,69,.07) 0%, var(--surface) 55%);
}
.card.unchecked {
  border-left: 3px solid var(--text-muted);
  background: linear-gradient(180deg, var(--surface-2) 0%, var(--surface) 100%);
}

.card-header {
  display: flex;
  align-items: center;
  gap: 9px;
  margin-bottom: 8px;
}

/* ── Status Dot ────────────────────────────── */
.status-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
}
.dot-up      { background: var(--st-up);  box-shadow: 0 0 0 3px var(--st-up-dim),  0 0 7px var(--st-up-glow); }
.dot-down    {
  background: var(--st-down);
  box-shadow: 0 0 0 3px var(--st-down-dim), 0 0 9px var(--st-down-glow);
  animation: pulse-red 1.8s ease-in-out infinite;
}
.dot-slow    { background: var(--st-degraded); box-shadow: 0 0 0 3px var(--st-degraded-dim), 0 0 7px var(--st-degraded-glow); }
.dot-unknown { background: var(--text-muted); }

@keyframes pulse-red {
  0%, 100% { box-shadow: 0 0 0 3px var(--st-down-dim); }
  50%       { box-shadow: 0 0 0 6px rgba(224,101,91,.05); }
}

.card-name {
  font-weight: 600;
  font-size: 14px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  letter-spacing: -.1px;
  flex: 1;              /* Name nimmt die ganze Breite ein (Ellipsis statt Überlappung) */
  min-width: 0;
}

.card-url {
  font-size: 11px;
  color: var(--text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  margin-bottom: 10px;
  font-family: 'Fira Code', 'Consolas', monospace;
}

/* ── Card Sparkline ────────────────────────── */
.card-sparkline {
  height: 28px;
  margin-bottom: 10px;
  overflow: hidden;
}
.card-sparkline svg { display: block; }
.card-sparkline .no-data { font-size: 11px; color: var(--text-muted); line-height: 28px; }

/* ── Card Meta ─────────────────────────────── */
.card-meta {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 12px;
  color: var(--text-muted);
}

.card-meta-right {
  display: flex;
  align-items: center;
  gap: 6px;
}

/* ── Uptime Badge ──────────────────────────── */
.uptime-badge {
  font-size: 10px;
  font-weight: 600;
  padding: 2px 6px;
  border-radius: 999px;
  letter-spacing: .1px;
}
.uptime-good { background: var(--st-up-dim); color: var(--st-up); }
.uptime-warn { background: var(--st-degraded-dim); color: var(--st-degraded); }
.uptime-bad  { background: var(--st-down-dim); color: var(--st-down); }

/* ── Card Action Buttons ───────────────────── */
.card-actions {
  display: flex;
  gap: 4px;
  margin-left: auto;
}

/* Eigene Zeile unter dem Namen — Name bleibt immer voll lesbar */
.card-actions-row {
  margin-left: 0;
  justify-content: flex-end;
  margin-top: -4px;
  margin-bottom: 6px;
}

.btn-card-action {
  background: transparent;
  color: var(--text-muted);
  border: none;
  padding: 6px 9px;
  border-radius: 6px;
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
  transition: background .1s, color .1s;
  flex-shrink: 0;
}
.btn-card-action:hover { background: var(--surface-2); color: var(--text); }
.btn-card-action.paused { color: var(--yellow); }
/* Favorit-Stern: gefüllt in der Akzentfarbe, dezent */
/* Favorit-Stern: oben rechts in der Karte, auf Höhe des Namens — klar erkennbar */
.card-fav {
  flex-shrink: 0;
  margin-left: auto;          /* schiebt den Stern an den rechten Rand des card-header */
  background: none;
  border: none;
  cursor: pointer;
  font-size: 18px;
  line-height: 1;
  padding: 0 0 0 6px;
  color: var(--text-muted);   /* ☆ Umriss dezent, wenn kein Favorit */
  transition: color .15s ease, transform .15s ease;
}
.card-fav:hover { color: var(--yellow); transform: scale(1.15); }
.card-fav.is-favorite { color: var(--yellow); }   /* ★ gold = Favorit */
#cards.select-mode .card .card-fav { pointer-events: none; opacity: .3; }

/* "Jetzt prüfen"-Button (⚡) */
.btn-ping-now:hover { color: var(--yellow); }
.btn-ping-now:disabled { cursor: default; opacity: .6; }
.btn-ping-now.pinging { animation: ping-pulse .7s ease-in-out infinite; }
@keyframes ping-pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50%      { opacity: .4; transform: scale(.85); }
}

.card-status-label { font-weight: 500; }
.label-up   { color: var(--st-up); }
.label-down { color: var(--st-down); }
.label-slow { color: var(--st-degraded); }
.label-maintenance { color: var(--blue); }

/* ── Toast ─────────────────────────────────── */
#toast {
  position: fixed;
  bottom: 24px;
  left: 50%;
  transform: translateX(-50%);
  background: var(--surface-3);
  color: var(--text);
  padding: 10px 20px;
  border-radius: 8px;
  font-size: 13px;
  z-index: 100;
  opacity: 0;
  transition: opacity .2s;
  border: 1px solid var(--border-2);
  pointer-events: none;
  white-space: nowrap;
}

/* ── Empty State ───────────────────────────── */
.empty-state {
  text-align: center;
  color: var(--text-muted);
  padding: 80px 20px;
  font-size: 14px;
  line-height: 1.8;
}
.empty-discover { margin: 18px 0 6px; }

/* ── Auto-Discovery (PIN-113): Domain → Kandidaten-Checkliste ── */
.disc-input-row { display: flex; gap: 8px; align-items: center; }
.disc-input-row .search-input { flex: 1; }
.disc-results-head {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 8px;
}
/* Der Zähler erbt sonst `.modal-hint { margin-bottom:16px; font-size:13px }` und sitzt
   dadurch 8px zu hoch und eine Stufe zu groß (Mockup: 12px, an der Grundlinie des
   Knopfes daneben). */
.disc-results-head #disc-count { font-size: 12px; margin: 0; line-height: 1.4; }
.disc-selall { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; color: var(--text-2); cursor: pointer; }
.disc-list { max-height: 46vh; overflow-y: auto; display: flex; flex-direction: column; gap: 6px; }
/* PIN-91 Politur: EINZEILIGE Kandidaten-Zeile — Checkbox · Name · URL (füllt die
   Mitte, keine Leere) · Status-Badges rechts. Alles nebeneinander, nichts gestapelt.
   PIN-448: feste Zeilenhöhe 43 statt Innenabstand, damit zehn Kandidaten ohne Scrollen
   ins Bild passen. Die Typ-Emojis 🏠 🔁 📄 sind ersatzlos entfallen (Dario 25.07.),
   der Name daneben trägt die Information schon. */
.disc-item {
  /* flex-direction + margin-bottom EXPLIZIT (wie .imp-rel-row): die globale Regel
     `label { flex-direction: column; margin-bottom: 14px }` (style.css:1169) würde die
     als <label> gebauten Zeilen sonst vertikal stapeln (bekannter PingMon-Fallstrick). */
  display: flex; flex-direction: row; align-items: center; gap: 12px; margin-bottom: 0;
  height: 43px; flex: 0 0 auto;
  padding: 0 13px; border: 1px solid var(--border); border-radius: 8px;
  background: var(--surface); cursor: pointer; transition: border-color .12s, background .12s;
}
.disc-item:hover { border-color: var(--accent, #2fd18a); background: rgba(47,209,138,.04); }
/* Angehakt: grüner Rahmen und sehr dezente Fläche (Mockup .row.sel). Kein Leuchten.
   🚨 :not(.disc-dup) ist PFLICHT. Bereits überwachte Zeilen tragen seit PIN-448 einen
   gesetzten, gesperrten Haken und wären sonst ebenfalls grün, also optisch nicht von einer
   gerade getroffenen Auswahl zu unterscheiden. Grün bedeutet „du hast das eben angehakt",
   nicht „läuft schon". Ohne den Ausschluss gewinnt diese Regel auch noch, weil :has() die
   Spezifität seines Arguments erbt: (0,3,0) gegen (0,2,0) von .disc-item.disc-dup. */
.disc-item:not(.disc-dup):has(.disc-cb:checked) {
  border-color: rgba(47,209,138,.48); background: rgba(47,209,138,.055);
}
/* PIN-446: die Discover-Checkbox trägt zusätzlich .imp-rel-cb und teilt sich damit das
   Custom-Aussehen der Import-Vorschau (eine Quelle, kein Duplikat). Größe/Rahmen/Häkchen
   kommen aus `input.imp-rel-cb`; hier bleibt nur das Flex-Verhalten. */
.disc-item .disc-cb { flex: 0 0 auto; cursor: pointer; }
.disc-name { flex: 0 0 auto; max-width: 38%; font-size: 13px; font-weight: 600; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.disc-url { flex: 1 1 auto; min-width: 0; font-size: 12px; color: var(--text-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.disc-badges { flex: 0 0 auto; display: flex; gap: 6px; }
/* Der Relevanz-Chip steht in der Discover-Zeile direkt neben den Abzeichen und muss
   dieselbe Form haben. Als Pille (999px) neben eckigen Abzeichen (5px) wirkte er wie ein
   Fremdkörper. Gilt nur hier, die Import-Vorschau behält ihre Pillenform. */
.disc-item .imp-chip { border-radius: 5px; padding: 2px 8px; }
.disc-item .disc-badges + .imp-chip { margin-left: -6px; }
/* PIN-448: Abzeichen sind Information, kein Zustandsurteil. Deshalb einheitlich neutral
   mit dünnem Rahmen statt farbiger Fläche. HTTP 307 ist keine Warnung und HTTP 200 kein
   Erfolg, beides ist schlicht der Code, den die Seite geliefert hat. */
.disc-badge {
  font-size: 10.5px; font-weight: 500; padding: 2px 6px; border-radius: 5px;
  background: transparent; border: 1px solid var(--border-2); color: var(--text-2);
  white-space: nowrap; font-variant-numeric: tabular-nums;
}
.disc-badge-ok, .disc-badge-warn { background: transparent; color: var(--text-2); }
/* --text-2, nicht --text-muted: das Abzeichen sitzt auf der abgesenkten Fläche und käme
   damit nur auf 4,1:1, bei 10,5px Schrift zu wenig. Mit --text-2 sind es 5,9:1. */
.disc-badge-dup { background: transparent; border-color: var(--border); color: var(--text-2); }
/* PIN-448: Bereits überwachte Zeilen setzen sich über die FLÄCHE ab, nicht über Transparenz.
   Vorher war es nur opacity:.55. Auf dunklem Grund ist das zu wenig, eine gedimmte Zeile
   sah einer normalen, nicht angehakten Zeile mit grauem „Mittel"-Chip zu ähnlich (Dario,
   25.07.). Jetzt liegt die Zeile sichtbar TIEFER als die anderen (Flächenton var(--bg)
   statt var(--surface), in beiden Modi eine Stufe dunkler) und trägt einen gesetzten, aber
   gesperrten Haken. Der Haken ist das eigentliche Signal: „läuft schon", nicht „auswählbar".
   Deshalb bewusst KEIN Grün, sonst sähe er nach frisch getroffener Auswahl aus. */
.disc-item.disc-dup {
  cursor: default; background: var(--bg); border-color: var(--border);
}
.disc-item.disc-dup:hover { border-color: var(--border); background: var(--bg); }
/* Gedämpft, aber NICHT unter die Lesbarkeitsschwelle. --text-muted läge auf der
   abgesenkten Fläche nur bei 4,0:1 (dunkel) bzw. 4,1:1 (hell), weil die Fläche selbst
   schon dunkler ist als eine normale Zeile. --text-2 kommt auf 7,6:1 bzw. 5,9:1.
   Zurückgenommen wirkt die Zeile trotzdem, über Fläche, Schriftschnitt und Größe. */
.disc-item.disc-dup .disc-name { color: var(--text-2); font-weight: 500; }
.disc-item.disc-dup .disc-url { color: var(--text-2); }
.disc-item.disc-dup input.disc-cb:checked {
  background: var(--surface-2); border-color: var(--border-2);
}
.disc-item.disc-dup input.disc-cb:checked::after { border-color: var(--text-muted); }
/* PIN-452: Unterzeile unter der Leitvariante. Sie gehört zur Zeile darüber, deshalb
   dicht darunter und um die Breite der Checkbox eingerückt. Kein eigener Rahmen und
   keine eigene Fläche — sie ist eine Fußnote, keine zweite Zeile.
   `flex: 0 0 auto` explizit: .disc-list ist eine Flex-Spalte, ohne das würde die
   Unterzeile bei knapper Höhe gestaucht und der Text abgeschnitten. */
.disc-langvar {
  display: flex; align-items: baseline; gap: 8px; flex: 0 0 auto;
  margin: -3px 0 1px 34px; min-width: 0;
  font-size: 11.5px; line-height: 1.45; color: var(--text-2);
}
.disc-langvar-txt { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.disc-langvar-sep { flex: 0 0 auto; color: var(--text-muted); }
/* Sprachkennung hinter dem Namen einer aufgeklappten Variante: „Preise (en)".
   Zurückgenommen, sie ergänzt den Namen und ersetzt ihn nicht. */
.disc-lang-tag { font-weight: 500; color: var(--text-2); }
/* Der Schalter ist ein <button>, damit er per Tastatur erreichbar ist, sieht aber wie
   ein Link aus. Ohne Unterstreichung (Dario 25.07.).
   🚨 var(--green), NICHT var(--accent). `--accent: var(--green)` steht nur auf :root
   (style.css:42) — CSS löst ein var() in einer Custom-Property-Deklaration auf dem
   DEKLARIERENDEN Element auf und vererbt danach nur noch das fertige Literal. `body.light`
   überschreibt --green, aber nicht --accent, also bliebe hier das dunkle Mintgrün stehen:
   im Browser gemessen #2fd18a auf #f8f9f5, macht 1,87:1 bei 11,5px. Der Schalter ist der
   EINZIGE Weg zu den eingeklappten Varianten, er darf nicht verschwinden. */
.disc-langvar-toggle {
  flex: 0 0 auto; background: none; border: 0; padding: 0;
  font: inherit; font-size: 11.5px; color: var(--green-text);
  cursor: pointer; white-space: nowrap;
  /* 🚨 --green-text, nicht --green. Im Dunkelmodus sind beide gleich, im
     Hellmodus ist --green das Fahnengrün und --green-text die dunklere Stufe
     aus PIN-458, die für Schrift auf hellem Papier gedacht ist. Der Schalter
     stand hier als einziger Link im Produkt auf der falschen Stufe. Aufgefallen
     am 02.08.2026, als der Hellmodus-Durchgang des Klicktests zum ersten Mal
     wirklich hell lief (das Konto trug ein theme_pref, das die Vorbelegung
     des Tests still überschrieb). */
  /* Unterstrichen wie .btn-link (style.css:3842), die Hausregel für Links. Nicht
     Geschmack, sondern Auffindbarkeit: --green kommt im Hellmodus auf der Ebenenfläche
     nur auf 2,6:1 (gemessen), und dieser Schalter ist der EINZIGE Weg zu den
     eingeklappten Sprachvarianten. Über die Farbe allein wäre er dort nicht als
     Bedienelement zu erkennen. Die schwache Grünstufe im Hellmodus ist ein
     produktweites Thema und hat ein eigenes Ticket. */
  text-decoration: underline; text-underline-offset: 2px;
}
.disc-langvar-toggle:hover { opacity: .85; }
.disc-langvar-toggle:focus-visible { outline: 2px solid var(--green, #2ea866); outline-offset: 2px; border-radius: 3px; }
/* Aufgeklappte Sprachvarianten liegen sichtbar unter ihrer Leitvariante: gleiche
   Einrückung wie die Unterzeile, damit die Zugehörigkeit ohne Linie klar ist. */
.disc-item.disc-var { margin-left: 34px; }
@media (max-width: 560px) {
  .disc-name { max-width: 50%; }
  .disc-langvar { margin-left: 20px; }
  .disc-item.disc-var { margin-left: 20px; }
}

/* ── PIN-448: die Bausteine der zweispaltigen Ebene ─────────────────────────────
   Nur Aussehen. Das Raster und die Scroll-Kette stehen in redesign.css Sektion 20c. */
.disc-head { margin-bottom: 20px; }
.disc-back {
  display: inline-flex; align-items: center; gap: 6px;
  background: none; border: 0; padding: 0; margin-bottom: 11px;
  color: var(--text-muted); font: inherit; font-size: 12.5px; cursor: pointer;
}
.disc-back::before { content: "\2190"; font-size: 14px; line-height: 1; }
.disc-back:hover { color: var(--text-2); }
/* Kompound-Selektor PFLICHT: `.modal-box h2 { font-size:15px; margin-bottom:20px }`
   (style.css:1287) steht später und gewänne bei gleicher Spezifität. Mockup: 20px, und
   der Abstand zur Erklärzeile sind 7px, nicht 20px. */
.modal-box-disc .disc-head h2 { font-size: 20px; margin: 0 0 7px; letter-spacing: -.02em; }
.disc-head .modal-hint { font-size: 12px; margin: 0; }
/* Einrichtpanel links. Die Trennlinien laufen über die volle Panelbreite. */
.disc-panel {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 12px; padding: 16px;
}
.disc-panel-div { height: 1px; background: var(--border); margin: 16px -16px; }
.disc-field { display: flex; flex-direction: column; gap: 7px; }
/* EXPLIZIT: die globale `label { display:flex; flex-direction:column; margin-bottom:14px }`
   würde sonst durchschlagen (bekannter PingMon-Fallstrick, siehe .disc-client-row). */
.disc-field-label {
  display: block; margin-bottom: 0;
  font-size: 11.5px; font-weight: 600; color: var(--text-2); letter-spacing: .02em;
}
.disc-panel .disc-input-row { display: flex; gap: 10px; }
.disc-panel .disc-input-row .search-input { flex: 1 1 auto; min-width: 0; }
.disc-hints.hidden { display: none; }
/* Panel „Kunde anlegen", öffnet rechts über der Liste. Rahmen einen Ton deutlicher als
   die Listenzeilen, weil es der aktive Vorgang ist. */
/* Kompound-Selektor PFLICHT: `.ql-add { display:flex }` steht weiter unten (style.css:3397)
   und würde bei gleicher Spezifität gewinnen. `.ql-add.hidden { display:none }` steht noch
   danach und behält damit korrekt Vorrang, wenn das Panel zu ist. */
.ql-add.disc-nc {
  display: block; flex: 0 0 auto; margin-bottom: 16px;
  background: var(--surface); border: 1px solid var(--border-2);
  border-radius: 12px; padding: 15px 16px 14px;
}
.disc-nc-h {
  font-size: 10.5px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase;
  color: var(--text-muted); margin-bottom: 12px;
}
.disc-nc-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
/* Auf Telefonen sind zwei Felder nebeneinander je unter 150px breit. Dann untereinander. */
@media (max-width: 560px) {
  .disc-nc-grid { grid-template-columns: 1fr; gap: 12px; }
  .disc-nc-foot { flex-direction: column; align-items: stretch; gap: 12px; }
}
.disc-nc .ql-add-label, .disc-nc .ql-add-url { width: auto; flex: none; min-width: 0; }
.disc-nc-foot {
  display: flex; align-items: center; justify-content: space-between; gap: 20px; margin-top: 13px;
}
.disc-nc-hint { font-size: 11.5px; color: var(--text-2); line-height: 1.5; margin: 0; max-width: 520px; }
.disc-nc-btns { display: flex; gap: 9px; flex: 0 0 auto; }

/* ── PIN-454: was der Import zusätzlich zu den geteilten Bausteinen braucht ──────
   Der Import benutzt .disc-head, .disc-panel, .disc-panel-div, .disc-field und
   .disc-field-label unverändert mit. Hier stehen nur die vier Stellen, an denen
   sein Inhalt sich von Finden unterscheidet. */
/* Kompound-Selektor PFLICHT, gleiche Begründung wie bei .modal-box-disc: die spätere
   Regel `.modal-box h2 { font-size:15px; margin-bottom:20px }` gewänne sonst. */
.modal-box-import .disc-head h2 { font-size: 20px; margin: 0 0 7px; letter-spacing: -.02em; }
/* Runde B: der Prüfset-Satz ist einen Satz länger geworden (Dario, 02.08.2026:
   „Bei https kommt die Zertifikatsprüfung dazu.") und bricht in der 336er-Spalte
   auf drei Zeilen statt zwei. Damit lief die linke Spalte bei 1440x900 um genau
   16 Pixel über und bekam einen ZWEITEN Scrollbalken; unten wurde der grüne
   Tarif-Hinweis angeschnitten.
   🚨 Die 16 Pixel kommen aus dem Abstandsgerüst zurück, nicht aus dem Text: Copy
   schreibt Dario. Acht am Kopf, acht an den beiden Trennlinien. `.imp-left` behält
   sein `overflow-y:auto` als Notventil für wirklich niedrige Fenster, aber bei
   üblicher Fensterhöhe bleibt die Liste der einzige Scrollbereich. */
.modal-box-import .disc-head { margin-bottom: 12px; }
/* Der Datei-Wähler stand bisher IN einem <label> und bezog seine Form aus der Regel
   `label input`. Seit er in .disc-field sitzt, braucht er sie explizit. box-sizing und
   max-width sind Pflicht: der vom Browser gerenderte „Durchsuchen"-Knopf plus Dateiname
   läuft in einer 336px-Spalte sonst waagerecht über den Rand hinaus. */
.disc-panel #import-file {
  width: 100%; max-width: 100%; box-sizing: border-box;
  background: var(--surface-2); border: 1px solid var(--border); border-radius: 8px;
  padding: 8px 11px; font-size: 13px; color: var(--text); cursor: pointer;
}
.disc-panel #import-file::file-selector-button {
  margin-right: 10px; padding: 4px 10px; border-radius: 6px;
  border: 1px solid var(--border-2); background: var(--surface-3);
  color: var(--text-2); font: inherit; font-size: 12px; cursor: pointer;
}
/* Runde A: das Ablagefeld ist der sichtbare Weg zur Datei, das echte Feld liegt
   unsichtbar darunter und wird vom Knopf im Ablagefeld bedient. Nicht display:none —
   ein ausgeblendetes Feld lässt sich nicht mehr programmatisch öffnen, und die
   Fehlermeldung des Browsers hätte keinen Anker mehr.
   🚨 Kompound-Selektor PFLICHT: die zwei Regeln darüber (0,2,0) gewönnen sonst und
   das Feld stünde in voller Breite unter dem Ablagefeld. */
.disc-panel #import-file.imp-file-off {
  position: absolute; width: 1px; height: 1px; padding: 0; border: 0;
  opacity: 0; pointer-events: none; overflow: hidden;
}
/* „Neuer Kunde" im Import: in der schmalen linken Spalte stehen die zwei Felder
   untereinander statt nebeneinander. Bei Finden löst das .disc-nc, das aber rechts
   über der Liste liegt — dort ist beim Import ohne Vorschau gar keine Spalte.
   🚨 Muss VOR `.ql-add.hidden` stehen: gleiche Spezifität (0,2,0), sonst gewönne
   diese Regel und das Panel ließe sich nicht mehr schließen. */
.ql-add.imp-nc { flex-wrap: wrap; margin-top: 8px; }
.imp-nc .ql-add-label, .imp-nc .ql-add-url { width: 100%; flex: 1 1 100%; min-width: 0; }
/* Still gestellter Hauptknopf in der Fußleiste, wie bei Finden: erkennbar ein Knopf,
   sichtbar nicht drückbar. `opacity:.35` allein lässt das Grün durch und sieht nach
   „lädt gerade" aus. */
.modal-box-import .form-actions .btn-primary:disabled {
  opacity: 1; background: var(--surface-3); border-color: var(--border-2);
  color: var(--text-muted); box-shadow: none; cursor: not-allowed;
}
/* Schmaler Balken im einzigen Scrollbereich (wie .disc-scroll). */
.imp-rel-list::-webkit-scrollbar { width: 8px; }
.imp-rel-list::-webkit-scrollbar-track { background: transparent; }
.imp-rel-list::-webkit-scrollbar-thumb { background: var(--border-2); border-radius: 99px; }
/* Endmarke: erklärt den Leerraum unter der Liste, statt ihn bloß zu lassen. */
.disc-list-end { font-size: 11px; color: var(--text-muted); padding: 12px 2px 2px; margin: 0; }
.disc-list-end.hidden { display: none; }
/* Stille Notiz in der Fußleiste: der Zähler im Listenkopf verschwindet beim Scrollen. */
/* Still gestellt statt nur blass: der Hauptknopf soll erkennbar ein Knopf bleiben, aber
   sichtbar nicht drückbar. `opacity:.35` allein (style.css:309) lässt das Grün durch und
   sieht nach „lädt gerade" aus. Werte nach Vorgabe: Fläche, gedämpfter Text, betonter
   Rahmen, jeweils über die Tokens. */
.modal-box-disc .form-actions .btn-primary:disabled {
  opacity: 1; background: var(--surface-3); border-color: var(--border-2);
  color: var(--text-muted); box-shadow: none; cursor: not-allowed;
}
.disc-foot-note { font-size: 12px; color: var(--text-muted); font-variant-numeric: tabular-nums; }
.disc-foot-note.hidden { display: none; }
/* Nullzustand rechts, wo sonst die Liste steht. */
.disc-zero {
  flex: 1; min-height: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 11px; text-align: center; padding-bottom: 40px;
}
.disc-zero.hidden { display: none; }
.disc-zero h3 { font-size: 16px; font-weight: 600; margin: 0; color: var(--text); }
.disc-zero p { font-size: 12.5px; color: var(--text-2); line-height: 1.6; margin: 0; max-width: 430px; }
/* Schmaler Balken statt des kaum greifbaren Standardbalkens (Mockup: 4px). */
.disc-scroll::-webkit-scrollbar { width: 8px; }
.disc-scroll::-webkit-scrollbar-track { background: transparent; }
.disc-scroll::-webkit-scrollbar-thumb { background: var(--border-2); border-radius: 99px; }

/* ── PIN-440 Phase 2: Import-Relevanz-Vorschau (V1 „Ruhige Liste") ──────────────
   Zeile: Custom-Checkbox links, Name, URL (füllt die Mitte), Stufe als Chip rechts.
   Die Stufe nutzt bewusst eine eigene RUHIGE Skala (Blau kräftig -> Grau), NICHT die
   Ampel/Grün-Töne, denn Relevanz ist kein Gesundheitssignal. */
/* Wie beim Discover-Fenster (.modal-box-disc): die Vorschau ist eine LISTE mit vier
   Spalten und braucht Breite. Der Kompound-Selektor (Spezifität 0,2,0) MUSS das später
   stehende `.modal-box { max-width: 400px }` schlagen, sonst bliebe das Fenster schmal. */
.modal-box.modal-box-import { max-width: 720px; }

.imp-rel { margin-top: 14px; }
.imp-rel-title { font-size: 15px; font-weight: 650; color: var(--text); margin: 2px 0 2px; }
.imp-rel-head { display: flex; align-items: center; justify-content: space-between; gap: 8px 12px; margin: 10px 0 6px; flex-wrap: wrap; }
.imp-rel-controls { display: flex; gap: 16px; }
/* Nie mitten im Label umbrechen (schmales Fenster/Mobil) — lieber wandert der Zähler um. */
.imp-rel-controls .btn-link { white-space: nowrap; }
.imp-rel-count { font-size: 12.5px; color: var(--text-muted); white-space: nowrap; }
/* Abstand 6 zwischen den Zeilen (Runde A). Vorher 7 — die Liste steht jetzt neben
   einem festen Erkannt-Streifen und soll ruhiger wirken. */
.imp-rel-list { max-height: 42vh; overflow-y: auto; display: flex; flex-direction: column; gap: 6px; }
.imp-rel-row {
  /* flex-direction + margin-bottom EXPLIZIT: die globale Regel `label { display:flex;
     flex-direction:column; margin-bottom:14px }` (style.css:1150) würde sonst die als
     <label> gebauten Zeilen vertikal stapeln (bekannter PingMon-Fallstrick). */
  display: flex; flex-direction: row; align-items: center; gap: 12px; margin-bottom: 0;
  /* Runde A: feste Höhe 43 statt Innenabstand, Radius 8 statt 10 — dieselbe Zeile
     wie bei Finden (.disc-item). `flex: 0 0 auto` ist Pflicht, .imp-rel-list ist eine
     Flex-Spalte und würde die Zeilen bei knapper Höhe sonst stauchen. */
  height: 43px; flex: 0 0 auto;
  padding: 0 13px; border: 1px solid var(--border); border-radius: 8px;
  background: var(--surface); cursor: pointer; transition: border-color .12s, background .12s;
}
.imp-rel-row:hover { border-color: var(--accent, #2fd18a); background: rgba(47,209,138,.04); }
/* Angehakt: grüner Rahmen und sehr dezente Fläche, wie .disc-item.
   🚨 Die beiden :not() sind PFLICHT. Bereits überwachte und nicht anlegbare Zeilen
   tragen ein gesetztes bzw. gesperrtes Kästchen und wären sonst ebenfalls grün, also
   optisch nicht von einer gerade getroffenen Auswahl zu unterscheiden. Grün heißt
   „du hast das eben angehakt", nicht „läuft schon".
   color-mix statt rgba-Literal: --green ist im Hellmodus ein anderer Ton, ein Literal
   stünde dort mit Dunkelmodus-Grün auf hellem Papier. Im Dunkelmodus kommt exakt
   dasselbe rgba(47,209,138,…) heraus wie bei .disc-item. */
.imp-rel-row:not(.ist-dublette):not(.ist-fehler):has(.imp-rel-cb:checked) {
  border-color: color-mix(in srgb, var(--green) 48%, transparent);
  background: color-mix(in srgb, var(--green) 5.5%, transparent);
}
/* Kopfzeile: gleiche Spaltenbreiten wie die Datenzeilen, aber ohne Kasten. */
.imp-rel-header { border: none; background: transparent; padding: 0 13px; cursor: default; }
.imp-rel-header:hover { border: none; background: transparent; }
.imp-rel-header .imp-rel-nm,
.imp-rel-header .imp-rel-url,
.imp-rel-header .imp-rel-zuord,
.imp-rel-header .imp-rel-iv,
.imp-rel-header .imp-rel-chip-h {
  font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: .05em;
  color: var(--text-muted);
}
.imp-rel-header .imp-rel-chip-h { flex: 0 0 auto; }
/* Runde A: der Name nimmt nur noch seine eigene Breite ein, damit die URL direkt
   dahinter steht statt hinter einer Leerspalte. Der Deckel bei 38% ist derselbe wie
   bei .disc-name: ohne ihn schiebt ein langer Name die URL aus der Zeile. */
.imp-rel-nm { flex: 0 1 auto; max-width: 38%; min-width: 0; font-size: 13px; font-weight: 600; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Rechte Gruppe der Zeile: Relevanz-Chip, dann das Intervall-Abzeichen. Ganz rechts
   bleibt bewusst Platz frei, dort kommen in Runde B „angepasst" und „URL fehlt". */
.imp-rel-rt { flex: 0 0 auto; margin-left: auto; display: flex; align-items: center; gap: 6px; }
.imp-rel-url { flex: 1 1 auto; min-width: 0; font-size: 12px; color: var(--text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Runde 3: Zuordnung und Intervall stehen jetzt in der Vorschau. Beide waren
   vorher unsichtbar, und genau darin steckte der Fehler „aus 60 Sekunden wird
   eine Stunde": man sah ihn erst an den fertig angelegten Monitoren. */
/* Zwei Zeilen: Kunde oben, Bereich darunter. Einzeilig schnitt die Spalte genau
   am Bereich ab, und der ist das, was diese Runde neu kann. */
.imp-rel-zuord { flex: 0 0 23%; min-width: 0; font-size: 12px; color: var(--text-muted);
  display: flex; flex-direction: column; gap: 1px; overflow: hidden; }
.imp-rel-zuord > span { display: block; min-width: 0; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
.imp-rel-zuord .imp-rel-kd { color: var(--text-2); }
.imp-rel-zuord .imp-rel-ber { opacity: .75; font-size: 11.5px; }
/* Die Kopfzeile bleibt einzeilig, sonst rutscht sie gegen die Datenzeilen. */
.imp-rel-header .imp-rel-zuord { display: block; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; }
.imp-rel-iv { flex: 0 0 62px; text-align: right; font-size: 12px; font-variant-numeric: tabular-nums; color: var(--text-2); white-space: nowrap; }
/* 🚨 Die Kopfzeile MUSS dieselben Spalten ausblenden wie die Zeilen darunter.
   `.imp-rel-header .imp-rel-zuord` (zwei Klassen) schlägt sonst die Regel hier
   (eine Klasse), egal in welcher Reihenfolge sie steht: schmal stand dann
   „KUNDE / BEREICH" als Überschrift über der URL-Spalte. Beim Hinsehen am
   390px-Fenster gefunden (02.08.2026), älter als PIN-492. */
@media (max-width: 760px) {
  .imp-rel-zuord,
  .imp-rel-header .imp-rel-zuord { display: none; }
}
/* PIN-492: Das Intervall bleibt auch schmal sichtbar. Es war hier ausgeblendet,
   solange es nur eine Zusatzangabe war. Seit der Einheiten-Umschalter existiert,
   ist diese Spalte die einzige Stelle, an der man SIEHT, was er bewirkt — ohne
   sie wäre er auf dem Handy ein Knopf ohne erkennbare Wirkung. Stattdessen
   schrumpft der Name (Review 02.08.2026). */
@media (max-width: 560px) {
  /* max-width statt flex-basis, seit der Name in Runde A keine feste Spalte mehr ist:
     ein flex-basis zwänge ihm die Breite auch dann auf, wenn er kürzer ist. 50% wie
     bei .disc-name — die Zuordnungsspalte ist weg, der Name hat den Platz jetzt,
     und bei 34% wurde aus „API Gesundheit" schon auf 390px „API Gesu…". */
  .imp-rel-nm { max-width: 50%; }
  .imp-rel-iv { flex-basis: 52px; }
}

/* PIN-492: Einheit der Intervall-Spalte. Erscheint nur, wenn die Datei sie nicht
   selbst nennt und deshalb geraten werden musste. Der Umschalter selbst ist das
   Segmented Control aus dem Bestand (.seg/.seg-btn, siehe „Erscheinungsbild" im
   Statusseiten-Studio) — hier steht nur, wie er sich in die schmale linke Spalte
   einfügt. Keine eigenen Farben, keine neuen Tokens. */
.imp-einheit { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px;
  margin: 8px 0 0; font-size: 12.5px; line-height: 1.5; }
.imp-einheit-frage { color: var(--text-2); }
.imp-einheit .seg { padding: 2px; }
.imp-einheit .seg-btn { padding: 3px 10px; }
/* Der Hinweis bricht auf eine eigene Zeile, sonst quetscht er den Umschalter. */
.imp-einheit-hinweis { flex-basis: 100%; color: var(--text-muted); }

/* Was der Import NICHT anlegen kann, und was er neu anlegen wird. Beides stand
   bisher nur in der Antwort und wurde nie gezeigt. */
.imp-notes { display: flex; flex-direction: column; gap: 6px; margin: 0 0 10px; }
.imp-note { font-size: 12.5px; line-height: 1.5; padding: 8px 11px; border-radius: 8px; border: 1px solid var(--border); }
.imp-note-titel { font-weight: 650; display: block; margin-bottom: 2px; }
.imp-note ul { margin: 0; padding-left: 18px; }
.imp-note-fehler { border-color: var(--yellow); background: var(--yellow-dim); color: var(--text-2); }
/* Bringt die Datei Kunde und Bereich selbst mit, sind die Auswahlfelder außer
   Kraft. Das MUSS man sehen: ein Feld, das sich bedienen lässt und nichts
   bewirkt, ist ein lügender Knopf. Das Haus hat keine allgemeine Optik für
   gesperrte Selects, deshalb hier eine (dasselbe .35/.5-Muster wie bei
   .btn-primary:disabled und .btn-danger:disabled). */
#import-client-select:disabled,
#import-bereich-select:disabled,
#import-client-new:disabled {
  opacity: .45; cursor: not-allowed; background: var(--surface-2, var(--surface));
}
/* Keine gültige Zeile: nur der Hinweiskasten, kein Tabellenkopf über nichts. */
.imp-rel-leer .imp-rel-head,
.imp-rel-leer .imp-rel-header,
.imp-rel-leer .imp-rel-list { display: none; }
.imp-note-neu { color: var(--text-muted); }

/* Custom-Checkbox (appearance:none, damit sie in beiden Themes gleich sitzt). */
.imp-rel-cb { flex: 0 0 auto; width: 20px; height: 20px; }
input.imp-rel-cb {
  appearance: none; -webkit-appearance: none; border-radius: 6px;
  border: 1.5px solid var(--text-muted); background: transparent; cursor: pointer;
  position: relative; transition: background .12s ease, border-color .12s ease;
  /* padding EXPLIZIT 0: die globale Regel `label input { padding: 8px 11px }`
     (style.css:1165) würde sonst in die 20px-Box hineinwirken. */
  padding: 0;
}
input.imp-rel-cb:checked { background: var(--accent, #2fd18a); border-color: var(--accent, #2fd18a); }
input.imp-rel-cb:checked::after {
  content: ""; position: absolute; left: 6px; top: 2.5px; width: 5px; height: 10px;
  border: solid #fff; border-width: 0 2px 2px 0; transform: rotate(42deg);
}
input.imp-rel-cb:focus-visible { outline: 2px solid var(--accent, #2fd18a); outline-offset: 2px; }

/* Relevanz-Chip: eigene ruhige Skala, bewusst NICHT die Ampel (Relevanz != Gesundheit). */
/* Variante B („Ruhig", von Dario gewählt 24.07.): KEIN gefüllter Chip. Die Auswahl
   (grünes Häkchen) ist die Handlung und bleibt das lauteste Element, die Relevanz ist
   nur Information und tritt einen Schritt zurück. „Hoch" trägt allein die blaue Kontur. */
.imp-chip {
  flex: 0 0 auto; font-size: 11px; font-weight: 600; letter-spacing: .03em;
  padding: 2px 9px; border-radius: 999px; white-space: nowrap; border: 1px solid transparent;
}
/* Blau bewusst dunkler als im Entwurf: 11px-Text braucht auf weißer Zeile ≥ 4.5:1
   (#5b8def kam nur auf 3.2, dieser Ton auf 4.9). Dunkelmodus liegt bei 8.7. */
.imp-chip.high { color: #2f6fd0; background: transparent; border-color: #2f6fd0; font-weight: 650; }
.imp-chip.medium { color: var(--text-2); background: transparent; border-color: var(--border-2); }
.imp-chip.low { color: var(--text-muted); background: transparent; border-color: var(--border); }
/* PIN-448: im Dunkelmodus auf den Mockup-Ton #5ea6da. Gerechnet auf der Zeilenfläche
   (--surface #141a17): 6,8:1, also klar über der Schwelle. Hell bleibt #2f6fd0, denn
   #5ea6da käme auf Weiß nur auf 2,6:1. Gilt auch für die Import-Vorschau, die sich die
   Klasse teilt, sonst stünden zwei Blautöne nebeneinander. */
body.dark .imp-chip.high { color: #5ea6da; background: transparent; border-color: #5ea6da; }

/* ══ Runde A der Import-Ebene: die neuen Bausteine ═══════════════════════════════
   Vorlage ist das Cowork-Paket „Import-Ebene" (import-styles-ergaenzung.css auf
   pin448-styles.css). Hier steht NUR, wie die Bausteine aussehen; Raster und
   Scroll-Kette stehen in redesign.css, Sektion 20c. Dieselbe Arbeitsteilung wie
   bei Finden, das Mockup-Stylesheet mischt beides.

   🚨 Maße und Radien kommen aus dem Mockup, FARBEN aus den Tokens. Das Mockup ist
   gegen die alte Palette gezeichnet (#0a0a0a/#161616), tatsächlich gelten die
   redesign.css-Werte (#0d1210/#141a17) — und ein Hex hätte im Hellmodus überhaupt
   keinen Gegenwert. Deshalb --surface/--border/--green statt --s1/--line/--acc.
   Der Hellmodus fällt damit fast überall von selbst richtig aus, genau wie bei
   .disc-* (das deshalb ohne eine einzige body.light-Regel auskommt). Die drei
   Stellen, an denen das nicht reicht, stehen gesammelt am Ende dieses Blocks. */

/* ── Quelle, linke Spalte ── */
/* Ablagefeld. Die einzige gestrichelte Fläche im Produkt, und sie markiert genau
   eine Sache: hier kann etwas fallen gelassen werden. */
.imp-drop {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 8px; height: 98px; padding: 0 14px; text-align: center;
  border: 1px dashed var(--border-2); border-radius: 8px; background: var(--surface-2);
  transition: border-color .12s, background .12s;
}
/* Während etwas darüber schwebt. Grün heißt hier „loslassen ist jetzt richtig". */
.imp-drop.over { border-color: var(--green); background: var(--green-dim); }
.imp-drop-t { font-size: 12.5px; color: var(--text-2); line-height: 1.5; }
/* Ersatzsymbol NUR, wenn im Markup keins steht. Kommt später ein <svg> hinein,
   verschwindet der Ersatz von selbst, statt sich zu verdoppeln. Ein Pfeil, kein
   Emoji (Hausregel: keine Emojis an Bedienelementen). */
.imp-drop-ic { flex: 0 0 auto; color: var(--text-muted); line-height: 1;
  /* 🚨 Eigene Höhe plus overflow:visible. Mit line-height:1 ist die Box kleiner
     als das 19px-Zeichen darin, und der Pfeil wurde oben und unten beschnitten.
     Gemessen am 02.08.2026 (scrollHeight > clientHeight). */
  height: 22px; display: block; overflow: visible; }
.imp-drop-ic:empty::before { content: "\2191"; font-size: 19px; line-height: 1; }
/* „oder Datei auswählen" und „andere Datei" sind Knöpfe, sehen aber wie Links aus:
   in den 304px Panelbreite frisst ein echter Knopf den Dateinamen auf.
   🚨 var(--green-text), NICHT var(--green): auf dem hellen Papier kommt --green nur
   auf 2,62:1 (PIN-458). Unterstrichen wie .btn-link, das ist die Hausregel für Links. */
.imp-drop-pick, .imp-src-other {
  background: none; border: 0; padding: 0; font: inherit;
  color: var(--green-text); font-weight: 500; cursor: pointer; white-space: nowrap;
  text-decoration: underline; text-underline-offset: 2px;
}
.imp-drop-pick:hover, .imp-src-other:hover { opacity: .85; }
.imp-drop-pick:focus-visible, .imp-src-other:focus-visible {
  outline: 2px solid var(--green); outline-offset: 2px; border-radius: 3px;
}
/* Quellkarte. Ersetzt Ablagefeld UND Einfügefeld, sobald eine Datei gewählt ist. */
.imp-src {
  padding: 9px 11px; border: 1px solid var(--border-2); border-radius: 8px;
  background: var(--surface-2);
}
.imp-src-top { display: flex; align-items: center; gap: 10px; }
.imp-src-i {
  flex: 0 0 30px; width: 30px; height: 30px; border-radius: 7px;
  background: var(--surface-3); color: var(--text-2);
  display: grid; place-items: center;
}
/* Ersatzsymbol wie beim Ablagefeld, nur ohne eigenes im Markup: ein Blatt Papier
   als schlichter Umriss. Hochkant und mit abgeknickter Ecke oben rechts, sonst
   liest sich das Quadrat wie ein zweites Kästchen. */
.imp-src-i:empty::before {
  content: ""; width: 13px; height: 16px; border-radius: 2px 5px 2px 2px;
  border: 1.5px solid currentColor;
}
.imp-src-n {
  flex: 1 1 auto; min-width: 0; font-size: 12.5px; font-weight: 600; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Metazeile mit eigener Trennlinie darüber: Zeilenzahl, Größe, erkanntes Format.
   Das Format steht hier und nicht in einer eigenen Pille. */
.imp-src-m {
  display: flex; align-items: center; gap: 6px; min-width: 0;
  margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--border);
  font-size: 11px; color: var(--text-2); font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.imp-src-m > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.imp-src-other { margin-left: auto; flex: 0 0 auto; font-size: 11px; }

/* ── Erkannt-Streifen über der Liste ── */
/* Ersetzt den Satz „Wir erkennen das automatisch" durch das Ergebnis der Erkennung.
   Fläche eine Stufe TIEFER als die Zeilen darunter (--bg statt --surface, in beiden
   Modi eine Stufe dunkler, wie bei .disc-item.disc-dup): der Streifen liest sich
   damit als Beschriftung und nicht als weitere Zeile. */
.imp-bar {
  flex: 0 0 auto; display: flex; flex-direction: column;
  padding: 0 13px; margin-bottom: 12px;
  border: 1px solid var(--border); border-radius: 8px; background: var(--bg);
  font-size: 11.5px; color: var(--text-2);
}
/* Einzeilig mit Auslassungspunkten: bei sieben erkannten Spalten wäre der Streifen
   sonst drei Zeilen hoch und schöbe die Liste nach unten.
   🚨 Runde C: die Zeile ist jetzt flex, weil rechts „ändern" steht. Die Kürzung
   sitzt deshalb am inneren .imp-bar-t und NICHT mehr an der Zeile — sonst würde
   der Link mit abgeschnitten, sobald der Satz lang wird. <b> und die Trennpunkte
   bleiben in .imp-bar-t inline, die Kürzung greift dort genauso. */
/* 🚨 Runde C, Abnahme Dario 03.08.2026: der Streifen war „ein Satz, den man
   irgendwann überliest" — 11,5 Pixel grau, und gemessen saß er bei 14 Prozent
   der Boxhöhe, weil der Einheiten-Umschalter darunter die Box auf 140 Pixel
   aufzieht und mehr Gewicht hat als die Aussage darüber. Jetzt trägt eine kleine
   Versalzeile die Einordnung, die Spaltennamen stehen als Chips darunter, und
   „ändern" ist selbst ein Chip auf derselben Linie. Man liest keinen Satz mehr,
   man sieht drei Zuordnungen. */
.imp-bar-zeile { min-width: 0; padding: 11px 0 12px; }
.imp-bar-vz {
  display: block; margin-bottom: 7px;
  font-size: 10px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase;
  color: var(--text-muted);
}
/* Die Paare links, „ändern" rechts, beide mittig auf derselben Linie. */
.imp-bar-linie { display: flex; align-items: center; gap: 12px; min-width: 0; }
.imp-bar-t {
  flex: 1 1 auto; min-width: 0; font-size: 12.5px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Die Spaltennamen als Chips, Bauform aus dem Bestand (.imp-bdg). */
.imp-bar-t b {
  display: inline-block; margin: 0 2px;
  padding: 2px 9px; border-radius: 999px;
  border: 1px solid var(--border-2); background: var(--surface-2);
  color: var(--text); font-weight: 600; font-size: 11.5px;
}
.imp-bar-zeile .dot { color: var(--text-muted); padding: 0 3px; }
/* „ändern" öffnet das Zuordnungspanel. Ein echter <button> statt eines <a> ohne
   href wie im Mockup: er ist der einzige Weg ins Panel und muss über die Tastatur
   erreichbar sein. Als grüner Chip in derselben Höhe wie die Spalten-Chips
   (Entscheidung Dario 03.08.2026) — kein Schein, kein Schatten, nur Farbe. */
.imp-bar-change {
  flex: 0 0 auto;
  padding: 2px 11px; border-radius: 999px;
  border: 1px solid var(--green); background: var(--green-dim);
  font: inherit; font-size: 11.5px; font-weight: 600;
  color: var(--green-text); cursor: pointer; white-space: nowrap;
  transition: background .12s, border-color .12s;
}
.imp-bar-change:hover { background: color-mix(in srgb, var(--green) 18%, transparent); }
.imp-bar-change:focus-visible { outline: 2px solid var(--green); outline-offset: 2px; }
.imp-bar-change.hidden { display: none; }
/* Nach einer Zuordnung von Hand ist der Streifen kein Befund mehr, sondern eine
   Bestätigung: derselbe Zustand, den das Mockup als .map-bar.on vorsieht. */
.imp-bar.on { border-color: color-mix(in srgb, var(--green) 48%, transparent); }
/* PIN-492: der Sekunden/Minuten-Umschalter zieht hierher um und erscheint weiter NUR,
   wenn die Datei die Einheit nicht selbst nennt. Eigene Zeile mit Trennlinie, sonst
   quetscht er den Erkannt-Satz. Der Umschalter selbst ist .seg/.seg-btn aus dem
   Bestand, hier steht nur, wie er sich einfügt. */
.imp-bar-einheit {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px;
  padding: 9px 0 10px; border-top: 1px solid var(--border);
  font-size: 12.5px; line-height: 1.5; color: var(--text-2);
}
.imp-bar-einheit .seg { padding: 2px; }
.imp-bar-einheit .seg-btn { padding: 3px 10px; }
/* Zähler im Listenkopf. Die Zahl trägt die Information, deshalb steht sie allein
   in --text und der Rest bleibt zurückgenommen. */
.imp-cnt { font-size: 12px; color: var(--text-2); font-variant-numeric: tabular-nums; white-space: nowrap; }
.imp-cnt b { color: var(--text); font-weight: 600; }

/* ── Runde C: Zuordnungspanel ──────────────────────────────────────────────
   Es ERSETZT den Erkannt-Streifen, es steht nicht zusätzlich darüber (Spezifikation
   Dario) — deshalb an derselben Stelle in .imp-right, fest, vor der Liste. Eine
   Stufe HÖHER als der Streifen (--surface statt --bg) und mit dem starken Rand:
   der Streifen ist eine Beschriftung, das Panel ist ein Formular.
   Maße aus der Vorlage: Radius 12, Innenabstand 15/16/14, 16 Abstand nach unten. */
.imp-map {
  flex: 0 0 auto;
  border: 1px solid var(--border-2); border-radius: 12px;
  background: var(--surface);
  padding: 15px 16px 14px; margin-bottom: 16px;
}
.imp-map.hidden { display: none; }
.imp-map-kopf {
  display: flex; align-items: center; gap: 6px;
  font-size: 10.5px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase;
  color: var(--text-muted); margin-bottom: 11px;
}
/* Ersatzsymbol wie bei .imp-grp-ic und .imp-zero-ic: ein Zeichen statt einer
   zweiten SVG-Quelle, die niemand mitpflegt. */
.imp-map-ic { flex: 0 0 auto; line-height: 1; font-size: 11px; color: var(--text-muted); }
.imp-map-ic:empty::before { content: "\25A6"; }
/* 🚨 minmax(0,1fr) statt 1fr, dieselbe Regel wie in der ganzen Kette: mit 1fr
   wächst eine lange Beispiel-URL über ihre Spalte hinaus und schiebt das Raster
   auseinander, statt gekürzt zu werden. Die 126px links stehen fest, damit die
   vier Feldnamen und die Auswahlfelder darunter eine Flucht bilden. */
.imp-map-raster {
  display: grid; grid-template-columns: 126px minmax(0, 1fr) minmax(0, 1fr);
  gap: 7px 14px; align-items: center;
}
.imp-map-hd {
  font-size: 10px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase;
  color: var(--text-muted); padding-bottom: 1px;
}
.imp-map-feld { font-size: 12.5px; font-weight: 500; color: var(--text-2); }
/* Das Auswahlfeld ist ein echtes <select>: der Bestand baut Attrappen nur dort,
   wo es nichts zu bedienen gibt. Hier gibt es etwas zu bedienen, und es muss über
   die Tastatur gehen. Die Höhe 34 kommt aus der Vorlage. */
.imp-map-sel {
  width: 100%; min-width: 0; height: 34px;
  padding: 0 8px 0 10px;
  border: 1px solid var(--border-2); border-radius: 8px;
  background: var(--surface-2); color: var(--text);
  font-family: inherit; font-size: 12.5px;
  outline: none; cursor: pointer;
  transition: border-color .15s, box-shadow .15s;
}
.imp-map-sel:focus { border-color: var(--green); box-shadow: 0 0 0 3px var(--green-dim); }
/* Nicht zugeordnet: gedämpft, wie das Beispiel daneben. Beides gehört zusammen,
   nur eines davon sieht halb richtig aus. */
.imp-map-sel.none { color: var(--text-muted); }
.imp-map-sel option { background: var(--surface-2); color: var(--text); }
/* Monospace, damit man sieht, was WIRKLICH in der Zelle steht: führende
   Leerzeichen, ein O statt einer 0, ein Semikolon mitten in der Adresse. */
.imp-map-bsp {
  min-width: 0; font-size: 12px; color: var(--text-2);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-variant-numeric: tabular-nums;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.imp-map-bsp.dim { color: var(--text-muted); }
/* 🚨 ZWEI Klassen im Selektor, und das ist Absicht: `label` trägt weiter unten
   (style.css:2070) global `display:flex; flex-direction:column; margin-bottom:14px`.
   Bei gleicher Spezifität gewinnt die spätere Regel, und das Kästchen stand
   dadurch ÜBER seinem Text statt daneben, mittig im Panel. Gesehen am 02.08.2026
   im Bild, von keinem Test gefunden. Dieselbe Falle wie bei PIN-440. */
.imp-map .imp-map-chk {
  display: flex; flex-direction: row; align-items: center; gap: 8px;
  margin: 13px 0 0; font-size: 11.5px; color: var(--text-2); cursor: pointer;
}
/* Das Kästchen ist dasselbe wie in der Liste (input.imp-rel-cb), nur kleiner:
   eine zweite Kästchen-Bauart im selben Bildschirm wäre eine Unstimmigkeit. */
.imp-map-chk .imp-rel-cb { width: 17px; height: 17px; flex: 0 0 17px; }
.imp-map-fuss {
  display: flex; align-items: center; justify-content: space-between; gap: 20px;
  margin-top: 13px;
}
.imp-map-hinweis {
  margin: 0; max-width: 430px;
  font-size: 11.5px; line-height: 1.5; color: var(--text-2);
}
.imp-map-btns { display: flex; gap: 9px; flex: 0 0 auto; }
/* Schmal wird es zweistufig: 126px plus zwei Spalten passen unter rund 700px
   nicht mehr nebeneinander. Der Feldname bleibt oben, Auswahl und Beispiel
   rutschen darunter — gemessen bei 390px, wo sonst das Beispiel auf zwei Zeichen
   zusammenfällt. */
@media (max-width: 700px) {
  .imp-map-raster { grid-template-columns: minmax(0, 1fr); gap: 4px; }
  .imp-map-hd { display: none; }
  .imp-map-feld { margin-top: 8px; }
  .imp-map-bsp { padding-left: 2px; }
  .imp-map-fuss { flex-direction: column; align-items: stretch; gap: 11px; }
  .imp-map-btns { justify-content: flex-end; }
}

/* ── Problem- und Bekannt-Streifen, einklappbar ── */
/* Beide sammeln ihre Zeilen AN ORT UND STELLE, nie zwischen den Kandidaten: bei einer
   Datei mit 300 Zeilen wäre eine gemischte Liste unlesbar. Fläche wie beim
   Erkannt-Streifen eine Stufe tiefer, die Zeilen darin liegen sichtbar darüber. */
.imp-grp {
  flex: 0 0 auto; overflow: hidden;
  border: 1px solid var(--border); border-radius: 8px; background: var(--bg);
}
.imp-grp-bar {
  display: flex; align-items: center; gap: 9px; min-height: 36px; padding: 0 13px;
  font-size: 11.5px; color: var(--text-2);
}
/* Der Auf- und Zuklapp-Schalter steht rechts außen, egal wie lang der Satz links ist. */
.imp-grp-bar > button, .imp-grp-bar > a { margin-left: auto; flex: 0 0 auto; }
/* Gelb markiert die EINE Sache, die eine Entscheidung braucht. Nur die Kante, keine
   gelbe Fläche: der Streifen ist ein Hinweis, keine Warnung.
   Gemischt gegen --border statt gegen transparent: 32% Gelb auf dem hellen Papier
   wären eine kaum sichtbare Linie, gegen die Rahmenfarbe bleibt sie in beiden Modi. */
.imp-grp.warn { border-color: color-mix(in srgb, var(--yellow) 40%, var(--border)); }
.imp-grp.warn .imp-grp-bar svg { color: var(--yellow); }
/* Zugeklappt ist der Normalfall, .open zeigt die Zeilen. Bewusst über CSS und nicht
   über .hidden: der Zustand gehört dem Streifen, nicht seinem Inhalt. */
.imp-grp-rows {
  display: none; flex-direction: column; gap: 5px;
  padding: 2px 8px 8px; border-top: 1px solid var(--border);
}
.imp-grp.open .imp-grp-rows { display: flex; }

/* ── Zeile mit Unterzeile ── */
/* Eine Zeile, die etwas zu sagen hat, wird umschlossen: Kasten und Auswahlzustand
   wandern auf die Klammer, die Zeile darin wird rahmenlos. NUR wo es etwas zu sagen
   gibt — „Ohne Kunde" unter jeder Zeile wäre Rauschen. Gleichzeitig ist das der
   Platz für die Korrekturen aus Runde B. */
.imp-zeile {
  flex: 0 0 auto; border: 1px solid var(--border); border-radius: 8px;
  background: var(--surface); transition: border-color .12s, background .12s;
}
.imp-zeile .imp-rel-row { height: 41px; border: 0; border-radius: 0; background: transparent; }
.imp-zeile .imp-rel-row:hover { border: 0; background: transparent; }
/* Die Rückmeldung beim Überfahren wandert mit auf die Klammer, sonst hätte die Zeile
   im Kasten gar keine mehr. var(--green), NICHT var(--accent): `--accent: var(--green)`
   steht nur auf :root und wird DORT aufgelöst, body.light überschreibt --green und
   nicht die Kette (PIN-458-Befund). */
.imp-zeile:hover { border-color: var(--green); }
.imp-zeile:has(.imp-rel-cb:checked) {
  border-color: color-mix(in srgb, var(--green) 48%, transparent);
  background: color-mix(in srgb, var(--green) 5.5%, transparent);
}
/* Fußnote zur Zeile darüber: kein eigener Rahmen, keine eigene Fläche. Eingerückt um
   die Breite des Kästchens (20) plus Abstand (12) plus Innenabstand (13), damit sie
   unter dem Namen beginnt und nicht unter dem Haken. */
/* Runde B: es können mehrere sein. Eine Zeile, an der drei Sachen geradegezogen
   wurden, trägt drei Unterzeilen (Entscheidung Dario, 02.08.2026). Der untere
   Innenabstand gehört deshalb der LETZTEN, sonst klafft zwischen je zwei
   Unterzeilen eine Lücke von 9 Pixeln und der Kasten wird doppelt so hoch. */
.imp-zeile-sub {
  display: flex; align-items: flex-start; gap: 7px;
  padding: 0 13px 4px 45px; font-size: 11px; line-height: 1.45; color: var(--text-2);
}
.imp-zeile-sub:last-child { padding-bottom: 9px; }
.imp-zeile-sub .imp-bar-dot,
.imp-zeile-sub .dot { color: var(--text-muted); }
/* Das Zeichen sitzt an der ersten Textzeile, nicht in der Mitte eines umgebrochenen
   Satzes: `align-items: flex-start` oben, hier der Ausgleich auf die Grundlinie. */
.imp-zeile-sub > svg { flex: 0 0 auto; margin-top: 2px; color: var(--text-muted); }

/* ── Abzeichen und Chips ── */
/* Intervall-Abzeichen: immer der Wert NACH dem Anlegen, nie der aus der Datei. */
.imp-bdg {
  display: inline-flex; align-items: center; gap: 4px; flex: 0 0 auto;
  padding: 2px 6px; border: 1px solid var(--border-2); border-radius: 5px;
  font-size: 10.5px; font-weight: 500; color: var(--text-2);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.imp-bdg svg { color: var(--text-muted); }
/* „bereits überwacht". --text-2 statt --text-muted und keine eigene Fläche: das
   Abzeichen sitzt auf der abgesenkten Fläche des Bekannt-Streifens und käme mit
   gedämpftem Grau nicht über die Lesbarkeitsschwelle (gleiche Rechnung wie bei
   .disc-badge-dup). Zurückgenommen wirkt es trotzdem, über Rahmen und Größe. */
.imp-bdg.done { color: var(--text-2); border-color: var(--border); background: transparent; }
/* Rot nur für die Zeile, die nicht anlegbar ist. Gleiche Form wie .imp-chip.schon-da. */
.imp-chip.fehler { color: var(--red); border-color: var(--red); background: transparent; }
/* Runde B: „angepasst" in Gelb, ganz rechts nach Relevanz-Chip und Abzeichen.
   Gelb heißt im Haus „hinsehen, aber kein Fehler" — genau das ist eine Zeile, die
   wir geradegezogen haben. Über var(--yellow), NICHT über den festen Wert aus dem
   Mockup: `body.light` überschreibt das Token, ein hart notiertes #e3a445 stünde
   im Hellmodus auf zu heller Fläche (PIN-458-Befund). */
.imp-chip.angepasst { color: var(--yellow); border-color: var(--yellow); background: transparent; }
/* ── Niedriges Fenster: die linke Spalte gibt Höhe ab, statt zu scrollen ──────
   Dario, 02.08.2026 beim Durchfahren: „das Scrollverhalten links nervt, man kann
   die ganze Seite scrollen oder innerhalb der Box". Der zweite Scrollbereich ist
   auch laut Spezifikation nicht vorgesehen.
   🚨 Gemessen, nicht geschätzt: der Inhalt der linken Spalte ist 756 Pixel hoch.
   Bei einem 900er Fenster passt er auf den Punkt, bei 800 fehlten 100 Pixel, bei
   720 sogar 180. Hier wird geholt, was OHNE Texteingriff zu holen ist: das
   Ablagefeld wird flacher, das Textfeld kürzer, die Trennlinien rücken zusammen.
   Copy schreibt Dario, deshalb wird kein Satz versteckt. Reicht das bei sehr
   niedrigen Fenstern nicht, bleibt der Scrollbalken als Notventil (redesign.css,
   `.imp-left { overflow-y:auto }`) — das ist immer noch besser, als den unteren
   Rand abzuschneiden. */
@media (min-width: 1101px) and (max-height: 899px) {
  body.import-page-open #modal-import .imp-drop { height: 74px; gap: 6px; }
  body.import-page-open #modal-import #import-paste { height: 56px; min-height: 56px; }
  body.import-page-open #modal-import .disc-panel-div { margin-top: 7px; margin-bottom: 7px; }
  body.import-page-open #modal-import .import-or { margin: 7px 0; }
  body.import-page-open #modal-import .imp-hint { padding: 7px 11px; }
  body.import-box .disc-panel { padding-bottom: 10px; }
}
@media (min-width: 1101px) and (max-height: 849px) {
  /* Noch flacher. Das Ablagefeld bleibt bedienbar (ein Ziel von 60 Pixeln trifft
     man mit der Maus), und das Textfeld ist ohnehin `resize:vertical`. */
  body.import-page-open #modal-import .imp-drop { height: 60px; }
  body.import-page-open #modal-import #import-paste { height: 46px; min-height: 46px; }
}
@media (min-width: 1101px) and (max-height: 799px) {
  /* Dritte Stufe für die verbreiteten 1366x768-Geräte. Hier rückt auch der
     Erklärkopf zusammen: engere Zeilen, kein kleinerer Schriftgrad. Der Text
     bleibt vollständig, nur der Durchschuss geht von 1,6 auf 1,45 zurück. */
  body.import-page-open #modal-import .disc-head .modal-hint { line-height: 1.45; }
  body.import-page-open #modal-import .disc-head { margin-bottom: 8px; }
  body.import-page-open #modal-import #import-hint-set { margin-top: 5px; }
  body.import-page-open #modal-import .disc-client-row { margin-bottom: 5px; }
  body.import-page-open #modal-import .disc-panel { padding-top: 12px; padding-bottom: 10px; }
  body.import-page-open #modal-import .imp-hint { padding: 5px 11px; }
}

/* Drei feste Plätze rechts, damit die Chips untereinander stehen (Dario, 02.08.2026
   beim Durchfahren: „das eiert so ein bisschen in der Gegend rum"). Ohne feste
   Breiten ist die Gruppe nur als Block rechtsbündig: weil „60 s" schmaler ist als
   „3600 s" und „angepasst" mal da ist und mal nicht, stand der Relevanz-Chip je
   Zeile woanders. Gemessen in EINER Liste: linke Kante bei 1197, 1204 und 1275.
   🚨 Die Breiten sind gemessen, nicht geschätzt, und zwar in beiden Sprachen:
   Relevanz bis 66px („Medium" auf Englisch ist breiter als „Niedrig"), Abzeichen
   bis 64px („1440 min"), „angepasst" 79px. Wer die Texte ändert, misst nach.
   Der 30-Tage-Deckel („2592000 s", 73px) sprengt den mittleren Platz bewusst: er
   kommt praktisch nie vor, und eine dauerhaft breitere Spalte für ihn wäre teurer
   als die eine schiefe Zeile.
   Nur Kandidatenzeilen: die Problem- und die Bekannt-Zeile tragen genau EIN
   Element rechts und würden im Raster in der linken Spalte landen. */
.imp-rel-row:not(.ist-fehler):not(.ist-dublette) .imp-rel-rt {
  display: grid; grid-template-columns: 68px 66px 80px; gap: 6px; align-items: center;
}
.imp-rel-row:not(.ist-fehler):not(.ist-dublette) .imp-rel-rt > .imp-chip { text-align: center; }
.imp-rel-row:not(.ist-fehler):not(.ist-dublette) .imp-rel-rt > .imp-bdg { justify-content: center; }

/* 🚨 Am Handy fliegt der Chip raus. Gemessen bei 390 Pixeln: rechts stehen jetzt
   DREI Sachen (Relevanz, Abzeichen, „angepasst") statt zwei, zusammen rund 174 der
   366 Pixel Zeilenbreite. Name und URL blieben als „Sta…" und „runde-b-ei…" übrig,
   und damit war die Zeile nicht mehr zu lesen.
   Verloren geht dabei nichts: den Chip gibt es nur, wenn darunter eine Unterzeile
   steht, und die sagt vollständig, was verändert wurde. Der Chip ist die
   Zusammenfassung für den Fall, dass man ihn NICHT gleich daneben liest.
   Gleiches Muster wie `.cockpit-row .cr-score` (redesign.css). */
@media (max-width: 640px) {
  .imp-chip.angepasst { display: none; }
  /* Ohne den dritten Platz bliebe eine leere Spalte von 86 Pixeln stehen, und die
     fehlt genau da, wo sie am teuersten ist. Etwas enger als am großen Bildschirm:
     „Niedrig" und „1440 min" passen weiterhin. */
  .imp-rel-row:not(.ist-fehler):not(.ist-dublette) .imp-rel-rt {
    grid-template-columns: 64px 64px;
  }
}

/* ── Problemzeile ── */
/* Nicht anlegbar: gesperrtes Kästchen, als Name die Zeilennummer, und statt der URL
   die ROHZEILE aus der Datei. Nur daran sieht man, woran es lag. */
.imp-rel-row.ist-fehler { cursor: default; }
.imp-rel-row.ist-fehler:hover { border-color: var(--border); background: var(--surface); }
.imp-rel-row.ist-fehler .imp-rel-nm { color: var(--text-2); }
.imp-rel-row.ist-fehler .imp-rel-url,
.imp-rel-url.mono {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 11.5px; color: var(--text-2);
}
/* Platzhalter für das Kästchen: dieselbe Größe und derselbe Radius wie
   input.imp-rel-cb, damit die Spalte fluchtet — aber ohne Häkchen und ohne
   Bedienbarkeit. Ein deaktiviertes echtes Kästchen wäre hier falsch: es gibt
   nichts auszuwählen, nicht einmal gesperrt. */
.imp-cb-lock {
  flex: 0 0 20px; width: 20px; height: 20px; border-radius: 6px;
  border: 1.5px solid var(--border-2); background: var(--surface-2);
}
/* Zeilennummer aus der Datei, rechtsbündig auf festem Raster. */

/* ── Endmarke und Nullzustände ── */
/* Erklärt den Leerraum unter der Liste, statt ihn bloß zu lassen. */
.imp-end { flex: 0 0 auto; margin: 0; padding: 12px 2px 2px; font-size: 11px; color: var(--text-muted); }
.imp-end.hidden { display: none; }
/* Die vier Nullzustände stehen rechts, wo sonst die Liste steht. Gleiche Form wie
   .disc-zero, damit Finden und Import sich nicht widersprechen. */
.imp-zero {
  flex: 1; min-height: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 11px; text-align: center; padding-bottom: 40px;
}
.imp-zero.hidden { display: none; }
.imp-zero h3 { margin: 0; font-size: 16px; font-weight: 600; color: var(--text); }
.imp-zero p { margin: 0; max-width: 430px; font-size: 12.5px; line-height: 1.6; color: var(--text-2); }
.imp-zero svg { color: var(--text-muted); }
.imp-zero.warn svg { color: var(--yellow); }
.imp-zero.ok svg { color: var(--green-text); }
/* Ohne Symbol im Markup blieben .warn und .ok ohne jede Wirkung, der Zustand wäre
   dann allein Text. Deshalb zeichnet CSS ersatzweise einen schlichten Ring in der
   Zustandsfarbe; sobald ein <svg> dasteht, entfällt er. */
.imp-zero:not(:has(svg))::before {
  content: ""; flex: 0 0 auto; width: 26px; height: 26px; border-radius: 50%;
  border: 1.5px solid currentColor; color: var(--text-muted);
}
.imp-zero.warn:not(:has(svg))::before { color: var(--yellow); }
.imp-zero.ok:not(:has(svg))::before { color: var(--green-text); }
.imp-zero-btns { display: flex; flex-wrap: wrap; justify-content: center; gap: 9px; margin-top: 5px; }
/* Stille Notiz in der Fußleiste: der Zähler im Listenkopf verschwindet beim Scrollen. */
.imp-foot-note { flex: 0 0 auto; font-size: 12px; color: var(--text-muted); font-variant-numeric: tabular-nums; }
.imp-foot-note.hidden { display: none; }

/* ── Hellmodus der neuen Bausteine ──
   Das Mockup ist reiner Dunkelmodus, die helle Fassung ist laut Spezifikation gar
   nicht gebaut. Weil oben durchgehend Tokens stehen, fällt sie fast überall von
   selbst richtig aus — genau deshalb hat auch .disc-* keine einzige body.light-Regel.
   Hier stehen nur die drei Stellen, an denen ein Token allein auf dem hellen Papier
   das Falsche tut. */
/* Erkannt- und Gruppenstreifen liegen auf --bg, also auf genau dem Ton der Ebene.
   Im Dunkelmodus trägt die Haarlinie das allein (die Fläche liest sich als
   „abgesenkt", wie bei .disc-item.disc-dup). Auf dem hellen Papier (--bg #dce1d8,
   Rahmen #cbd2c6) verschwinden Kasten und Fläche ineinander. Eine halbe Stufe zur
   Panelfläche hin, dann liest der Streifen wieder als eigener Kasten und bleibt
   trotzdem tiefer als die Zeilen darüber. */
body.light .imp-bar,
body.light .imp-grp { background: color-mix(in srgb, var(--surface) 45%, var(--bg)); }
/* Die gestrichelte Kante ist die einzige Einladung im Ablagefeld. --border-2 kommt
   auf dem Papier nur auf eine Haarlinie und sähe nach gesperrtem Feld aus, nicht
   nach „hier kann etwas fallen gelassen werden".
   🚨 :not(.over) ist PFLICHT: .imp-drop.over hat dieselbe Spezifität (0,2,0) und
   steht weiter oben — ohne den Ausschluss bliebe die Kante beim Ziehen grau statt
   grün, und zwar nur im Hellmodus. */
body.light .imp-drop:not(.over) { border-color: var(--text-muted); }
/* Der gesperrte Kästchen-Platzhalter darf hell nicht wie ein leeres Eingabefeld
   wirken: --surface-2 ist auf Papier fast die Panelfläche. Eine Stufe tiefer, dann
   sieht man, dass hier nichts anzuhaken ist. */
body.light .imp-cb-lock { background: var(--surface-3); }

/* 5. Das Einrichtpanel muss bei 1440x900 OHNE eigenen Scrollbalken auskommen.
   🚨 Die Ebene hat genau EINEN Scrollbereich, und das ist die Vorschauliste. Am
   02.08.2026 lief das Panel um 15 Pixel über, weil der Import zwei Blöcke mehr
   trägt als das Mockup: den Zuordnungs-Hinweis (PIN-346) und den Prüfset-Satz.
   Statt eines der beiden zu streichen, rückt der Rhythmus im Panel zusammen.
   Gemessen, nicht geschätzt: 622 -> 606 Pixel Panelhöhe, 150 Pixel Luft bleiben.
   Der Prüfset-Satz ist am 02.08. nach OBEN in den Kopfbereich gewandert, weil man
   ihn unten erst nach dem Scrollen sah (Dario beim Durchfahren).
   🚨 Runde B, gleiche Rechnung noch einmal: Darios neuer Prüfset-Satz („Bei https
   kommt die Zertifikatsprüfung dazu.") bricht auf drei Zeilen statt zwei, und die
   Spalte lief wieder über, diesmal um 16 Pixel. Acht kommen aus dem Kopfbereich
   (.modal-box-import .disc-head), acht von hier. Wieder gemessen statt geschätzt:
   772 -> 756 Pixel, also genau bündig. Wer hier weiter zusammenrückt, sollte
   vorher nachmessen und nicht am Text sparen. */
#modal-import .disc-panel-div { margin: 10px -16px; }
#modal-import .disc-panel > .modal-hint { margin-bottom: 0; }
#modal-import #import-hint-set { margin: 8px 0 0; }

/* ── Runde A, Nachbesserungen nach dem ersten Hinsehen (02.08.2026) ──
   Vier Sachen, die erst am gerenderten Bildschirm auffielen. Sie stehen bewusst
   am Ende des Blocks: hier gewinnen sie in der Kaskade gegen die Regeln darüber,
   ohne dass irgendwo ein !important nötig wird. */

/* 1. Der Auf-/Zuklapper der Streifen war ein nackter <button>: im Dunkelmodus kam
      damit die weiße Standardfläche des Browsers durch, mitten im Streifen.
      Er sieht aus wie ein Link, ist aber ein Knopf, weil er nirgendwo hinführt. */
.imp-grp-toggle {
  margin-left: auto; flex: 0 0 auto;
  background: none; border: 0; padding: 0;
  font: inherit; font-size: 11.5px; font-weight: 500;
  color: var(--text-2); cursor: pointer; white-space: nowrap;
}
.imp-grp-toggle:hover { color: var(--text); text-decoration: underline; text-underline-offset: 2px; }
.imp-grp-toggle:focus-visible { outline: 2px solid var(--green); outline-offset: 2px; border-radius: 3px; }

/* 2. Der Hinweiskasten links: grüne Kante, KEIN Rahmen. Sonst steht Kasten in
      Kasten, weil er schon im Einrichtpanel sitzt (Spezifikation Abschnitt 3). */
.imp-hint {
  border: 0; border-left: 2px solid var(--green);
  border-radius: 0 6px 6px 0;
  padding: 9px 11px;
  margin-top: 2px;
}

/* 3. Symbole. Das Mockup zeichnet sie als SVG, im Haus werden solche Marken sonst
      als Zeichen gesetzt (siehe .disc-back::before). Keine Emojis: ▲ ist dasselbe
      Zeichen, mit dem das Dashboard seine Ausfälle markiert. */
.imp-grp-ic { flex: 0 0 auto; line-height: 1; font-size: 11px; color: var(--text-muted); }
.imp-grp-ic:empty::before { content: "\2713"; }              /* ✓ bereits überwacht */
.imp-grp.warn .imp-grp-ic { color: var(--yellow); }
.imp-grp.warn .imp-grp-ic:empty::before { content: "\25B2"; } /* ▲ Problemzeile */

.imp-zero-ic { line-height: 1; font-size: 26px; color: var(--text-muted); }
.imp-zero-ic:empty::before { content: "\21A5"; }               /* ↥ nichts geladen */
.imp-zero.warn .imp-zero-ic { color: var(--yellow); }
.imp-zero.warn .imp-zero-ic:empty::before { content: "\25B2"; }
.imp-zero.ok .imp-zero-ic { color: var(--green-text); }
.imp-zero.ok .imp-zero-ic:empty::before { content: "\2713"; }
/* Der Platzhalter-Ring des Nullzustands weicht, sobald eine echte Marke dasteht. */
.imp-zero:has(.imp-zero-ic)::before { content: none; }

/* 4. „oder Datei auswählen" ist im Mockup ein schlichter grüner Link ohne Strich.
      Der Strich kommt beim Zeigen und beim Tastaturfokus zurück, damit er trotzdem
      als anklickbar zu erkennen bleibt. */
.imp-drop-pick, .imp-src-other { text-decoration: none; }
.imp-drop-pick:hover, .imp-src-other:hover,
.imp-drop-pick:focus-visible, .imp-src-other:focus-visible {
  text-decoration: underline; text-underline-offset: 2px;
}


/* PIN-91: Kunde-Zuordnung der Übernahme + sichtbares Standard-Prüfset / MX-Hinweis */
.disc-client-row {
  /* PIN-444: flex-direction EXPLIZIT row — sonst greift die globale
     `label { flex-direction: column }`-Regel und die Box („Diesem Kunden zuordnen")
     stapelt + zentriert statt linksbündig zu stehen. Gilt für Import- UND Finden-Modal. */
  display: flex; flex-direction: row; align-items: center; gap: 10px; flex-wrap: wrap;
  margin-bottom: 8px; font-size: 13px; color: var(--text-2);
}
.disc-client-row select {
  flex: 1 1 auto; min-width: 160px;
  padding: 7px 10px; border: 1px solid var(--border); border-radius: 8px;
  background: var(--surface); color: var(--text); font-size: 13px;
}
.disc-checkset { margin: 0 0 9px; font-size: 11.5px; color: var(--text-2); line-height: 1.5; }
/* MX-Hinweis: KEIN Rahmen, nur eine grüne Kante links. Sonst steht im Panel Kasten in
   Kasten in Kasten (Spezifikation Punkt 2). Text auf --text-2 statt --text-muted, weil
   gedämpftes Grau auf der Panelfläche nur rund 2,9:1 erreicht. */
.disc-mail {
  margin: 0; padding: 8px 10px; border: 0; border-left: 2px solid var(--green);
  border-radius: 0 6px 6px 0; background: rgba(47,209,138,.05);
  color: var(--text-2); font-size: 11.5px; line-height: 1.5;
}
/* PIN-91 Politur: breiteres Discover-Fenster (weg vom Smartphone-Look) + Toggle-Kopf.
   Kompound-Selektor `.modal-box.modal-box-disc` (Spezifität 0,2,0) MUSS das spätere
   `.modal-box { max-width: 400px }` schlagen — sonst bliebe das Fenster schmal. */
.modal-box.modal-box-disc { max-width: 760px; }
.modal-box.modal-box-disc .disc-list { max-height: 54vh; }
.disc-results-head #disc-toggle-all { flex: 0 0 auto; }
/* PIN-91 Politur: Website-Live-Status (erreichbar?) + zusammengehörige Checkbox-Hinweise */
.site-status { display: inline-block; margin-top: 6px; font-size: 12px; font-weight: 600; }
.site-status-checking { color: var(--text-muted); }
.site-status-ok { color: #16a34a; }
.site-status-bad { color: #d97706; }
.cust-check { margin: 10px 0; }
.cust-check-hint { display: block; margin-top: 3px; padding-left: 26px; color: var(--text-muted); }

/* ── Visuelles Feedback: frisch angelegtes Element leuchtet kurz grün auf ── */
@keyframes pmFlash {
  0%   { box-shadow: 0 0 0 0 rgba(47,209,138,.55); }
  60%  { box-shadow: 0 0 0 10px rgba(47,209,138,.12); }
  100% { box-shadow: 0 0 0 16px rgba(47,209,138,0); }
}
.pm-flash {
  animation: pmFlash 1.6s ease-out 1;
  border-color: var(--green) !important;
}
/* Sanfter Bereichs-Highlight (z.B. Alarm-Sektion nach einem Sprung dorthin) */
@keyframes pmHighlight {
  0%, 100% { background: transparent; }
  25%      { background: var(--green-dim); }
}
.pm-highlight {
  animation: pmHighlight 2.4s ease-in-out 1;
  border-radius: 12px;
}

/* ── Kontextuelle Hilfe: dezentes ⓘ am Feld, Erklärung klappt inline darunter auf ── */
label { position: relative; }
.info-i {
  position: absolute; top: 0; right: 0;
  display: inline-flex; align-items: center; justify-content: center;
  width: 17px; height: 17px; padding: 0;
  border: 1px solid var(--border-2, var(--border)); border-radius: 50%;
  background: var(--surface-2); color: var(--text-muted);
  font-size: 11px; font-weight: 700; font-style: italic;
  font-family: Georgia, "Times New Roman", serif; line-height: 1; cursor: pointer;
  transition: color .15s, border-color .15s;
}
.info-i:hover { color: var(--green-text); border-color: var(--green); }
.field-help {
  flex-basis: 100%;
  margin-top: 2px;
  font-size: 12px; line-height: 1.45; color: var(--text-2); font-weight: 400;
  letter-spacing: 0;
  padding: 9px 11px; border-left: 2px solid var(--green);
  background: var(--green-dim); border-radius: 0 6px 6px 0;
}
.label-check { flex-wrap: wrap; }

/* ── Limit-Hinweis ─────────────────────────── */
.limit-hint {
  padding: 8px 24px;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  font-size: 12px;
  color: var(--text-muted);
  text-align: center;
}
.limit-hint-link {
  color: var(--green-text);
  text-decoration: none;
  font-weight: 500;
}
.limit-hint-link:hover { text-decoration: underline; }

/* ── Detail Panel ──────────────────────────── */
.overlay {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,.6);
  backdrop-filter: blur(2px);
  z-index: 10;
}

/* Zentriertes Modal statt Seiten-Drawer — die Tages-Balken brauchen Breite,
   und ein echtes Fenster passt zur restlichen Modal-UI (.modal-box-Optik
   kommt aus dem Rebrand-Block weiter unten) */
.panel {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: min(780px, calc(100vw - 32px));
  max-height: min(88vh, 860px);
  background: linear-gradient(180deg, var(--surface-2) 0%, var(--surface) 60px);
  border-radius: 16px;
  z-index: 20;
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  animation: panel-in .18s ease-out;
}
@keyframes panel-in {
  from { opacity: 0; transform: translate(-50%, -49%) scale(.97); }
  to   { opacity: 1; transform: translate(-50%, -50%) scale(1); }
}
@media (prefers-reduced-motion: reduce) { .panel { animation: none; } }

.panel-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  padding: 20px 20px 16px;
  border-bottom: 1px solid var(--border);
  gap: 12px;
  position: sticky;
  top: 0;
  background: var(--surface);
  z-index: 1;
  border-radius: 16px 16px 0 0;  /* deckt die runden Modal-Ecken beim Scrollen ab */
}

.panel-header > div {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}

.panel-header h2 {
  font-size: 15px;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  letter-spacing: -.2px;
}

.detail-url {
  font-size: 11px;
  color: var(--text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  font-family: 'Fira Code', 'Consolas', monospace;
}
.detail-url:hover { color: var(--blue); }

.panel-stats {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1px;
  background: var(--border);
  border-bottom: 1px solid var(--border);
}

.stat {
  background: var(--surface);
  padding: 14px 16px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.stat-label { font-size: 10px; color: var(--text-muted); text-transform: uppercase; letter-spacing: .6px; font-weight: 500; }
.stat-value { font-size: 14px; font-weight: 600; }

.panel-section { padding: 20px; border-bottom: 1px solid var(--border); }
.panel-section h3 { font-size: 10px; color: var(--text-muted); text-transform: uppercase; letter-spacing: .6px; font-weight: 600; margin-bottom: 14px; }

.panel-footer {
  padding: 16px 20px;
  margin-top: auto;
  display: flex;
  gap: 10px;
}

/* ── Funktions-Wächter (Detail-Panel) ─────────
   Stille Defekte (noindex, robots.txt, Mixed Content, Mail-DNS …) als klare,
   nach Schweregrad sortierte Liste. Geteilt von echtem Dashboard + Demo. */
.fn-intro { font-size: 12.5px; color: var(--text-2); margin: -4px 0 12px; line-height: 1.5; }
.fn-list { display: flex; flex-direction: column; gap: 8px; }
.fn-finding {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 11px 13px; border-radius: 10px;
  background: var(--surface); border: 1px solid var(--border);
  border-left: 3px solid var(--border);
}
.fn-finding.fn-hoch    { border-left-color: var(--red); }
.fn-finding.fn-mittel  { border-left-color: var(--yellow); }
.fn-finding.fn-niedrig { border-left-color: var(--text-muted); }
.fn-sev-badge {
  flex-shrink: 0; margin-top: 1px;
  font-size: 9.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .5px;
  padding: 3px 8px; border-radius: 999px; line-height: 1.5;
}
.fn-sev-hoch    { color: #fff; background: var(--red); }
.fn-sev-mittel  { color: #2a1d00; background: var(--yellow); }
.fn-sev-niedrig { color: var(--text); background: var(--surface-2); border: 1px solid var(--border); }
.fn-finding-text { font-size: 13px; color: var(--text); line-height: 1.5; }

/* ── Sparkline ─────────────────────────────── */
#detail-sparkline { height: 48px; }
#detail-sparkline svg { display: block; }
.no-data { color: var(--text-muted); font-size: 12px; }

/* ── Check-Tabelle ─────────────────────────── */
#detail-table-wrap { overflow-x: auto; }

table { width: 100%; border-collapse: collapse; font-size: 13px; }
th {
  text-align: left;
  color: var(--text-muted);
  font-weight: 500;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .4px;
  padding: 6px 8px;
  border-bottom: 1px solid var(--border);
}
td { padding: 7px 8px; border-bottom: 1px solid rgba(255,255,255,.025); color: var(--text-2); }
tr:last-child td { border-bottom: none; }
tr:hover td { background: rgba(255,255,255,.025); }

.td-up   { color: var(--st-up); font-weight: 500; }
.td-down { color: var(--st-down);   font-weight: 500; }

/* ── Modal ─────────────────────────────────── */
.modal {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0,0,0,.7);
  backdrop-filter: blur(4px);
  z-index: 30;
  padding: 20px;
}
/* Hintergrund-Scroll sperren, solange ein Modal offen ist → nur das Modal (und die
   Live-Vorschau) scrollen, nie mehr das Dashboard dahinter (Dario-Feedback). */
body.modal-open { overflow: hidden; }

.modal-box {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 28px;
  width: 100%;
  max-width: 400px;
  max-height: 85vh;
  overflow-y: auto;
  box-shadow: var(--shadow);
}

.modal-box::-webkit-scrollbar { width: 4px; }
.modal-box::-webkit-scrollbar-thumb { background: var(--border); border-radius: 4px; }

.modal-box h2 { font-size: 15px; font-weight: 600; margin-bottom: 20px; letter-spacing: -.2px; }

label {
  display: flex;
  flex-direction: column;
  gap: 5px;
  margin-bottom: 14px;
  font-size: 12px;
  color: var(--text-muted);
  font-weight: 500;
  letter-spacing: .1px;
}

label input, label select {
  background: var(--surface-2);
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: var(--radius);
  padding: 8px 11px;
  font-size: 14px;
  font-family: inherit;
  outline: none;
  transition: border-color .15s, box-shadow .15s;
}
label input:focus, label select:focus {
  border-color: var(--green);
  box-shadow: 0 0 0 3px var(--green-dim);
}
label select option { background: var(--surface-2); }

.form-error {
  background: var(--red-dim);
  border: 1px solid rgba(224,101,91,.25);
  color: var(--red);
  padding: 8px 12px;
  border-radius: var(--radius);
  font-size: 13px;
  margin-bottom: 12px;
}

.form-actions { display: flex; gap: 10px; justify-content: flex-end; margin-top: 8px; }

/* ── Utilities ─────────────────────────────── */
.hidden { display: none !important; }

/* ── Advanced Form Options ──────────────────── */
.advanced-opts { margin-bottom: 14px; }
.advanced-opts summary {
  cursor: pointer;
  font-size: 12px;
  color: var(--text-muted);
  padding: 6px 0;
  user-select: none;
  list-style: none;
  display: flex;
  align-items: center;
  gap: 6px;
  font-weight: 500;
}
.advanced-opts summary::before {
  content: '▶';
  font-size: 9px;
  transition: transform .15s;
  color: var(--text-muted);
}
.advanced-opts[open] summary::before { transform: rotate(90deg); }
.advanced-content { padding: 10px 0 0; display: flex; flex-direction: column; }
.label-check {
  flex-direction: row !important;
  align-items: center;
  gap: 8px !important;
  margin-bottom: 14px;
  cursor: pointer;
  font-size: 13px;
  color: var(--text-2);
}
.label-check input { width: auto; }

/* ── Maintenance ───────────────────────────── */
.dot-maintenance { background: var(--blue); box-shadow: 0 0 0 3px var(--blue-dim), 0 0 7px rgba(94,166,218,.4); }
.card.is-maintenance {
  border-left: 3px solid var(--blue);
  background: linear-gradient(135deg, rgba(94,166,218,.07) 0%, var(--surface) 55%);
}
.label-maintenance { color: var(--blue); }

.btn-maintenance {
  background: var(--blue-dim);
  color: var(--blue);
  padding: 8px 16px;
  border-radius: var(--radius);
  font-weight: 500;
  flex: 1;
  border: 1px solid rgba(94,166,218,.2);
}
.btn-maintenance:hover { background: rgba(94,166,218,.16); }

/* ── Gesperrte Endpunkte (Tier-Limit nach Downgrade) ── */
.card.is-locked {
  opacity: .55;
  filter: grayscale(.6);
  border-left: 3px solid var(--text-muted);
}
.card.is-locked .card-sparkline { opacity: .4; }
.dot-locked   { background: var(--text-muted); }
.label-locked { color: var(--text-muted); }

/* ── Suche (Endpunkte + Heartbeats) ────────── */
.search-input {
  background: var(--surface-2);
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: var(--radius);
  padding: 8px 12px;
  font-size: 13px;
  font-family: inherit;
  width: 240px;
  max-width: 100%;
  transition: border-color .15s, box-shadow .15s;
}
.search-input::placeholder { color: var(--text-muted); }
.search-input:focus {
  outline: none;
  border-color: #2fd18a;
  box-shadow: 0 0 0 3px rgba(47,209,138,.18);
}
.search-empty { font-size: 12.5px; color: var(--text-muted); margin-right: auto; }

/* Heartbeat-Suche: per Lupe auf-/zuklappbar */
.section-actions { display: flex; align-items: center; gap: 8px; }
.hb-search {
  width: 0;
  padding-left: 0;
  padding-right: 0;
  border-width: 0;
  opacity: 0;
  transition: width .2s ease, opacity .2s ease, padding .2s ease;
}
.hb-search.open {
  width: 200px;
  padding-left: 12px;
  padding-right: 12px;
  border-width: 1px;
  opacity: 1;
}

/* ── Aufklapp-Button (Liste > 20 Karten) ───── */
.card-filtered { display: none !important; }
.show-all-row { display: flex; justify-content: center; margin: 14px 0 4px; }
.btn-show-all {
  background: var(--surface-2);
  border: 1px solid var(--border);
  color: var(--text-muted);
  padding: 8px 18px;
  border-radius: 999px;
  font-size: 12.5px;
  font-weight: 500;
  cursor: pointer;
  transition: color .15s, border-color .15s;
}
.btn-show-all:hover { color: var(--text); border-color: var(--border-2); }

/* ── Auswahl-Modus (Mehrfach-Löschen) ─────── */
.select-toolbar { display: flex; gap: 8px; margin-bottom: 12px; justify-content: flex-end; align-items: center; }
.select-toolbar .search-input { margin-right: auto; }
#cards.select-mode .card { cursor: pointer; }
#cards.select-mode .card .card-actions { pointer-events: none; opacity: .3; }
.card.is-selected {
  outline: 2px solid var(--red);
  outline-offset: -2px;
  background: var(--red-dim);
}
.btn-danger {
  background: var(--red-dim);
  color: var(--red);
  border: 1px solid rgba(224,101,91,.3);
}
.btn-danger:hover:not(:disabled) { background: rgba(224,101,91,.18); }
.btn-danger:disabled { opacity: .5; cursor: not-allowed; }

/* ── Heartbeat Section (legacy alias) ──────── */
.hb-section-header { display: flex; align-items: center; justify-content: space-between; padding: 24px 0 12px; margin-top: 24px; }
.hb-section-title {
  display: flex;
  align-items: center;
  gap: 8px;
  font-weight: 600;
  font-size: 14px;
  color: var(--text);
}
.hb-icon { font-size: 15px; }
.hb-section-hint {
  font-size: 12px;
  color: var(--text-muted);
  font-weight: 400;
}
.btn-sm { padding: 7px 14px; font-size: 13px; }

/* ── Heartbeat Detail Modal ─────────────────── */
.modal-box-hb { max-width: 480px; }
.modal-hb-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 4px; }
.hb-detail-title { display: flex; align-items: center; gap: 8px; }
.hb-url-box {
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 14px;
}
.hb-url-label { font-size: 11px; color: var(--text-muted); margin-bottom: 8px; font-weight: 500; text-transform: uppercase; letter-spacing: .4px; }
.hb-url-row { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
.hb-url-code {
  font-family: 'Fira Code', 'Consolas', monospace;
  font-size: 12px;
  color: var(--text);
  word-break: break-all;
  flex: 1;
}
.hb-url-example {
  font-family: 'Fira Code', 'Consolas', monospace;
  font-size: 11px;
  color: var(--text-muted);
  white-space: pre;
  overflow-x: auto;
  line-height: 1.7;
  margin-top: 4px;
}
.modal-hint { font-size: 13px; color: var(--text-muted); margin-bottom: 16px; line-height: 1.6; }

/* ── Status Page Widget (Dashboard-intern) ──── */
.w-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 16px;
}
.w-badge {
  font-size: 15px;
  font-weight: 600;
  display: flex;
  align-items: center;
  gap: 6px;
}
.w-icon { font-size: 18px; }
.w-summary {
  font-size: 12px;
  color: var(--text-muted);
}
.w-section-title {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .6px;
  color: var(--text-muted);
  margin: 16px 0 8px;
  font-weight: 500;
}

/* ── Monitor List ── */
.w-monitors {
  display: flex;
  flex-direction: column;
  gap: 1px;
  background: var(--border);
  border: 1px solid var(--border);
  border-radius: 8px;
  overflow: hidden;
}

/* Kunden-Gruppen im „System Status"-Widget (PIN-167) — einklappbar, nur privat im Dashboard */
.w-groups { display: flex; flex-direction: column; gap: 8px; }
.w-group { border: 1px solid var(--border); border-radius: 10px; background: var(--surface-2); }
.w-group-head {
  display: flex; align-items: center; gap: 8px; width: 100%;
  padding: 9px 12px; background: none; border: 0; border-radius: 10px;
  cursor: pointer; font: inherit; color: var(--text); text-align: left;
}
.w-group-head:hover { background: var(--surface-3); }
.w-group-name { font-weight: 600; font-size: 13.5px; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.w-group-summary { margin-left: auto; font-size: 12px; color: var(--text-muted); white-space: nowrap; }
.w-group-caret { font-size: 11px; color: var(--text-muted); width: 12px; text-align: center; flex-shrink: 0; }
.w-group-body { padding: 0 10px 10px; }
.w-group-body.hidden { display: none; }
.w-group-hint { margin: 2px 2px 0; font-size: 11.5px; color: var(--text-muted); }
.w-monitor {
  background: var(--surface);
  padding: 10px 14px;
}
.w-monitor-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 6px;
}
.w-monitor-left {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}
.w-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  flex-shrink: 0;
}
.w-dot-up      { background: var(--st-up); box-shadow: 0 0 4px var(--st-up); }
.w-dot-down    { background: var(--st-down); box-shadow: 0 0 4px var(--st-down); }
.w-dot-unknown { background: var(--text-muted); }
.w-monitor-name {
  font-size: 13px;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.w-monitor-right {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-shrink: 0;
}
.w-uptime {
  font-size: 12px;
  font-weight: 600;
  color: var(--st-up);
  font-variant-numeric: tabular-nums;
}
.w-label {
  font-size: 11px;
  font-weight: 500;
  padding: 1px 7px;
  border-radius: 999px;
}
.w-lbl-up      { background: rgb(var(--st-up-rgb) / .12); color: var(--st-up); }
.w-lbl-down    { background: rgb(var(--st-down-rgb) / .12); color: var(--st-down); }
.w-lbl-unknown { background: var(--surface-2); color: var(--text-muted); }

/* ── 30-Day History (compact für Widget) ── */
.w-history-bar {
  display: flex;
  gap: 1px;
  align-items: flex-end;
}
.w-day {
  flex: 1;
  height: 16px;
  border-radius: 2px;
  cursor: default;
}
.w-day-up      { background: var(--st-up); opacity: .65; }
.w-day-up:hover { opacity: 1; }
.w-day-partial  { background: var(--st-degraded); opacity: .65; }
.w-day-partial:hover { opacity: 1; }
.w-day-down    { background: var(--st-down); opacity: .65; }
.w-day-down:hover { opacity: 1; }
.w-day-empty   { background: var(--border); }

/* ── Incidents ── */
.w-incidents {
  display: flex;
  flex-direction: column;
  gap: 1px;
  background: var(--border);
  border: 1px solid var(--border);
  border-radius: 8px;
  overflow: hidden;
}
.w-incident {
  background: var(--surface);
  padding: 8px 14px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.w-incident-title {
  font-size: 12px;
  font-weight: 600;
}
.w-incident-meta {
  font-size: 11px;
  color: var(--text-muted);
  flex-shrink: 0;
}
.w-no-incidents {
  font-size: 12px;
  color: var(--st-up);
  padding: 8px 0;
}

/* ── Footer (URL + Buttons) ── */
.w-footer {
  margin-top: 16px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 8px;
}
.w-url-row {
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
}
.w-url {
  font-family: 'Fira Code', 'Consolas', monospace;
  font-size: 11px;
  color: var(--text-muted);
  word-break: break-all;
  min-width: 0;
}
.w-url:hover { color: var(--green-text); }
/* Embed-Snippet-Zeile im Status-Widget-Footer (PIN-272) — eigene volle Zeile */
.w-embed-row { display: flex; align-items: center; gap: 6px; flex-basis: 100%; min-width: 0; }
.w-embed-lbl { font-size: 11px; color: var(--text-muted); font-weight: 600; white-space: nowrap; }
.w-embed-input { font-size: 10px; padding: 4px 8px; }
/* PIN-271: Kunden-Chip in der Wartungsliste — dezent, flach */
.maint-client-chip { color: var(--text); background: var(--surface-2); border: 1px solid var(--border); border-radius: 999px; padding: 1px 8px; font-size: 11px; white-space: nowrap; }
/* PIN-273: Telemetrie-Schalter für Nicht-Business gesperrt (Dario 10.07.) */
.pm-switch-locked { opacity: .5; cursor: not-allowed; }
.pm-switch-locked .pm-switch-lbl::before { content: "🔒 "; }
#cust-telemetry-hint.is-locked::after { content: " → Upgrade in den Einstellungen."; color: var(--accent, #0b7a3c); }
/* ── Helper: kleine Aktions-Buttons (Status-Widget-Footer, Incident-Modal) ──
   Marken-Stil statt nackter blauer Links: Pill mit Surface + Border,
   grüner Hover. Gilt auch für <a>-Elemente (Öffnen →). */
.btn-text {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  color: var(--text-2);
  cursor: pointer;
  padding: 5px 12px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 600;
  font-family: inherit;
  line-height: 1;
  text-decoration: none;
  transition: color .15s, border-color .15s, background .15s;
}
.btn-text:hover {
  color: var(--green-text);
  border-color: rgba(47,209,138, .45);
  background: var(--green-dim);
}
/* Deaktivieren = destruktiv: gedämpft, Hover rot (nach .btn-text, damit es gewinnt) */
.btn-text.w-disable { color: var(--text-muted); }
.btn-text.w-disable:hover {
  color: var(--red);
  border-color: rgba(224,101,91, .4);
  background: var(--red-dim);
}
.btn-xs { font-size: 11px; }

/* ── Branding: Grünes MON ──────────────────── */
.mon-accent { color: var(--green-text); }

/* ── Status Page Header ─────────────────────── */
.hb-section-header.sp-header { margin-top: 0; }

/* ── Responsive ────────────────────────────── */
@media (max-width: 640px) {
  .nav-center { display: none; }
}
@media (max-width: 480px) {
  header { padding: 12px 16px; }
  main { padding: 16px; }
  .metrics-row { grid-template-columns: 1fr 1fr; }
  .metrics-row .metric-card:last-child { grid-column: 1 / -1; }
  .panel { width: calc(100vw - 16px); max-height: 92vh; }
  .panel-stats { grid-template-columns: 1fr 1fr; }
}

/* ── Settings Page ─────────────────────────── */
.settings-layout {
  display: flex;
  gap: 32px;
  max-width: 960px;
  margin: 32px auto;
  padding: 0 24px;
}

.settings-nav {
  flex-shrink: 0;
  width: 180px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.settings-nav-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 14px;
  border-radius: 8px;
  background: none;
  border: none;
  color: var(--text-muted);
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  text-align: left;
  width: 100%;
  transition: background .15s, color .15s;
}
.settings-nav-item:hover {
  background: var(--surface);
  color: var(--text);
}
.settings-nav-item.active {
  background: rgba(94,166,218,.1);
  color: var(--blue);
  font-weight: 600;
}
.nav-icon { font-size: 16px; line-height: 1; }

.settings-content {
  flex: 1;
  min-width: 0;
}

.settings-tab {
  display: block;
}
.settings-tab.hidden {
  display: none;
}

.settings-section {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 20px 24px;
  margin-bottom: 16px;
}
.settings-section .section-title {
  font-size: 14px;
  font-weight: 600;
  color: var(--text);
  margin: 0 0 4px;
  text-transform: none;
  letter-spacing: 0;
}
.section-desc {
  font-size: 13px;
  color: var(--text-muted);
  margin: 0 0 14px;
  line-height: 1.6;
}
.settings-section label {
  display: block;
  font-size: 12px;
  font-weight: 500;
  color: var(--text-muted);
  margin-bottom: 14px;
}
.settings-section label:last-of-type { margin-bottom: 0; }
.settings-section label input,
.settings-section label select {
  display: block;
  width: 100%;
  margin-top: 6px;
}
.settings-section-danger {
  border-color: rgba(224,101,91,.2);
}
.section-title-danger { color: var(--red) !important; }

.form-error {
  font-size: 13px;
  color: var(--red);
  margin-top: 8px;
  padding: 8px 12px;
  background: rgba(224,101,91,.08);
  border-radius: 6px;
}
.form-success {
  font-size: 13px;
  color: var(--green-text);
  margin-top: 8px;
  padding: 8px 12px;
  background: rgba(47,209,138,.08);
  border-radius: 6px;
}
.form-actions {
  display: flex;
  gap: 8px;
  margin-top: 16px;
}
.form-actions .btn-primary,
.form-actions .btn-secondary { width: auto; }

.copy-field {
  display: flex;
  gap: 6px;
  align-items: center;
}
.copy-field input {
  flex: 1;
  font-family: 'Fira Code', 'Consolas', monospace;
  font-size: 12px;
  color: var(--text-muted);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 8px 12px;
  cursor: default;
  outline: none;
}
.copy-hint {
  font-size: 11px;
  color: var(--green-text);
  margin-top: 4px;
}

.input-row {
  display: flex;
  gap: 6px;
  align-items: center;
  margin-top: 6px;
}
.input-row input { flex: 1; margin-top: 0; }
.test-btn {
  background: var(--surface-2);
  border: 1px solid var(--border);
  color: var(--text);
  padding: 7px 14px;
  border-radius: 6px;
  font-size: 12px;
  cursor: pointer;
  white-space: nowrap;
}
.test-btn:hover { background: var(--border); }

.quiet-hours {
  display: flex;
  gap: 16px;
  margin-top: 8px;
}
.quiet-hours label {
  flex: 1;
  margin-bottom: 0;
}
.alert-feedback {
  font-size: 12px;
  margin-top: 6px;
  padding: 6px 10px;
  border-radius: 5px;
}
.link-blue { color: var(--blue); }
.link-blue:hover { text-decoration: underline; }

/* ── Alarm-Kanäle (Status-Liste) ── */
.ch-row {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: 10px;
  padding: 14px 16px;
  border: 1px solid var(--border);
  border-radius: 10px;
  margin-bottom: 10px;
  background: var(--surface-2);
}
.ch-row.is-active  { border-left: 3px solid var(--green); }
.ch-row.is-muted   { border-left: 3px solid var(--text-muted); opacity: .8; }
.ch-row.is-empty   { border-left: 3px solid var(--border-2); }
.ch-main { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; min-width: 0; }
.ch-name { font-weight: 600; font-size: 14px; }
.ch-value {
  font-size: 12px; color: var(--text-muted);
  font-family: 'Fira Code', 'Consolas', monospace;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ch-badge { font-size: 11px; font-weight: 600; padding: 2px 8px; border-radius: 999px; white-space: nowrap; }
.ch-badge-active { background: var(--green-dim); color: var(--green-text); }
.ch-badge-muted  { background: var(--surface-3); color: var(--text-muted); }
.ch-badge-off    { background: transparent; color: var(--text-muted); font-weight: 500; }
.ch-acts { display: flex; gap: 6px; align-items: center; }
.ch-btn {
  background: var(--surface-3); border: 1px solid var(--border);
  color: var(--text); padding: 6px 12px; border-radius: 6px;
  font-size: 12px; cursor: pointer; white-space: nowrap;
}
.ch-btn:hover:not(:disabled) { background: var(--border); }
.ch-btn:disabled { opacity: .5; cursor: default; }
.ch-btn-del { color: var(--red); padding: 6px 10px; }
.ch-btn-del:hover { background: var(--red-dim); }
.ch-btn-add { color: var(--green-text); }
.ch-edit { grid-column: 1 / -1; margin-top: 4px; }
/* Kanal-Eingabefelder (Nummer, Code, Webhook-URLs …): bisher ungestylter
   Browser-Default (weiße Box) — jetzt Haus-Look wie .search-input (PIN-124-
   Feedback 12.07.). Gilt für ALLE Kanäle im Alarm-Tab. */
.ch-input {
  flex: 1;
  min-width: 0;
  background: var(--surface-2);
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: var(--radius);
  padding: 8px 12px;
  font-size: 13px;
  font-family: inherit;
  transition: border-color .15s, box-shadow .15s;
}
.ch-input::placeholder { color: var(--text-muted); }
.ch-input:focus {
  outline: none;
  border-color: #2fd18a;
  box-shadow: 0 0 0 3px rgba(47,209,138,.18);
}
.prof-input { flex: 1; min-width: 0; }
.prof-pending {
  grid-column: 1 / -1; margin-top: 8px; font-size: 12.5px;
  color: var(--text-muted); display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
}
.ch-help { font-size: 12px; color: var(--text-muted); margin: 0 0 8px; }
.ch-fb { grid-column: 1 / -1; font-size: 12px; padding: 4px 0 0; }
.feedback-ok  { color: var(--green-text); }
.feedback-err { color: var(--red); }
@media (max-width: 640px) {
  .ch-row { grid-template-columns: 1fr; }
  .ch-acts { justify-content: flex-start; }
}

/* ── Billing / Pricing Cards ── */
.billing-current-plan {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 4px 0;
}
.billing-tier-badge {
  font-size: 13px;
  font-weight: 700;
  padding: 4px 12px;
  border-radius: 999px;
  background: rgba(94,166,218,.12);
  color: var(--blue);
}
.billing-limits {
  font-size: 13px;
  color: var(--text-muted);
}

.billing-plans {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 12px;
}

.billing-plan-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 20px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  position: relative;
  transition: border-color .15s;
}
.billing-plan-card:hover { border-color: var(--text-muted); }
.billing-plan-featured {
  border-color: var(--blue);
  background: linear-gradient(135deg, rgba(94,166,218,.03), var(--surface));
}
.billing-plan-featured:hover { border-color: var(--blue); }

.plan-badge {
  position: absolute;
  top: -10px;
  left: 50%;
  transform: translateX(-50%);
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .5px;
  padding: 3px 10px;
  border-radius: 999px;
  background: var(--blue);
  color: #fff;
  white-space: nowrap;
}

.plan-header {
  text-align: center;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--border);
}
.plan-name {
  font-size: 15px;
  font-weight: 600;
  color: var(--text);
  margin-bottom: 4px;
}
.plan-price {
  font-size: 28px;
  font-weight: 700;
  color: var(--text);
}
.plan-price span {
  font-size: 13px;
  font-weight: 400;
  color: var(--text-muted);
}

.plan-features {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
  flex: 1;
}
.plan-features li {
  font-size: 13px;
  color: var(--text);
  padding-left: 18px;
  position: relative;
}
.plan-features li::before {
  content: '✓';
  position: absolute;
  left: 0;
  color: var(--green-text);
  font-weight: 700;
}

.plan-btn {
  width: 100%;
  padding: 9px;
  border-radius: 8px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  border: none;
  margin-top: auto;
}
.btn-checkout {
  background: var(--blue);
  color: #fff;
}
.btn-checkout:hover { opacity: .9; }
.plan-btn[disabled] { opacity: .4; cursor: default; }

/* ── Settings Responsive ── */
@media (max-width: 768px) {
  .settings-layout { flex-direction: column; gap: 12px; margin: 16px auto; }
  .settings-nav { width: 100%; flex-direction: row; }
  .settings-nav-item { flex: 1; justify-content: center; font-size: 13px; padding: 8px 10px; }
  .billing-plans { grid-template-columns: 1fr; }
}
@media (max-width: 480px) {
  .settings-section { padding: 14px 16px; }
  .quiet-hours { flex-direction: column; gap: 8px; }
  .input-row { flex-direction: column; }
  .test-btn { width: 100%; }
}

/* ── Badge Modal ─────────────────────────────── */
.modal-badge-box { max-width: 520px; }
.badge-modal-hint { font-size: 12px; color: var(--text-muted); margin-bottom: 20px; line-height: 1.5; }
.badge-preview-section { margin-bottom: 18px; }
.badge-preview-label { font-size: 11px; color: var(--text-muted); font-weight: 600; letter-spacing: .3px; text-transform: uppercase; display: block; margin-bottom: 8px; }
.badge-preview-frame { background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius); padding: 14px 16px; margin-bottom: 8px; min-height: 48px; display: flex; align-items: center; }
.badge-preview-frame img { display: block; }
.badge-copy-row { display: flex; gap: 8px; }
.badge-code-input { flex: 1; background: var(--surface-2); border: 1px solid var(--border); color: var(--text-muted); border-radius: var(--radius); padding: 7px 10px; font-size: 11px; font-family: monospace; outline: none; min-width: 0; }
.btn-copy-badge { background: var(--surface-2); border: 1px solid var(--border); color: var(--text); border-radius: var(--radius); padding: 7px 14px; font-size: 12px; font-weight: 500; cursor: pointer; white-space: nowrap; transition: background .15s; }
.btn-copy-badge:hover { background: var(--border); }

/* ── Embed-Badge-Snippet: Varianten-Umschalter (PIN-272), flach/kein Glow ── */
.embed-variant-row { display: flex; gap: 16px; margin-bottom: 8px; font-size: 12px; color: var(--text-muted); }
.embed-variant-opt { display: inline-flex; align-items: center; gap: 5px; cursor: pointer; }
.embed-variant-opt input { margin: 0; accent-color: var(--accent, #0b7a3c); }

/* ── Trust-Badge: Domain-Binding-Whitelist (PIN-30) ── */
.badge-domains-hint { font-size: 12px; color: var(--text-muted); line-height: 1.5; margin: 0 0 10px; }
.badge-domains-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 8px; }
.badge-domain-chip { display: inline-flex; align-items: center; gap: 6px; background: var(--surface-2); border: 1px solid var(--border); border-radius: 999px; padding: 4px 6px 4px 12px; font-size: 12px; color: var(--text); }
.badge-domain-rm { background: none; border: none; color: var(--text-muted); cursor: pointer; font-size: 15px; line-height: 1; padding: 0 2px; border-radius: 50%; }
.badge-domain-rm:hover { color: var(--red); }
.badge-domains-msg { display: block; font-size: 12px; color: var(--text-muted); margin-top: 6px; }
.badge-domains-msg.feedback-err { color: var(--red); }
.badge-code-input:disabled { opacity: .5; cursor: not-allowed; }
.btn-copy-badge:disabled { opacity: .5; cursor: not-allowed; }

/* ── Trust Badges (Landing Page) ───────────── */
.trust-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 20px;
  max-width: 900px;
  margin: 0 auto;
  padding: 0 24px;
}
.trust-badge {
  background: #141414;
  border: 1px solid #1e1e1e;
  border-radius: 10px;
  padding: 20px 12px;
  text-align: center;
  transition: border-color 0.2s;
}
.trust-badge:hover { border-color: #2fd18a; }
.trust-badge .badge-icon { font-size: 24px; margin-bottom: 8px; }
.trust-badge .badge-title { font-size: 14px; font-weight: 600; color: #d4d4d4; margin-bottom: 4px; }
.trust-badge .badge-sub { font-size: 12px; color: #666; line-height: 1.4; }

/* ── Domain Expiry Badge ───────────────────── */
.card-domain-expiry {
  font-size: 11px;
  padding: 2px 6px;
  border-radius: 4px;
  display: inline-block;
  margin-bottom: 6px;
  font-weight: 500;
}
.expiry-ok       { color: var(--text-muted); background: transparent; }
.expiry-warn     { color: var(--st-degraded); background: var(--st-degraded-dim); }
.expiry-critical { color: var(--st-down);    background: var(--st-down-dim); }

/* Funktions-Wächter: dezenter Warn-Chip („still kaputt", trotz Status 200) */
.card-function-warn {
  font-size: 11px;
  padding: 2px 6px;
  border-radius: 4px;
  display: inline-block;
  margin-bottom: 6px;
  font-weight: 500;
  color: var(--yellow);
  background: var(--yellow-dim);
  cursor: help;
}

/* Multi-Region (PIN-122): „nur bei uns down — weltweit OK"-Chip auf der Karte.
   Grün statt Gelb: die Botschaft ist beruhigend (kein echter Ausfall). */
.card-mr-localonly {
  font-size: 11px;
  padding: 2px 6px;
  border-radius: 4px;
  display: inline-block;
  margin-bottom: 6px;
  font-weight: 500;
  color: var(--green-text);
  background: var(--green-dim);
  cursor: help;
}

/* Multi-Region (PIN-122): Upsell-Hinweis unter dem gesperrten Toggle —
   gleiche Blockform wie .field-help, aber neutral statt grün. */
.mr-lock {
  flex-basis: 100%;
  margin-top: 2px;
  font-size: 12px; line-height: 1.45; color: var(--text-muted); font-weight: 400;
  padding: 9px 11px; border-left: 2px solid var(--border);
  background: var(--surface-2); border-radius: 0 6px 6px 0;
}
.mr-toggle input:disabled + span { opacity: .55; }

/* ── Ablauf-Cockpit („Fällig demnächst") ───── */
.expiry-toggle {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: var(--text-muted);
  cursor: pointer;
  user-select: none;
}
.expiry-toggle input { cursor: pointer; }
.expiry-card { cursor: default; }
.expiry-card:hover { transform: none; }
/* Resttage-Pille: nutzt die vorhandenen Ampel-Klassen für die Farbe */
.expiry-pill {
  font-size: 11px;
  font-weight: 600;
  padding: 2px 8px;
  border-radius: 999px;
  white-space: nowrap;
  flex-shrink: 0;
}
.expiry-date { font-size: 11px; color: var(--text-muted); }

/* ── Payment Banner Animation ──────────────── */
@keyframes fadeIn {
  from { opacity: 0; transform: translateY(-8px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* ── Feedback Widget ────────────────────────── */
.btn-feedback {
  position: fixed; bottom: 24px; right: 24px;
  width: 48px; height: 48px; border-radius: 50%;
  background: var(--green); color: #fff;
  border: none; font-size: 20px;
  cursor: pointer; z-index: 100;
  box-shadow: 0 4px 16px rgba(0,0,0,.3);
  transition: transform .15s, box-shadow .15s;
}
.btn-feedback:hover { transform: scale(1.08); box-shadow: 0 6px 24px rgba(0,0,0,.4); }

/* Stern-Auswahl im Bewertungs-Modal */
.rate-stars { display: flex; gap: 4px; font-size: 30px; line-height: 1; cursor: pointer; }
.rate-star { color: var(--border, #444); transition: color .1s, transform .1s; user-select: none; }
.rate-star:hover { transform: scale(1.1); }
.rate-star.on { color: #f5b301; }

.modal-header {
  display: flex; justify-content: space-between; align-items: center;
  padding: 20px 24px 0;
}
.modal-header h2 { margin: 0; font-size: 18px; }
.modal-close {
  background: none; border: none; font-size: 24px;
  cursor: pointer; color: var(--text-muted); line-height: 1;
}
.modal-body { padding: 16px 24px; }
.form-group { margin-bottom: 14px; }
.form-group label {
  display: block; font-size: 13px; font-weight: 600;
  margin-bottom: 6px; color: var(--text-2);
}
.form-select, .form-textarea, .form-input {
  width: 100%; padding: 9px 12px; border-radius: 8px;
  border: 1px solid var(--border); background: var(--surface);
  color: var(--text); font-size: 14px; font-family: inherit;
}
.form-textarea { resize: vertical; min-height: 80px; }
.form-select:focus, .form-textarea:focus, .form-input:focus {
  outline: none; border-color: var(--green); box-shadow: 0 0 0 2px var(--green-dim);
}

/* ── PingMon Logo Animation ── */
.pm-logo{width:64px;height:64px;display:block}
.pm-logo .ring{stroke-dasharray:1;stroke-dashoffset:1}
.pm-logo .dot,.pm-logo .hi,.pm-logo .ping,.pm-logo .glow{transform-box:fill-box;transform-origin:center}
.pm-logo .ping,.pm-logo .glow{opacity:0}

.pm-play .glow{animation:pm-glow .6s ease-out both}
.pm-play .ring{animation:pm-draw .65s ease-out both}
.pm-play .dot,.pm-play .hi{animation:pm-dot .5s cubic-bezier(.2,1.5,.3,1) .42s both}
.pm-play .ping.p1{animation:pm-ping 2.2s ease-out .75s infinite}
.pm-play .ping.p2{animation:pm-ping 2.2s ease-out 1.85s infinite}
.pm-play.pm-paused .ping{animation:none;opacity:0}

@keyframes pm-draw{to{stroke-dashoffset:0}}
@keyframes pm-dot{0%{opacity:0;transform:scale(0)}60%{opacity:1;transform:scale(1.3)}100%{transform:scale(1)}}
@keyframes pm-ping{0%{opacity:.5;transform:scale(.45)}70%{opacity:0}100%{opacity:0;transform:scale(2.8)}}
@keyframes pm-glow{to{opacity:1}}
@media (prefers-reduced-motion:reduce){.pm-logo *{animation:none!important}.pm-logo .ring{stroke-dashoffset:0}.pm-logo .glow,.pm-logo .dot,.pm-logo .hi{opacity:1;transform:none}}

/* Logo-Größen je Container (überschreibt die 64px-Basis per Spezifität) */
.logo-badge {
  display: inline-flex;
  align-items: center; justify-content: center;
  flex-shrink: 0;
}
.logo-badge .pm-logo { width: 40px; height: 40px; }
.logo-wrap .pm-logo{width:48px;height:48px;flex-shrink:0}
.auth-logo .pm-logo{width:24px;height:24px;flex-shrink:0}


/* ===== PINGMON COWORK REBRAND: App-Override (Dashboard/Settings/Login/Reset) ===== */
/* ============================================================================
   PingMon — App-Bereich Brand-Override  (Dashboard, Settings, Login, Status)
   CSS-ONLY, appearance-only. An `style.css` anhängen.
   ----------------------------------------------------------------------------
   THEME-MECHANIK DER APP (bestätigt):
     <body class="dark">  = Default (dunkel)
     <body class="light"> = hell (Toggle: body.classList.toggle('light'))
   -> Wir hängen NICHT an [data-theme] oder prefers-color-scheme.
   -> Wir nutzen EURE Variablen (var(--bg) / var(--surface) / var(--text) /
      var(--green) / var(--red) / var(--yellow)); dadurch laufen hell/dunkel
      automatisch mit. Nur die Glow-/Schatten-Layer sind theme-unabhängig.
   Kein Layout, kein Markup, kein JS. (Sollte ein Variablenname abweichen,
   nur den var()-Namen anpassen — die Fallback-Werte greifen sonst.)
   ============================================================================ */

:root{ --pm-g500:#2fd18a; --pm-g600:#16a34a; --pm-g400:#3ee0a0; --pm-red:#e0655b; --pm-yellow:#d97706; }

/* ---- Seiten-Hintergrund: Hybrid (Glow + ausgefadete Dots) über eurem --bg ---- */
body::before{ content:""; position:fixed; inset:0; z-index:0; pointer-events:none;
  background:radial-gradient(1200px 480px at 50% -12%, rgba(47,209,138,.10), transparent 70%); }
body::after{ content:""; position:fixed; inset:0; z-index:0; pointer-events:none;
  background-image:radial-gradient(circle, rgba(255,255,255,.05) 1px, transparent 1.4px); background-size:22px 22px;
  -webkit-mask-image:radial-gradient(125% 75% at 50% -8%, #000, rgba(0,0,0,.5) 38%, transparent 78%);
          mask-image:radial-gradient(125% 75% at 50% -8%, #000, rgba(0,0,0,.5) 38%, transparent 78%); }
body.light::after{ background-image:radial-gradient(circle, rgba(20,40,28,.06) 1px, transparent 1.4px); }
nav, main, aside, footer, .settings-layout{ position:relative; z-index:1; }

/* ---- Endpunkt- & Heartbeat-Karten ---- */
.card, .hb-card{
  background:radial-gradient(120% 90% at 50% -20%, rgba(47,209,138,.10), transparent 60%), var(--surface, #161616);
  border:1px solid rgba(47,209,138,.16); border-radius:18px;
  box-shadow:0 16px 30px -18px rgba(47,209,138,.28), inset 0 1px 0 rgba(255,255,255,.05);
}
/* Zustände (eure echten Klassen) — Left-Border-Konvention beibehalten, Glow ergänzt */
.card.is-up,   .hb-card.is-up   { border-left:3px solid var(--green, #2fd18a); }
.card.is-down, .hb-card.is-down {
  border-left:3px solid var(--red, #e0655b); border-color:rgba(224,101,91,.22);
  background:radial-gradient(120% 90% at 50% -20%, rgba(224,101,91,.12), transparent 60%),
             linear-gradient(135deg, rgba(224,101,91,.10) 0%, var(--surface, #161616) 55%);
  box-shadow:0 16px 30px -18px rgba(224,101,91,.32), inset 0 1px 0 rgba(255,255,255,.05);
}
.card.is-slow, .hb-card.is-slow {
  border-left:3px solid var(--yellow, #d97706); border-color:rgba(217,119,6,.22);
  background:radial-gradient(120% 90% at 50% -20%, rgba(217,119,6,.12), transparent 60%),
             linear-gradient(135deg, rgba(217,119,6,.10) 0%, var(--surface, #161616) 55%);
}
.card.unchecked, .hb-card.unchecked{ border-left:3px solid #6b7280; }

/* ---- Metrik-Karten oben ---- */
.metric-card{
  background:radial-gradient(120% 90% at 50% -20%, rgba(47,209,138,.06), transparent 60%), var(--surface, #161616);
  border:1px solid rgba(255,255,255,.07); border-radius:16px;
  box-shadow:0 14px 28px -20px rgba(0,0,0,.6), inset 0 1px 0 rgba(255,255,255,.04);
}

/* ---- Status-Page-Box im Dashboard ---- */
.sp-card{
  background:radial-gradient(80% 130% at 12% -10%, rgba(47,209,138,.10), transparent 60%), var(--surface, #161616);
  border:1px solid rgba(47,209,138,.14); border-radius:20px;
  box-shadow:0 22px 44px -28px rgba(0,0,0,.7), inset 0 1px 0 rgba(255,255,255,.05);
}

/* ---- Detail-Panel + Modals ---- */
.panel, .modal-box{
  background:var(--surface, #161616);
  border:1px solid rgba(255,255,255,.08);
  box-shadow:0 30px 60px -30px rgba(0,0,0,.8), inset 0 1px 0 rgba(255,255,255,.04);
}

/* ---- Buttons ---- */
.btn-primary, .plan-btn, .btn-checkout.plan-btn{
  background-image:linear-gradient(180deg, var(--pm-g500), var(--pm-g600));
  border:1px solid var(--pm-g600); color:#06210f;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.28), 0 14px 24px -12px rgba(47,209,138,.6);
}

/* ---- Settings: Billing-Karten + Nav ---- */
.billing-plan-card{
  background:var(--surface, #161616); border:1px solid rgba(255,255,255,.08); border-radius:16px;
  box-shadow:0 16px 30px -24px rgba(0,0,0,.7), inset 0 1px 0 rgba(255,255,255,.04);
}
.billing-plan-card.billing-plan-featured{
  background:radial-gradient(120% 85% at 50% -12%, rgba(47,209,138,.20), transparent 60%), var(--surface, #161616);
  border:2px solid var(--pm-g500);
  box-shadow:0 28px 52px -24px rgba(47,209,138,.6), inset 0 1px 0 rgba(255,255,255,.05);
}
.settings-nav-item.active{ color:var(--pm-g500); }

/* ---- Login-Box + Tabs ---- */
.auth-box{
  background:radial-gradient(120% 90% at 50% -20%, rgba(47,209,138,.10), transparent 60%), var(--surface, #161616);
  border:1px solid rgba(47,209,138,.14); border-radius:18px;
  box-shadow:0 30px 60px -28px rgba(47,209,138,.4), inset 0 1px 0 rgba(255,255,255,.05);
}
.tab.active{ color:var(--pm-g500); }

/* ---- Optionale Dynamik (css/pingmon-motion.css) + weicher Theme-Wechsel
        (css/pingmon-theme-transition.css) separat einbinden. ---- */

/* ===== PINGMON COWORK REBRAND: Weicher Theme-Wechsel (Option A, ohne JS) ===== */
body,
.card, .hb-card, .metric-card, .sp-card, .panel, .modal-box,
nav, aside, .settings-layout, .auth-box, input, select, textarea,
.btn-primary, .plan-btn, .billing-plan-card, .tab{
  transition: background-color .38s ease, color .38s ease,
              border-color .38s ease, box-shadow .38s ease;
}
@media (prefers-reduced-motion: reduce){
  body, .card, .hb-card, .metric-card, .sp-card, .panel, .modal-box,
  nav, aside, .settings-layout, .auth-box, input, select, textarea,
  .btn-primary, .plan-btn, .billing-plan-card, .tab{ transition:none; }
}

/* ===== PINGMON COWORK REBRAND: Mockup-Niveau Verstärkung (Teil 1) =====
   WICHTIG: theme-gescopet (body.dark/body.light), weil die Original-Regeln
   `body.dark .card` etc. (Spezifität 0,2,1) die schlichten Cowork-Selektoren
   sonst überschreiben — DAS war der Grund für "zu subtil". Additiv, kein Markup/JS. */

/* ---- Hintergrund: Hybrid-Glow oben kräftiger + Dots minimal präsenter ---- */
body::before{ background:radial-gradient(1200px 540px at 50% -12%, rgba(47,209,138,.14), transparent 70%); }
body.dark::after{ background-image:radial-gradient(circle, rgba(255,255,255,.06) 1px, transparent 1.4px); }

/* ---- Endpunkt-/HB-Karten: Basis plastischer + Hover-Lift ---- */
body.dark .card, body.dark .hb-card{
  background:radial-gradient(130% 100% at 50% -25%, rgba(47,209,138,.06), transparent 60%), #161616;
  border:1px solid rgba(47,209,138,.10); border-top:1px solid rgba(47,209,138,.10); border-radius:16px;
  box-shadow:0 18px 34px -22px rgba(0,0,0,.6), inset 0 1px 0 rgba(255,255,255,.05);
}
.card, .hb-card{ transition:transform .22s ease, box-shadow .22s ease, border-color .22s ease, background-color .38s ease; }
.card:hover, .hb-card:hover{ transform:translateY(-3px); }

/* ONLINE — voller grüner Verlauf + Glow + Akzent (beide Themes) */
body.dark .card.is-up, body.dark .hb-card.is-up{
  border:1px solid rgb(var(--st-up-rgb) / .30); border-left:3px solid var(--st-up);
  background:radial-gradient(130% 100% at 50% -20%, rgb(var(--st-up-rgb) / .22), transparent 60%),
            linear-gradient(165deg, rgb(var(--st-up-rgb) / .06) 0%, #16191b 60%);
  box-shadow:0 20px 40px -18px rgb(var(--st-up-rgb) / .55), inset 0 1px 0 rgba(255,255,255,.06);
}
body.dark .card.is-up:hover, body.dark .hb-card.is-up:hover{ box-shadow:0 26px 48px -18px rgb(var(--st-up-rgb) / .72), inset 0 1px 0 rgba(255,255,255,.07); }
body.light .card.is-up, body.light .hb-card.is-up{
  border:1px solid rgb(var(--st-up-rgb) / .22); border-left:3px solid var(--st-up);
  background:radial-gradient(130% 100% at 50% -20%, rgb(var(--st-up-rgb) / .12), transparent 60%),
            linear-gradient(165deg, #f0fdf4 0%, #ffffff 60%);
  box-shadow:0 16px 30px -18px rgb(var(--st-up-rgb) / .35), inset 0 1px 0 rgba(255,255,255,.8);
}

/* OFFLINE — roter Verlauf + Glow */
body.dark .card.is-down, body.dark .hb-card.is-down{
  border:1px solid rgb(var(--st-down-rgb) / .34); border-left:3px solid var(--st-down);
  background:radial-gradient(130% 100% at 50% -20%, rgb(var(--st-down-rgb) / .22), transparent 60%),
            linear-gradient(165deg, rgb(var(--st-down-rgb) / .08) 0%, #1a1617 60%);
  box-shadow:0 20px 40px -18px rgb(var(--st-down-rgb) / .55), inset 0 1px 0 rgba(255,255,255,.06);
}
body.light .card.is-down, body.light .hb-card.is-down{
  border:1px solid rgb(var(--st-down-rgb) / .28); border-left:3px solid var(--st-down);
  background:radial-gradient(130% 100% at 50% -20%, rgb(var(--st-down-rgb) / .10), transparent 60%),
            linear-gradient(165deg, #fef2f2 0%, #ffffff 60%);
  box-shadow:0 16px 30px -18px rgb(var(--st-down-rgb) / .32), inset 0 1px 0 rgba(255,255,255,.8);
}

/* SLOW — amber Verlauf */
body.dark .card.is-slow, body.dark .hb-card.is-slow{
  border:1px solid rgb(var(--st-degraded-rgb) / .34); border-left:3px solid var(--st-degraded);
  background:radial-gradient(130% 100% at 50% -20%, rgb(var(--st-degraded-rgb) / .20), transparent 60%),
            linear-gradient(165deg, rgb(var(--st-degraded-rgb) / .08) 0%, #1a1714 60%);
  box-shadow:0 20px 40px -18px rgb(var(--st-degraded-rgb) / .45), inset 0 1px 0 rgba(255,255,255,.06);
}
body.light .card.is-slow, body.light .hb-card.is-slow{
  border:1px solid rgb(var(--st-degraded-rgb) / .26); border-left:3px solid var(--st-degraded);
  background:radial-gradient(130% 100% at 50% -20%, rgb(var(--st-degraded-rgb) / .10), transparent 60%),
            linear-gradient(165deg, #fffbeb 0%, #ffffff 60%);
  box-shadow:0 16px 30px -18px rgb(var(--st-degraded-rgb) / .3), inset 0 1px 0 rgba(255,255,255,.8);
}
body.dark .card.unchecked, body.dark .hb-card.unchecked{ border-left:3px solid #6b7280; }

/* Status-Punkt in den Karten: Glow-Ring */
.status-dot.dot-up{ box-shadow:0 0 0 4px var(--st-up-dim); }
.status-dot.dot-down{ box-shadow:0 0 0 4px var(--st-down-dim); }
.status-dot.dot-slow{ box-shadow:0 0 0 4px var(--st-degraded-dim); }

/* ---- Metrik-Karten: plastischer + grüner Top-Glow ---- */
body.dark .metric-card{
  background:radial-gradient(120% 100% at 50% -30%, rgba(47,209,138,.12), transparent 60%), #161616;
  border:1px solid rgba(47,209,138,.12); border-radius:16px;
  box-shadow:0 18px 36px -24px rgba(0,0,0,.7), inset 0 1px 0 rgba(255,255,255,.05);
}
body.light .metric-card{
  background:radial-gradient(120% 100% at 50% -30%, rgba(47,209,138,.10), transparent 60%), #ffffff;
  border:1px solid rgba(47,209,138,.14); border-radius:16px;
  box-shadow:0 16px 30px -22px rgba(16,40,26,.22), inset 0 1px 0 rgba(255,255,255,.8);
}

/* ---- Status-Sektion: Spotlight stärker ---- */
body.dark .sp-card, body.dark #sp-box{
  background:radial-gradient(70% 130% at 10% -10%, rgba(47,209,138,.16), transparent 60%), linear-gradient(180deg,#16191b,#121517);
  border:1px solid rgba(47,209,138,.18); border-radius:20px;
  box-shadow:0 26px 50px -28px rgba(47,209,138,.4), inset 0 1px 0 rgba(255,255,255,.06);
}
body.light .sp-card, body.light #sp-box{
  background:radial-gradient(70% 130% at 10% -10%, rgba(47,209,138,.12), transparent 60%), #ffffff;
  border:1px solid rgba(47,209,138,.16); border-radius:20px;
  box-shadow:0 22px 44px -30px rgba(47,209,138,.3), inset 0 1px 0 rgba(255,255,255,.8);
}

/* ---- Primär-Buttons: kräftigerer Glow + Hover ---- */
.btn-primary, .plan-btn, .btn-checkout.plan-btn{
  box-shadow:inset 0 1px 0 rgba(255,255,255,.3), 0 16px 28px -12px rgba(47,209,138,.7);
}
.btn-primary:hover, .plan-btn:hover, .btn-checkout.plan-btn:hover{
  box-shadow:inset 0 1px 0 rgba(255,255,255,.35), 0 20px 34px -12px rgba(47,209,138,.85);
}
/* Featured Billing-Karte: stärkerer Glow */
.billing-plan-card.billing-plan-featured{ box-shadow:0 30px 58px -22px rgba(47,209,138,.7), inset 0 1px 0 rgba(255,255,255,.06); }

/* ===== Motion (Teil 2) — nur Dashboard, sparsam. Grün dauerhaft / Rot endlich.
   Keyframes kommen aus pingmon-motion.css (global per <link>). Sheen läuft über
   die Klasse .pm-anim-sheen an #sp-box. Live/Alert hier per CSS, weil die Karten
   von JS erzeugt werden (kein Klassen-Eingriff möglich). ===== */
#cards > .card:first-child .status-dot.dot-up{ position:relative; }
#cards > .card:first-child .status-dot.dot-up::after{
  content:""; position:absolute; inset:-3px; border-radius:50%; pointer-events:none;
  border:2px solid rgb(var(--st-up-rgb) / .5); animation:pm-live 2.8s ease-out infinite;
}
.card.is-down, .hb-card.is-down{ animation:pm-alert 1s ease-out 3; }
@media (prefers-reduced-motion: reduce){
  #cards > .card:first-child .status-dot.dot-up::after{ animation:none; }
  .card.is-down, .hb-card.is-down{ animation:none; }
}

/* ===== PINGMON COWORK REBRAND: Mockup-Feinschliff — Karten-Akzentlinie + Spotlight =====
   Repliziert den Foundation-".pm-card"-Look direkt auf den ECHTEN Klassen
   (.card/.hb-card sind JS-generiert → keine Klassen-Ergänzung möglich; Foundation
   global laden würde den Dark-Hintergrund kippen). Reines CSS, kein Markup/JS. */

/* Dünne Akzentlinie oben (wie .pm-card::before im Mockup) */
.card.is-up::before,   .hb-card.is-up::before,
.card.is-down::before, .hb-card.is-down::before,
.card.is-slow::before, .hb-card.is-slow::before{
  content:""; position:absolute; left:16px; right:16px; top:0; height:2px;
  border-radius:0 0 4px 4px; pointer-events:none; opacity:.6;
}
.card.is-up::before,   .hb-card.is-up::before  { background:linear-gradient(90deg,transparent,var(--st-up-line),transparent); }
.card.is-down::before, .hb-card.is-down::before{ background:linear-gradient(90deg,transparent,var(--st-down-line),transparent); }
.card.is-slow::before, .hb-card.is-slow::before{ background:linear-gradient(90deg,transparent,var(--st-degraded-line),transparent); }

/* Metrik-Zahlen etwas präsenter */
.metric-value{ font-size:30px; }

/* Status-Sektion: Spotlight intensiver */
body.dark .sp-card, body.dark #sp-box{
  background:radial-gradient(80% 120% at 6% 30%, rgba(47,209,138,.13), transparent 65%), linear-gradient(180deg,#16191b,#111417);
  border:1px solid rgba(47,209,138,.22);
  box-shadow:0 28px 54px -26px rgba(47,209,138,.5), inset 0 1px 0 rgba(255,255,255,.06);
}
body.light .sp-card, body.light #sp-box{
  background:radial-gradient(72% 135% at 8% -12%, rgba(47,209,138,.16), transparent 58%), #ffffff;
  border:1px solid rgba(47,209,138,.20);
  box-shadow:0 24px 48px -28px rgba(47,209,138,.38), inset 0 1px 0 rgba(255,255,255,.8);
}

/* ===== PINGMON COWORK REBRAND: pm-card / pm-stat: echte Cowork-Hooks =====
   Getragen vom Token in app.js (Karten) + index.html (Metrik). Gleicher Look
   wie .card/.metric-card — die Cowork-Foundation greift jetzt über die
   offiziellen Klassennamen. Zustände (.is-up/.is-down/.is-slow) gewinnen per
   höherer Spezifität und liefern den Voll-Verlauf. Kein Markup-Risiko. */
.pm-card{ position:relative; transition:transform .22s ease, box-shadow .22s ease, border-color .22s ease, background-color .38s ease; }
.pm-card:hover{ transform:translateY(-3px); }
body.dark .pm-card{
  background:radial-gradient(130% 100% at 50% -25%, rgba(47,209,138,.06), transparent 60%), #161616;
  border:1px solid rgba(47,209,138,.10); border-radius:16px;
  box-shadow:0 18px 34px -22px rgba(0,0,0,.6), inset 0 1px 0 rgba(255,255,255,.05);
}
body.light .pm-card{
  background:radial-gradient(130% 100% at 50% -25%, rgba(47,209,138,.06), transparent 60%), #ffffff;
  border:1px solid rgba(47,209,138,.12); border-radius:16px;
  box-shadow:0 16px 30px -22px rgba(16,40,26,.2), inset 0 1px 0 rgba(255,255,255,.8);
}
body.dark .pm-stat{
  background:radial-gradient(120% 100% at 50% -30%, rgba(47,209,138,.12), transparent 60%), #161616;
  border:1px solid rgba(47,209,138,.12); border-radius:16px;
  box-shadow:0 18px 36px -24px rgba(0,0,0,.7), inset 0 1px 0 rgba(255,255,255,.05);
}
body.light .pm-stat{
  background:radial-gradient(120% 100% at 50% -30%, rgba(47,209,138,.10), transparent 60%), #ffffff;
  border:1px solid rgba(47,209,138,.14); border-radius:16px;
  box-shadow:0 16px 30px -22px rgba(16,40,26,.22), inset 0 1px 0 rgba(255,255,255,.8);
}

/* ===== PINGMON COWORK REBRAND: Cowork Card-Tokens (body.dark-gehookt) =====
   Foundation-Tokens als CSS-Variablen — bewusst unter :root (hell) und body.dark
   (dunkel), NICHT [data-theme="dark"], weil PingMon body.dark nutzt. Dadurch
   greifen die Glows im Dark Mode korrekt. */
:root{
  --card-bg:radial-gradient(120% 90% at 50% -20%, rgba(47,209,138,.10), transparent 60%), linear-gradient(165deg,#ffffff 0%,#fafcfb 100%);
  --card-border:rgba(20,40,28,.08);
  --card-shadow:inset 0 1px 0 rgba(255,255,255,.7), 0 1px 2px rgba(16,32,22,.04), 0 14px 28px -18px rgba(16,40,26,.28);
  --card-online-bg:radial-gradient(120% 90% at 50% -20%, rgba(47,209,138,.18), transparent 60%), linear-gradient(165deg,#ffffff 0%,#f0fdf4 52%,#dcfce7 100%);
  --card-online-border:rgba(47,209,138,.22);
  --card-online-shadow:inset 0 1px 0 rgba(255,255,255,.75), 0 1px 2px rgba(16,32,22,.04), 0 16px 30px -16px rgba(47,209,138,.42);
  --card-error-bg:radial-gradient(120% 90% at 50% -20%, rgba(224,101,91,.18), transparent 60%), linear-gradient(165deg,#ffffff 0%,#fef2f2 52%,#fee2e2 100%);
  --card-error-border:rgba(224,101,91,.26);
  --card-error-shadow:inset 0 1px 0 rgba(255,255,255,.75), 0 1px 2px rgba(32,16,16,.04), 0 16px 30px -16px rgba(224,101,91,.44);
}
body.dark{
  --card-bg:radial-gradient(120% 90% at 50% -20%, rgba(74,222,128,.08), transparent 60%), linear-gradient(165deg,#15181a 0%,#121517 100%);
  --card-border:rgba(255,255,255,.08);
  --card-shadow:inset 0 1px 0 rgba(255,255,255,.04), 0 1px 2px rgba(0,0,0,.4), 0 18px 34px -20px rgba(0,0,0,.7);
  --card-online-bg:radial-gradient(120% 90% at 50% -20%, rgba(74,222,128,.18), transparent 60%), linear-gradient(165deg,#16191b 0%,#142019 100%);
  --card-online-border:rgba(91,201,140,.30);
  --card-online-shadow:inset 0 1px 0 rgba(255,255,255,.05), 0 1px 2px rgba(0,0,0,.4), 0 18px 34px -16px rgba(47,209,138,.6);
  --card-error-bg:radial-gradient(120% 90% at 50% -20%, rgba(244,108,103,.18), transparent 60%), linear-gradient(165deg,#1a1617 0%,#241416 100%);
  --card-error-border:rgba(224,101,91,.34);
  --card-error-shadow:inset 0 1px 0 rgba(255,255,255,.05), 0 1px 2px rgba(0,0,0,.4), 0 18px 34px -16px rgba(224,101,91,.6);
}

/* PIN-198 Nachbesserung: Metrik-Tiles (#metric-up/#metric-down) folgen der CVD-/HC-
   Palette statt fixem Grün/Rot. Muss NACH den body.dark --card-*-Defaults stehen, um
   sie zu schlagen (gleiche Spezifität → Quelltext-Reihenfolge). var(--surface) macht
   den Grund themen-tauglich, sodass EIN Wertsatz je Modus Hell+Dunkel abdeckt. Ohne
   aktiven Modus komplett unberührt → Standard-Look byte-identisch. */
body.contrast{
  --card-online-bg:radial-gradient(120% 90% at 50% -20%, rgba(0,230,118,.20), transparent 60%), var(--surface);
  --card-online-border:rgba(0,230,118,.34);
  --card-online-shadow:inset 0 1px 0 rgba(255,255,255,.06), 0 1px 2px rgba(0,0,0,.4), 0 16px 30px -16px rgba(0,230,118,.55);
  --card-error-bg:radial-gradient(120% 90% at 50% -20%, rgba(255,82,82,.20), transparent 60%), var(--surface);
  --card-error-border:rgba(255,82,82,.34);
  --card-error-shadow:inset 0 1px 0 rgba(255,255,255,.06), 0 1px 2px rgba(0,0,0,.4), 0 16px 30px -16px rgba(255,82,82,.55);
}
body.cvd-protan{
  --card-online-bg:radial-gradient(120% 90% at 50% -20%, rgba(0,114,178,.18), transparent 60%), var(--surface);
  --card-online-border:rgba(0,114,178,.30);
  --card-online-shadow:inset 0 1px 0 rgba(255,255,255,.05), 0 1px 2px rgba(0,0,0,.4), 0 16px 30px -16px rgba(0,114,178,.5);
  --card-error-bg:radial-gradient(120% 90% at 50% -20%, rgba(208,47,47,.18), transparent 60%), var(--surface);
  --card-error-border:rgba(208,47,47,.30);
  --card-error-shadow:inset 0 1px 0 rgba(255,255,255,.05), 0 1px 2px rgba(0,0,0,.4), 0 16px 30px -16px rgba(208,47,47,.5);
}
body.cvd-deutan{
  --card-online-bg:radial-gradient(120% 90% at 50% -20%, rgba(26,111,176,.18), transparent 60%), var(--surface);
  --card-online-border:rgba(26,111,176,.30);
  --card-online-shadow:inset 0 1px 0 rgba(255,255,255,.05), 0 1px 2px rgba(0,0,0,.4), 0 16px 30px -16px rgba(26,111,176,.5);
  --card-error-bg:radial-gradient(120% 90% at 50% -20%, rgba(204,51,17,.18), transparent 60%), var(--surface);
  --card-error-border:rgba(204,51,17,.30);
  --card-error-shadow:inset 0 1px 0 rgba(255,255,255,.05), 0 1px 2px rgba(0,0,0,.4), 0 16px 30px -16px rgba(204,51,17,.5);
}
body.cvd-tritan{
  --card-online-bg:radial-gradient(120% 90% at 50% -20%, rgba(15,122,61,.18), transparent 60%), var(--surface);
  --card-online-border:rgba(15,122,61,.30);
  --card-online-shadow:inset 0 1px 0 rgba(255,255,255,.05), 0 1px 2px rgba(0,0,0,.4), 0 16px 30px -16px rgba(15,122,61,.5);
  --card-error-bg:radial-gradient(120% 90% at 50% -20%, rgba(196,32,32,.18), transparent 60%), var(--surface);
  --card-error-border:rgba(196,32,32,.30);
  --card-error-shadow:inset 0 1px 0 rgba(255,255,255,.05), 0 1px 2px rgba(0,0,0,.4), 0 16px 30px -16px rgba(196,32,32,.5);
}

/* Metrik-Karten semantisch: Online=grün, Offline=rot, Antwortzeit=neutral.
   Per ID (Spezifität 1,0,0) gewinnen sie sicher; Variablen schalten Theme automatisch. */
#metric-up   { background-image:var(--card-online-bg); border:1px solid var(--card-online-border); box-shadow:var(--card-online-shadow); }
#metric-down { background-image:var(--card-error-bg);  border:1px solid var(--card-error-border);  box-shadow:var(--card-error-shadow); }
#metric-avg  { background-image:var(--card-bg);        border:1px solid var(--card-border);        box-shadow:var(--card-shadow); }

/* ===== PINGMON COWORK REBRAND: Status-Box Zustands-Glow =====
   #sp-box bekommt data-status (operational|degraded|down) vom JS (loadPublicStatus).
   operational/leer = grün (bestehende sp-card-Regel). Spezifität ID+Attr gewinnt
   über body.dark #sp-box. Dauer-Schimmer nur auf grün; Down endlich gepulst. */
body.dark #sp-box[data-status="degraded"]{
  background:radial-gradient(80% 120% at 6% 30%, rgba(217,119,6,.14), transparent 65%), linear-gradient(180deg,#1a1712,#13110d);
  border:1px solid rgba(217,119,6,.32);
  box-shadow:0 28px 54px -26px rgba(217,119,6,.5), inset 0 1px 0 rgba(255,255,255,.05);
}
body.light #sp-box[data-status="degraded"]{
  background:radial-gradient(72% 135% at 8% -12%, rgba(217,119,6,.16), transparent 58%), #fffbeb;
  border:1px solid rgba(217,119,6,.28);
  box-shadow:0 24px 48px -28px rgba(217,119,6,.4), inset 0 1px 0 rgba(255,255,255,.8);
}
body.dark #sp-box[data-status="down"]{
  background:radial-gradient(80% 120% at 6% 30%, rgba(224,101,91,.15), transparent 65%), linear-gradient(180deg,#1a1516,#130e0e);
  border:1px solid rgba(224,101,91,.36);
  box-shadow:0 28px 54px -26px rgba(224,101,91,.55), inset 0 1px 0 rgba(255,255,255,.05);
}
body.light #sp-box[data-status="down"]{
  background:radial-gradient(72% 135% at 8% -12%, rgba(224,101,91,.16), transparent 58%), #fef2f2;
  border:1px solid rgba(224,101,91,.30);
  box-shadow:0 24px 48px -28px rgba(224,101,91,.42), inset 0 1px 0 rgba(255,255,255,.8);
}
/* Dauer-Schimmer NUR auf grün: bei amber/rot den Sheen-Layer KOMPLETT ausblenden.
   (Nur animation:none würde den schrägen Streifen am Startpunkt left:-60% "parken"
   → statische weiße Kante oben links. Daher display:none.) */
#sp-box[data-status="degraded"]::after, #sp-box[data-status="down"]::after{ display:none; }
/* Down: einmaliger, endlicher Aufmerksamkeits-Puls (3x) — kein Dauerblinken */
#sp-box[data-status="down"]{ animation:pm-alert 1s ease-out 3; }
@media (prefers-reduced-motion: reduce){ #sp-box[data-status="down"]{ animation:none; } }

/* ===== PINGMON COWORK REBRAND: Header-Polish (Tiefe + Marke) =====
   Header wirkte v.a. im Light Mode nackt/steril. Subtiler grüner Hauch +
   Frost + Tiefe — kein Overload. Marken-Grün #2fd18a (konsistent zur Seite). */
/* Dunkler App-Header (Dashboard): grünen Glow sichtbarer */
header{
  border-bottom:1px solid rgba(47,209,138,.12);
  box-shadow:0 1px 0 rgba(47,209,138,.10), 0 4px 20px -2px rgba(0,0,0,.35);
}
/* Heller App-Header (Settings/Login/Light Mode): Frost + grüner Hauch statt Weiß */
body.light header{
  background:linear-gradient(180deg, rgba(255,255,255,.93), rgba(246,251,248,.85));
  border-bottom:1px solid rgba(47,209,138,.14);
  box-shadow:0 1px 0 rgba(47,209,138,.07), 0 8px 26px -18px rgba(16,40,26,.16);
  backdrop-filter:blur(16px) saturate(1.25);
  -webkit-backdrop-filter:blur(16px) saturate(1.25);
}

/* ===== PINGMON COWORK REBRAND: Header-Emoji-Buttons als Chips =====
   Emoji-Icons (Sprache/Theme/Logout) im Header in saubere Chip-Kästchen wie die
   Feature-Icons der Landing — etwas größer. Nur im <header>, nicht der Primär-
   Button (+Endpunkt) und nicht das Modal-✕ (das ist außerhalb des Headers). */
header .btn-icon{
  display:inline-flex; align-items:center; justify-content:center;
  width:36px; height:36px; padding:0;
  font-size:18px; color:var(--text);
  background:radial-gradient(120% 120% at 30% 15%, rgba(47,209,138,.16), transparent 70%),
            linear-gradient(180deg, var(--surface-2), var(--surface-3));
  border:1px solid rgba(47,209,138,.24); border-radius:10px;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.06), 0 2px 6px -2px rgba(0,0,0,.3);
}
header .btn-icon:hover{
  color:var(--text);
  border-color:rgba(47,209,138,.42);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.08), 0 4px 10px -3px rgba(47,209,138,.3);
}

/* ── Tages-Uptime-Balken (Detail-Panel, Kuma-Style) ── */
.daily-bars { display: flex; gap: 2px; align-items: flex-end; }
.daily-bar {
  flex: 1; height: 24px; min-width: 0; border-radius: 2px;
  position: relative; cursor: default;
}
@media (max-width: 480px) {
  .daily-bars { gap: 1px; }
  .daily-bar { height: 20px; border-radius: 1px; }
}
.daily-bar.day-up      { background: var(--st-up);  opacity: .75; }
.daily-bar.day-partial { background: var(--st-degraded); opacity: .75; }
.daily-bar.day-down    { background: var(--st-down);    opacity: .75; }
.daily-bar.day-empty   { background: var(--border); }
.daily-bar:hover { opacity: 1; }
.daily-bar:hover::after {
  content: attr(data-tip);
  position: absolute; bottom: 30px; left: 50%; transform: translateX(-50%);
  background: #000; color: #fff; padding: 4px 8px; border-radius: 5px;
  font-size: 11px; white-space: nowrap; pointer-events: none; z-index: 10;
}
.daily-bars-labels {
  display: flex; justify-content: space-between;
  margin-top: 6px; font-size: 11px; color: var(--text-muted);
}

/* ── Incident-Verwaltung (Status-Page v2) ── */
.modal-incident-box { max-width: 560px; }
.inc-empty { color: var(--text-muted); font-size: 13px; margin: 4px 0 16px; }
.inc-item {
  border: 1px solid var(--border); border-radius: 10px;
  padding: 12px 14px; margin-bottom: 10px; background: var(--surface-2);
}
.inc-item.inc-resolved { opacity: .6; }
.inc-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.inc-title { flex: 1; font-size: 13px; min-width: 120px; }
.inc-badge { font-size: 11px; padding: 2px 8px; border-radius: 999px; background: var(--surface-3); color: var(--text-2); }
.inc-date { font-size: 11px; color: var(--text-muted); }
.inc-del {
  background: none; border: 1px solid var(--border); color: var(--text-muted);
  border-radius: 6px; padding: 2px 8px; cursor: pointer; font-size: 12px;
}
.inc-del:hover { color: var(--red); border-color: var(--red); }
.inc-updates { margin-top: 8px; }
.inc-update { font-size: 12px; color: var(--text-2); margin: 4px 0; padding-left: 10px; border-left: 2px solid var(--border-2); }
.inc-utime { color: var(--text-muted); margin-right: 6px; }
.inc-ubadge { font-weight: 600; margin-right: 6px; }
.inc-update-form { display: flex; gap: 8px; margin-top: 10px; align-items: center; flex-wrap: wrap; }
.inc-update-form .form-select { width: auto; padding: 6px 10px; font-size: 12px; }
.inc-update-form .form-input { flex: 1; min-width: 140px; padding: 6px 10px; font-size: 12px; }
.inc-new-title { font-size: 10px; color: var(--text-muted); text-transform: uppercase; letter-spacing: .6px; margin: 18px 0 12px; font-weight: 600; }
.inc-row-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.inc-feedback { font-size: 12px; margin-bottom: 10px; }
.inc-feedback.feedback-ok { color: var(--green-text); }
.inc-feedback.feedback-err { color: var(--red); }

/* ── Cron-Hilfetext im Heartbeat-Formular ── */
.hb-cron-help { display: block; margin-top: 6px; font-size: 11px; color: var(--text-muted); line-height: 1.6; }
.hb-cron-help code { background: var(--surface-2); padding: 1px 5px; border-radius: 4px; color: var(--text-2); }

/* ── Cron-Segmente: 5 Mini-Felder, Leerzeichen setzt das UI ── */
.cron-segments { display: flex; gap: 6px; }
.cron-seg { flex: 1; display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.cron-seg input {
  width: 100%; text-align: center; padding: 8px 4px; border-radius: 8px;
  border: 1px solid var(--border); background: var(--surface); color: var(--text);
  font-family: 'Fira Code', 'Consolas', monospace; font-size: 13px;
}
.cron-seg input:focus { outline: none; border-color: var(--green); box-shadow: 0 0 0 2px var(--green-dim); }
.cron-seg small { text-align: center; font-size: 10px; color: var(--text-muted); text-transform: uppercase; letter-spacing: .4px; }

/* ── Monitor-Typ-Chip (TCP/PING) auf den Karten ── */
.type-chip {
  display: inline-block; font-size: 9px; font-weight: 700; letter-spacing: .5px;
  padding: 1px 6px; border-radius: 4px; background: var(--surface-3);
  color: var(--text-2); vertical-align: 1px;
}

/* ── Kunden-Gruppierung: Filter-Select + Karten-Chip ── */
.cust-filter { width: auto; min-width: 150px; cursor: pointer; }
.customer-chip {
  text-transform: none; letter-spacing: 0; font-weight: 600;
  background: rgba(47,209,138,.12); color: #2fd18a;
}
/* Bereichs-Chip (PIN-396): steht neben dem Kunden-Chip, aber bewusst neutral —
   der Kunde ist die Hauptzuordnung, der Bereich seine Unterebene. */
.bereich-chip {
  text-transform: none; letter-spacing: 0; font-weight: 600;
  background: rgba(148,163,184,.14); color: var(--text-2);
}

/* Dezentes „intern"-Badge (PIN-88): gedämpft, KEIN Status-Grün/Rot. */
.ep-badge-internal {
  display: inline-block; font-size: 9px; font-weight: 700; letter-spacing: .5px;
  text-transform: uppercase;
  padding: 1px 6px; border-radius: 4px;
  background: var(--surface-2); color: var(--text-2);
  border: 1px solid var(--border); vertical-align: 1px;
}

/* Gruppen-Kopfzeile in der Gesamtübersicht: volle Grid-Breite, dezente Trennlinie.
   Subtil halten — „leichte Linie", keine fette Sektion (Wunsch Dario). */
.client-group-header {
  grid-column: 1 / -1;
  display: flex;
  align-items: baseline;
  gap: 6px;
  margin-top: 14px;
  padding-top: 10px;
  border-top: 1px solid var(--border);
  font-size: 12px;
  color: var(--text-2);
}
/* Erster Header oben: keine Linie/kein Abstand nach oben (sitzt direkt an der Toolbar). */
.client-group-header.is-first {
  margin-top: 0;
  padding-top: 0;
  border-top: none;
}
.client-group-header .cg-name {
  font-weight: 600;
  letter-spacing: .2px;
}
.client-group-header .cg-count { color: var(--text-muted); }

/* ── Trust-Badge: „Monitored by PingMon Germany" (Dashboard-Footer) ──
   Nutzt die Theme-Variablen → funktioniert in Dark UND Light automatisch. */
.dash-footer { display: flex; justify-content: center; padding: 26px 16px 34px; position: relative; z-index: 1; }
.pm-trustbadge {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 8px 14px;
  border: 1px solid var(--border); border-radius: 999px;
  background: var(--surface);
  font-size: 13px; color: var(--text-2); text-decoration: none;
  transition: border-color .15s, box-shadow .15s;
}
.pm-trustbadge:hover { border-color: var(--green); box-shadow: 0 2px 10px rgba(47,209,138,.12); }
.pm-tb-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--text-muted); flex: none; }
.pm-tb-loading .pm-tb-dot { animation: pmTbPulse 1.2s ease-in-out infinite; }
.pm-tb-operational .pm-tb-dot { background: #2fd18a; box-shadow: 0 0 0 3px rgba(47,209,138,.15); }
.pm-tb-degraded   .pm-tb-dot { background: #e3a445; box-shadow: 0 0 0 3px rgba(227,164,69,.15); }
.pm-tb-down       .pm-tb-dot { background: #e0655b; box-shadow: 0 0 0 3px rgba(224,101,91,.15); }
.pm-tb-text strong { color: var(--text); font-weight: 600; }
.pm-tb-uptime { color: var(--text-muted); font-variant-numeric: tabular-nums; }
.pm-tb-uptime:empty { display: none; }
@keyframes pmTbPulse { 0%, 100% { opacity: .35; } 50% { opacity: 1; } }

/* ── KI-Analyse (AI Alert Summarization) ───────────────── */
/* Detail-Panel: grün akzentuierter Befund-Block (Marken-Grün wie die Alarm-Mail),
   dark-mode-tauglich via translucentem BG + var(--text). */
.ai-section .ai-text {
  margin: 0;
  padding: 12px 14px;
  background: rgba(47,209,138, .10);
  border-left: 3px solid #2fd18a;
  border-radius: 8px;
  font-size: 14px;
  line-height: 1.55;
  color: var(--text);
}
/* Karte: dezentes, pulsierendes 🤖-Symbol als Hinweis "KI-Analyse vorhanden,
   zum Ansehen Karte anklicken". Voller Text nur im Detail-Panel. */
.card-ai-icon {
  margin-left: auto;
  font-size: 15px;
  line-height: 1;
  cursor: pointer;
  flex: none;
  animation: aiPulse 1.6s ease-in-out infinite;
}
@keyframes aiPulse {
  0%, 100% { opacity: .5;  transform: scale(1);    filter: drop-shadow(0 0 1px rgba(47,209,138, 0)); }
  50%      { opacity: 1;   transform: scale(1.18); filter: drop-shadow(0 0 6px rgba(47,209,138, .75)); }
}
@media (prefers-reduced-motion: reduce) {
  .card-ai-icon { animation: none; opacity: 1; }
}

/* ── Response-Anomalie (Predictive light) — der „Wow"-Insight-Block ──────────
   Eigene violette Farbwelt, bewusst abgesetzt vom Marken-Grün (up) und Rot (down):
   Violett = „schlau / Predictive". Der Block lebt durch einen sanft driftenden
   Lichtschimmer + ein schwebendes Icon → lädt zum Hinschauen & Klicken ein. */
.anomaly-section { border-bottom: 0; }
.anomaly-card {
  position: relative;
  overflow: hidden;
  border-radius: 14px;
  padding: 16px 16px 15px;
  background:
    radial-gradient(120% 140% at 0% 0%, rgba(168,85,247,.16), transparent 55%),
    linear-gradient(160deg, rgba(99,102,241,.16) 0%, rgba(168,85,247,.11) 52%, rgba(15,15,20,.34) 100%);
  border: 1px solid rgba(168,85,247,.34);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.06), 0 10px 30px -14px rgba(168,85,247,.55);
  animation: anomalyRing 4.5s ease-in-out infinite;
}
@keyframes anomalyRing {
  0%, 100% { box-shadow: inset 0 1px 0 rgba(255,255,255,.06), 0 10px 30px -14px rgba(168,85,247,.45); border-color: rgba(168,85,247,.30); }
  50%      { box-shadow: inset 0 1px 0 rgba(255,255,255,.06), 0 14px 40px -12px rgba(168,85,247,.72); border-color: rgba(168,85,247,.58); }
}
/* driftender Lichtschimmer im Hintergrund */
.anomaly-glow {
  position: absolute;
  width: 220px; height: 220px;
  top: -92px; right: -64px;
  background: radial-gradient(circle, rgba(168,85,247,.55), transparent 64%);
  filter: blur(20px);
  pointer-events: none;
  opacity: .6;
  animation: anomalyDrift 9s ease-in-out infinite;
}
@keyframes anomalyDrift {
  0%, 100% { transform: translate(0, 0) scale(1);      opacity: .55; }
  50%      { transform: translate(-28px, 24px) scale(1.18); opacity: .85; }
}
/* Pro-Trial Angebot-Banner: pulsierender violetter Glow (gleiche Farbwelt wie
   die Anomalie-Erkennung), damit das Gratis-Angebot heraussticht. */
#trial-banner.trial-glow { animation: trialGlow 2.4s ease-in-out infinite; }
@keyframes trialGlow {
  0%,100% { box-shadow: 0 6px 22px -10px rgba(139,92,246,.6); }
  50%     { box-shadow: inset 0 0 26px -6px rgba(255,255,255,.22), 0 12px 34px -6px rgba(139,92,246,.95); }
}
@media (prefers-reduced-motion: reduce) { #trial-banner.trial-glow { animation: none; } }

.anomaly-head { position: relative; display: flex; align-items: flex-start; gap: 12px; }
.anomaly-icon {
  font-size: 26px; line-height: 1; flex: none;
  filter: drop-shadow(0 0 9px rgba(168,85,247,.9));
  animation: anomalyFloat 3.2s ease-in-out infinite;
}
@keyframes anomalyFloat {
  0%, 100% { transform: translateY(0) rotate(0deg); }
  50%      { transform: translateY(-3px) rotate(-5deg); }
}
.anomaly-head-text { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.anomaly-title {
  font-weight: 700; font-size: 15px; letter-spacing: -.01em; color: #f3e8ff;
}
.anomaly-sub { font-size: 12.5px; line-height: 1.45; color: var(--text-2); }
.anomaly-tag {
  flex: none; align-self: flex-start;
  font-size: 10px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
  padding: 3px 8px; border-radius: 999px; white-space: nowrap;
  color: #e9d5ff;
  background: linear-gradient(135deg, rgba(168,85,247,.5), rgba(99,102,241,.5));
  border: 1px solid rgba(196,181,253,.42);
}
.anomaly-ai {
  position: relative;
  margin-top: 12px; padding: 11px 13px; border-radius: 10px;
  background: rgba(10,10,14,.5);
  border: 1px solid rgba(168,85,247,.22);
}
.anomaly-ai-label {
  display: block; font-size: 11px; font-weight: 700; letter-spacing: .04em;
  text-transform: uppercase; color: #c4b5fd; margin-bottom: 5px;
}
.anomaly-ai-text { margin: 0; font-size: 14px; line-height: 1.55; color: var(--text); }
/* Upgrade-Hook (Free/Starter): KI-Ursache ab Pro */
.anomaly-lock {
  position: relative;
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  margin-top: 12px; padding: 10px 13px; border-radius: 10px;
  background: rgba(10,10,14,.5);
  border: 1px dashed rgba(168,85,247,.42);
  text-decoration: none;
  transition: border-color .2s, background .2s, transform .12s;
}
.anomaly-lock:hover { border-color: rgba(196,181,253,.72); background: rgba(168,85,247,.12); transform: translateY(-1px); }
.anomaly-lock-text { font-size: 13px; color: #e9d5ff; }
.anomaly-lock-cta {
  flex: none; font-size: 12px; font-weight: 700; color: #fff; white-space: nowrap;
  padding: 5px 11px; border-radius: 999px;
  background: linear-gradient(135deg, #a855f7, #6366f1);
  box-shadow: 0 4px 14px -4px rgba(168,85,247,.8);
}
/* dezentes violettes Karten-Signal im Grid — die auffällige Karte „atmet" */
.card-anomaly-icon {
  margin-left: auto; font-size: 15px; line-height: 1; cursor: pointer; flex: none;
  filter: drop-shadow(0 0 5px rgba(168,85,247,.85));
  animation: anomalyIconPulse 1.8s ease-in-out infinite;
}
@keyframes anomalyIconPulse {
  0%, 100% { opacity: .55; transform: scale(1); }
  50%      { opacity: 1;   transform: scale(1.16); }
}
/* Anomalie-Karte = KOMPLETT violette Box: alle grünen „Online"-Signale werden
   violett (Hintergrund-Tint, linke Leiste, Akzentlinie, Status-Punkt, „Online"-
   Label, Uptime-Badge) → man sieht auf einen Blick an der ganzen Box „hier ist was". */
.pm-card.has-anomaly,
body.dark .pm-card.has-anomaly {
  border: 1px solid rgba(168,85,247,.5);
  border-left: 3px solid #a855f7;
  background:
    radial-gradient(130% 100% at 50% -20%, rgba(168,85,247,.24), transparent 60%),
    linear-gradient(165deg, rgba(168,85,247,.08) 0%, #17151c 60%);
  animation: anomalyCardBreathe 3.6s ease-in-out infinite;
}
.pm-card.has-anomaly::before {
  background: linear-gradient(90deg, transparent, #c084fc, transparent) !important;
  opacity: .75 !important;
}
.pm-card.has-anomaly .status-dot,
.pm-card.has-anomaly .status-dot.dot-up {
  background: #a855f7;
  box-shadow: 0 0 0 4px rgba(168,85,247,.18), 0 0 8px rgba(168,85,247,.6);
}
.pm-card.has-anomaly .card-status-label { color: #c4b5fd; }
.pm-card.has-anomaly .uptime-badge { background: rgba(168,85,247,.16); color: #c4b5fd; }
@keyframes anomalyCardBreathe {
  0%, 100% { box-shadow: 0 0 0 1px rgba(168,85,247,.28), 0 8px 24px -14px rgba(168,85,247,.45); }
  50%      { box-shadow: 0 0 0 1px rgba(168,85,247,.55), 0 10px 32px -10px rgba(168,85,247,.78); }
}
@media (prefers-reduced-motion: reduce) {
  .anomaly-card, .anomaly-glow, .anomaly-icon, .card-anomaly-icon, .pm-card.has-anomaly { animation: none; }
}

/* ===== KARTEN-STATUS-GLOW „mehr Wumms" (Dario 24.06.) ============================
   Problem: body.dark .pm-card (Spez. 0,2,1) gewann über .card.is-down/.is-slow
   (0,2,0) → in Dark Mode sahen ALLE Karten gleich grün-getönt aus, egal ob
   online/offline. Lösung: status-spezifische Regeln mit höherer Spezifität
   (body.<theme> .card.is-X:not(.has-anomaly) = 0,4,1), die jeder Karte ihre
   Statusfarbe geben — Tint + farbiger Glow rund um die ganze Box + dicker
   linker Akzentbalken. Offline = stärker + sanfter Puls (Problem sticht raus).
   :not(.has-anomaly) lässt die violetten Anomalie-Karten unangetastet.
   Reines CSS, kein Markup/JS. ============================================== */

/* ── DARK MODE ──────────────────────────────────────────── */
body.dark .card.is-up:not(.has-anomaly) {
  background: radial-gradient(130% 100% at 50% -25%, rgb(var(--st-up-rgb) / .16), transparent 60%), #14181a;
  border: 1px solid rgb(var(--st-up-rgb) / .32);
  border-left: 3px solid var(--st-up);
  box-shadow: 0 16px 30px -22px rgba(0,0,0,.6), 0 0 22px -8px rgb(var(--st-up-rgb) / .34), inset 0 1px 0 rgba(255,255,255,.05);
}
body.dark .card.is-slow:not(.has-anomaly) {
  background: radial-gradient(130% 100% at 50% -25%, rgb(var(--st-degraded-rgb) / .20), transparent 60%), #1a1611;
  border: 1px solid rgb(var(--st-degraded-rgb) / .42);
  border-left: 3px solid var(--st-degraded);
  box-shadow: 0 16px 30px -22px rgba(0,0,0,.6), 0 0 24px -7px rgb(var(--st-degraded-rgb) / .42), inset 0 1px 0 rgba(255,255,255,.05);
}
body.dark .card.is-down:not(.has-anomaly) {
  background: radial-gradient(130% 100% at 50% -25%, rgb(var(--st-down-rgb) / .24), transparent 58%), #1c1315;
  border: 1px solid rgb(var(--st-down-rgb) / .58);
  border-left: 3px solid var(--st-down);
  box-shadow: 0 16px 30px -20px rgba(0,0,0,.65), 0 0 26px -6px rgb(var(--st-down-rgb) / .5), inset 0 1px 0 rgba(255,255,255,.04);
  animation: cardDownGlow 2.6s ease-in-out infinite;
}

/* ── LIGHT MODE ─────────────────────────────────────────── */
body.light .card.is-up:not(.has-anomaly) {
  background: radial-gradient(130% 100% at 50% -25%, rgb(var(--st-up-rgb) / .12), transparent 62%), #ffffff;
  border: 1px solid rgb(var(--st-up-rgb) / .28);
  border-left: 3px solid var(--st-up);
  box-shadow: 0 14px 26px -22px rgba(16,40,26,.22), 0 0 20px -10px rgb(var(--st-up-rgb) / .30), inset 0 1px 0 rgba(255,255,255,.8);
}
body.light .card.is-slow:not(.has-anomaly) {
  background: radial-gradient(130% 100% at 50% -25%, rgb(var(--st-degraded-rgb) / .16), transparent 62%), #ffffff;
  border: 1px solid rgb(var(--st-degraded-rgb) / .38);
  border-left: 3px solid var(--st-degraded);
  box-shadow: 0 14px 26px -22px rgba(16,40,26,.22), 0 0 22px -9px rgb(var(--st-degraded-rgb) / .38), inset 0 1px 0 rgba(255,255,255,.8);
}
body.light .card.is-down:not(.has-anomaly) {
  background: radial-gradient(130% 100% at 50% -25%, rgb(var(--st-down-rgb) / .18), transparent 60%), #ffffff;
  border: 1px solid rgb(var(--st-down-rgb) / .50);
  border-left: 3px solid var(--st-down);
  box-shadow: 0 14px 26px -20px rgba(40,16,16,.24), 0 0 24px -8px rgb(var(--st-down-rgb) / .45), inset 0 1px 0 rgba(255,255,255,.8);
  animation: cardDownGlow 2.6s ease-in-out infinite;
}

/* Akzentlinie oben kräftiger, wenn Karte einen Status trägt */
.card.is-up::before, .card.is-down::before, .card.is-slow::before { opacity: .9; }

/* Offline-Karte: sanfter, langsamer Puls des roten Glows (zieht den Blick) */
@keyframes cardDownGlow {
  0%, 100% { box-shadow: 0 16px 30px -20px rgba(0,0,0,.65), 0 0 20px -9px rgba(224,101,91,.40), inset 0 1px 0 rgba(255,255,255,.04); }
  50%      { box-shadow: 0 16px 30px -20px rgba(0,0,0,.65), 0 0 34px -4px rgba(224,101,91,.62), inset 0 1px 0 rgba(255,255,255,.04); }
}

/* ── Werkzeug-Reihe (⚡ ⎘ ⏸ ✏ 👤 🛡️) erst beim Hover — aufgeräumter Standard ──
   opacity statt display/height → kein Layout-Sprung. Favorit-Stern bleibt sichtbar
   (sitzt im card-header). Tastatur-Fokus (focus-within) zeigt sie ebenfalls.
   Touch-Geräte ohne Hover bekommen sie dauerhaft. */
.card .card-actions-row { opacity: 0; pointer-events: none; transition: opacity .15s ease; }
.card:hover .card-actions-row,
.card:focus-within .card-actions-row { opacity: 1; pointer-events: auto; }
@media (hover: none) {
  .card .card-actions-row { opacity: 1; pointer-events: auto; }
}

/* Hover hebt die Karte klarer an + verstärkt den Glow (gilt für alle Status) */
body.dark .card.is-up:not(.has-anomaly):hover   { box-shadow: 0 22px 38px -22px rgba(0,0,0,.7), 0 0 30px -6px rgb(var(--st-up-rgb) / .5),        inset 0 1px 0 rgba(255,255,255,.06); }
body.dark .card.is-slow:not(.has-anomaly):hover  { box-shadow: 0 22px 38px -22px rgba(0,0,0,.7), 0 0 32px -5px rgb(var(--st-degraded-rgb) / .55), inset 0 1px 0 rgba(255,255,255,.06); }
body.light .card.is-up:not(.has-anomaly):hover   { box-shadow: 0 20px 34px -22px rgba(16,40,26,.28), 0 0 28px -8px rgb(var(--st-up-rgb) / .42),      inset 0 1px 0 rgba(255,255,255,.85); }
body.light .card.is-slow:not(.has-anomaly):hover { box-shadow: 0 20px 34px -22px rgba(16,40,26,.28), 0 0 30px -7px rgb(var(--st-degraded-rgb) / .5), inset 0 1px 0 rgba(255,255,255,.85); }

@media (prefers-reduced-motion: reduce) {
  .card.is-down:not(.has-anomaly) { animation: none; }
}

/* ===== ABLAUF-COCKPIT-BOXEN: Dringlichkeit trägt die ganze Box (Dario 24.06.) =====
   Vorher: alle Cockpit-Boxen sahen gleich grün-getönt aus (body.dark .pm-card
   gewann), die Dringlichkeit steckte nur in der kleinen Pille → „nur Kästen".
   Jetzt trägt die ganze Box ihre Ampelfarbe — rot (bald/abgelaufen) sticht mit
   Puls heraus, gelb = Warnung, ruhig grün = ok, neutral = kein Datum. Gleiche
   Logik wie der Endpunkt-Glow. Box-Status-Klasse kommt aus app.js
   (expiryCardStateClass). ================================================= */

/* ── DARK MODE ── */
body.dark .expiry-card.exp-critical {
  background: radial-gradient(130% 100% at 50% -25%, rgb(var(--st-down-rgb) / .22), transparent 58%), #1c1315;
  border: 1px solid rgb(var(--st-down-rgb) / .55);
  border-left: 3px solid var(--st-down);
  box-shadow: 0 14px 28px -22px rgba(0,0,0,.6), 0 0 24px -7px rgb(var(--st-down-rgb) / .46), inset 0 1px 0 rgba(255,255,255,.04);
  animation: cardDownGlow 2.6s ease-in-out infinite;
}
body.dark .expiry-card.exp-warn {
  background: radial-gradient(130% 100% at 50% -25%, rgb(var(--st-degraded-rgb) / .18), transparent 60%), #1a1611;
  border: 1px solid rgb(var(--st-degraded-rgb) / .40);
  border-left: 3px solid var(--st-degraded);
  box-shadow: 0 14px 28px -22px rgba(0,0,0,.6), 0 0 22px -8px rgb(var(--st-degraded-rgb) / .38), inset 0 1px 0 rgba(255,255,255,.05);
}
body.dark .expiry-card.exp-ok {
  background: radial-gradient(130% 100% at 50% -25%, rgb(var(--st-up-rgb) / .13), transparent 62%), #14181a;
  border: 1px solid rgb(var(--st-up-rgb) / .26);
  border-left: 3px solid var(--st-up);
  box-shadow: 0 14px 28px -22px rgba(0,0,0,.6), 0 0 18px -9px rgb(var(--st-up-rgb) / .26), inset 0 1px 0 rgba(255,255,255,.05);
}
body.dark .expiry-card.exp-neutral {
  border-left: 3px solid var(--text-muted);
}

/* ── LIGHT MODE ── */
body.light .expiry-card.exp-critical {
  background: radial-gradient(130% 100% at 50% -25%, rgb(var(--st-down-rgb) / .18), transparent 60%), #ffffff;
  border: 1px solid rgb(var(--st-down-rgb) / .50);
  border-left: 3px solid var(--st-down);
  box-shadow: 0 12px 24px -22px rgba(40,16,16,.24), 0 0 22px -8px rgb(var(--st-down-rgb) / .42), inset 0 1px 0 rgba(255,255,255,.8);
  animation: cardDownGlow 2.6s ease-in-out infinite;
}
body.light .expiry-card.exp-warn {
  background: radial-gradient(130% 100% at 50% -25%, rgb(var(--st-degraded-rgb) / .15), transparent 62%), #ffffff;
  border: 1px solid rgb(var(--st-degraded-rgb) / .38);
  border-left: 3px solid var(--st-degraded);
  box-shadow: 0 12px 24px -22px rgba(16,40,26,.2), 0 0 22px -9px rgb(var(--st-degraded-rgb) / .36), inset 0 1px 0 rgba(255,255,255,.8);
}
body.light .expiry-card.exp-ok {
  background: radial-gradient(130% 100% at 50% -25%, rgb(var(--st-up-rgb) / .1), transparent 62%), #ffffff;
  border: 1px solid rgb(var(--st-up-rgb) / .24);
  border-left: 3px solid var(--st-up);
  box-shadow: 0 12px 24px -22px rgba(16,40,26,.2), 0 0 16px -10px rgb(var(--st-up-rgb) / .24), inset 0 1px 0 rgba(255,255,255,.8);
}
body.light .expiry-card.exp-neutral {
  border-left: 3px solid var(--text-muted);
}

/* Hover: sanftes Anheben + Glow verstärken (Cursor bleibt default — keine Detail-Ansicht) */
.expiry-card:hover { transform: translateY(-2px); }
body.dark .expiry-card.exp-critical:hover  { box-shadow: 0 20px 34px -22px rgba(0,0,0,.7), 0 0 32px -5px rgb(var(--st-down-rgb) / .6),  inset 0 1px 0 rgba(255,255,255,.06); }
body.dark .expiry-card.exp-warn:hover      { box-shadow: 0 20px 34px -22px rgba(0,0,0,.7), 0 0 30px -6px rgb(var(--st-degraded-rgb) / .5), inset 0 1px 0 rgba(255,255,255,.06); }
body.dark .expiry-card.exp-ok:hover        { box-shadow: 0 20px 34px -22px rgba(0,0,0,.7), 0 0 26px -7px rgb(var(--st-up-rgb) / .4),  inset 0 1px 0 rgba(255,255,255,.06); }
body.light .expiry-card.exp-critical:hover { box-shadow: 0 18px 30px -22px rgba(40,16,16,.3), 0 0 28px -7px rgb(var(--st-down-rgb) / .5),  inset 0 1px 0 rgba(255,255,255,.85); }
body.light .expiry-card.exp-warn:hover     { box-shadow: 0 18px 30px -22px rgba(16,40,26,.26), 0 0 28px -8px rgb(var(--st-degraded-rgb) / .45), inset 0 1px 0 rgba(255,255,255,.85); }
body.light .expiry-card.exp-ok:hover       { box-shadow: 0 18px 30px -22px rgba(16,40,26,.26), 0 0 22px -9px rgb(var(--st-up-rgb) / .34), inset 0 1px 0 rgba(255,255,255,.85); }

/* ✕ Löschen erscheint erst beim Hover (aufgeräumt; nur manuelle Termine haben es) */
.expiry-card .expiry-del { opacity: 0; pointer-events: none; transition: opacity .15s ease; }
.expiry-card:hover .expiry-del,
.expiry-card:focus-within .expiry-del { opacity: 1; pointer-events: auto; }
@media (hover: none) { .expiry-card .expiry-del { opacity: 1; pointer-events: auto; } }

@media (prefers-reduced-motion: reduce) {
  .expiry-card.exp-critical { animation: none; }
}

/* ===== Kunden verwalten — Liste im Modal (24.06.) ===== */
.manage-cust-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin: 4px 0 16px;
  max-height: 52vh;
  overflow-y: auto;
}
.manage-cust-empty {
  color: var(--text-muted);
  font-size: 13px;
  text-align: center;
  padding: 14px 0 22px;
}
.manage-cust-row {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 12px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface-2);
}
.manage-cust-main { display: flex; align-items: center; gap: 10px; }
.manage-cust-row.is-archived { opacity: .5; }
.manage-cust-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  flex-shrink: 0;
}
.manage-cust-name {
  font-weight: 600;
  font-size: 14px;
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.manage-cust-count {
  font-size: 12px;
  color: var(--text-muted);
  flex-shrink: 0;
}
.manage-cust-actions {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}
/* Beschriftete Aktions-Buttons (Icon + Text) — klar statt nacktem Emoji */
.mc-btn {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 13px; line-height: 1; padding: 7px 12px;
  border: 1px solid var(--border); border-radius: 8px;
  background: var(--surface); color: var(--text);
  cursor: pointer; text-decoration: none;
}
.mc-btn:hover { background: var(--surface-2); border-color: var(--text-muted); }
.mc-btn.mc-status { color: var(--green-text); border-color: rgba(47,209,138,.4); }
.mc-btn.mc-status:hover { background: rgba(47,209,138,.1); }
.mc-btn.mc-report { color: var(--blue); border-color: rgba(94,166,218,.4); }
.mc-btn.mc-report:hover { background: var(--blue-dim); }
.mc-btn.mc-del:hover { color: var(--red); border-color: var(--red); background: rgba(224,101,91,.1); }
.manage-cust-logo {
  width: 22px; height: 22px; flex-shrink: 0; border-radius: 6px;
  border: 1px solid var(--border); background-color: var(--surface-2);
  background-size: contain; background-position: center; background-repeat: no-repeat;
}

/* ── Statusseiten-Übersicht (PIN-167): Agentur öffnet/teilt je Kunde + Gesamt ── */
.cockpit-head-left { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.sp-ov-overall {
  border-color: color-mix(in srgb, var(--blue) 32%, var(--border));
  background: color-mix(in srgb, var(--blue) 6%, var(--surface-2));
}
.sp-ov-icon { font-size: 17px; width: 22px; text-align: center; flex-shrink: 0; }
.sp-ov-url { font-size: 12px; color: var(--text-muted); word-break: break-all; }
.sp-ov-none { font-size: 12.5px; color: var(--text-muted); align-self: center; margin-right: auto; }

/* ── Kunden-Logo-Upload (PIN-82 White-Label-Branding) ───────────────── */
.logo-field { margin: 14px 0; }
.field-label { display: block; font-size: 14px; font-weight: 500; margin-bottom: 6px; }
.logo-upload { display: flex; align-items: center; gap: 14px; }
.logo-preview {
  width: 56px; height: 56px; flex-shrink: 0; box-sizing: border-box; padding: 5px;
  border-radius: 10px; border: 1px solid var(--border);
  background-color: var(--surface-2);
  /* Innerhalb des Innenabstands anzeigen → randfüllende Favicons wirken nicht abgeschnitten */
  background-size: contain; background-origin: content-box;
  background-position: center; background-repeat: no-repeat;
}
.logo-preview.is-empty { position: relative; }
.logo-preview.is-empty::after {
  content: "🖼"; position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  font-size: 22px; opacity: .35;
}
.logo-upload-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.logo-pick { cursor: pointer; margin: 0; }
.logo-hint { display: block; margin-top: 6px; font-size: 12px; color: var(--text-muted); }
.form-section-label { font-size: 13px; font-weight: 600; margin: 18px 0 2px; }
.modal-hint-sm { font-size: 12px; margin-bottom: 10px; }

/* ── Kunden-Modal: breiter, strukturiert, mobil (PIN-82/85, Politur 28.06.) ── */
#modal-customer .modal-box { max-width: 620px; }
/* 2-Spalten-Raster → weniger „hochkantig"; volle Breite via .cg-full */
.cust-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0 18px; align-items: start; }
.cust-grid > .cg-full { grid-column: 1 / -1; }
/* Klar abgesetzte Abschnitte */
.cust-section { margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--border); }
.cust-section-title { font-size: 13px; font-weight: 600; color: var(--text); margin-bottom: 4px; letter-spacing: .1px; }
.cust-section-title small { font-weight: 400; color: var(--text-muted); }

/* Farb-/Glow-Feld: gewählte Farbe bleibt als Balken + Hex sichtbar */
.color-field { display: flex; align-items: center; gap: 10px; }
.color-field input[type="color"] {
  width: 46px; height: 34px; padding: 2px; flex-shrink: 0; cursor: pointer;
  background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius);
}
.color-bar { flex: 1; height: 14px; border-radius: 7px; border: 1px solid var(--border); background: #2fd18a; }
.color-hex { font-size: 13px; color: var(--text-muted); font-variant-numeric: tabular-nums; flex-shrink: 0; min-width: 64px; }

/* White-Label-Sektion als abgesetzte Karte */
.sp-section { border: 1px solid var(--border); border-radius: 12px; background: var(--surface-2); padding: 16px 18px; margin-top: 18px; }
.sp-toggle { flex-direction: row; align-items: center; gap: 10px; margin: 12px 0; font-size: 14px; color: var(--text); font-weight: 500; cursor: pointer; }
.sp-toggle input { width: auto; margin: 0; flex-shrink: 0; width: 16px; height: 16px; }
.sp-url-row { display: flex; flex-direction: column; gap: 8px; margin: 4px 0 14px; }
/* Link klar hervorgehoben: grün getönt, fett, monospace, volle Breite */
.sp-url-row input {
  width: 100%; font-size: 13px; font-weight: 600;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  color: var(--green-text); background: rgba(47,209,138,.08); border-color: rgba(47,209,138,.45);
}
/* „Kopieren" + „Öffnen" nebeneinander statt untereinander */
.sp-url-actions { display: flex; gap: 8px; }
.sp-url-actions .btn-sm { white-space: nowrap; text-decoration: none; }
.manage-cust-actions .mc-status { text-decoration: none; }

@media (max-width: 560px) {
  #modal-customer .modal-box { padding: 22px 16px; }
  .cust-grid { grid-template-columns: 1fr; gap: 0; }
}

/* ═══ Kundenkartei — Detail-/Anlege-Fenster mit Reitern (PIN-158) ═══════════
   Ein Fenster für alles zu einem Kunden. Dunkel, on-brand; die Dossier-Kopf-
   zeile + Akzente werden in der Kundenfarbe (--client-accent) getönt. color-mix
   mit solidem Fallback davor (ältere Engines ignorieren die 2. Deklaration). */
#modal-customer .modal-box-kartei {
  max-width: 820px; padding: 0; overflow: hidden;
  display: flex; flex-direction: column; max-height: 88vh;
}
/* Dossier-Kopfzeile */
.cust-dossier { position: relative; padding: 22px 26px 18px; border-bottom: 1px solid var(--border); flex-shrink: 0; }
.cust-dossier { background: var(--surface); }
.cust-dossier {
  background:
    radial-gradient(120% 150% at 0% 0%, color-mix(in srgb, var(--client-accent, var(--green)) 22%, transparent) 0%, transparent 62%),
    var(--surface);
}
.cust-dossier-close { position: absolute; top: 12px; right: 12px; }
.cust-dossier-id { display: flex; align-items: center; gap: 14px; }
.cust-dossier-avatar {
  width: 46px; height: 46px; border-radius: 12px; flex-shrink: 0;
  /* Logo vollständig einpassen statt beschneiden (PIN-166) */
  background-size: contain; background-repeat: no-repeat; background-position: center;
  display: flex; align-items: center; justify-content: center;
  font-size: 19px; font-weight: 700; color: var(--text);
  background-color: var(--surface-3); border: 1px solid var(--border-2);
}
.cust-dossier-avatar {
  background-color: color-mix(in srgb, var(--client-accent, var(--green)) 20%, var(--surface-3));
  border-color: color-mix(in srgb, var(--client-accent, var(--green)) 45%, var(--border));
}
.cust-dossier-idtext { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.cust-dossier-name {
  font-size: 19px; font-weight: 700; color: var(--text); margin: 0; letter-spacing: -.3px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.cust-dossier-pill { align-self: flex-start; font-size: 11.5px; font-weight: 700; padding: 2px 10px; border-radius: 999px; letter-spacing: .2px; }
.cust-dossier-pill[hidden] { display: none; }
/* „Statusseite öffnen" im Kunden-Kopf (nur bei aktiver White-Label-Seite) */
.cust-dossier-sp {
  align-self: flex-start; display: inline-flex; align-items: center; gap: 5px;
  font-size: 12.5px; font-weight: 600; text-decoration: none; color: var(--green-text);
  border: 1px solid rgba(47,209,138,.4); border-radius: 8px; padding: 4px 10px;
}
.cust-dossier-sp:hover { background: rgba(47,209,138,.1); }
.cust-dossier-sp.hidden { display: none; }
/* Editierbarer Statusseiten-Slug + Anzeigename (Branding-Tab, PIN-174) */
.sp-title-field { margin-top: 10px; }
.sp-slug-row { margin: 8px 0 2px; }
.sp-slug-lbl { display: block; font-size: 13px; font-weight: 500; margin-bottom: 5px; color: var(--text-2); }
.sp-slug-field { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.sp-slug-prefix { font-size: 12.5px; color: var(--text-muted); white-space: nowrap; }
.sp-slug-field input { flex: 1 1 150px; min-width: 120px; }
.sp-slug-warn { color: var(--yellow); margin-top: 5px; }
.cust-dossier-pill.is-up { background: var(--st-up-dim); color: var(--st-up); }
.cust-dossier-pill.is-down { background: var(--st-down-dim); color: var(--st-down); }
.cust-dossier-pill.is-partial { background: var(--st-degraded-dim); color: var(--st-degraded); }
.cust-dossier-pill.is-unknown { background: var(--surface-3); color: var(--text-muted); }
.cust-dossier-stats { display: flex; gap: 22px; margin-top: 14px; flex-wrap: wrap; }
.cust-dossier-stats[hidden] { display: none; }
.cds-item { display: flex; flex-direction: column; gap: 1px; }
.cds-k { font-size: 10.5px; text-transform: uppercase; letter-spacing: .4px; color: var(--text-muted); }
.cds-v { font-size: 14px; font-weight: 700; color: var(--text); font-variant-numeric: tabular-nums; }
.cds-v.expiry-critical { color: var(--st-down); }
.cds-v.expiry-warn { color: var(--st-degraded); }

/* Reiter-Leiste */
.cust-tabs { display: flex; gap: 2px; padding: 0 16px; border-bottom: 1px solid var(--border); background: var(--surface); overflow-x: auto; scrollbar-width: none; flex-shrink: 0; }
.cust-tabs::-webkit-scrollbar { display: none; }
.cust-tab { background: none; border: none; font: inherit; cursor: pointer; padding: 12px 14px; font-size: 13.5px; font-weight: 600; color: var(--text-muted); border-bottom: 2px solid transparent; white-space: nowrap; transition: color .15s, border-color .15s; }
.cust-tab:hover { color: var(--text); }
.cust-tab.active { color: var(--green-text); border-bottom-color: var(--green); }
.cust-tab[hidden] { display: none; }

/* Panels + scrollender Formular-Körper */
#form-customer { display: flex; flex-direction: column; min-height: 0; flex: 1; overflow: hidden; }
.cust-panel { display: none; flex: 1 1 auto; min-height: 0; overflow-y: auto; padding: 22px 26px; }
.cust-panel.active { display: block; }
#modal-customer #customer-form-error { margin: 0 26px; flex-shrink: 0; }
#modal-customer .form-actions { padding: 14px 26px; border-top: 1px solid var(--border); margin: 0; background: var(--surface); flex-shrink: 0; }

/* Eigene Schalter statt nackter Checkboxen */
.pm-switch { display: flex; flex-direction: row; align-items: center; gap: 11px; margin: 12px 0; font-size: 14px; color: var(--text); font-weight: 500; cursor: pointer; }
.pm-switch input { position: absolute; width: 1px; height: 1px; opacity: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.pm-switch-track { position: relative; flex-shrink: 0; width: 38px; height: 22px; border-radius: 999px; background: var(--surface-3); border: 1px solid var(--border-2); transition: background .18s, border-color .18s; }
.pm-switch-track::after { content: ""; position: absolute; top: 2px; left: 2px; width: 16px; height: 16px; border-radius: 50%; background: var(--text-2); transition: transform .18s, background .18s; }
.pm-switch input:checked + .pm-switch-track { background: var(--green-dim); border-color: var(--green); }
.pm-switch input:checked + .pm-switch-track::after { transform: translateX(16px); background: var(--green); }
.pm-switch input:focus-visible + .pm-switch-track { box-shadow: 0 0 0 3px var(--green-dim); }
.pm-switch-lbl { line-height: 1.4; }

/* Notizen + Textareas im Panel */
.cust-panel textarea { background: var(--surface-2); border: 1px solid var(--border); color: var(--text); border-radius: var(--radius); padding: 10px 12px; font: inherit; font-size: 14px; width: 100%; outline: none; resize: vertical; transition: border-color .15s, box-shadow .15s; }
.cust-panel textarea:focus { border-color: var(--green); box-shadow: 0 0 0 3px var(--green-dim); }
.cust-notes { min-height: 96px; line-height: 1.55; border-left: 3px solid var(--border-2); }
.cust-notes { border-left-color: color-mix(in srgb, var(--client-accent, var(--green)) 70%, var(--border)); }

/* Schnellzugriff-Links als Chips */
.ql-list { display: flex; flex-wrap: wrap; gap: 8px; margin: 4px 0 10px; }
.ql-chip { display: inline-flex; align-items: stretch; max-width: 100%; background: var(--surface-2); border: 1px solid var(--border); border-radius: 10px; transition: border-color .15s, box-shadow .15s; }
.ql-chip:hover { border-color: var(--green); box-shadow: 0 0 0 3px var(--green-dim); }
.ql-chip-link { display: inline-flex; align-items: center; gap: 8px; min-width: 0; padding: 7px 4px 7px 10px; text-decoration: none; color: var(--text); font-size: 13px; font-weight: 500; }
.ql-chip-ico { width: 22px; height: 22px; border-radius: 6px; flex-shrink: 0; display: flex; align-items: center; justify-content: center; font-size: 11px; font-weight: 700; text-transform: uppercase; color: var(--text); background: var(--surface-3); }
.ql-chip-ico { background: color-mix(in srgb, var(--client-accent, var(--green)) 22%, var(--surface-3)); }
.ql-chip-lbl { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ql-chip-x { border: none; background: none; color: var(--text-muted); cursor: pointer; font-size: 14px; line-height: 1; padding: 0 9px; flex-shrink: 0; }
.ql-chip-x:hover { color: var(--red); }
.ql-add-btn { background: none; border: 1px dashed var(--border-2); color: var(--text-2); border-radius: 10px; padding: 7px 12px; font: inherit; font-size: 13px; font-weight: 600; cursor: pointer; transition: border-color .15s, color .15s; }
.ql-add-btn:hover { border-color: var(--green); color: var(--green-text); }
.ql-add { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; margin-bottom: 10px; }
.ql-add.hidden, .ql-add-btn.hidden { display: none; }
.ql-add input { background: var(--surface-2); border: 1px solid var(--border); color: var(--text); border-radius: var(--radius); padding: 8px 11px; font: inherit; font-size: 14px; outline: none; }
.ql-add input:focus { border-color: var(--green); box-shadow: 0 0 0 3px var(--green-dim); }
.ql-add-label { width: 150px; }
.ql-add-url { flex: 1; min-width: 160px; }
.ql-error { color: var(--red); font-size: 12.5px; margin-top: 2px; }
.ql-error.hidden { display: none; }
/* Ausweg neben der Dubletten-Meldung (Cowork 25.07.): wählt den vorhandenen Kunden aus,
   statt einen zweiten anzulegen. Als <button> gebaut, damit er per Tastatur erreichbar
   ist; sieht aus wie ein Link. Akzentgrün, ohne Unterstreichung, gleiche Größe wie die
   Meldung daneben. */
.ql-dup-use {
  background: none; border: 0; padding: 0;
  font: inherit; font-size: 12.5px; color: var(--green, #2ea866);
  cursor: pointer; text-decoration: none; white-space: nowrap;
}
.ql-dup-use:hover { text-decoration: underline; }
.ql-dup-use:focus-visible { outline: 2px solid var(--green, #2ea866); outline-offset: 2px; border-radius: 3px; }

/* Zuschaltbare Zusatzfelder + „+ Weitere Angabe" */
.cust-addon { margin-top: 16px; }
.cust-addon.hidden { display: none; }
.cust-addon-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; font-size: 13px; font-weight: 600; color: var(--text); margin-bottom: 5px; }
.cust-addon-remove { color: var(--text-muted); }
.cust-addon-remove:hover { color: var(--red); }
.cust-addon-menu { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 18px; padding-top: 14px; border-top: 1px dashed var(--border); }
.cust-addon-menu.hidden { display: none; }
.cust-addon-menu-lbl { font-size: 12.5px; color: var(--text-muted); font-weight: 500; }
.addon-chip { background: var(--surface-2); border: 1px solid var(--border); color: var(--text-2); border-radius: 999px; padding: 5px 12px; font: inherit; font-size: 12.5px; font-weight: 600; cursor: pointer; transition: border-color .15s, color .15s; }
.addon-chip:hover { border-color: var(--green); color: var(--green-text); }
.addon-chip.hidden { display: none; }

/* Tags */
.tag-list { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 8px; }
.tag-pill { display: inline-flex; align-items: center; gap: 6px; background: var(--surface-2); border: 1px solid var(--border); color: var(--text); border-radius: 999px; padding: 3px 10px; font-size: 12.5px; font-weight: 600; }
.tag-pill { background: color-mix(in srgb, var(--client-accent, var(--green)) 14%, var(--surface-2)); border-color: color-mix(in srgb, var(--client-accent, var(--green)) 35%, var(--border)); }
.tag-pill-x { border: none; background: none; color: var(--text-muted); cursor: pointer; font-size: 13px; line-height: 1; padding: 0; }
.tag-pill-x:hover { color: var(--red); }
.tag-input { background: var(--surface-2); border: 1px solid var(--border); color: var(--text); border-radius: var(--radius); padding: 8px 11px; font: inherit; font-size: 14px; width: 100%; outline: none; }
.tag-input:focus { border-color: var(--green); box-shadow: 0 0 0 3px var(--green-dim); }

/* Tätigkeits-Log / Wartungsnachweis (PIN-162) */
.cust-log-list { display: flex; flex-direction: column; margin: 6px 0 10px; }
.cust-log-item { display: flex; align-items: baseline; gap: 12px; padding: 8px 0; border-top: 1px solid var(--border); }
.cust-log-item:first-child { border-top: none; }
.cust-log-date { font-size: 12px; color: var(--text-muted); font-weight: 600; white-space: nowrap; font-variant-numeric: tabular-nums; }
.cust-log-text { color: var(--text); flex: 1; word-break: break-word; }
.cust-log-x { border: none; background: none; color: var(--text-muted); cursor: pointer; font-size: 13px; line-height: 1; padding: 0; }
.cust-log-x:hover { color: var(--red); }
.cust-log-add .cust-log-date-input { width: 150px; }
.cust-log-add .cust-log-time-input { width: 110px; }
.cust-log-add .cust-log-hours-input { width: 90px; }
.cust-log-add .cust-log-cat-input { width: 130px; }
.cust-log-add .cust-log-text-input { flex: 1; min-width: 160px; }
/* Dauer-Chip in der Log-Zeile (Stundensatz-Abrechnung) */
.cust-log-hours { font-size: 12px; color: var(--text-muted); white-space: nowrap; margin-left: 2px; }
/* Kategorie-Chip je Eintrag */
.cust-log-cat { font-size: 11px; font-weight: 600; white-space: nowrap; padding: 1px 7px; border-radius: 999px;
  color: color-mix(in srgb, var(--client-accent, var(--green)) 80%, var(--text)); margin-left: 2px;
  background: color-mix(in srgb, var(--client-accent, var(--green)) 16%, transparent); }
/* Übersichts-Toolbar + Kategorie-Filter über der Liste */
.cust-log-toolbar { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; margin-bottom: 8px; }
.cust-log-summary { font-size: 12px; color: var(--text-muted); }
.cust-log-filter { font-size: 12px; padding: 4px 8px; border-radius: 8px; border: 1px solid var(--border);
  background: var(--surface-2); color: var(--text); }
/* Einklappbare Monatsgruppen */
.cust-log-month { border-top: 1px solid var(--border); }
.cust-log-month:first-of-type { border-top: none; }
.cust-log-month-head { display: flex; align-items: center; gap: 8px; width: 100%; background: none; border: none;
  cursor: pointer; padding: 9px 2px; color: var(--text); font-size: 13px; text-align: left; }
.cust-log-month-head:hover { color: color-mix(in srgb, var(--client-accent, var(--green)) 75%, var(--text)); }
.cust-log-caret { width: 12px; color: var(--text-muted); }
.cust-log-month-name { font-weight: 600; }
.cust-log-month-sum { margin-left: auto; font-size: 12px; color: var(--text-muted); white-space: nowrap; }
.cust-log-month-body { padding-left: 20px; }

/* Abrechnungs-Export (PIN-161): Zeitraum-Wähler + CSV-Download-Zeile in der Kartei */
.cust-export { display: flex; flex-direction: column; gap: 8px; margin-top: 12px; }
.cust-export-lbl { font-size: 12px; color: var(--text-muted); margin-right: 2px; }
.cust-export-period, .cust-export-btns { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
#customer-export-period { font-size: 12px; padding: 4px 8px; border-radius: 8px; border: 1px solid var(--border); background: var(--surface-2); color: var(--text); }
.cust-export-custom { display: inline-flex; align-items: center; gap: 6px; }
.cust-export-custom input[type=date] { font-size: 12px; padding: 3px 6px; }
/* Monats-Sammel-Export über der Verwalten-Liste */
.manage-export { margin: 4px 0 14px; padding-bottom: 12px; border-bottom: 1px solid var(--border); }

/* Übersicht-Panel */
.cust-ov-hero { display: flex; align-items: center; gap: 12px; padding: 16px 18px; border-radius: 12px; background: var(--surface-2); border: 1px solid var(--border); margin-bottom: 16px; }
.cust-ov-hero-dot { width: 12px; height: 12px; border-radius: 50%; flex-shrink: 0; background: var(--text-muted); }
.cust-ov-hero.is-up .cust-ov-hero-dot { background: var(--st-up); }
.cust-ov-hero.is-down .cust-ov-hero-dot { background: var(--st-down); }
.cust-ov-hero.is-partial .cust-ov-hero-dot { background: var(--st-degraded); }
.cust-ov-hero-txt { font-size: 15px; font-weight: 700; color: var(--text); }
.cust-ov-hero-sub { font-size: 12.5px; color: var(--text-muted); font-weight: 500; margin-left: auto; }
.cust-ov-tiles { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin-bottom: 16px; }
.cust-ov-tile { background: var(--surface-2); border: 1px solid var(--border); border-radius: 10px; padding: 12px 14px; text-align: center; }
.cust-ov-tile-k { font-size: 11px; color: var(--text-muted); text-transform: uppercase; letter-spacing: .3px; }
.cust-ov-tile-v { font-size: 20px; font-weight: 700; margin-top: 3px; font-variant-numeric: tabular-nums; color: var(--text); }
.cust-ov-tile-v.uptime-good { color: var(--st-up); }
.cust-ov-tile-v.uptime-warn { color: var(--st-degraded); }
.cust-ov-tile-v.uptime-bad { color: var(--st-down); }
.cust-ov-tile-v.uptime-none { color: var(--text-muted); }
.cust-ov-row { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; padding: 11px 2px; border-top: 1px solid var(--border); font-size: 13px; }
.cust-ov-row-k { color: var(--text-muted); }
.cust-ov-row-v { color: var(--text-2); text-align: right; font-weight: 600; word-break: break-word; }
.cust-ov-row-v.expiry-critical { color: var(--st-down); }
.cust-ov-row-v.expiry-warn { color: var(--st-degraded); }
.cust-ov-row-v.expiry-ok { color: var(--st-up); }
.cust-ov-empty { text-align: center; color: var(--text-muted); font-size: 13.5px; padding: 26px 12px; }

/* Endpunkte-Panel */
.cust-ep-row { display: flex; align-items: center; gap: 10px; padding: 10px 2px; border-top: 1px solid var(--border); font-size: 13px; }
.cust-ep-row:first-child { border-top: none; }
.cust-ep-dot { width: 9px; height: 9px; border-radius: 50%; flex-shrink: 0; background: var(--text-muted); }
.cust-ep-dot.is-up { background: var(--st-up); }
.cust-ep-dot.is-down { background: var(--st-down); }
.cust-ep-name { font-weight: 600; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; flex: 1; min-width: 0; }
.cust-ep-meta { display: flex; align-items: center; gap: 8px; flex-shrink: 0; color: var(--text-muted); font-size: 12px; }
.cust-ep-meta .expiry-critical { color: var(--st-down); }
.cust-ep-meta .expiry-warn { color: var(--st-degraded); }
.cust-ep-show { margin-top: 14px; }
.cust-ep-empty { text-align: center; color: var(--text-muted); font-size: 13.5px; padding: 26px 12px; }

/* Bereiche je Kunde (PIN-396) — Verwaltung im Endpunkte-Reiter der Kartei */
.cust-ber-block { margin-bottom: 22px; padding-bottom: 18px; border-bottom: 1px solid var(--border); }
.cust-ber-title { font-size: 12px; font-weight: 700; letter-spacing: .04em;
                  text-transform: uppercase; color: var(--text-muted); margin: 0 0 8px; }
.cust-ber-row { display: flex; align-items: center; gap: 10px; padding: 7px 2px; font-size: 13px; }
.cust-ber-name { flex: 1; min-width: 0; font-weight: 600; color: var(--text);
                 white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cust-ber-act { display: flex; gap: 12px; flex-shrink: 0; }
.cust-ber-act .btn-danger-link { color: var(--st-down); }
.cust-ber-add { display: flex; gap: 8px; margin-top: 10px; }
.cust-ber-add input { flex: 1; min-width: 0; }
/* Zwischenüberschrift in der Endpunktliste der Kartei */
.cust-ber-head { margin: 16px 0 2px; font-size: 12px; font-weight: 700;
                 letter-spacing: .03em; color: var(--text-muted); }
.cust-ber-head + .cust-ep-row { border-top: none; }

@media (max-width: 620px) {
  #modal-customer .modal-box-kartei { max-height: 92vh; }
  .cust-panel { padding: 18px 16px; }
  .cust-dossier { padding: 18px 16px 14px; }
  .cust-tabs { padding: 0 8px; }
  .cust-ov-tiles { grid-template-columns: 1fr 1fr; }
}

/* ── Kunden-Cockpit (Agentur-Sicht, PIN-83) ──────────────────────────────
   Aggregat-Status pro Kunde oben im Dashboard. Karten nutzen die bestehenden
   .card.is-up/.is-down/.is-slow/.unchecked-Glows (nicht neu erfinden). */
.client-cockpit { margin: 8px 0 26px; }
.client-cockpit.hidden { display: none; }
.cockpit-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; flex-wrap: wrap; margin-bottom: 14px;
}
.cockpit-title { font-size: 17px; font-weight: 700; color: var(--text); margin: 0; }
.cockpit-tiles { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }

.cockpit-tile {
  display: inline-flex; align-items: baseline; gap: 7px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 999px; padding: 6px 14px; cursor: pointer; font: inherit;
  color: var(--text-2); transition: border-color .15s, background .15s, color .15s;
}
.cockpit-tile:hover { border-color: var(--text-muted); color: var(--text); }
.cockpit-tile .ct-num { font-size: 15px; font-weight: 700; color: var(--text); }
.cockpit-tile .ct-lbl { font-size: 12.5px; font-weight: 500; }
#cockpit-tile-down.is-active {
  border-color: rgb(var(--st-down-rgb) / .55); background: rgb(var(--st-down-rgb) / .12); color: var(--st-down);
}
#cockpit-tile-down.is-active .ct-num { color: var(--st-down); }
#cockpit-tile-expiring.is-active {
  border-color: rgb(var(--st-degraded-rgb) / .55); background: rgb(var(--st-degraded-rgb) / .12); color: var(--st-degraded);
}
#cockpit-tile-expiring.is-active .ct-num { color: var(--st-degraded); }

.cockpit-attn {
  display: inline-flex; align-items: center; gap: 7px;
  font-size: 12.5px; color: var(--text-2); cursor: pointer; user-select: none;
}
.cockpit-attn input { width: 15px; height: 15px; margin: 0; flex-shrink: 0; cursor: pointer; }

.cockpit-card { cursor: pointer; }
.cockpit-card-head { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
.cockpit-card .cockpit-dot,
.cockpit-card .cockpit-logo { width: 18px; height: 18px; border-radius: 5px; flex-shrink: 0; }
/* Kunden-Logo vollständig zeigen statt beschneiden (PIN-166): contain + kein Kacheln.
   Dezenter Rahmen wie bei den anderen Logo-Kacheln, damit transparente/breite Logos
   nicht in die Karte „auslaufen" (box-sizing:border-box ist global → bleibt 18×18). */
.cockpit-card .cockpit-logo {
  background-size: contain; background-repeat: no-repeat; background-position: center;
  background-color: var(--surface-2); border: 1px solid var(--border);
}
.cockpit-name {
  font-size: 14px; font-weight: 600; color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.cockpit-statusline {
  display: flex; align-items: center; justify-content: space-between;
  gap: 8px; font-size: 12.5px; margin-bottom: 10px;
}
.cockpit-st-label { font-weight: 600; color: var(--text-2); }
.cockpit-counts { color: var(--text-muted); }
.cockpit-down-n { color: var(--st-down); font-weight: 700; }

.cockpit-uptime {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  font-size: 12px; padding: 8px 0; border-top: 1px solid var(--border);
}
.cockpit-uptime-lbl { color: var(--text-muted); }
.cu-col { display: inline-flex; align-items: baseline; gap: 4px; }
.cu-col .cu-k { color: var(--text-muted); font-size: 11px; }
.cockpit-uptime .uptime-good,
.cockpit-uptime .uptime-warn,
.cockpit-uptime .uptime-bad { background: transparent; padding: 0; font-weight: 700; }
.cockpit-uptime .uptime-none { color: var(--text-muted); }

.cockpit-row {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 10px; font-size: 12px; padding-top: 8px; border-top: 1px solid var(--border);
}
.cockpit-row-lbl { color: var(--text-muted); flex-shrink: 0; }
.cockpit-row-val { color: var(--text-2); text-align: right; word-break: break-word; }
.cockpit-exp.expiry-critical .cockpit-row-val { color: var(--st-down); font-weight: 600; }
.cockpit-exp.expiry-warn .cockpit-row-val { color: var(--st-degraded); font-weight: 600; }
.cockpit-exp.expiry-ok .cockpit-row-val { color: var(--st-up); }
/* Funktions-Wächter im Cockpit (PIN-87): kompakter Chip + ausklappbare Detail-Liste */
.cockpit-fn-chip {
  border: none; cursor: pointer; font: inherit;
  font-size: 11.5px; font-weight: 700; line-height: 1.5;
  padding: 2px 9px; border-radius: 999px; flex-shrink: 0;
}
.cockpit-fn-detail { margin-top: 8px; }
.cockpit-fn-detail.hidden { display: none; }

.cockpit-allok { text-align: center; color: var(--text-muted); font-size: 13.5px; padding: 22px 12px; }
.cockpit-allok.hidden { display: none; }

/* ── Import-Paste + Export + Migrations-CTA (PIN-109) ──────────────────── */
/* Runde A der Import-Ebene: aus dem zentrierten Wörtchen wird ein echter Trenner mit
   Linien links und rechts. Er steht zwischen zwei gleichwertigen Wegen (Datei ablegen
   oder Zeilen einfügen), und genau das soll man sehen.
   🚨 Diese Regel bleibt HIER stehen und wandert nicht in den Import-Block weiter oben:
   .import-or hat dieselbe Spezifität (0,1,0), und die spätere Regel gewänne. */
.import-or {
  display: flex; align-items: center; gap: 11px; margin: 14px 0 13px;
  color: var(--text-muted); font-size: 11px;
}
.import-or::before, .import-or::after { content: ""; flex: 1; height: 1px; background: var(--border); }
.import-paste {
  /* 🚨 78px wie in der Spezifikation, nicht 96. Mit 96 lief das Einrichtpanel bei
     1440x900 um 33 Pixel über und bekam einen eigenen Scrollbalken — die Ebene soll
     genau EINEN haben. Aufgefallen beim Hinsehen am 02.08.2026, nachdem der
     Prüfset-Satz dazukam. Ziehen kann man es weiterhin (resize:vertical). */
  width: 100%; min-height: 78px; resize: vertical; box-sizing: border-box;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px;
  padding: 9px 11px; border: 1px solid var(--border); border-radius: 8px;
  background: var(--bg-elev, rgba(255,255,255,.02)); color: var(--text, #fff);
}
.btn-link {
  background: none; border: none; padding: 0; cursor: pointer; font-family: inherit;
  color: var(--green-text); font-size: 13.5px; font-weight: 600;
  text-decoration: underline; text-underline-offset: 2px;
}
.btn-link:hover { opacity: .85; }
.empty-migrate { margin-top: 10px; }

/* Canvas hinter <body> einfärben → kein heller Streifen beim Overscroll am unteren
   Seitenrand (das Theme liegt auf <body>, <html> blieb sonst auf Browser-Weiß).
   Default = Dark (Dashboard); bei hellen Seiten via :has() auf den Light-Ton. */
html { background: #0a0a0a; }
html:has(body.light) { background: #f6f8fa; }

/* ── PIN-116: Drag-and-Drop der Endpunkt-Karten ─────────────────────────── */
.card[draggable="true"] { cursor: grab; }
.card.dragging { opacity: .45; cursor: grabbing; }

/* Gruppierte Ansicht: jede Kunden-Gruppe ist ein eigener Block mit eigenem Karten-Grid
   → die GANZE Fläche (Header + Karten + Lücken) ist EIN großes Drop-Feld. */
#cards.is-grouped { display: block; }
.client-group { border-radius: 12px; padding: 0 4px 6px; transition: background .15s ease, outline-color .15s ease; }
.client-group > .cg-cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(264px, 1fr));
  gap: 16px;
}
.client-group.card-filtered { display: none; }

/* Zuordnungs-Drop-Ziele: ganze Gruppe (großes Feld), Cockpit-Kachel, sonst einzelne Karte */
.client-group.drag-over {
  outline: 2px dashed var(--green);
  outline-offset: 4px;
  background: var(--green-dim);
}
.cockpit-card.drag-over,
.card.drag-over {
  outline: 2px dashed var(--green);
  outline-offset: 2px;
  background: var(--green-dim);
  border-radius: 8px;
}
/* Tausch-Ziel im manuellen Modus: Zielkarte hervorheben (Plätze tauschen beim Ablegen) */
.card.swap-target { outline: 2px solid var(--green); outline-offset: 2px; border-radius: 8px; }
/* „Snap": dezentes Einrasten nach einer Zuordnung (kein Opacity-Blitzen → cleaner) */
@keyframes pmSnap {
  0%   { transform: scale(.94); }
  55%  { transform: scale(1.03); }
  100% { transform: scale(1); }
}
.card.pm-snap { animation: pmSnap .26s ease-out 1; }

/* ── PIN-117: Status-Page-Builder (Komponenten-Reihenfolge per Drag) ────── */
.sp-order { margin-top: 14px; }
.sp-order-list { list-style: none; margin: 8px 0 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.sp-order-item {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 12px; border: 1px solid var(--border); border-radius: 8px;
  background: var(--surface-2); cursor: grab; user-select: none;
}
.sp-order-item.dragging { opacity: .45; cursor: grabbing; }
.sp-order-item .sp-order-grip { color: var(--text-muted); letter-spacing: -2px; }
.sp-order-item .sp-order-name { font-weight: 600; font-size: 14px; }


/* ═══ PIN-188 Statuspage-Studio ══════════════════════════════════════════ */
#modal-customer .modal-box-kartei.is-studio { max-width: min(1120px, 94vw); }

.studio-grid { display: grid; grid-template-columns: minmax(0,1fr) minmax(320px,44%); gap: 22px; align-items: start; }
.studio-grid.studio-create { grid-template-columns: 1fr; }
.studio-create .studio-edit-only { display: none !important; }
.studio-controls { min-width: 0; display: flex; flex-direction: column; gap: 12px; }

/* Kontroll-Gruppen (native <details>) */
.studio-group { border: 1px solid var(--border); border-radius: 12px; background: var(--surface-2); overflow: hidden; }
.studio-group > summary { list-style: none; cursor: pointer; padding: 12px 14px; font-size: 13.5px; font-weight: 600;
  color: var(--text); display: flex; align-items: center; gap: 8px; user-select: none; }
.studio-group > summary::-webkit-details-marker { display: none; }
.studio-group > summary::after { content: "⌄"; margin-left: auto; color: var(--text-muted); transition: transform .18s; }
.studio-group[open] > summary::after { transform: rotate(180deg); }
.studio-group[open] > summary { border-bottom: 1px solid var(--border); }
.studio-group > summary:focus-visible { outline: 2px solid var(--green); outline-offset: -2px; }
/* Aktive Gruppe hervorheben: was man gerade bearbeitet, ist sofort erkennbar (Studio-UX). */
.studio-group:focus-within { border-color: var(--green); box-shadow: 0 0 0 1px var(--green); }
.studio-group:focus-within > summary { color: var(--green-text); }
.studio-group-body { padding: 14px; display: grid; grid-template-columns: 1fr 1fr; gap: 14px 16px; align-items: start; }
.studio-group-body > .cg-full, .studio-group-body > .field-label, .studio-group-body > .seg,
.studio-group-body > .studio-field, .studio-group-body > .studio-optcolors { grid-column: 1 / -1; }
.studio-hook { opacity: .82; }
.studio-soon { margin-left: 6px; font-size: 10.5px; font-weight: 700; letter-spacing: .3px; text-transform: uppercase;
  color: var(--text-muted); background: var(--surface-3); border-radius: 999px; padding: 1px 8px; }
.field-label { display: block; font-size: 12.5px; font-weight: 600; color: var(--text-2); margin-bottom: 6px; }
.field-label-mt { margin-top: 6px; }

/* Segmented Control */
.seg { display: inline-flex; background: var(--surface-3); border: 1px solid var(--border-2); border-radius: 10px; padding: 3px; gap: 2px; }
.seg.seg-wrap { display: flex; flex-wrap: wrap; }
.seg-btn { flex: 1 1 auto; border: none; background: none; font: inherit; font-size: 12.5px; font-weight: 600;
  color: var(--text-muted); padding: 6px 12px; border-radius: 8px; cursor: pointer; white-space: nowrap; transition: background .15s, color .15s; }
.seg-btn:hover { color: var(--text); }
.seg-btn.active { background: var(--green-dim); color: var(--green-text); }
.seg-btn:focus-visible { outline: 2px solid var(--green); outline-offset: 1px; }

/* Optionale Farben mit Auto-Schalter */
.studio-optcolors { display: flex; flex-direction: column; gap: 10px; }
.studio-color-row { display: flex; align-items: center; gap: 10px; }
.studio-color-row .scr-lbl { flex: 1 1 auto; font-size: 13px; color: var(--text-2); }
.studio-color-row .scr-auto { display: inline-flex; align-items: center; gap: 5px; font-size: 12px; color: var(--text-muted); cursor: pointer; }
.studio-color-row input[type="color"] { width: 34px; height: 26px; border: 1px solid var(--border-2); border-radius: 7px; background: none; cursor: pointer; padding: 0; }
.studio-color-row input[type="color"]:disabled { opacity: .4; cursor: not-allowed; }

/* Favicon-/OG-Vorschau */
.logo-preview-sm   { width: 36px; height: 36px; }
.logo-preview-wide { width: 120px; height: 63px; border-radius: 8px; }

/* Rechte Spalte: sticky Vorschau in Browser-Chrome — bleibt beim Scrollen der Regler
   IMMER im Blick (Studio-UX: man tippt links und sieht rechts sofort das Ergebnis). */
.studio-preview { position: sticky; top: 8px; align-self: start; max-height: calc(100vh - 24px); }
.sp-chrome { display: flex; align-items: center; gap: 10px; padding: 8px 12px; background: var(--surface-3);
  border: 1px solid var(--border); border-bottom: none; border-radius: 12px 12px 0 0; }
.sp-chrome-dots { display: inline-flex; gap: 5px; }
.sp-chrome-dots i { width: 10px; height: 10px; border-radius: 50%; display: inline-block; background: var(--border-2); }
.sp-chrome-dots i:nth-child(1){background:#ff5f57} .sp-chrome-dots i:nth-child(2){background:#febc2e} .sp-chrome-dots i:nth-child(3){background:#28c840}
.sp-chrome-url { flex: 1; font-size: 11.5px; color: var(--text-muted); font-family: ui-monospace, Menlo, monospace;
  background: var(--surface); border-radius: 6px; padding: 3px 10px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.studio-frame { border: 1px solid var(--border-2); border-radius: 0 0 14px 14px; overflow: hidden; background: var(--surface-3); height: min(72vh, 640px); }
.studio-iframe { width: 100%; height: 100%; border: 0; display: block; background: #fff; }
/* Kurzer Puls, sobald die Vorschau eine Änderung übernimmt → sichtbares „hat reagiert". */
@keyframes studioPulse { from { box-shadow: 0 0 0 3px rgba(47,209,138,.55); } to { box-shadow: 0 0 0 3px rgba(47,209,138,0); } }
.studio-frame.is-updated { animation: studioPulse .6s ease-out; }
.sp-chrome-live { margin-left: 8px; display: inline-flex; align-items: center; gap: 5px; font-size: 10.5px;
  font-weight: 700; letter-spacing: .3px; text-transform: uppercase; color: var(--green-text); }
.sp-chrome-live::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: var(--green);
  box-shadow: 0 0 6px var(--green); animation: liveBlink 1.6s ease-in-out infinite; }
@keyframes liveBlink { 0%, 100% { opacity: 1; } 50% { opacity: .35; } }
.studio-preview-toggle { display: none; }   /* nur mobil */

@media (max-width: 900px) {
  #modal-customer .modal-box-kartei.is-studio { max-width: 94vw; }
  .studio-grid { grid-template-columns: 1fr; gap: 14px; }
  .studio-preview-toggle { display: block; width: 100%; margin-top: 8px; }
  .studio-preview { display: none; position: static; }
  .studio-open .studio-preview { display: block; }
  .studio-open .studio-frame { height: 60vh; }
}
@media (max-width: 560px) { .studio-group-body { grid-template-columns: 1fr; } }

/* Ausfall-Kommunikation pro Kunde (PIN-179 / T8) */
.cust-inccomm-actions { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-top: 12px; }
.cust-inccomm-count { font-size: 12.5px; color: var(--text-muted); }

/* Vorlagen-Galerie (PIN-189 / T5) */
.tpl-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; --tpl-accent: #2fd18a; }
.tpl-card { display: flex; flex-direction: column; gap: 6px; padding: 6px; border: 1.5px solid var(--border);
  border-radius: 11px; background: var(--surface-2); cursor: pointer; text-align: center; transition: border-color .12s, transform .12s; }
.tpl-card:hover { border-color: var(--border-2); transform: translateY(-1px); }
.tpl-card.tpl-active { border-color: var(--tpl-accent); box-shadow: 0 0 0 1px var(--tpl-accent); }
.tpl-thumb { position: relative; display: block; height: 58px; border-radius: 7px; overflow: hidden;
  padding: 6px; box-sizing: border-box; }
.tpl-thumb-head { display: flex; align-items: center; height: 12px; border-radius: 3px; margin-bottom: 6px; padding: 0 4px; }
.tpl-thumb-dot { width: 5px; height: 5px; border-radius: 50%; background: var(--tpl-accent); display: inline-block; }
.tpl-thumb-line { display: block; height: 5px; border-radius: 3px; margin: 4px 0; width: 80%; opacity: .9; }
.tpl-thumb-line--sm { width: 55%; opacity: .7; }
.tpl-thumb-pill { position: absolute; right: 6px; bottom: 6px; width: 22px; height: 8px; border-radius: 999px;
  border: 1px solid var(--tpl-accent); }
/* Thumbnail deutet den Hintergrund-Stil an (PIN-210): Akzent-Wash je bg_style. */
.tpl-thumb[data-bgstyle="gradient"]::after,
.tpl-thumb[data-bgstyle="radial"]::after { content: ''; position: absolute; inset: 0; pointer-events: none; }
.tpl-thumb[data-bgstyle="gradient"]::after { background: linear-gradient(180deg, var(--tpl-accent), transparent 62%); opacity: .20; }
.tpl-thumb[data-bgstyle="radial"]::after { background: radial-gradient(60% 55% at 50% -5%, var(--tpl-accent), transparent 70%); opacity: .28; }
.tpl-name { font-size: 11.5px; font-weight: 600; color: var(--text-2); }
.tpl-card.tpl-active .tpl-name { color: var(--tpl-accent); }
@media (max-width: 560px) { .tpl-grid { grid-template-columns: repeat(2, 1fr); } }

/* ═════ REPORT-KAPITEL-BAUKASTEN (PIN-376; seit PIN-406 im eigenen Dialog
   #modal-repsec, aufgerufen aus der Karte „White-Label-Report") ═══════════ */
.repsec-grid {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 4px 14px; margin-top: 10px;
}
/* flex-direction + margin-bottom MÜSSEN hier stehen: die globale Regel
   `label { display:flex; flex-direction:column; margin-bottom:14px }` (Z.1176)
   greift sonst durch und stellt den Haken ÜBER den Text, mit 14px Luft je
   Zeile. Das war seit PIN-376 so (im alten Editor-Ort genauso), fiel dort nur
   niemandem auf. Gefunden per Sichtprüfung 19.07. */
.repsec-item {
  display: flex; flex-direction: row; align-items: center; gap: 7px;
  font-size: .8rem; cursor: pointer; padding: 2px 0; margin-bottom: 0;
}
.repsec-item input[type="checkbox"] { margin: 0; flex: none; }
.repsec-previewhint { margin-top: 14px; }
@media (max-width: 560px) {
  /* Einspaltig, aber mit gedeckelter Höhe: 14 Kapitel untereinander machen den
     Dialog sonst ~717px hoch, die Fußzeile rutscht damit unter die fixierten
     Overlays (Feedback-Blasen z-index 100, ⌘K-Hinweis z-index 50 — beide liegen
     über JEDEM Dialog, der nur z-index 30 hat). Gedeckelt endet die Fußzeile
     wieder oberhalb davon, wie beim Bestands-Dialog. Gemessen 19.07. */
  .repsec-grid { grid-template-columns: 1fr; max-height: 28vh; overflow-y: auto; }
}

/* ═════ REDUCED MOTION — GLOBALES BLANKET (Paket 2 Craft) ═════════════════
   Ersetzt NICHT die punktuellen Guards weiter oben (die korrigieren teils
   End-Zustände, z. B. pm-logo Z. 2183) — es dichtet alles Übrige ab, inkl.
   Inline-Styles (FLIP/Glide/Toast), weil !important im Stylesheet Inline-
   Styles schlägt. 0.01ms statt none: animationend/transitionend feuern
   weiter. Gilt auf ALLEN Seiten, die style.css laden (Dashboard, Settings,
   Agentur-Demo, Login, Invite, Reset). ::view-transition-*-Pseudos erfasst
   der *-Selektor NICHT → eigener Guard in redesign.css Sektion 21. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    transition-delay: 0s !important;
    scroll-behavior: auto !important;
  }
}

/* ── Startzustand (PIN-349) ─────────────────────────────────────────────
   Eine ruhige Begrüßungskarte statt Checkliste + Muster-Kacheln. Bewusst
   flach: kein Fortschrittsbalken, keine Animation, keine Emojis an den
   Bedienelementen. Bleibt im Container-Fluss über dem Karten-Grid. */
.start-state {
  position: relative;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg, 14px);
  padding: 22px 24px;
  margin-bottom: 22px;
  box-shadow: var(--shadow-card, 0 1px 3px rgba(0,0,0,.3));
}
.start-state.hidden { display: none; }
.st-title { font-size: 19px; font-weight: 700; margin: 0 0 4px; color: var(--text); }
.st-sub   { font-size: 14px; color: var(--text-2); margin: 0; line-height: 1.55; }
.st-sub:empty { display: none; }
.st-dismiss {
  position: absolute; top: 14px; right: 14px;
  background: none; border: none; color: var(--text-muted);
  font-size: 12px; cursor: pointer; padding: 4px 8px; border-radius: 6px;
  font-family: inherit;
}
.st-dismiss:hover { color: var(--text); background: var(--surface-2); }
/* Eigene Klasse + explizites flex-direction:row — die globale label-Regel
   (style.css „label { display:flex; flex-direction:column }") greift hier zwar
   nicht (kein <label>), die Richtung steht trotzdem bewusst da. */
.st-actions { display: flex; flex-direction: row; flex-wrap: wrap; gap: 10px; margin-top: 16px; }
.st-actions:empty { display: none; }
.st-actions .hidden { display: none; }
.st-actions button { width: auto; padding: 9px 18px; }
@media (max-width: 600px) {
  .st-actions { flex-direction: column; align-items: stretch; }
}

/* Runde 3, Dario-Abnahme: Zeilen, die es im Konto schon gibt. Sichtbar
   zurückgenommen, aber NICHT gesperrt — zwei Monitore auf derselben URL sind ein
   echter Fall (Erreichbarkeit und Schlüsselwort getrennt), nur eben keiner, den
   man aus Versehen anlegt. */
.imp-rel-row.ist-dublette { opacity: .62; }
.imp-rel-row.ist-dublette:hover { opacity: 1; }
.imp-chip.schon-da { color: var(--yellow); border-color: var(--yellow); background: transparent; }

/* ══ Wartungs-Ebene, Runde B: die Bausteine ═══════════════════════════════════
   Vorlage ist das Cowork-Paket vom 25.07. (Wartung-Uebergabe-ClaudeCode).
   Arbeitsteilung wie beim Import: hier steht NUR, wie die Bausteine aussehen.
   Raster, Scroll-Kette und Ebenenform stehen in redesign.css, Sektion 20c.

   🚨 Maße und Radien kommen aus dem Mockup, FARBEN aus den Tokens. Das Mockup ist
   gegen die alte Palette gezeichnet (#0a0a0a/#161616/#2ea866), tatsächlich gelten
   die redesign.css-Werte — und ein Hex hätte im Hellmodus überhaupt keinen
   Gegenwert. Deshalb --surface/--border/--green statt --s1/--line/--acc.

   Präfix .wtg-, per grep über static/, tests/ und scripts/ als frei geprüft.
   .maint- war halb belegt (.maint-client-chip, .maint-row) und schied aus.
   Wiederverwendet statt neu gebaut: .imp-bar (Streifen), .imp-map (Panel),
   .imp-rel-row (Zeile), .imp-zeile/.imp-zeile-sub (Zeile mit Unterzeile),
   .imp-chip.angepasst (gelber Chip), .imp-hint (Kasten), .imp-cnt (Zähler),
   .form-actions (Fußleiste), .disc-head/.disc-panel/.disc-field (linke Spalte). */

/* ── Zeitraum: zwei Zeilen Von/Bis, Raster 34px | 1fr ── */
.wtg-dt-row { display: grid; grid-template-columns: 34px minmax(0, 1fr); align-items: center; gap: 10px; }
.wtg-dt-row + .wtg-dt-row { margin-top: 8px; }
.wtg-dt-k { font-size: 11.5px; font-weight: 600; color: var(--text-2); }
/* Eigene Höhe statt .search-input: das Mockup gibt 38px und den kräftigeren Rand
   vor, weil die beiden Felder allein in ihrem Block stehen. tabular-nums, damit
   Von und Bis stellengenau untereinander stehen. */
.wtg-dt {
  width: 100%; height: 38px; box-sizing: border-box;
  padding: 0 11px 0 12px;
  border: 1px solid var(--border-2); border-radius: 8px;
  background: var(--surface-2); color: var(--text);
  font: inherit; font-size: 13px; font-variant-numeric: tabular-nums;
}
.wtg-dt:focus { outline: none; border-color: var(--green); }
/* Das Kalendersymbol des Browsers ist im Dunkelmodus schwarz auf dunkel und damit
   unsichtbar. invert dreht es, ohne eine eigene Grafik einzuführen. */
body:not(.light) .wtg-dt::-webkit-calendar-picker-indicator { filter: invert(.75); }
.wtg-meta {
  display: flex; align-items: center; flex-wrap: wrap; gap: 7px;
  margin: 10px 0 0;
  font-size: 11px; line-height: 1.5; color: var(--text-2);
  font-variant-numeric: tabular-nums;
}
.wtg-meta .dot { color: var(--text-muted); }
/* Der Zeitraum stimmt nicht: gelb wie jeder andere Hinweis im Haus, nicht rot —
   ein Fenster in der Vergangenheit ist erlaubt, nur meist nicht gemeint. */
.wtg-meta.warn { color: var(--yellow); }
.wtg-meta.bad { color: var(--red); }

/* ── Notiz: mehrzeilig, Höhe 58 wie in der Vorlage ── */
.wtg-tx {
  width: 100%; box-sizing: border-box;
  height: 58px; min-height: 58px; resize: vertical;
  padding: 9px 12px;
  border: 1px solid var(--border); border-radius: 8px;
  background: var(--surface-2); color: var(--text);
  font: inherit; font-size: 12.5px; line-height: 1.5;
}
.wtg-tx:focus { outline: none; border-color: var(--green); }
.wtg-fld-gap { margin-top: 12px; }

/* ── Kästchenzeile + Hinweise im Einrichtpanel ──
   🚨 flex-direction:row EXPLIZIT: die globale Regel
   `label { display:flex; flex-direction:column; margin-bottom:14px }` würde die
   Zeile sonst stapeln. Derselbe Fallstrick wie bei .imp-rel-row und .label-check. */
.wtg-cbline {
  display: flex; flex-direction: row; align-items: flex-start; gap: 9px;
  margin-bottom: 0; cursor: pointer;
  font-size: 12px; font-weight: normal; line-height: 1.45; color: var(--text-2);
}
.wtg-cbline input { flex: 0 0 auto; margin: 1px 0 0; padding: 0; cursor: pointer; }
.wtg-subhint { margin: 7px 0 0 26px; font-size: 11px; line-height: 1.45; color: var(--yellow); }
.wtg-subhint.hidden { display: none; }
.wtg-hint {
  margin: 13px 0 0;
  font-size: 11.5px; line-height: 1.5; color: var(--text-2);
}
/* Bearbeiten-Streifen über dem Panel. Gelbe Kante: es ist ein Zustand, in dem der
   Hauptknopf etwas anderes tut als sonst. */
.wtg-edit {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin-bottom: 12px; padding: 8px 11px;
  border: 0; border-left: 2px solid var(--yellow); border-radius: 0 6px 6px 0;
  background: color-mix(in srgb, var(--yellow) 7%, transparent);
  font-size: 11.5px; line-height: 1.45; color: var(--text-2);
}
.wtg-edit.hidden { display: none; }
.wtg-edit #maint-edit-cancel { margin-left: auto; flex: 0 0 auto; }

/* ── Textlink im Ebenen-Stil ──
   Wie .imp-grp-toggle ein <button>, der aussieht wie ein Link: er führt nirgendwo
   hin. Ohne background/border käme im Dunkelmodus die weiße Standardfläche durch. */
.wtg-lnk {
  background: none; border: 0; padding: 0;
  font: inherit; font-size: 11.5px; font-weight: 500;
  color: var(--green-text); cursor: pointer; white-space: nowrap;
}
.wtg-lnk:hover { text-decoration: underline; text-underline-offset: 2px; }
.wtg-lnk:focus-visible { outline: 2px solid var(--green); outline-offset: 2px; border-radius: 3px; }
.wtg-lnk.dim { color: var(--text-2); }
.wtg-lnk.dim:hover { color: var(--text); }

/* ── Streifen „3 Fenster geplant, eines läuft gerade" ──
   Erbt Fläche, Rahmen und Radius von .imp-bar, bringt nur die eigene Zeile mit. */
.wtg-bar.hidden { display: none; }
.wtg-bar-zeile { display: flex; align-items: center; gap: 10px; min-height: 36px; }
.wtg-bar-t { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wtg-bar-t b { color: var(--text); font-weight: 600; }
.wtg-bar-zeile .wtg-lnk { flex: 0 0 auto; }

/* ── Panel „Geplante Fenster" ── */
.wtg-win-panel.hidden { display: none; }
.wtg-win {
  display: flex; align-items: center; gap: 12px;
  min-height: 40px; padding: 6px 12px;
  border: 1px solid var(--border); border-radius: 8px; background: var(--surface-2);
}
.wtg-win + .wtg-win { margin-top: 6px; }
/* Ein laufendes Fenster: grüne Kante und grüner Grund wie eine ausgewählte Zeile.
   🚨 Der Punkt daneben ist BLAU und eine Raute, nicht grün und rund — im Haus ist
   „Wartung/geplant" seit dem Redesign genau das (redesign.css, .dot-maintenance),
   und Status wird nie allein über Farbe gesagt (WCAG 1.4.1). */
.wtg-win.live {
  border-color: color-mix(in srgb, var(--green) 48%, transparent);
  background: color-mix(in srgb, var(--green) 5.5%, transparent);
}
.wtg-win-dot {
  flex: 0 0 8px; width: 8px; height: 8px;
  background: var(--border-2);
  clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%);
}
.wtg-win.live .wtg-win-dot { background: var(--blue); }
.wtg-win-t { flex: 0 0 auto; max-width: 34%; font-size: 12.5px; font-weight: 600; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wtg-win-w { flex: 1 1 auto; min-width: 0; font-size: 12px; color: var(--text-2); font-variant-numeric: tabular-nums; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wtg-win-n { flex: 0 0 auto; font-size: 11.5px; color: var(--text-muted); font-variant-numeric: tabular-nums; }
.wtg-win-a { flex: 0 0 auto; display: flex; gap: 11px; }
.wtg-win-leer { margin: 0; font-size: 12px; color: var(--text-2); }

/* ── Listenkopf: Suchfeld links, Umschalter und Zähler rechts ── */
.wtg-head { display: flex; align-items: center; gap: 12px; margin-bottom: 8px; }
.wtg-spacer { flex: 1 1 auto; }
.wtg-head #maint-selectall,
.wtg-head .imp-cnt { flex: 0 0 auto; }
.wtg-srch {
  position: relative; display: flex; align-items: center;
  flex: 0 0 250px; max-width: 250px;
}
.wtg-srch svg { position: absolute; left: 10px; width: 14px; height: 14px; color: var(--text-muted); pointer-events: none; }
.wtg-srch input {
  width: 100%; box-sizing: border-box; height: 32px;
  padding: 0 10px 0 30px;
  border: 1px solid var(--border); border-radius: 8px;
  background: var(--surface-2); color: var(--text);
  font: inherit; font-size: 12.5px;
}
.wtg-srch input:focus { outline: none; border-color: var(--green); }
.wtg-srch input::placeholder { color: var(--text-muted); }

/* ── Zeile „Alle Monitore, auch künftige" ──
   Steht fest über der Liste, damit sie bei 128 Zeilen nicht wegscrollt. Fläche
   eine Stufe tiefer als die Zeilen darunter, wie .imp-bar: sie gehört zum Kopf. */
.wtg-alle {
  display: flex; flex-direction: row; align-items: center; gap: 12px;
  flex: 0 0 auto; margin-bottom: 8px;
  height: 38px; padding: 0 13px;
  border: 1px solid var(--border); border-radius: 8px; background: var(--bg);
  cursor: pointer; transition: border-color .12s, background .12s;
}
.wtg-alle:hover { border-color: var(--green); }
.wtg-alle:has(#maint-all:checked) {
  border-color: color-mix(in srgb, var(--green) 48%, transparent);
  background: color-mix(in srgb, var(--green) 5.5%, transparent);
}
.wtg-alle-t { font-size: 12.5px; font-weight: 600; color: var(--text); }

/* Still gestellter Hauptknopf in der Fußleiste, wortgleich zu Finden und Import:
   `opacity:.35` allein (style.css:321) lässt das Grün durch und sieht nach
   „lädt gerade" aus statt nach „geht gerade nicht". */
.modal-box-maint .form-actions .btn-primary:disabled {
  opacity: 1; background: var(--surface-3); border-color: var(--border-2);
  color: var(--text-muted); box-shadow: none; cursor: not-allowed;
}
/* Schmaler Balken im einzigen Scrollbereich (wie .disc-scroll und .imp-rel-list). */
.wtg-list::-webkit-scrollbar,
#maint-eplist::-webkit-scrollbar { width: 8px; }
#maint-eplist::-webkit-scrollbar-track { background: transparent; }
#maint-eplist::-webkit-scrollbar-thumb { background: var(--border-2); border-radius: 99px; }

/* ── Die Endpunktliste ── */
.wtg-picker { display: flex; flex-direction: column; min-height: 0; }
.wtg-list { display: flex; flex-direction: column; gap: 6px; }
/* Gruppenkopf in Versalien, Maße aus der Vorlage. Erste Gruppe ohne den oberen
   Abstand, sonst klafft über der Liste eine Lücke. */
.wtg-ghd {
  display: flex; align-items: baseline; gap: 6px;
  padding: 15px 2px 8px;
  font-size: 10.5px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase;
  color: var(--text-muted);
}
.wtg-ghd:first-child { padding-top: 2px; }
.wtg-ghd .wtg-ghd-n { color: var(--border-2); }
.wtg-ghd .wtg-lnk { margin-left: auto; text-transform: none; letter-spacing: 0; }
/* Die Zeilen sind die bekannten .imp-rel-row (43px). Nur der Rest der Zeile ist
   hier anders: rechts steht höchstens der Überschneidungs-Chip, sonst nichts —
   bei 128 Zeilen ist jede weitere Angabe Rauschen (Spezifikation Abschnitt 4). */
.wtg-list .imp-rel-rt { flex: 0 0 auto; display: flex; align-items: center; gap: 8px; margin-left: auto; }
.wtg-list .imp-chip { border-radius: 5px; padding: 2px 8px; font-size: 10.5px; }
.wtg-leer { margin: 18px 2px; font-size: 12.5px; color: var(--text-2); }

/* ── Hellmodus ──
   Weil oben durchgehend Tokens stehen, fällt er fast überall von selbst richtig
   aus. Übrig bleiben die zwei Flächen, die im Dunkeln bewusst eine Stufe TIEFER
   liegen (--bg): auf dem hellen Papier ist --bg dunkler als --surface, der
   Streifen läge also plötzlich oben statt unten. */
body.light .wtg-bar,
body.light .wtg-alle { background: color-mix(in srgb, var(--surface) 45%, var(--bg)); }
body.light .wtg-win-dot { background: var(--border-2); }
body.light .wtg-win.live .wtg-win-dot { background: var(--blue); }

/* Breite und Titelgröße wie bei den anderen beiden Ebenen. Kompound-Selektor beim
   h2 ist PFLICHT: `.modal-box h2 { font-size:15px; margin-bottom:20px }` steht
   später und gewänne bei gleicher Spezifität. */
.modal-box.modal-box-maint { max-width: 720px; }
.modal-box-maint .disc-head h2 { font-size: 20px; margin: 0 0 7px; letter-spacing: -.02em; }
/* Das Einrichtpanel ist mit Zeitraum, Sofort-Knöpfen, Reichweite, Titel, Notiz,
   Haken und Kasten voll. Dieselbe Kur wie beim Import: die Trennlinien rücken
   zusammen, damit die Spalte bei 900px Fensterhöhe ohne eigenen Scrollbalken
   auskommt.
   🚨 Gemessen am 04.08.2026 bei 1440x900, nicht geschätzt: deutsch 756 von 756
   Pixeln, also exakt bündig. ENGLISCH lief um 6 Pixel über, weil der Hinweiskasten
   dort drei statt zwei Zeilen braucht — und damit hatte die Ebene zwei
   Scrollbereiche statt einem. Drei Trennlinien mal 4 Pixel weniger geben die
   nötige Luft. Wer hier weiter zusammenrückt, misst vorher nach, und zwar in
   BEIDEN Sprachen: die deutsche allein hätte den Fehler nie gezeigt. */
#modal-maintenance .disc-panel-div { margin: 10px -16px; }

/* ── Schmal (gemessen bei 390px, 03.08.2026) ──
   Die Zeile eines geplanten Fensters traegt sechs Dinge nebeneinander: Punkt,
   Titel, Zeitraum, Anzahl und bis zu drei Links. Bei 390px lief sie 55 Pixel
   ueber den Rand hinaus, und der Zeitraum wurde auf ein „h" zusammengestaucht.
   Also umbrechen statt stauchen: Titel oben, Zeitraum in eigener Zeile darunter,
   Anzahl und Links zuletzt. Kein Weglassen, der Zeitraum ist die Kernangabe. */
@media (max-width: 760px) {
  .wtg-win { flex-wrap: wrap; row-gap: 7px; min-height: 0; padding: 10px 12px; }
  .wtg-win-dot { order: 1; }
  .wtg-win-t { order: 2; flex: 1 1 auto; max-width: none; }
  .wtg-win-w { order: 3; flex: 1 1 100%; white-space: normal; }
  .wtg-win-n { order: 4; }
  .wtg-win-a { order: 5; margin-left: auto; }
}

/* Ist „Alle Monitore, auch künftige" gesetzt, ist die Einzelauswahl gegenstandslos.
   Sichtbar abschalten statt nur `disabled` setzen: ein Klick ohne Wirkung ist
   schlimmer als ein erkennbar stillgelegter Bereich. Die Überschneidungs-Chips
   bleiben dabei lesbar, denn bei kontoweiter Wartung zählen sie erst recht. */
.wtg-picker.alle-an .wtg-ghd,
.wtg-picker.alle-an .wtg-list { opacity: .42; pointer-events: none; }
.wtg-srch input:disabled { opacity: .5; cursor: not-allowed; }

/* ── Zwei geerbte Import-Regeln, die hier schaden ──
   1. `.imp-rel-row:not(.ist-fehler):not(.ist-dublette) .imp-rel-rt` (style.css:1646)
      hat Spezifität (0,3,0) und macht aus der rechten Zelle ein Raster
      68|66|80. Die Import-Zeile trägt dort DREI Sachen, die Wartungs-Zeile
      trägt höchstens EINE: der Chip „überschneidet sich" landete in der 68er
      Spalte und lief aus seiner Pille heraus, dazu blieben 226 Pixel rechts
      dauerhaft reserviert. Die ID hebt die Spezifität auf (1,2,0).
   2. Bei 640px blendet der Import `.imp-chip.angepasst` aus, weil dort drei
      Elemente um 366 Pixel streiten. Hier ist der Chip der einzige, und die
      Zeile hat Platz. Also wieder einschalten. */
#maint-eplist .imp-rel-row .imp-rel-rt {
  display: flex; align-items: center; justify-content: flex-end;
  grid-template-columns: none; margin-left: auto; flex: 0 0 auto; gap: 8px;
}
@media (max-width: 640px) {
  #maint-eplist .imp-chip.angepasst { display: inline-block; }
}

/* Die Felder der linken Spalte füllen das Panel. `.search-input` bringt
   `width: 240px` mit (style.css:2212) — im alten Pop-up stand deshalb überall
   `style="width:100%"` daneben. Das gehört in die Stilvorlage, nicht ins Markup.
   Ohne das standen Reichweite und Titel 240 Pixel breit neben einer 292 Pixel
   breiten Notiz. */
.wtg-left .disc-field .search-input { width: 100%; box-sizing: border-box; }

/* Der Listenkopf darf umbrechen. Zwischen 1100 und rund 1300 Pixeln passen
   Suchfeld (250), Knopf und Zähler nicht nebeneinander, und alle drei sind
   ausdrücklich unschrumpfbar: der Zähler wurde vom Rand der Spalte
   abgeschnitten. */
.wtg-head { flex-wrap: wrap; row-gap: 8px; }

/* Ein Kästchen-Muster je Bildschirm: der Haken „Abonnenten informieren" trägt
   jetzt dieselbe Bauart wie die Zeilen der Liste (.imp-rel-cb), statt daneben
   als nacktes Browser-Kästchen zu stehen. */
.wtg-cbline .imp-rel-cb { width: 17px; height: 17px; flex: 0 0 17px; margin-top: 1px; }

/* Niedrige Fenster: dieselbe Kur wie beim Import (style.css:1607). Ohne sie
   läuft die linke Spalte über und das Notventil `overflow-y:auto` macht einen
   zweiten Scrollbalken auf, obwohl die Ebene genau EINEN haben soll. */
@media (min-width: 1101px) and (max-height: 899px) {
  body.maint-page-open #modal-maintenance .disc-panel-div { margin: 8px -16px; }
  body.maint-page-open #modal-maintenance .wtg-tx { height: 46px; min-height: 46px; }
  body.maint-page-open #modal-maintenance .disc-head { margin-bottom: 14px; }
  body.maint-page-open #modal-maintenance .wtg-hint { margin-top: 10px; }
}

/* Sofort-Wartung (Dario, 04.08.2026). Die drei Knöpfe sitzen unter der Meta-Zeile
   und füllen nur Von und Bis. Bewusst klein und zurückgenommen: sie sind eine
   Abkürzung, nicht die Hauptsache. Form wie .imp-bdg, damit kein viertes
   Knopf-Muster auf den Bildschirm kommt. */
.wtg-jetzt { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; margin-top: 9px; }
.wtg-jetzt-k { font-size: 11px; color: var(--text-2); margin-right: 2px; }
.wtg-jetzt-b {
  flex: 0 0 auto; padding: 3px 9px;
  border: 1px solid var(--border-2); border-radius: 5px; background: var(--surface-2);
  font: inherit; font-size: 11px; font-weight: 500; color: var(--text-2);
  font-variant-numeric: tabular-nums; cursor: pointer;
  transition: border-color .12s, color .12s;
}
.wtg-jetzt-b:hover { border-color: var(--green); color: var(--text); }
.wtg-jetzt-b:focus-visible { outline: 2px solid var(--green); outline-offset: 2px; }
