/*
 * ui.css – gemeinsamer UI-Baukasten für Daysi UND alle Tools.
 *
 * Patrick: "Patrick will jetzt, dass Daysi und alle Tools IDENTISCH
 * aussehen. Eine Bestandsaufnahme hat gezeigt: Alle nutzen die
 * --ms-*-Tokens, aber Seitenkopf, Pfadleiste, Info-Icon, Karten, Knöpfe,
 * Tabellen, Bestätigungen, Kurzmeldungen, Icons und Datumsformat hat jedes
 * Tool selbst nachgebaut." Diese Datei ist die EINE Quelle für die
 * generischen Bausteine – ausgeliefert unter ZWEI Adressen (dasselbe Muster
 * wie sidebar-main.css, siehe dortigen Kommentar):
 *   - /public/css/ui.css  – Daysi selbst (versioniert, views/layout.js)
 *   - /_daysi/ui.css     – JEDES Tool (unversioniert wie bar.css/
 *                           sidebar.css/sidebar-main.css, siehe
 *                           routes/daysi.js)
 * KEINE zweite, auseinanderlaufende Kopie – ms.css nutzt für Karten/
 * Tabellen/Knöpfe/Formularfelder/Badges/Seitenbreite genau diese Regeln
 * (siehe dortigen Abschnitt "UI-Baukasten (ausgelagert)").
 *
 * Einbindung in einem Tool (siehe WORKSPACES.md, Abschnitt "UI-Baukasten"):
 *   <link rel="stylesheet" href="/_daysi/ui.css">
 *   <script src="/_daysi/ui.js" defer></script>
 *
 * WICHTIG – was HIER steht: nur REINE Klassen-Selektoren, die auf
 * --ms-*-Tokens aufbauen (keine festen Farben, keine `html.…`/`body.…`/
 * `:host(…)`-Auswahl, keine Element-Selektoren ohne Klasse) – exakt dasselbe
 * Prinzip wie sidebar-main.css (siehe dortigen Kommentar), nur diesmal für
 * Seiteninhalt statt Navigation. Daysi (Light DOM, :root-Tokens) und Tools
 * (die --ms-*-Tokens kommen dort aus dem jeweils eigenen Stylesheet, z. B.
 * einer Kopie von ms.css) definieren die Token-WERTE unabhängig – diese
 * Datei verwendet nur die Namen. Durchgehend Klassenpräfix "ms-" (Vorgabe:
 * "keine Kollision mit Tool-eigenen Klassen"). Einzige, bewusste Ausnahme:
 * Abschnitt 14 (Seitenhintergrund mit Tiefe auf html/body, siehe dort).
 *
 * Aufbau:
 *   0. Icons (.ms-icon, <ms-icon>, siehe public/js/ui.js)
 *   1. Seitenkopf (.ms-page-head, .ms-breadcrumb) + Seitenbreite (.ms-page)
 *   2. Karten (.ms-card)
 *   3. Knöpfe (.ms-btn)
 *   4. Formularfelder (.ms-field, .ms-form, .ms-checkbox)
 *   5. Tabellen (.ms-table)
 *   6. Badges / Status-Chips (.ms-badge)
 *   7. Reiter (.ms-tabs)
 *   8. Leerer Zustand (.ms-empty)
 *   9. Ladezustand (.ms-skeleton, .ms-spinner)
 *  10. Info-Popover (<ms-info>, siehe public/js/ui.js)
 *  11. Kurzmeldungen / Toast (MSDaysi.toast, siehe public/js/ui.js)
 *  12. Pop-ups / Modal-Baukasten (.ms-modal, .ms-modal-backdrop) +
 *      Bestätigungsdialog (MSDaysi.confirm, siehe public/js/ui.js)
 *  13. Zwei-Spalten-Zuordnung (.ms-board, .ms-board-picker, .ms-board-search
 *      Live-Suche, .ms-board-confirm Rückfrage; Verhalten:
 *      public/js/roles-board.js, Vertrag siehe WORKSPACES.md §5a)
 *  14. Seitenhintergrund mit Tiefe (html/body-Ebene – die EINZIGE bewusste
 *      Ausnahme von der Regel „nur Klassen-Selektoren" oben, siehe dort)
 *  15. Barrierefreiheit: Sprungziel (main[tabindex=-1] - zweite, bewusste
 *      Ausnahme: das Ziel des Sprunglinks liegt im Tool-Markup)
 */

/* ==========================================================================
   0. Icons
   ========================================================================== */
/* .ms-icon: Klasse, die lib/icons.js#icon() serverseitig auf JEDES
   Inline-SVG setzt (überall in Daysi bereits in Gebrauch). ms-icon (ohne
   Punkt): das NEUE Custom Element <ms-icon name="…"> aus public/js/ui.js,
   das dasselbe SVG client-seitig von /_daysi/icons/*.svg nachlädt (Statistik
   kann damit z. B. Emojis ersetzen) - lädt selbst KEIN eigenes CSS (kein
   Shadow DOM, siehe ui.js-Kommentar), die Größe kommt von hier. */

.ms-icon {
  display: inline-flex;
  width: 18px;
  height: 18px;
  flex-shrink: 0;
}

ms-icon {
  display: inline-flex;
  width: 18px;
  height: 18px;
  flex-shrink: 0;
}

ms-icon svg {
  display: block;
  width: 100%;
  height: 100%;
}

/* ==========================================================================
   1. Seitenkopf + Seitenbreite
   ========================================================================== */

/* Inhaltsbreite (Patrick: "max. 1280px für Übersichten und Tabellen, 880px
   für Einstellungs- und Formularseiten"). .ms-page ersetzt das frühere,
   Daysi-interne .ms-container für alle Seiten mit Bar+Sidebar (siehe
   views/layout.js#renderAppPage) – Login/Legal/Reset behalten ihr eigenes,
   schmaleres .ms-container (siehe ms.css), das ist außerhalb dieses
   Baukastens (keine Bar, kein Tool-Äquivalent). */
/* Seitenrand gestaffelt (Patrick, 2026-09-25: "zu nah am Rand links und
   rechts"): --ms-gutter (16px) ist der Handy-Wert; ab Tablet/Laptop mehr
   Luft zur Sidebar und zum Fensterrand, auf großen Bildschirmen noch mehr. */
.ms-page {
  --ms-page-gutter: var(--ms-gutter);
  max-width: 1280px;
  margin: 0 auto;
  padding: var(--ms-space-8) var(--ms-page-gutter);
  width: 100%;
  box-sizing: border-box;
}

@media (min-width: 768px) {
  .ms-page {
    --ms-page-gutter: 32px;
  }
}

@media (min-width: 1440px) {
  .ms-page {
    --ms-page-gutter: 48px;
  }
}

.ms-page--narrow {
  max-width: 880px;
}

/* Laptops (13–16 Zoll): etwas weniger Luft oben/unten und im Seitenkopf. */
@media (max-width: 1439px) {
  .ms-page {
    padding-top: var(--ms-space-6);
    padding-bottom: var(--ms-space-6);
  }
}

/* -- Pfadleiste (Breadcrumbs) über dem Seitentitel ------------------------- */

.ms-breadcrumb {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin-bottom: var(--ms-space-3);
  font-size: 12.5px;
  color: var(--ms-text-subtle);
}

.ms-breadcrumb a {
  color: inherit;
  text-decoration: none;
}

.ms-breadcrumb a:hover {
  color: var(--ms-text);
  text-decoration: underline;
}

.ms-breadcrumb [aria-current='page'] {
  color: var(--ms-text-muted);
  font-weight: 500;
}

.ms-breadcrumb__sep {
  color: var(--ms-border-strong);
}

/* -- Seitenkopf: Titel (Playfair, siehe h1-Regel im jeweiligen Basis-CSS),
   optionales <ms-info> direkt dahinter, rechts ein optionaler
   Aktionsbereich. Zwei Größen: die normale (Dashboard/Übersichten) und
   .ms-page-head--compact (Einstellungs-/Detailseiten, z. B. "Konto ->
   Darstellung" - kleinerer Titel, engerer Abstand nach unten, dieselbe
   Familie wie zuvor .ms-settings__head/-__title). Mobil bricht der
   Aktionsbereich sauber um (flex-wrap). ------------------------------------ */

.ms-page-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--ms-space-4);
  flex-wrap: wrap;
  margin-bottom: var(--ms-space-8);
}

.ms-page-head--compact {
  align-items: flex-start;
  margin-bottom: var(--ms-space-6);
}

/* Kleiner Vorspann über dem Titel (z. B. Begrüßung im Dashboard, "Verwaltung"
   im MCP-Protokoll - bestehende Klasse, siehe views/dashboard.js/-mcpAdmin.js). */
.ms-page-head__greeting {
  font-size: 13.5px;
  color: var(--ms-text-muted);
  margin: 0 0 4px;
}

/* Titel + <ms-info> nebeneinander, vertikal mittig zum Titeltext. */
.ms-page-head__title-row {
  display: flex;
  align-items: center;
  gap: var(--ms-space-2);
  flex-wrap: wrap;
}

/* margin/line-height fest hier statt aus der h1-Regel des jeweiligen Tools
   (Patrick, 2026-09-27: Abstand Pfadleiste → Titel überall gleich, Vorlage
   „Projekte"): Daysi hatte line-height 1.15 (ms.css), Cashflow den
   Browser-Standardabstand 0.67em über/unter h1, Planung/Statistik
   line-height normal ohne Margin - letzteres gilt jetzt überall. */
.ms-page-head__title {
  font-size: clamp(34px, 4.5vw, 52px);
  line-height: normal;
  margin: 0;
}

.ms-page-head--compact .ms-page-head__title {
  font-size: clamp(28px, 3.6vw, 40px);
}

.ms-page-head__intro {
  margin: var(--ms-space-2) 0 0;
  color: var(--ms-text-muted);
  font-size: 14.5px;
  max-width: 62ch;
}

.ms-page-head__date {
  color: var(--ms-text-muted);
  font-size: 13.5px;
  white-space: nowrap;
}

.ms-page-head__meta {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: var(--ms-space-2);
}

.ms-page-head__actions {
  display: flex;
  align-items: center;
  gap: var(--ms-space-2);
  flex-wrap: wrap;
}

/* ==========================================================================
   2. Karten
   ========================================================================== */

/* Rand + Schatten über die Tiefe-Token (Patrick, 2026-09-27, siehe
   Abschnitt 14): hell zarter Rand + weicher, zweistufiger Schatten
   („Ebenen & Schatten"), dunkel wie bisher --ms-border ohne Schatten. Die
   Modifikatoren unten (--highlight/--danger) und farbige Dashboard-Kacheln
   (ms.css, .ms-block--c-*) setzen ihre Randfarbe weiterhin darüber. */
.ms-card {
  background: var(--ms-surface);
  border: 1px solid var(--ms-card-border-depth, var(--ms-border));
  border-radius: var(--ms-radius-lg);
  padding: 26px;
  box-shadow: var(--ms-shadow-card, none);
}

.ms-card--narrow {
  max-width: 480px;
}

.ms-card--highlight {
  border-color: color-mix(in srgb, var(--ms-accent) 45%, var(--ms-border));
}

.ms-card--danger {
  border-color: color-mix(in srgb, var(--ms-danger) 45%, var(--ms-border));
  background: color-mix(in srgb, var(--ms-danger) 4%, var(--ms-surface));
}

.ms-card__title {
  font-family: var(--ms-font-display);
  font-size: 26px;
  font-weight: 400;
  margin: 0 0 2px;
}

.ms-card--danger .ms-card__title {
  color: var(--ms-danger-text, var(--ms-danger));
}

.ms-card__subtitle {
  color: var(--ms-text-muted);
  font-size: 13.5px;
  margin: 0 0 var(--ms-space-4);
  max-width: 64ch;
}

.ms-card__grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--ms-space-4);
}

@media (max-width: 860px) {
  .ms-card__grid {
    grid-template-columns: 1fr;
  }
}

.ms-card__stack {
  display: flex;
  flex-direction: column;
  gap: var(--ms-space-4);
}

/* ==========================================================================
   3. Knöpfe
   ========================================================================== */
/* Patrick: "EINE Standardhöhe von 40px, klein 32px" - keine eigene, größere
   Höhe für --primary mehr (bisher 44/48px, jetzt einheitlich). */

.ms-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--ms-space-2);
  height: 40px;
  padding: 0 var(--ms-space-4);
  border-radius: var(--ms-radius);
  border: 1px solid var(--ms-border);
  background: var(--ms-surface);
  color: var(--ms-text);
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  transition: background var(--ms-transition-fast), border-color var(--ms-transition-fast), color var(--ms-transition-fast);
}

.ms-btn:hover {
  border-color: var(--ms-border-strong);
}

.ms-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.ms-btn--primary {
  background: var(--ms-accent);
  /* Standard "transparent" -> Hintergrundfarbe scheint durch (border-box-
     Clipping), optisch identisch zu vorher. Weicht die Akzentfarbe zu
     wenig von --ms-bg ab (z. B. sehr helles Gelb), liefert das eigene
     Stylesheet stattdessen einen sichtbaren, kontraststarken Rahmenton
     (siehe public/js/palette.js#finalizeAccentLight/-Dark). */
  border-color: var(--ms-accent-border);
  color: var(--ms-on-accent);
}

.ms-btn--primary:hover {
  background: var(--ms-accent-hover);
  border-color: var(--ms-accent-hover);
}

.ms-btn--ghost {
  background: transparent;
  border-color: transparent;
}

.ms-btn--ghost:hover {
  background: var(--ms-surface-2);
  border-color: var(--ms-surface-2);
}

/* Sekundär (Patrick 2026-10-01, Fußzeile der KI-Checkliste: „schöne Buttons"):
   dezenter Rahmen und leicht abgesetzte Fläche statt eines nackten Ghost-Links
   - für Nebenaktionen am Kartenrand oder neben einem Primärknopf. Nur Tokens
   (hell/dunkel ziehen mit); --ms-surface-hover steht in ms.css, ohne ihn gilt
   die Kartenfläche. Neue Variante - bestehende Seiten nutzen sie nicht. */

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

.ms-btn--secondary:hover:not(:disabled) {
  background: var(--ms-surface-hover, var(--ms-surface));
  border-color: var(--ms-border-strong);
}

.ms-btn--secondary:focus-visible {
  outline: 2px solid var(--ms-focus-outline, var(--ms-accent));
  outline-offset: 2px;
}

.ms-btn--danger {
  background: transparent;
  border-color: var(--ms-danger);
  color: var(--ms-danger-text, var(--ms-danger));
}

.ms-btn--danger:hover {
  background: var(--ms-danger);
  color: #ffffff;
}

.ms-btn--small {
  height: 32px;
  padding: 0 var(--ms-space-3);
  font-size: 13px;
}

.ms-btn--block {
  width: 100%;
}

.ms-btn .ms-icon,
.ms-btn ms-icon {
  width: 16px;
  height: 16px;
}

/* ==========================================================================
   4. Formulare
   ========================================================================== */

.ms-form {
  display: flex;
  flex-direction: column;
  gap: var(--ms-space-4);
}

/* display:flex würde das hidden-Attribut sonst überstimmen (z. B.
   umschaltbare Feldgruppen in einem Pop-up). */
.ms-form[hidden] {
  display: none;
}

.ms-field {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.ms-field__label {
  font-size: 13px;
  font-weight: 500;
  color: var(--ms-text-muted);
}

.ms-field input[type='text'],
.ms-field input[type='email'],
.ms-field input[type='password'],
.ms-field input[type='search'],
.ms-field input[type='number'],
.ms-field select,
.ms-field textarea {
  height: 44px;
  padding: 0 var(--ms-space-3);
  background: var(--ms-surface);
  color: var(--ms-text);
  border: 1px solid var(--ms-border);
  border-radius: var(--ms-radius);
  font: inherit;
  font-size: 14.5px;
  width: 100%;
}

.ms-field textarea {
  height: auto;
  padding: var(--ms-space-3);
  min-height: 96px;
}

.ms-field input:focus,
.ms-field select:focus,
.ms-field textarea:focus {
  outline: none;
  border-color: var(--ms-focus-outline, var(--ms-accent));
  box-shadow: 0 0 0 3px var(--ms-focus-ring);
}

/* Kurzer Hinweis unter einem Feld (z. B. Namens-Syntax ROLE_/GROUP_). */
.ms-field__hint {
  margin: 0;
  font-size: 12.5px;
  color: var(--ms-text-subtle);
}

/* Eingabefeld mit fest davorstehendem, nicht editierbarem Prefix
   (Rollenverwaltung: „ROLE_" / „GROUP_" - der Server stellt es voran). */
.ms-input-prefix {
  display: flex;
  align-items: stretch;
  min-width: 0;
}

.ms-input-prefix__label {
  display: inline-flex;
  align-items: center;
  flex-shrink: 0;
  padding: 0 var(--ms-space-3);
  background: var(--ms-surface-2);
  color: var(--ms-text-muted);
  border: 1px solid var(--ms-border);
  border-right: none;
  border-radius: var(--ms-radius) 0 0 var(--ms-radius);
  font-size: 13.5px;
  font-weight: 600;
  letter-spacing: 0.02em;
}

.ms-field .ms-input-prefix input[type='text'] {
  flex: 1 1 auto;
  min-width: 0;
  border-radius: 0 var(--ms-radius) var(--ms-radius) 0;
}

.ms-field--with-action {
  position: relative;
}

.ms-field__action {
  position: absolute;
  right: 6px;
  bottom: 6px;
  width: 32px;
  height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: none;
  border-radius: 6px;
  color: var(--ms-text-muted);
  cursor: pointer;
}

.ms-field--with-action .ms-field__action {
  top: 28px;
}

.ms-field__action:hover {
  color: var(--ms-text);
  background: var(--ms-surface-2);
}

.ms-checkbox {
  display: inline-flex;
  align-items: center;
  gap: var(--ms-space-2);
  font-size: 13.5px;
  color: var(--ms-text);
  cursor: pointer;
}

.ms-checkbox input {
  width: 17px;
  height: 17px;
  accent-color: var(--ms-accent);
  cursor: pointer;
}

fieldset.ms-fieldset {
  border: 1px solid var(--ms-border);
  border-radius: var(--ms-radius);
  padding: var(--ms-space-3);
  margin: 0;
}

fieldset.ms-fieldset legend {
  padding: 0 6px;
  font-size: 13px;
  color: var(--ms-text-muted);
}

/* ==========================================================================
   5. Tabellen
   ========================================================================== */

.ms-table-wrap {
  overflow-x: auto;
  max-width: 100%;
}

.ms-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13.5px;
}

.ms-table th,
.ms-table td {
  text-align: left;
  padding: 12px 14px;
  border-bottom: 1px solid var(--ms-border);
  white-space: nowrap;
}

.ms-table th {
  color: var(--ms-text-muted);
  font-weight: 600;
  font-size: 11.5px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.ms-table tbody tr:last-child td {
  border-bottom: none;
}

/* Fließtext in einer Zelle (z. B. Beschreibung in der Rollen-Liste): bricht
   um statt die Tabelle über die Kartenbreite hinaus zu verbreitern (sonst
   horizontaler Scrollbalken); max. ~36 Zeichen je Zeile. */
.ms-table-text {
  white-space: normal;
  min-width: 14ch;
  max-width: 36ch;
}

/* Zweite Zeile innerhalb einer Zelle, z. B. Status-Badge unter dem Namen. */
.ms-table-sub {
  margin-top: 4px;
}

@media (max-width: 560px) {
  .ms-table th,
  .ms-table td {
    padding: 10px 8px;
    white-space: normal;
  }
}

/* In Tabellen auf ein <div> IN der Zelle setzen, nie auf das <td> selbst:
   display:flex macht das <td> sonst zu einem Nicht-Tabellenfeld (Höhe und
   Trennlinie laufen bei mehrzeiligen Zeilen aus dem Raster). */
.ms-table-actions {
  display: flex;
  gap: var(--ms-space-2);
  flex-wrap: wrap;
}

.ms-inline-form {
  display: inline;
}

/* ==========================================================================
   6. Badges / Status-Chips
   ========================================================================== */

.ms-badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  background: var(--ms-surface-2);
  border: 1px solid var(--ms-border);
  color: var(--ms-text-muted);
  border-radius: var(--ms-radius-pill);
  padding: 3px 10px;
  font-size: 11px;
  font-weight: 600;
}

.ms-badge--success {
  background: color-mix(in srgb, var(--ms-success) 16%, transparent);
  border-color: transparent;
  color: var(--ms-success-text, var(--ms-success));
}

.ms-badge--warn {
  background: color-mix(in srgb, var(--ms-warn) 16%, transparent);
  border-color: transparent;
  color: var(--ms-warn-text, var(--ms-warn));
}

.ms-badge--danger {
  background: color-mix(in srgb, var(--ms-danger) 14%, transparent);
  border-color: transparent;
  color: var(--ms-danger-text, var(--ms-danger));
}

.ms-badge--accent {
  background: var(--ms-accent-soft);
  border-color: transparent;
  color: var(--ms-accent-soft-text);
}

/* -- Meldungen (Formular-Fehler/-Erfolg BLEIBEN inline am Formular, siehe
   Modulkommentar - nur die ?ok=…-Kurzmeldungen nach einem Redirect werden
   zu Toasts, siehe Abschnitt 11 unten) ------------------------------------- */

.ms-alert {
  display: flex;
  align-items: flex-start;
  gap: var(--ms-space-2);
  border-radius: var(--ms-radius);
  padding: 12px 14px;
  font-size: 13.5px;
  border: 1px solid transparent;
}

.ms-alert[hidden] {
  display: none;
}

.ms-alert--danger {
  background: color-mix(in srgb, var(--ms-danger) 12%, transparent);
  border-color: var(--ms-danger);
  color: var(--ms-danger-text, var(--ms-danger));
}

.ms-alert--success {
  background: color-mix(in srgb, var(--ms-success) 14%, transparent);
  border-color: var(--ms-success);
  color: var(--ms-success-text, var(--ms-success));
}

.ms-alert--warn {
  background: color-mix(in srgb, var(--ms-warn) 14%, transparent);
  border-color: var(--ms-warn);
  color: var(--ms-warn-text, var(--ms-warn));
}

/* ==========================================================================
   7. Reiter (Unterlinien-Stil, z. B. Einstellungsseiten eines Tools)
   ========================================================================== */

/* Grundlinie per inset-Schatten statt border-bottom + negativem Tab-Margin:
   so ragt nichts über den Container hinaus, und overflow-x:auto erzeugt
   keinen ungewollten SENKRECHTEN Scrollbalken mehr (Patrick, 2026-09-25).
   Die Leiste bleibt auf schmalen Bildschirmen seitlich wischbar, ohne
   sichtbaren Balken. Einheitlicher Abstand zum Inhalt darunter. */
.ms-tabs {
  display: flex;
  gap: var(--ms-space-1);
  box-shadow: inset 0 -1px 0 var(--ms-border);
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: none;
  margin-bottom: var(--ms-space-6);
}

.ms-tabs::-webkit-scrollbar {
  display: none;
}

.ms-tabs__tab {
  flex-shrink: 0;
  padding: 10px var(--ms-space-3);
  border: none;
  border-bottom: 2px solid transparent;
  border-radius: var(--ms-radius) var(--ms-radius) 0 0;
  background: transparent;
  color: var(--ms-text-muted);
  font: inherit;
  font-size: 13.5px;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
}

.ms-tabs__tab:hover {
  color: var(--ms-text);
}

.ms-tabs__tab[aria-selected='true'],
.ms-tabs__tab[aria-current='page'] {
  color: var(--ms-text);
  border-bottom-color: var(--ms-accent);
}

/* ==========================================================================
   8. Leerer Zustand
   ========================================================================== */

.ms-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--ms-space-2);
  padding: var(--ms-space-12) var(--ms-space-4);
  text-align: center;
  color: var(--ms-text-subtle);
}

.ms-empty__icon {
  width: 32px;
  height: 32px;
  color: var(--ms-text-subtle);
}

.ms-empty__title {
  font-size: 14.5px;
  font-weight: 600;
  color: var(--ms-text-muted);
}

.ms-empty__text {
  font-size: 13.5px;
  max-width: 44ch;
}

/* ==========================================================================
   9. Ladezustand
   ========================================================================== */

.ms-skeleton {
  display: block;
  border-radius: var(--ms-radius);
  background: linear-gradient(
    90deg,
    var(--ms-surface-2) 25%,
    var(--ms-border) 37%,
    var(--ms-surface-2) 63%
  );
  background-size: 400% 100%;
  animation: ms-skeleton-shimmer 1.4s ease infinite;
}

@keyframes ms-skeleton-shimmer {
  0% {
    background-position: 100% 50%;
  }
  100% {
    background-position: 0 50%;
  }
}

@media (prefers-reduced-motion: reduce) {
  .ms-skeleton {
    animation: none;
    background: var(--ms-surface-2);
  }
}

.ms-skeleton--text {
  height: 0.9em;
  width: 100%;
}

.ms-skeleton--title {
  height: 1.6em;
  width: 40%;
}

.ms-spinner {
  display: inline-block;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  border: 2px solid var(--ms-border);
  border-top-color: var(--ms-accent);
  animation: ms-spinner-spin 0.7s linear infinite;
}

@keyframes ms-spinner-spin {
  to {
    transform: rotate(360deg);
  }
}

@media (prefers-reduced-motion: reduce) {
  .ms-spinner {
    animation-duration: 1.4s;
  }
}

/* ==========================================================================
   10. Info-Popover (<ms-info>, siehe public/js/ui.js)
   ========================================================================== */
/* <ms-info>Erklärsatz…</ms-info> - kein Shadow DOM (siehe ui.js-Kommentar:
   diese Datei ist bereits die EINE globale Seiten-CSS, ein zweiter,
   gekapselter Stylesheet-Satz je Instanz wäre unnötige Redundanz). Verhalten
   wie 01 Cashflow/client/src/components/InfoTooltip.tsx bzw. 10 Planungstool
   Projekt/client/src/components/InfoTip.tsx: Hover ODER Klick/Tastatur
   öffnen, Escape/Klick außerhalb schließen, [data-open] ist der von ui.js
   gesetzte Klick-Zustand (zusätzlich zu :hover/:focus-within rein per CSS). */

.ms-info {
  position: relative;
  display: inline-flex;
  align-items: center;
  vertical-align: middle;
}

.ms-info__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  padding: 0;
  border: none;
  border-radius: 50%;
  background: transparent;
  color: var(--ms-text-subtle);
  cursor: pointer;
}

.ms-info__btn:hover {
  background: var(--ms-surface-2);
  color: var(--ms-text-muted);
}

.ms-info__btn ms-icon {
  width: 15px;
  height: 15px;
}

.ms-info__panel {
  position: absolute;
  z-index: 80;
  top: calc(100% + 6px);
  left: 0;
  width: max-content;
  max-width: min(320px, 80vw);
  padding: 10px 12px;
  border-radius: var(--ms-radius);
  border: 1px solid var(--ms-border);
  background: var(--ms-elevated);
  box-shadow: var(--ms-shadow-dropdown);
  color: var(--ms-text);
  font-size: 13px;
  font-weight: 400;
  line-height: 1.5;
  text-transform: none;
  letter-spacing: normal;
  white-space: normal;
  opacity: 0;
  visibility: hidden;
  transform: translateY(-2px);
  transition: opacity var(--ms-transition-fast), transform var(--ms-transition-fast), visibility var(--ms-transition-fast);
  pointer-events: none;
}

.ms-info__panel--right {
  left: auto;
  right: 0;
}

.ms-info:hover .ms-info__panel,
.ms-info:focus-within .ms-info__panel,
.ms-info[data-open] .ms-info__panel {
  opacity: 1;
  visibility: visible;
  transform: none;
  pointer-events: auto;
}

@media (prefers-reduced-motion: reduce) {
  .ms-info__panel {
    transition: none;
  }
}

/* ==========================================================================
   11. Kurzmeldungen (MSDaysi.toast, siehe public/js/ui.js)
   ========================================================================== */
/* Patrick: "Kurzmeldungen ('Gespeichert') erscheinen OBEN MITTIG unter der
   Bar; Vorschau-Banner und Bar-Höhe über --ms-bar-height beachten." Der
   Region-Container wird von ui.js einmalig erzeugt (Singleton, siehe
   dortigen Kommentar) - top-Wert berücksichtigt --ms-bar-height IMMER,
   zusätzlich --ms-preview-banner-height, wenn eine Vorschau läuft (ui.js
   liest dafür dasselbe body/html-Signal wie die Sidebar). */

.ms-toast-region {
  position: fixed;
  top: calc(var(--ms-bar-height) + var(--ms-space-3));
  left: 50%;
  transform: translateX(-50%);
  z-index: 1200; /* über Tool-Pop-ups (1100) */
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--ms-space-2);
  width: max-content;
  max-width: min(420px, calc(100vw - 2 * var(--ms-gutter)));
  pointer-events: none;
}

.ms-toast {
  display: flex;
  align-items: flex-start;
  gap: var(--ms-space-2);
  padding: 12px 14px;
  border-radius: var(--ms-radius);
  border: 1px solid var(--ms-border);
  background: var(--ms-elevated);
  box-shadow: var(--ms-shadow-dropdown);
  color: var(--ms-text);
  font-size: 13.5px;
  line-height: 1.45;
  pointer-events: auto;
  opacity: 0;
  transform: translateY(-6px);
  transition: opacity var(--ms-transition), transform var(--ms-transition);
}

.ms-toast[data-shown] {
  opacity: 1;
  transform: none;
}

.ms-toast--success {
  border-color: color-mix(in srgb, var(--ms-success) 45%, var(--ms-border));
}

.ms-toast--error {
  border-color: color-mix(in srgb, var(--ms-danger) 45%, var(--ms-border));
}

.ms-toast__icon {
  flex-shrink: 0;
  margin-top: 1px;
  width: 17px;
  height: 17px;
}

.ms-toast--success .ms-toast__icon {
  color: var(--ms-success-text, var(--ms-success));
}

.ms-toast--error .ms-toast__icon {
  color: var(--ms-danger-text, var(--ms-danger));
}

.ms-toast--info .ms-toast__icon {
  color: var(--ms-text-muted);
}

.ms-toast__text {
  flex: 1;
  min-width: 0;
  overflow-wrap: anywhere;
}

.ms-toast__close {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  margin: -2px -4px -2px 0;
  padding: 0;
  border: none;
  border-radius: 6px;
  background: transparent;
  color: var(--ms-text-subtle);
  cursor: pointer;
}

.ms-toast__close:hover {
  background: var(--ms-surface-2);
  color: var(--ms-text);
}

.ms-toast__close ms-icon {
  width: 13px;
  height: 13px;
}

@media (prefers-reduced-motion: reduce) {
  .ms-toast {
    transition: none;
  }
}

@media (max-width: 480px) {
  .ms-toast-region {
    left: var(--ms-gutter);
    right: var(--ms-gutter);
    transform: none;
    max-width: none;
    width: auto;
  }
}

/* ==========================================================================
   12. Pop-ups / Modal-Baukasten (.ms-modal) + Bestätigungsdialog
   ========================================================================== */
/* Patrick, 2026-09-29: „Bitte alle Popups einheitlich bauen. Das Feedback-
   Popup ist die Vorlage (mit dem unscharfen Hintergrund)." - DIES ist die
   EINE Quelle für Aussehen von Hintergrund (Abdunklung + Unschärfe) und
   Pop-up-Fläche in Daysi UND allen Tools (Doku + Regeln: WORKSPACES.md
   §5a „Pop-ups"). Tools bauen KEINE eigenen Overlays/Backdrops mehr.

   Zwei Varianten, identische Optik:
   a) Natives <dialog class="ms-modal"> + showModal() (bevorzugt): liegt im
      Top-Layer, also IMMER über Bar, Sidebar und Tool - kein z-index nötig.
      Esc schließt nativ; Klick auf den Hintergrund trifft das <dialog>
      selbst (e.target === dialog) und wird vom jeweiligen Skript
      geschlossen.
   b) Div-Overlay für React/ohne <dialog>:
        <div class="ms-modal-backdrop">            (fixed, z-index 1100)
          <div class="ms-modal" role="dialog" aria-modal="true">…</div>
        </div>
      z-index 1100 liegt über Daysi-Bar (1000/1001) und Sidebar (39-60),
      Kurzmeldungen (.ms-toast-region, 1200) bleiben darüber. Das Overlay
      scrollt selbst (hohe Formulare, Popover wie <ms-info> werden nicht
      abgeschnitten).

   Aufbau der Fläche (alle Teile optional):
     .ms-modal__head   > .ms-modal__titles (> __eyebrow, __title, __meta)
                       + button.ms-modal__close (×)
     .ms-modal__body   Inhalt (Spalte, 14px Abstand)
     .ms-modal__actions  Knöpfe rechtsbündig (Abbrechen links daneben)
     .ms-modal__content  freier Inhalt mit Rand (statt head/body/actions,
                       z. B. React-Formulare mit eigenem Titel) - dazu
                       .ms-modal__close--corner (× oben rechts, nur Variante b)
   Breiten: Standard 520px, --sm 420px (Rückfragen), --lg 720px, --xl 960px.

   Läuft auch im Shadow DOM von Bar/Sidebar (Tool-Hosts laden diesen
   Abschnitt dort als /_daysi/modal.css, routes/daysi.js schneidet ihn
   zwischen den Markern unten aus DIESER Datei aus - keine Kopie). Deshalb
   nur Klassen-Selektoren und für jedes Token ein Fallback-Wert (bar.css
   definiert z. B. kein --ms-radius-lg/--ms-font-display). ::backdrop erbt
   (noch nicht überall) keine Custom Properties - dort bewusst feste Werte. */

/* @ms-modal-kit:start */
.ms-modal {
  box-sizing: border-box;
  width: min(520px, calc(100vw - 32px));
  max-width: none;
  max-height: calc(100dvh - 32px);
  padding: 0;
  margin: auto;
  border: 1px solid var(--ms-border, #dfdcd4);
  border-radius: var(--ms-radius-lg, 12px);
  background: var(--ms-elevated, #ffffff);
  color: var(--ms-text, #1f1d1a);
  box-shadow: 0 24px 64px rgba(0, 0, 0, 0.32);
  font-family: var(--ms-font-ui, 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif);
  font-size: 14px;
  line-height: 1.5;
  text-align: left;
  overflow: auto;
}

.ms-modal--sm {
  width: min(420px, calc(100vw - 32px));
}

.ms-modal--lg {
  width: min(720px, calc(100vw - 32px));
}

.ms-modal--xl {
  width: min(960px, calc(100vw - 32px));
}

.ms-modal:focus {
  outline: none;
}

/* a) natives <dialog>: Hintergrund = Vorlage Feedback-Pop-up */
.ms-modal::backdrop {
  background: rgba(10, 12, 10, 0.68);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}

/* b) Div-Overlay: derselbe Hintergrund als eigenes Element */
.ms-modal-backdrop {
  position: fixed;
  inset: 0;
  z-index: 1100;
  box-sizing: border-box;
  display: flex;
  /* "safe center": zentriert; ist das Pop-up höher als das Fenster, fällt
     es auf Top-Ausrichtung zurück und das Overlay scrollt (nichts wird
     oben abgeschnitten). */
  align-items: safe center;
  justify-content: center;
  padding: 32px 16px;
  overflow-y: auto;
  overscroll-behavior: contain;
  background: rgba(10, 12, 10, 0.68);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}

.ms-modal-backdrop[hidden] {
  display: none;
}

/* Blockierende Fortschrittsanzeige (kein Schließen per Klick/Esc). */
.ms-modal-backdrop--busy {
  cursor: progress;
}

.ms-modal-backdrop > .ms-modal {
  position: relative;
  flex-shrink: 0;
  max-height: none;
  margin: auto;
  overflow: visible;
}

@media (prefers-reduced-motion: no-preference) {
  .ms-modal[open],
  .ms-modal-backdrop > .ms-modal {
    animation: ms-modal-in 0.16s ease-out;
  }
}

@keyframes ms-modal-in {
  from {
    opacity: 0;
    transform: translateY(8px) scale(0.99);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

.ms-modal__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  padding: 20px 24px 0;
}

.ms-modal__titles {
  flex: 1;
  min-width: 0;
}

.ms-modal__eyebrow {
  margin: 0 0 2px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ms-text-subtle, #6b6761);
}

/* Serifen-Titel wie Seiten- und Kartentitel (Playfair Display). */
.ms-modal__title {
  margin: 0;
  font-family: var(--ms-font-display, 'Playfair Display', Georgia, 'Times New Roman', serif);
  font-size: 22px;
  font-weight: 400;
  line-height: 1.3;
  letter-spacing: normal;
  color: var(--ms-text, #1f1d1a);
  overflow-wrap: anywhere;
}

.ms-modal__title:focus {
  outline: none;
}

.ms-modal--danger .ms-modal__title {
  color: var(--ms-danger-text, var(--ms-danger, #a8392f));
}

.ms-modal__meta {
  margin: 4px 0 0;
  font-size: 13px;
  color: var(--ms-text-muted, #64615a);
}

.ms-modal__close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 32px;
  height: 32px;
  margin: -4px -8px 0 0;
  padding: 0;
  border: none;
  border-radius: var(--ms-radius, 8px);
  background: transparent;
  color: var(--ms-text-muted, #64615a);
  font: inherit;
  cursor: pointer;
}

.ms-modal__close:hover {
  background: var(--ms-surface-2, #f8f6f2);
  color: var(--ms-text, #1f1d1a);
}

.ms-modal__close:focus-visible {
  outline: 2px solid var(--ms-accent, #f5cb69);
  outline-offset: 2px;
}

.ms-modal__close svg,
.ms-modal__close .ms-icon,
.ms-modal__close ms-icon {
  width: 18px;
  height: 18px;
}

/* × oben rechts über freiem Inhalt (.ms-modal__content, nur Variante b). */
.ms-modal__close--corner {
  position: absolute;
  top: 14px;
  right: 14px;
  z-index: 1;
  margin: 0;
}

.ms-modal__body {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 12px 24px 4px;
}

.ms-modal__text {
  margin: 0;
  color: var(--ms-text-muted, #64615a);
}

.ms-modal__actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 8px;
  padding: 16px 24px 20px;
}

.ms-modal__content {
  padding: 20px 24px;
}

.ms-modal__head[hidden],
.ms-modal__body[hidden],
.ms-modal__actions[hidden] {
  display: none;
}

.ms-modal__content .ms-modal__title {
  margin: 0 0 12px;
}

.ms-modal__close--corner ~ .ms-modal__content .ms-modal__title {
  padding-right: 32px;
}

@media (max-width: 480px) {
  .ms-modal__head {
    padding: 16px 16px 0;
  }
  .ms-modal__body {
    padding: 12px 16px 4px;
  }
  .ms-modal__actions {
    padding: 14px 16px 16px;
  }
  .ms-modal__content {
    padding: 16px;
  }
  .ms-modal__close--corner {
    top: 10px;
    right: 10px;
  }
  .ms-modal-backdrop {
    padding: 16px 8px;
  }
  .ms-modal-backdrop > .ms-modal {
    width: 100%;
  }
}
/* @ms-modal-kit:end */

/* Bestätigungsdialog (MSDaysi.confirm, public/js/ui.js), Zwei-Faktor-
   Rückfrage (public/js/roles-board.js) und „Erledigt"-Dialog der Feedback-
   Verwaltung (views/adminFeedback.js) sind reine .ms-modal-Pop-ups (--sm
   bzw. Standard) - keine eigenen Regeln mehr (früher .ms-confirm-dlg*). */

/* ==========================================================================
   13. Zwei-Spalten-Zuordnung (.ms-board)
   ========================================================================== */
/* Patrick, 2026-09-27 (Rollenverwaltung): „zwei Spalten … links zugeordnet,
   rechts nicht zugeordnet, per Drag and Drop verschiebbar. Dazu muss man
   vorher natürlich auswählen, zu wem oder was ich es zuordne." Generischer
   Baustein: oben die Auswahl (.ms-board-picker), darunter zwei Karten-Spalten
   (.ms-board__col--assigned / --available) mit Einträgen (.ms-board__item),
   jeder mit einem Pfeil-Knopf (echtes POST-Formular, .ms-board__form).
   Drag & Drop, fetch und Zähler übernimmt public/js/roles-board.js
   (data-ms-board*-Attribute, siehe WORKSPACES.md §5a) - ohne JS bleibt
   alles über die Formulare bedienbar. Mobil (< 720px) stehen die Spalten
   untereinander, die Pfeile zeigen dann nach unten/oben. */

.ms-board-picker {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--ms-space-3) var(--ms-space-4);
  margin-bottom: var(--ms-space-6);
}

.ms-board-picker__form {
  display: flex;
  align-items: flex-end;
  gap: var(--ms-space-2);
  flex: 1 1 280px;
  min-width: 0;
}

.ms-board-picker__form .ms-field {
  flex: 1 1 auto;
  min-width: 0;
  max-width: 440px;
}

.ms-board-picker__submit {
  margin-bottom: 6px;
}

.ms-board-picker__submit[hidden] {
  display: none;
}

.ms-board-picker__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--ms-space-2);
}

.ms-board-picker__meta {
  flex-basis: 100%;
  margin: 0;
  color: var(--ms-text-muted);
  font-size: 13.5px;
}

.ms-board {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--ms-space-4);
}

@media (max-width: 719px) {
  .ms-board {
    grid-template-columns: minmax(0, 1fr);
  }
}

.ms-board__col {
  display: flex;
  flex-direction: column;
  gap: var(--ms-space-3);
  min-width: 0;
  min-height: 180px;
  padding: var(--ms-space-4);
  transition: border-color var(--ms-transition-fast), background var(--ms-transition-fast), box-shadow var(--ms-transition-fast);
}

/* Drop-Ziel während des Ziehens (gesetzt von roles-board.js). */
.ms-board__col--over {
  border-color: var(--ms-accent);
  background: color-mix(in srgb, var(--ms-accent) 6%, var(--ms-surface));
  box-shadow: 0 0 0 3px var(--ms-focus-ring);
}

.ms-board__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--ms-space-2);
}

.ms-board__title {
  margin: 0;
  font-family: var(--ms-font-ui);
  font-size: 14.5px;
  font-weight: 600;
  line-height: 1.3;
  color: var(--ms-text);
}

.ms-board__count {
  font-variant-numeric: tabular-nums;
}

.ms-board__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--ms-space-2);
}

.ms-board__item {
  display: flex;
  align-items: center;
  gap: var(--ms-space-3);
  padding: 10px 10px 10px 12px;
  border: 1px solid var(--ms-border);
  border-radius: var(--ms-radius);
  background: var(--ms-surface);
  cursor: grab;
  transition: opacity var(--ms-transition-fast), border-color var(--ms-transition-fast), box-shadow var(--ms-transition-fast);
}

.ms-board__item:hover {
  border-color: var(--ms-border-strong);
}

.ms-board__item--dragging {
  opacity: 0.45;
  cursor: grabbing;
}

.ms-board__item--busy {
  opacity: 0.7;
}

/* Kurzes Aufleuchten nach erfolgreichem Verschieben. */
.ms-board__item--moved {
  animation: ms-board-moved 0.7s ease-out;
}

@keyframes ms-board-moved {
  from {
    border-color: var(--ms-accent);
    box-shadow: 0 0 0 3px var(--ms-focus-ring);
  }
  to {
    border-color: var(--ms-border);
    box-shadow: none;
  }
}

.ms-board__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 32px;
  height: 32px;
  border-radius: var(--ms-radius);
  background: var(--ms-surface-2);
  color: var(--ms-text-muted);
}

.ms-board__body {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1 1 auto;
  min-width: 0;
}

.ms-board__name {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
  font-size: 13.5px;
  font-weight: 500;
  color: var(--ms-text);
}

.ms-board__label {
  overflow-wrap: anywhere;
}

.ms-board__sub {
  font-size: 12.5px;
  color: var(--ms-text-subtle);
  overflow-wrap: anywhere;
}

.ms-board__form {
  flex-shrink: 0;
  margin: 0;
}

.ms-board__move {
  width: 32px;
  padding: 0;
}

/* Pfeil je nach Spalte: links (zugeordnet) „→ entfernen", rechts (nicht
   zugeordnet) „← zuordnen" - beide Icons stehen im Markup, damit
   roles-board.js beim Verschieben nichts neu rendern muss. */
.ms-board__col--assigned .ms-board__move-assign,
.ms-board__col--available .ms-board__move-revoke {
  display: none;
}

@media (max-width: 719px) {
  .ms-board__move .ms-icon {
    transform: rotate(90deg);
  }
}

.ms-board__empty {
  margin: 0;
  padding: var(--ms-space-4) var(--ms-space-2);
  border: 1px dashed var(--ms-border);
  border-radius: var(--ms-radius);
  text-align: center;
  font-size: 13.5px;
  color: var(--ms-text-subtle);
}

.ms-board__empty[hidden] {
  display: none;
}

.ms-board__hint,
.ms-board__summary {
  margin: var(--ms-space-3) 0 0;
  font-size: 13px;
  color: var(--ms-text-muted);
}

.ms-board__summary strong {
  color: var(--ms-text);
  font-weight: 600;
}

/* -- Runde 2 (2026-09-27): Live-Suche, Gruppen-Überschriften, gesperrte
   Einträge, technische Schlüssel, Rückfrage-Karte ------------------------ */

/* Ausgewählter Eintrag als Zeile über dem Board („Ausgewählt: … · Ändern"). */
.ms-board-picker__selected strong {
  color: var(--ms-text);
  font-weight: 600;
}

.ms-board-picker__selected .ms-badge {
  margin-left: 4px;
}

/* Suchfeld mit Vorschlagsliste (role="listbox", public/js/roles-board.js). */
.ms-board-search {
  position: relative;
}

.ms-board-search__list {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  z-index: 50;
  margin: 0;
  padding: var(--ms-space-1);
  list-style: none;
  max-height: min(360px, 60vh);
  overflow-y: auto;
  background: var(--ms-elevated);
  border: 1px solid var(--ms-border);
  border-radius: var(--ms-radius);
  box-shadow: var(--ms-shadow-dropdown);
}

.ms-board-search__list[hidden] {
  display: none;
}

.ms-board-search__option {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--ms-space-2);
  padding: 8px 10px;
  border-radius: calc(var(--ms-radius) - 2px);
  cursor: pointer;
}

.ms-board-search__option[aria-selected='true'] {
  background: var(--ms-accent-soft);
  color: var(--ms-accent-soft-text);
}

.ms-board-search__body {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.ms-board-search__name {
  font-size: 14px;
  font-weight: 500;
  color: inherit;
  overflow-wrap: anywhere;
}

.ms-board-search__sub {
  font-size: 12.5px;
  color: var(--ms-text-subtle);
  overflow-wrap: anywhere;
}

.ms-board-search__badges {
  display: inline-flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 4px;
  flex-shrink: 0;
}

.ms-board-search__empty {
  padding: 8px 10px;
  font-size: 13.5px;
  color: var(--ms-text-subtle);
}

/* Trefferliste der Suche ohne JS (?suche=). */
.ms-board-hits {
  display: flex;
  flex-direction: column;
  gap: var(--ms-space-3);
  padding: var(--ms-space-4);
}

.ms-board-hits__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--ms-space-2);
}

.ms-board-hits__item {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
}

.ms-board-hits__link {
  display: inline-flex;
  flex-direction: column;
  min-width: 0;
  color: var(--ms-text);
  text-decoration: none;
}

.ms-board-hits__link:hover .ms-board-search__name,
.ms-board-hits__link:focus-visible .ms-board-search__name {
  text-decoration: underline;
}

/* Gruppen-Überschrift innerhalb einer Spalte (Reiter 3: „Daysi › Dashboard",
   „Planung", …) - roles-board.js blendet leere Gruppen aus. */
.ms-board__heading {
  margin: var(--ms-space-2) 0 0;
  padding: 0 2px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ms-text-subtle);
}

.ms-board__heading:first-child {
  margin-top: 0;
}

.ms-board__heading[hidden] {
  display: none;
}

/* Technischer Schlüssel (FN_…) unter dem Namen. */
.ms-board__code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 12px;
  padding: 1px 5px;
  border-radius: 4px;
  background: var(--ms-surface-2);
  color: var(--ms-text-muted);
  overflow-wrap: anywhere;
}

.ms-board__sub-text {
  overflow-wrap: anywhere;
}

.ms-board__name ms-info {
  flex-shrink: 0;
}

/* Gesperrte System-Zuordnung: nicht ziehbar, kein Pfeil-Knopf. */
.ms-board__item--locked {
  cursor: default;
  background: var(--ms-surface-2);
}

.ms-board__fixed {
  flex-shrink: 0;
}

/* Live-Filter der Spalte „Nicht zugeordnet" (ab 6 Einträgen, rein
   clientseitig über roles-board.js - ohne JS bleibt das Feld hidden).
   Kleiner als ein normales Formularfeld; „(3 von 12)" steht in der
   Spaltenüberschrift. Per Filter ausgeblendete Einträge tragen `hidden`
   (die Klasse setzt sonst display:flex). */
.ms-board__filter[hidden],
.ms-board__item[hidden] {
  display: none;
}

.ms-board__filter input[type='search'] {
  height: 34px;
  padding: 0 10px;
  font-size: 13.5px;
}

.ms-board__filter-status {
  font-weight: 400;
  color: var(--ms-text-muted);
  font-variant-numeric: tabular-nums;
}

/* Rückfrage ohne JS („Der Benutzer kann sich danach nicht mehr anmelden …"). */
.ms-board-confirm {
  display: flex;
  flex-direction: column;
  gap: var(--ms-space-3);
  margin-bottom: var(--ms-space-6);
  padding: var(--ms-space-4);
  border-color: var(--ms-danger);
}

.ms-board-confirm__title {
  display: flex;
  align-items: center;
  gap: var(--ms-space-2);
  margin: 0;
  font-family: var(--ms-font-ui);
  font-size: 15px;
  font-weight: 600;
  color: var(--ms-text);
}

.ms-board-confirm__title .ms-icon {
  color: var(--ms-danger-text, var(--ms-danger));
}

.ms-board-confirm__text {
  margin: 0;
  color: var(--ms-text-muted);
}

.ms-board-confirm__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--ms-space-2);
  margin: 0;
}

@media (prefers-reduced-motion: reduce) {
  .ms-board__col,
  .ms-board__item {
    transition: none;
  }

  .ms-board__item--moved {
    animation: none;
  }
}

/* ==========================================================================
   14. Seitenhintergrund mit Tiefe
   ========================================================================== */
/* Patrick, 2026-09-27 (abgestimmtes Mockup „Tool-Hintergrund mit Tiefe"):
   ein dezenter Hintergrund mit Tiefe hinter den Inhalten - in Daysi UND in
   allen Tools, ohne DOM-Änderung in den Tools.
     - Dunkel „Lichtschein + Punkte": weicher Schein in der Akzentfarbe oben
       links im Inhaltsbereich (30 % der Fensterbreite, also rechts der
       Seitenleiste) plus feines Punktraster (18px, 1px-Punkte, 9 % der
       Textfarbe), nach unten auf 35 % auslaufend; Gesamtstärke 50 %.
     - Hell „Ebenen & Schatten": KEINE Struktur - der Grund wird eine Spur
       dunkler/wärmer (--ms-page-bg) mit sehr sanftem Verlauf (oben etwas
       heller, unten etwas dunkler, wie im Mockup), die Tiefe kommt von den
       Karten (--ms-shadow-card/--ms-card-border-depth, Abschnitt 2).
   Farben ausschließlich über die Tiefe-Token aus ms.css Abschnitt
   „2. Design-Tokens" (im Tool über /_daysi/tokens.css) - eigene Paletten
   ziehen automatisch mit.

   BEWUSSTE AUSNAHME von der Regel im Kopfkommentar (nur Klassen-Selektoren):
   die Ebene hängt an html/body, damit kein Tool sein Markup ändern muss.
     - <html> trägt den Seitengrund (auch beim Über-/Zurückscrollen sichtbar).
     - <body> wird transparent - `!important` ABSICHTLICH: Daysi (ms.css)
       und jedes Tool (index.css/style.css) färben <body> heute selbst; so
       muss dort nichts angefasst werden. Ein Tool darf deshalb <html> NICHT
       selbst färben (sonst verdeckt es diesen Grund).
     - body::before ist die eigentliche Ebene: fest am Fenster, z-index -1.
       Das funktioniert, weil <body> transparent ist und keinen eigenen
       Stacking-Context bildet (kein position+z-index/transform/filter auf
       <body>) - die Ebene liegt damit über dem html-Grund und unter dem
       gesamten Seiteninhalt. Bar, Sidebar und zweite Spalte sind fest
       positioniert mit deckender eigener Fläche und liegen darüber; die
       Bild-Ebene der Daysi-Startseite (ms.css .ms-start-bg, ebenfalls
       z-index -1, aber später im Dokument) liegt ebenfalls darüber.
   Karten/Tabellen/Dialoge bleiben deckend. Keine Animation. */

html {
  background: var(--ms-page-bg, var(--ms-bg));
}

body {
  background: transparent !important;
}

body::before {
  content: '';
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  /* Hell: nur der sanfte Verlauf des Grundes (≈ 3 % → 7 % Richtung
     Textfarbe, um --ms-page-bg mit 5 % herum), keine Punkte. */
  background: linear-gradient(
    to bottom,
    color-mix(in srgb, var(--ms-page-bg) 65%, var(--ms-bg)),
    color-mix(in srgb, var(--ms-page-bg) 98%, var(--ms-text))
  );
}

/* Dunkel „Lichtschein + Punkte" - dieselben zwei Selektor-Blöcke wie die
   Token selbst (automatisch nach Systemeinstellung bzw. explizit gewählt),
   Inhalt in beiden Blöcken identisch. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) body::before {
    background:
      radial-gradient(ellipse 60% 50% at 30% 0%, color-mix(in srgb, var(--ms-depth-glow) 12%, transparent), transparent 70%),
      radial-gradient(color-mix(in srgb, var(--ms-depth-dots) 9%, transparent) 1px, transparent 1.2px);
    background-size: auto, 18px 18px;
    -webkit-mask-image: linear-gradient(to bottom, #000, rgba(0, 0, 0, 0.35));
    mask-image: linear-gradient(to bottom, #000, rgba(0, 0, 0, 0.35));
    opacity: 0.5;
  }
}

:root[data-theme='dark'] body::before {
  background:
    radial-gradient(ellipse 60% 50% at 30% 0%, color-mix(in srgb, var(--ms-depth-glow) 12%, transparent), transparent 70%),
    radial-gradient(color-mix(in srgb, var(--ms-depth-dots) 9%, transparent) 1px, transparent 1.2px);
  background-size: auto, 18px 18px;
  -webkit-mask-image: linear-gradient(to bottom, #000, rgba(0, 0, 0, 0.35));
  mask-image: linear-gradient(to bottom, #000, rgba(0, 0, 0, 0.35));
  opacity: 0.5;
}

@media print {
  body::before {
    display: none;
  }
}

/* ==========================================================================
   15. Barrierefreiheit: Sprungziel
   ========================================================================== */
/* Ziel des Sprunglinks (views/bar.js, .ms-skip-link): bekommt per Skript
   tabindex="-1" + Fokus - der Fokus soll dort keinen Rahmen um den ganzen
   Inhaltsbereich zeichnen (die nächste Tab-Taste landet im Inhalt). */
main[tabindex='-1']:focus,
#ms-main:focus {
  outline: none;
}
