/* ═══════════════════════════════════════════════════════════════
   hub-base.css – Basis-Schicht der Plattform-Stylesheets
   Genutzt von: ALLEN Plattform-Seiten
                login.php · dashboard.php · profile.php · admin/*.php

   DREI-DATEI-ARCHITEKTUR:
   Die Plattform-UI verteilt sich auf drei Stylesheets:
     hub-base.css   – Tokens + Reset + bereichsagnostische Komponenten
                      (diese Datei). Auf ALLEN Seiten geladen.
     hub-user.css   – Login-, Dashboard- und Profil-spezifische Stile.
                      Auf User- UND Admin-Seiten geladen.
     hub-admin.css  – ausschließlich Admin-Bereich.

   LADE-REIHENFOLGE (zwingend):
     1. hub-base.css
     2. hub-user.css
     3. hub-admin.css   (nur Admin-Seiten)
     4. der branding_css()-<style>-Block  (nach ALLEN <link>-Tags)

   ARCHITEKTUR – DREI TOKEN-SCHICHTEN:
   1. Primitive Tokens   – rohe Farbwerte, NIE direkt in Komponenten
   2. Semantische Tokens – Bedeutung, HIER greifen Komponenten zu;
                           branding_css() überschreibt NUR diese Schicht
   3. Komponenten/Layout – nutzen ausschließlich semantische Tokens

   SEKTIONSÜBERSICHT (diese Datei):
   1.  Primitive Tokens
   2.  Semantische Tokens
       2a. Globale semantische Tokens
       2b. Admin-spezifische Tokens (scoped auf body.page-admin)
       2c. Branding-Override-Ziel (body.page-hub/login/admin)
       2d. Rückwärtskompatibilitäts-Aliase
   3.  Reset & Base
   4.  Komponenten – bereichsagnostisch
       4.1  Footer
       4.2  Header
       4.3  Formulare (allgemein)
       4.4  Buttons (allgemein)
       4.5  Alerts & Badges
       4.6  Passwort-Stärke-Anzeige
       4.7  iFrame-Overlay (Dashboard)
       4.8  Hilfsklassen
       4.9  Schlüsseldatei-/Geräte-Tabelle
       4.10 Nachrichten-Links & Link-Auswahl
   ═══════════════════════════════════════════════════════════════ */


/* ═══════════════════════════════════════════════════════════════
   1. PRIMITIVE TOKENS
   Rohe Farbwerte und unveränderliche Größen ohne semantische
   Bedeutung. Diese Werte dürfen NIEMALS direkt in Komponenten
   oder Layouts referenziert werden – immer über semantische
   Tokens aus Schicht 2 indirekt ansprechen.
   ═══════════════════════════════════════════════════════════════ */
:root {
  /* Blau-Palette */
  --_blue-50:    #eef2ff;
  --_blue-100:   #dbeafe;
  --_blue-200:   #bfdbfe;
  --_blue-300:   #93c5fd;
  --_blue-500:   #1455C0;
  --_blue-600:   #0f44a8;
  --_blue-700:   #1e40af;
  --_blue-900:   #1e3a8a;

  /* Rot-Palette */
  --_red-50:     #fee2e2;
  --_red-100:    #fca5a5;
  --_red-500:    #FF0000;
  --_red-600:    #d60000;
  --_red-700:    #dc2626;
  --_red-800:    #991b1b;
  --_red-900:    #7f1d1d;

  /* Grün-Palette */
  --_green-50:   #dcfce7;
  --_green-100:  #f0fdf4;
  --_green-200:  #86efac;
  --_green-500:  #10b981;
  --_green-800:  #166534;

  /* Gelb/Orange-Palette */
  --_yellow-50:  #fef9c3;
  --_yellow-200: #fbbf24;
  --_yellow-500: #f97316;
  --_yellow-600: #ffedd5;
  --_yellow-700: #fff7ed;
  --_yellow-800: #92400e;
  --_yellow-900: #854d0e;

  /* Neutral-Palette */
  --_neutral-0:   #ffffff;
  --_neutral-50:  #F7F7F9;
  --_neutral-100: #f3f4f6;
  --_neutral-200: #e1e4ec;
  --_neutral-300: #cfd3df;
  --_neutral-400: #9ca3af;
  --_neutral-500: #4a5568;
  --_neutral-600: #374151;
  --_neutral-800: #1f2937;
  --_neutral-900: #333333;

  /* Sonderwerte */
  --_black:      0, 0, 0;    /* RGB-Kanäle für rgba()-Schatten */
  --_footer-bg:  #111827;
  --_footer-text:#e5e7eb;
}


/* ═══════════════════════════════════════════════════════════════
   2. SEMANTISCHE TOKENS
   ═══════════════════════════════════════════════════════════════ */

/* ── 2a. Globale semantische Tokens ─────────────────────────────
   Alle Komponenten (Schicht 3) greifen ausschließlich auf diese
   Variablen zu – niemals auf Primitives aus Schicht 1.
   ─────────────────────────────────────────────────────────────── */
:root {
  /* Brand-Farben */
  --color-brand:        var(--_blue-500);   /* Primärfarbe: Links, Buttons, Akzente */
  --color-brand-dark:   var(--_blue-600);   /* Hover auf brand */
  --color-brand-subtle: var(--_blue-50);    /* Sehr heller Brand-Hintergrund */
  --color-brand-light:  var(--_blue-100);   /* Heller Brand-Hintergrund */
  --color-brand-border: var(--_blue-300);   /* Brand-Rahmen */
  --color-brand-muted:  var(--_blue-200);   /* Gedämpfter Brand-Ton */

  /* Aktion / CTA */
  --color-action:       var(--_red-500);    /* Primäre CTA-Farbe (Login-Button) */
  --color-action-dark:  var(--_red-600);    /* Hover auf action */

  /* Gefahr / Destruktive Aktionen */
  --color-danger:       var(--_red-700);    /* Destruktive Buttons (Löschen, Sperren) */
  --color-danger-dark:  var(--_red-800);    /* Hover auf danger */
  --color-danger-subtle: var(--_red-50);    /* Sehr heller Danger-Hintergrund */
  --color-danger-light:  var(--_red-100);   /* Heller Danger-Hintergrund */
  
  /* Text */
  --color-text-primary:   var(--_neutral-900); /* Fließtext */
  --color-text-secondary: var(--_neutral-500); /* Untertitel, Hinweistexte */
  --color-text-label:     var(--_neutral-600); /* Formular-Labels */
  --color-text-hint:      var(--_neutral-400); /* Platzhalter, deaktiviert */
  --color-text-heading:   var(--_neutral-800); /* Überschriften */

  /* Oberflächen */
  --color-surface:      var(--_neutral-0);    /* Weiße Karten, Formulare */
  --color-bg:           var(--_neutral-50);   /* Seitenhintergrund */
  --color-bg-subtle:    var(--_neutral-100);  /* Tabellen-Header, Readonly */

  /* Rahmen */
  --color-border:        var(--_neutral-200); /* Standard-Rahmen */
  --color-border-strong: var(--_neutral-300); /* Stärkerer Rahmen (Inputs) */

  /* Status: Erfolg */
  --color-ok-bg:        var(--_green-50);   /* Alert-Hintergrund */
  --color-ok-bg-subtle: var(--_green-100);  /* Mitglieder-Tag-Hintergrund */
  --color-ok-border:    var(--_green-200);  /* Alert-Rahmen, Hover-Ton */
  --color-ok:           var(--_green-500);  /* Icon-Farbe */
  --color-ok-text:      var(--_green-800);  /* Text auf ok-Hintergründen */

  /* Status: Warnung */
  --color-warn-bg:       var(--_yellow-50);  /* Alert-Hintergrund */
  --color-warn-border:   var(--_yellow-200); /* Alert-Rahmen */
  --color-warn:          var(--_yellow-500); /* Icon, CLI-Rahmen */
  --color-warn-text:     var(--_yellow-900); /* Text auf warn-Hintergrund */
  --color-warn-deep:     var(--_yellow-800); /* Überschriften in warn-Bereichen */
  --color-warn-bg-mid:   var(--_yellow-700); /* CLI-Toggle-Hintergrund */
  --color-warn-bg-light: var(--_yellow-600); /* CLI-Toggle-Hover */

  /* Status: Fehler */
  --color-err-bg:     var(--_red-50);   /* Alert-Hintergrund */
  --color-err-border: var(--_red-100);  /* Alert-Rahmen */
  --color-err:        var(--_red-700);  /* Icon, Rahmen */
  --color-err-text:   var(--_red-900);  /* Textfarbe */
  --color-err-mid:    var(--_red-800);  /* Löschen-Button, Lockout-Banner */

  /* Schatten */
  --shadow-sm:      rgba(var(--_black), 0.06); /* Leichter Shadow */
  --shadow-md:      rgba(var(--_black), 0.08); /* Login-Card */
  --shadow-lg:      rgba(var(--_black), 0.09); /* Service-Tile Hover */
  --shadow-overlay: rgba(var(--_black), 0.50); /* Modal-Overlay */

  /* Schriften */
  --font-base: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --font-mono: monospace; /* CLI-Code, Eingaben für Hex-Werte */

  /* Layout */
  --max-width:   1100px;
  --radius-sm:   6px;
  --radius-md:   10px;
  --radius-lg:   12px;
  --radius-xl:   14px;
  --radius-pill: 999px;

  /* Footer */
  --color-footer-bg:   var(--_footer-bg);
  --color-footer-text: var(--_footer-text);

  /* Split-View: Breite der linken Spalte in Split-Layouts */
  --split-list-width: 260px;

  /* Dashboard-Service-Kacheln: Grundgröße und davon abgeleiteter Mindest-Gap.
     Der Gap skaliert mit der Kachelgröße – bei kleineren Kacheln (geplante
     Ausbaustufe M/S) bleibt das Verhältnis 12:1 zwischen Kachel und Gap. */
  --tile-size:    240px;
  --tile-min-gap: calc(var(--tile-size) / 12);

  /* Gradient für alle Plattform-Header */
  --gradient-header: linear-gradient(135deg, #ffffff 0%, #e8eefb 40%, #fdfdfd 100%);
  
  /* Blau-Akzent-Tokens (vormals 2b, body.page-admin).
     Global, weil die bereichsagnostische base-Komponente .btn-edit
     (Sektion 4.4) sie referenziert und auch im User-Frontend gerendert
     wird. Token und nutzende Komponente müssen in derselben Schicht
     verfügbar sein – andernfalls fallen die Werte auf User-Seiten
     (body.page-hub, ohne page-admin) ins Leere. */
  --color-blue-deep:    var(--_blue-700);   /* Tags, btn-edit Text */
  --color-blue-light:   var(--_blue-100);   /* Tag-Hintergrund, btn-edit BG */
  --color-blue-border:  var(--_blue-300);   /* Tag-Rahmen, btn-edit Hover-BG */
  --color-blue-lighter: var(--_blue-200);   /* Rollen-Tag Hover */
}

/* ── 2b. Admin-spezifische Tokens (scoped) ──────────────────────
   Ergänzen die globalen semantischen Tokens um Farbnuancen die
   ausschließlich im Admin-Bereich benötigt werden.
   Scoped auf body.page-admin.

   Die hier verbliebenen Tokens werden ausschließlich von Komponenten
   in hub-admin.css konsumiert (z.B. .member-tag, .cli-*, .code-display),
   die nur auf Admin-Seiten geladen werden – ihr page-admin-Scope ist
   daher korrekt. Die blau-Akzent-Tokens (--color-blue-*) sind dagegen
   nach 2a (global) gewandert, weil die base-Komponente .btn-edit sie
   auch im User-Frontend referenziert.
   ─────────────────────────────────────────────────────────────── */
body.page-admin {
  --color-red-mid:      var(--_red-800);    /* Löschen-Button, Lockout-Banner */
  --color-green-bg:     var(--_green-50);   /* Entsperren-Button Hintergrund */
  --color-member-bg:    var(--_green-100);  /* Mitglieder-Tag Hintergrund */
  --color-member-border:var(--_green-200);  /* Mitglieder-Tag Rahmen */
  --color-yellow-deep:  var(--_yellow-800); /* CLI-Hilfe Überschriften */
  --color-orange:       var(--_yellow-500); /* CLI-Hilfe Rahmen */
  --color-orange-bg:    var(--_yellow-700); /* CLI-Hilfe Toggle Hintergrund */
  --color-orange-light: var(--_yellow-600); /* CLI-Hilfe Toggle Hover */
  --color-code-text:    var(--_green-200);  /* CLI-Code-Block Schriftfarbe */
  --max-width:          1280px;             /* Standardbreite des Arbeitsbereichs für den admin-Bereich */
}

/* ── 2c. Branding-Override-Ziel ─────────────────────────────────
   branding_css() in includes/branding.php schreibt einen
   <style>-Block der diese Variablen überschreibt.
   Da body.page-hub spezifischer ist als :root, gewinnen die
   Inline-Werte gegen die Defaults aus 2a.
   Leere Felder in branding.json erzeugen keine Ausgabe –
   die Defaults aus :root gelten dann unverändert.
   ─────────────────────────────────────────────────────────────── */
body.page-hub,
body.page-login,
body.page-admin {
  --color-brand:         #1455C0;
  --color-brand-dark:    #0f44a8;
  --color-action:        #FF0000;
  --color-action-dark:   #d60000;
  --color-danger:        #dc2626;
  --color-danger-dark:   #991b1b;
  --color-danger-subtle: #fee2e2;
  --color-danger-light:  #fca5a5;
}

/* ── 2d. Rückwärtskompatibilitäts-Aliase ────────────────────────
   Diese Aliase werden von älteren Komponenten noch genutzt,
   solange das PHP-Refactoring läuft. Neue Komponenten sollen
   ausschließlich die semantischen Tokens aus 2a verwenden.
   Können schrittweise entfernt werden sobald alle Referenzen
   auf die neuen Namen umgestellt sind.
   ─────────────────────────────────────────────────────────────── */
:root {
  --primary-blue:         var(--_blue-500);
  --primary-blue-dark:    var(--_blue-600);
  --accent-red:           var(--_red-500);
  --accent-red-dark:      var(--_red-600);
  --text-dark:            var(--_neutral-900);
  --dark:                 var(--_neutral-800);
  --bg-light:             var(--_neutral-50);
  --bg-white:             var(--_neutral-0);
  --bg-subtle:            var(--_neutral-100);
  --bg-hover-blue:        var(--_blue-50);
  --border-default:       var(--_neutral-200);
  --border-strong:        var(--_neutral-300);
  --color-red-text:       var(--_red-900);
  --color-red-border:     var(--_red-700);
  --color-red-bg:         var(--_red-50);
  --color-red-muted:      var(--_red-100);
  --color-green-border:   var(--_green-500);
  --color-green-text:     var(--_green-800);
  --color-yellow-border:  var(--_yellow-200);
  --color-yellow-bg:      var(--_yellow-50);
  --color-yellow-text:    var(--_yellow-900);
  --primary-blue-06:      rgba(20, 85, 192, 0.06);
  --shadow-08:            rgba(var(--_black), 0.08);
  --shadow-09:            rgba(var(--_black), 0.09);
  --shadow-50:            rgba(var(--_black), 0.50);
  --green-10:             rgba(16, 185, 129, 0.10);
  --accent-red-08:        rgba(220, 38, 38, 0.08);
}
/* Rückwärtskompatibilität im Branding-Override */
body.page-hub,
body.page-login,
body.page-admin {
  --primary-blue:      #1455C0;
  --primary-blue-dark: #0f44a8;
  --accent-red:        #FF0000;
  --accent-red-dark:   #d60000;
}


/* ═══════════════════════════════════════════════════════════════
   3. RESET & BASE
   Minimaler Reset + globale Basis-Stile. Gelten für alle Seiten.
   ═══════════════════════════════════════════════════════════════ */

html { scrollbar-gutter: stable; }

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

body {
  font-family: var(--font-base);
  color: var(--color-text-primary);
  background-color: var(--color-bg);
  line-height: 1.6;
}

button, input, select, textarea {
  font-family: inherit;
}

a { color: inherit; text-decoration: none; }
img { max-width: 100%; height: auto; display: block; }

.container {
  max-width: var(--max-width);
  margin: 0 auto;
  padding: 0 1.5rem;
}

/* Spam-Schutz für E-Mail-Adressen:
   RTL-Rendering + CSS-Präfix verhindert automatisches Harvesting.
   Screenreader lesen die Werte korrekt vor. */
.textschutz { direction: rtl; unicode-bidi: bidi-override; display: inline-block; user-select: none; }
.textschutz .keintext { display: none; }
.mailschutz::before   { content: "ed."; }


/* ═══════════════════════════════════════════════════════════════
   4. KOMPONENTEN – BEREICHSAGNOSTISCH
   Alle Klassen in diesem Abschnitt sind auf Login-, Hub- UND
   Admin-Seiten einsetzbar. Keine Abhängigkeit von page-admin,
   page-login oder page-hub.
   ═══════════════════════════════════════════════════════════════ */

/* ── 4.1 Footer ─────────────────────────────────────────────────
   Plattform-Footer auf allen Seiten (login, dashboard, admin,
   profil). Inhalte kommen dynamisch aus branding_get():
   Unternehmensname, Impressum, Datenschutz, Custom Links,
   optionaler Produkthinweis.
   ─────────────────────────────────────────────────────────────── */
footer {
  background-color: var(--color-footer-bg);
  color: var(--color-footer-text);
  padding: 1.5rem 0 1.8rem;
  font-size: 0.85rem;
  margin-top: 2rem;
}
.footer-inner { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 1rem; align-items: center; }
.footer-links { display: flex; gap: 1.2rem; flex-wrap: wrap; }
.footer-links a { color: var(--color-text-hint); }
.footer-links a:hover { color: var(--color-surface); }
/* "Plattform: tabillyHub" – nur sichtbar wenn PRODUCT_WHITE_LABEL = false */
.footer-product-hint,
.footer-product-hint a { font-size: 0.8rem; color: var(--color-text-hint); text-decoration: none; }
.footer-product-hint a:hover { color: var(--color-footer-text); }
/* Impressum/Datenschutz: per JS mit .open eingeblendet */
.legal-section { display: none; }
.legal-section.open { display: block; }

/* ── 4.2 Header ─────────────────────────────────────────────────
   Gemeinsamer Header auf allen Plattform-Seiten.
   Logo-Link zeigt auf PRODUCT_URL (Produktwebsite).
   ─────────────────────────────────────────────────────────────── */
header {
  background: var(--gradient-header);
  border-bottom: 1px solid var(--color-border);
  padding: 0;
}
.header-inner {
  max-width: var(--max-width);
  margin: 0 auto;
  padding: 0.75rem 1.5rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap; /* Ermöglicht Umbruch auf Mobile */
}
.site-logo { width: 180px; aspect-ratio: 6714 / 2160; object-fit: contain; display: block; }

/* ── 4.3 Formulare (allgemein) ──────────────────────────────────
   Basis-Stile für alle Formularelemente. Gelten plattformweit.
   Admin-spezifische Formular-Layouts stehen in hub-admin.css.
   Profil-spezifische Formular-Layouts stehen in hub-user.css.
   ─────────────────────────────────────────────────────────────── */
label { display: block; margin-bottom: 0.2rem; }
/* Pflichtfeld-Marker: wird via PHP class="required" gesetzt */
label.required::after { content: ' *'; color: var(--color-err); font-weight: 700; }

input:not([type="checkbox"]):not([type="radio"]):not([type="color"]):not([type="range"]),
textarea,
select {
  width: 100%;
  padding: 0.6rem 0.7rem;
  border-radius: var(--radius-sm);
  border: 1px solid var(--color-border-strong);
  font-size: 0.95rem;
  font-family: var(--font-base);
  background: var(--color-surface);
  color: var(--color-text-primary);
}
textarea { min-height: 120px; resize: vertical; }
input:not([type="checkbox"]):not([type="radio"]):not([type="color"]):not([type="range"]):focus,
textarea:focus,
select:focus {
  outline: 2px solid var(--color-brand);
  border-color: var(--color-brand);
}
/* Geerbter Default-Wert: Feld zeigt einen Wert aus übergeordneter Quelle
   (z.B. Cartridge), nicht aus dem eigenen Override. JS entfernt die Klasse
   sobald der User tippt – das Feld wird damit zum echten Override. */
input.input-inherited-default,
select.input-inherited-default,
textarea.input-inherited-default {
  color: var(--color-text-hint);
  font-style: italic;
  opacity: 0.75;
}

/* Hinweistext direkt unter einem Feld mit geerbtem Default */
.form-inherit-hint {
  display: block;
  margin-top: 0.15rem;
  font-size: 0.75rem;
  color: var(--color-text-hint);
  opacity: 0.85;
}

/* Inline-Formular: kompakte horizontale Anordnung von Feldern/Buttons
   in einer Zeile (z.B. Umbenennen-, Revoke-, Renew-Aktionen direkt in
   Tabellenzellen und Karten). */
.inline-form { margin-top: 0; display: flex; gap: 0.5rem; align-items: center; flex-wrap: wrap; }

/* ── 4.4 Buttons (allgemein) ────────────────────────────────────
   Buttons die auf Login-, Hub- und Admin-Seiten vorkommen.
   Admin-spezifische Aktionsleisten-Buttons (btn-bar-*) stehen
   in hub-admin.css.
   ─────────────────────────────────────────────────────────────── */

/* Primärer Login-Button – roter Pill, volle Breite */
.btn-login {
  width: 100%; padding: 0.8rem;
  background: var(--color-action); color: var(--color-surface);
  border: 1px solid var(--color-action); border-radius: var(--radius-pill);
  font-size: 1rem; font-weight: 600; cursor: pointer; letter-spacing: 0.02em;
  display: inline-flex; align-items: center; justify-content: center;
  line-height: 1.2; vertical-align: middle;
}
.btn-login:hover  { background: var(--color-action-dark); border-color: var(--color-action-dark); }
.btn-login:active { transform: scale(0.97) translateY(1px); }
/* Warnvariante: HIBP-Bestätigung */
.btn-login--warn { background: var(--color-warn-bg); border: 1px solid var(--color-warn-border); color: var(--color-warn-text); }
.btn-login--warn:hover { filter: brightness(0.9); }

/* Ghost-Button "Abbrechen" auf Login-Seite – verweist auf PRODUCT_URL */
.btn-cancel-login {
  display: inline-flex; align-items: center; justify-content: center;
  width: 100%; padding: 0.8rem;
  background: transparent; color: var(--color-brand);
  border: 1px solid var(--color-brand); border-radius: var(--radius-pill);
  font-size: 1rem; font-weight: 600; text-align: center;
  letter-spacing: 0.02em; line-height: 1.2; cursor: pointer; vertical-align: middle;
}
.btn-cancel-login:hover  { background: color-mix(in srgb, var(--color-brand) 6%, transparent); }
.btn-cancel-login:active { transform: scale(0.97) translateY(1px); }

/* 2FA-Formular: "Code erneut senden"-Button */
.tfa-resend-form .btn-link {
  margin-top: 1rem; background: transparent; color: var(--color-brand);
  border: 1px solid var(--color-brand); border-radius: var(--radius-pill);
  padding: 0.8rem; font-size: 1rem; font-weight: 600; cursor: pointer; width: 100%;
  display: inline-flex; align-items: center; justify-content: center;
}
.btn-link:hover  { background: color-mix(in srgb, var(--color-brand) 6%, transparent); }
.btn-link:active { transform: scale(0.97) translateY(1px); }
.tfa-resend-form .btn-cancel-login { margin-top: 1rem; display: inline-flex; }

/* Abmelden-Button im Header (alle Seiten) */
.btn-logout {
  background: transparent; color: var(--color-brand);
  border: 1px solid var(--color-brand); border-radius: var(--radius-pill);
  padding: 0.4rem 1rem; font-size: 0.85rem; cursor: pointer; font-weight: 500; line-height: 1rem;
  display: inline-flex; align-items: center; justify-content: center; white-space: nowrap;
}
.btn-logout:hover  { background: color-mix(in srgb, var(--color-brand) 6%, transparent); }
.btn-logout:active { transform: scale(0.97) translateY(1px); }

/* Primärer blauer Pill-Button (Service öffnen, Formular absenden) */
.btn-open {
  margin-top: 0.5rem; background: var(--color-brand); border: 1px solid var(--color-brand);
  color: var(--color-surface); border-radius: var(--radius-pill);
  padding: 0.55rem 1.2rem; font-size: 0.9rem; font-weight: 600; cursor: pointer; width: 100%;
  display: inline-flex; align-items: center; justify-content: center;
  line-height: 1.4; vertical-align: middle; text-decoration: none;
}
.btn-open:hover  { background: var(--color-brand-dark); }
.btn-open:active { transform: scale(0.97) translateY(1px); }
/* --auto: width:auto, kein margin-top (für Inline-Verwendung in Leisten) */
.btn-open--auto  { width: auto; padding: 0.55rem 1.5rem; margin-top: 0; }
.btn-open.btn-open--auto { padding: 0.4rem 1rem; font-size: 0.85rem; }

/* Ghost-Pill-Button "Abbrechen" (Formulare) */
.btn-cancel {
  margin-top: 0.5rem; background: transparent; color: var(--color-brand);
  border: 1px solid var(--color-brand); border-radius: var(--radius-pill);
  padding: 0.55rem 1.2rem; font-size: 0.9rem; font-weight: 600; cursor: pointer; width: 100%;
  display: inline-flex; align-items: center; justify-content: center;
  line-height: 1.4; vertical-align: middle; text-decoration: none;
}
.btn-cancel:hover  { background: color-mix(in srgb, var(--color-brand) 6%, transparent); }
.btn-cancel:active { transform: scale(0.97) translateY(1px); }
.btn-cancel--auto  { width: auto; padding: 0.55rem 1.5rem; margin-top: 0; }
.btn-cancel.btn-cancel--auto { padding: 0.4rem 1rem; font-size: 0.85rem; }

/* Kleine Buttons in Tabellenzellen (Basis-Klasse) */
.btn-sm {
  padding: 0.3rem 0.7rem; font-size: 0.82rem; border-radius: var(--radius-sm);
  border: none; cursor: pointer; font-weight: 500;
  display: inline-flex; align-items: center; justify-content: center; line-height: 1.4;
}
.btn-edit   { background: var(--color-blue-light);  color: var(--color-blue-deep); }  /* Bearbeiten – Tabellenzeilen-Aktion */
.btn-del    { background: var(--color-err-bg);       color: var(--color-err-mid); }   /* Löschen – Tabellenzeilen-Aktion */
.btn-toggle { background: var(--color-warn-bg);      color: var(--color-warn-text); } /* Aktivieren/Deaktivieren – Listeneintrag */
.btn-unlock { background: var(--color-ok-bg);        color: var(--color-ok-text); }   /* Entsperren / Anfrage annehmen */
.btn-del:disabled { opacity: 0.35; cursor: not-allowed; }
.btn-edit:hover   { background: var(--color-blue-border); }
.btn-del:hover    { background: var(--color-err); color: var(--color-surface); }
.btn-toggle:hover { background: var(--color-warn-border); }
.btn-unlock:hover { background: var(--color-ok-border); }
.btn-sm:active    { transform: scale(0.96) translateY(1px); }

/* Kleine Buttons für den User-Bereich (Hub/Profil) –
   nutzen ausschließlich globale semantische Tokens, kein Admin-Scoping */
.btn-sm-brand {
  /* Primäre Aktion: Umbenennen, Bearbeiten */
  padding: 0.3rem 0.7rem; font-size: 0.82rem; border-radius: var(--radius-sm);
  border: 1px solid var(--color-brand-border); cursor: pointer; font-weight: 500;
  display: inline-flex; align-items: center; justify-content: center; line-height: 1.4;
  background: var(--color-brand-light); color: var(--color-brand);
}
.btn-sm-brand:hover  { background: var(--color-brand-subtle); border-color: var(--color-brand); }
.btn-sm-brand:active { transform: scale(0.96) translateY(1px); }

.btn-sm-danger {
  /* Destruktive Aktion: Sperren, Löschen */
  padding: 0.3rem 0.7rem; font-size: 0.82rem; border-radius: var(--radius-sm);
  border: 1px solid var(--color-danger-light); cursor: pointer; font-weight: 500;
  display: inline-flex; align-items: center; justify-content: center; line-height: 1.4;
  background: var(--color-danger-subtle); color: var(--color-danger);
}
.btn-sm-danger:hover  { background: var(--color-danger); color: var(--color-surface); border-color: var(--color-danger); }
.btn-sm-danger:active { transform: scale(0.96) translateY(1px); }
.btn-sm-danger:disabled { opacity: 0.35; cursor: not-allowed; }

.btn-sm-warn {
  /* Warnende Aktion: Erneuern */
  padding: 0.3rem 0.7rem; font-size: 0.82rem; border-radius: var(--radius-sm);
  border: 1px solid var(--color-warn-border); cursor: pointer; font-weight: 500;
  display: inline-flex; align-items: center; justify-content: center; line-height: 1.4;
  background: var(--color-warn-bg); color: var(--color-warn-text);
}
.btn-sm-warn:hover  { background: var(--color-warn-border); }
.btn-sm-warn:active { transform: scale(0.96) translateY(1px); }

/* Passwort-Reset-Button (gelb, Pill) */
.btn-pw {
  background: var(--color-warn-bg); color: var(--color-warn-text);
  border: 1px solid var(--color-warn-text); border-radius: var(--radius-pill);
  padding: 0.55rem 1.2rem; font-size: 0.9rem; font-weight: 600; cursor: pointer; width: 100%;
  display: inline-flex; align-items: center; justify-content: center; line-height: 1.4;
}
.btn-pw--auto { width: auto; padding: 0.55rem 1.5rem; }
/* Kleine Variante für Tabellenzellen */
.btn-sm.btn-pw { margin: 0; border-radius: var(--radius-sm); padding: 0.3rem 0.7rem; font-size: 0.82rem; font-weight: 500; width: auto; }
.btn-pw:hover  { background: var(--color-warn-border); }
.btn-pw:active { transform: scale(0.96) translateY(1px); }

/* Kleiner Ghost-Abbrechen-Button (Formular- und Drawer-Aktionsleisten) */
.btn-sm.btn-cancel { margin-top: 0; width: auto; border: 1px solid var(--color-brand); border-radius: var(--radius-sm); }
.btn-sm.btn-cancel:hover  { background: color-mix(in srgb, var(--color-brand) 6%, transparent); }
.btn-sm.btn-cancel:active { transform: scale(0.96) translateY(1px); }

/* Kleiner neutraler Icon-Button (z.B. Inhalt in die Zwischenablage kopieren) */
.btn-icon-sm {
  background: var(--color-bg-subtle);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  padding: 0.3rem 0.7rem;
  font-size: 0.82rem; font-weight: 500; cursor: pointer;
  display: inline-flex; align-items: center; gap: 0.3rem;
  color: var(--color-text-secondary); line-height: 1.4;
}
.btn-icon-sm:hover  { background: var(--color-border); }
.btn-icon-sm:active { transform: scale(0.96) translateY(1px); }

/* ── 4.5 Alerts & Badges ────────────────────────────────────────
   Flash-Messages und Status-Badges. Gelten auf allen Seiten.
   ─────────────────────────────────────────────────────────────── */
.alert { padding: 0.7rem 1rem; border-radius: var(--radius-sm); margin-bottom: 1rem; font-size: 0.9rem; }
.alert-ok   { background: color-mix(in srgb, var(--color-ok)  10%, transparent); border-left: 4px solid var(--color-ok);  color: var(--color-ok-text); }
.alert-err  { background: color-mix(in srgb, var(--color-err)  8%, transparent); border-left: 4px solid var(--color-err); color: var(--color-err-text); }
.alert-warn { background: var(--color-warn-bg); border-left: 4px solid var(--color-warn-border); color: var(--color-warn-text); }

/* Status-Badges (Pill-Form) */
.badge-active      { color: var(--color-ok-text);   background: var(--color-ok-bg);   border-radius: var(--radius-pill); padding: 0.15rem 0.6rem;  font-size: 0.78rem; }
.badge-inactive    { color: var(--color-err-text);  background: var(--color-err-bg);  border-radius: var(--radius-pill); padding: 0.15rem 0.6rem;  font-size: 0.78rem; }
.badge-ok          { color: var(--color-ok-text);   background: var(--color-ok-bg);   border-radius: var(--radius-pill); padding: 0.15rem 0.55rem; font-size: 0.75rem; }
.badge-locked      { color: var(--color-err-text);  background: var(--color-err-bg);  border-radius: var(--radius-pill); padding: 0.15rem 0.55rem; font-size: 0.75rem; white-space: nowrap; }
.badge-temp-locked { color: var(--color-warn-text); background: var(--color-warn-bg); border-radius: var(--radius-pill); padding: 0.15rem 0.55rem; font-size: 0.75rem; white-space: nowrap; }
/* Zählabzeichen in Tab-Leisten und Überschriften */
.count-badge { background: var(--color-border); border: 1px solid var(--color-border-strong); border-radius: var(--radius-pill); padding: 0.1rem 0.6rem; font-size: 0.75rem; color: var(--color-text-secondary); }

/* ── 4.6 Passwort-Stärke-Anzeige ───────────────────────────────
   Fortschrittsbalken und Anforderungsliste beim Passwort-Eingeben
   (login.php Forced-Change, profile.php, admin/users.php).
   Breite und Farbe von .pw-strength-fill werden per JS gesetzt.
   ─────────────────────────────────────────────────────────────── */
.pw-strength-bar  { height: 0.35rem; background: var(--color-border); border-radius: 2px; margin-top: 0.35rem; overflow: hidden; }
.pw-strength-fill { height: 100%; width: 0; border-radius: 2px; transition: width 0.2s ease, background 0.2s ease; }
.pw-requirements  { list-style: none; margin: 0.4rem 0 0; padding: 0; display: flex; flex-wrap: wrap; gap: 0.25rem 0.75rem; font-size: 0.8rem; }
.pw-requirements li { white-space: nowrap; }
.req-ok   { color: var(--color-ok); }
.req-fail { color: var(--color-err); }

/* ── 4.7 iFrame-Overlay ─────────────────────────────────────────
   Modales Overlay für iframe-Dienste im Dashboard.
   .overlay.open wird per JS gesetzt.
   ─────────────────────────────────────────────────────────────── */
.overlay { display: none; position: fixed; inset: 0; background: var(--shadow-overlay); z-index: 100; align-items: center; justify-content: center; }
.overlay.open { display: flex; }
.iframe-box { background: var(--color-surface); border-radius: var(--radius-xl); overflow: hidden; width: 92vw; height: 88vh; display: flex; flex-direction: column; }
.iframe-header { display: flex; align-items: center; justify-content: space-between; padding: 0.75rem 1rem; border-bottom: 1px solid var(--color-border); font-weight: 600; color: var(--color-text-heading); }
.iframe-close { background: none; border: none; font-size: 1.4rem; cursor: pointer; color: var(--color-text-hint); line-height: 1; }
.iframe-close:hover { color: var(--color-text-heading); }
iframe { flex: 1; border: none; width: 100%; }

/* ── 4.8 Hilfsklassen ───────────────────────────────────────────
   Utility-Klassen für häufige Einzel-Eigenschaften.
   ─────────────────────────────────────────────────────────────── */
.u-hidden      { display: none; }
.mt-xs         { margin-top: 0.5rem; }
.mt-sm         { margin-top: 0.75rem; }
.text-muted-sm { font-size: 0.8rem; color: var(--color-text-hint); }
.drag-handle   { cursor: grab; color: var(--color-text-hint); padding-right: 0.5rem; }
.empty         { text-align: center; color: var(--color-text-hint); padding: 3rem; font-size: 0.95rem; }
.td-center     { text-align: center; }
.td-nowrap     { white-space: nowrap; }

/* ── 4.9 Schlüsseldatei-/Geräte-Tabelle ─────────────────────────
   Spaltenbreiten und Aktions-Layout für die Tabelle der
   2FA-Schlüsseldateien/Geräte. Bereichsagnostisch: dieselbe
   Tabelle wird im User-Profil (Geräteliste) und in der
   Admin-Geräteverwaltung dargestellt.
   ─────────────────────────────────────────────────────────────── */
.kf-table { table-layout: fixed; width: 100%; }
.kf-table col.col-name,
.kf-table col.col-actions { width: 18rem; }
.kf-table col.col-created,
.kf-table col.col-expires,
.kf-table col.col-lastused { width: auto; }
.kf-table th { white-space: nowrap; }
.kf-actions-edit,
.kf-actions-view { display: flex; padding-top: 0; gap: 0.5rem; }
.kf-name-input { width: 100%; max-width: 18rem; }

/* ── 4.10 Nachrichten-Links & Link-Auswahl ──────────────────────
   Verlinkte Pfade/Service-URLs im Nachrichtentext sowie die
   aufklappbare Link-Hilfe zur Auswahl einer Service-URL.
   Bereichsagnostisch: das Compose-Modal im User-Frontend und der
   Onboarding-Editor im Admin-Bereich rendern dieselben Klassen.
   ─────────────────────────────────────────────────────────────── */

/* Verlinkter Pfad / Service-URL im Nachrichtentext */
.msg-body-link {
  color: var(--color-brand);
  text-decoration: underline;
  word-break: break-all;
}
.msg-body-link:hover { color: var(--color-brand-dark); }

/* Gesperrter Link (Empfänger hat keine Berechtigung) */
.msg-body-link--locked {
  color: var(--color-text-hint);
  text-decoration: none;
  cursor: default;
  word-break: break-all;
}

/* Link-Hilfe im Compose-Modal */
.msg-link-helper {
  margin-top: .5rem;
  font-size: .82rem;
}
.msg-link-helper summary {
  cursor: pointer;
  color: var(--color-brand);
  user-select: none;
  list-style: none;
  display: flex;
  align-items: center;
  gap: .3rem;
}
.msg-link-helper summary::-webkit-details-marker { display: none; }
.msg-link-helper summary::before {
  content: '▶';
  font-size: .6rem;
  transition: transform .15s;
}
.msg-link-helper[open] summary::before { transform: rotate(90deg); }

.msg-link-helper__body {
  margin-top: .4rem;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-bg);
  max-height: 180px;
  overflow-y: auto;
}

.msg-link-helper__section {
  padding: .3rem .6rem .15rem;
  font-size: .75rem;
  font-weight: 600;
  color: var(--color-text-hint);
  text-transform: uppercase;
  letter-spacing: .04em;
  border-bottom: 1px solid var(--color-border);
}

.msg-link-helper__item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .5rem;
  padding: .3rem .6rem;
  border-bottom: 1px solid var(--color-border);
  cursor: pointer;
  transition: background .1s;
}
.msg-link-helper__item:last-child { border-bottom: none; }
.msg-link-helper__item:hover { background: var(--color-brand-subtle); }

.msg-link-helper__label {
  font-size: .82rem;
  color: var(--color-text-primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  flex: 1;
}
.msg-link-helper__url {
  font-size: .75rem;
  color: var(--color-text-hint);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 160px;
  flex-shrink: 0;
}

/* ── Mobile Breakpoints ─────────────────────────────────────────── */
@media (max-width: 768px) {
  .header-inner {
    flex-direction: column;
    align-items: stretch;
    gap: 0.75rem;
  }
  
  .site-logo {
    align-self: center;
    width: 160px;
  }
  
  .user-bar {
    justify-content: center;
    gap: 0.4rem;
    font-size: 0.85rem;
  }
  
  .user-bar span:first-child {
    /* "Hallo, Username" auf eigener Zeile */
    width: 100%;
    text-align: center;
    margin-bottom: 0.25rem;
  }
  
  .btn-logout {
    flex: 1;
    min-width: 0;
    padding: 0.35rem 0.75rem;
    font-size: 0.8rem;
  }
}

@media (max-width: 480px) {
  .header-inner {
    padding: 0.5rem 1rem;
  }
  
  .site-logo {
    width: 140px;
  }
  
  .btn-logout {
    padding: 0.3rem 0.6rem;
    font-size: 0.75rem;
  }
}
