/* Apollon UI-Redesign — adesso design system, scoped under .crm
   ===================================================================
   GEPFLEGTE QUELLE — diese Datei wird DIREKT bearbeitet.
   Verbindliche Änderungsregel: .context/conventions/21-redesign-css-source.md
   ===================================================================

   Herkunft: einmalig aus dem Design-Handoff-Bundle "Apollon neues Design"
   (2. Export, 2026-07-16) erzeugt — dessen vier Quelldateien (tokens.css,
   components.css, flow.css, flow-modules.css) lagen ausschliesslich in einem
   temporaeren Sitzungsordner und wurden nie versioniert. Sie sind unwiederbringlich
   weg. Der einmalige Generator (scripts/pr4.15-scope-redesign-css.mjs) war damit
   nicht mehr lauffaehig und wurde in RD1.10 (#333) entfernt.

   Der frueher hier stehende Hinweis, die Datei sei generiert und duerfe nur ueber einen
   erneuten Skriptlauf geaendert werden, war doppelt unwahr: das Skript lief nicht mehr,
   und die Datei wurde seither zweimal korrekt von Hand geaendert (PR4.17 P6 — AA-Kontrast
   --text-3; PR1.128 — .conf-unrated). Ein erneuter Lauf haette genau diese Korrekturen
   still zurueckgerollt.

   Aufbau (aus der urspruenglichen Erzeugung, weiterhin gueltig):
   - Google-Fonts @import entfernt (Self-Hosting via fonts.css)
   - Komponenten-CSS traegt den Praefix .crm, um das Legacy-Layout nicht zu beruehren
   - @keyframes bleiben global (werden ueber ihren Namen referenziert)
   - Dark laeuft ueber html[data-theme="dark"] .crm (ein Schalter, FOUC-sicher);
     der Klassen-Alias .crm.dark steht zur Paritaet daneben

   Maschinelle Absicherung: scripts/check-ui-craft.mjs (8 Pruefungen, Ratchet) und
   scripts/check-crm-contrast.mjs (WCAG-AA) — beide blockierend in CI. */

/* ===================================================================
   MOUNT SWITCH — legacy vs redesign shell (global, flag-gated)
   =================================================================== */
#app-crm { display: none; }
html[data-ui="new"] .app-wrapper { display: none !important; }
html[data-ui="new"] #app-crm { display: block; }
#app-crm.crm { height: 100vh; height: 100dvh; width: 100%; overflow: hidden; }

/* ===================================================================
   TOKENS (already .crm / .crm.dark scoped)
   =================================================================== */
/* ──────────────────────────────────────────────────────────────
   Apollon Redesign — Design Tokens
   adesso-Palette: #006EC7 (Blue) · #461EBE (Violet) · #FF9868 (Orange)
                   #76C800 (Green) · #28DCAA (Turquoise)
                   #887D75 (Grey) · #E7E5E3 (Grey-20) · #CFCBC8 (Grey-40)
   Typografie: Fira Sans / Fira Sans Condensed
   ────────────────────────────────────────────────────────────── */


.crm {
  /* Brand */
  --ad-blue: #006EC7;
  /* RD1.11 #334 — die helle Blau-Stufe fuer Dark. Stand bisher fuenfmal als Literal
     #62B5FF in der Datei (Badge, Tabellen-Link, Chip, aktiver Tab) — jetzt einmal
     benannt. Gehoert in die Palette, nicht in den Dark-Block: es ist eine Farbe des
     adesso-Faechers, kein themenabhaengiger Wert. */
  --ad-blue-300: #62B5FF;
  --ad-blue-700: #005AA3;
  --ad-blue-800: #003F75;
  --ad-blue-900: #002B52;
  --ad-violet: #461EBE;
  --ad-violet-600: #5A38C9;
  /* RD1.11 #334 — Rot war als einzige Ampelfarbe nie benannt: #E5484D und #C4353A
     standen viermal verstreut in Heat-, NKV-, Konfidenz- und Ablehnen-Regeln. Gleiche
     Stufung wie die uebrigen Faecherfarben (Grundton + -700 fuer Text auf hellem Grund). */
  --ad-red: #E5484D;
  --ad-red-700: #C4353A;
  /* RD1.13 #336 Reparatur — weisse Schrift auf --ad-red kommt nur auf 3.91:1. Der
     Loesch-Knopf traegt sie in 12px/normal, also gilt 4.5:1. Grundton wird --ad-red-700
     (5.36:1), und weil der Hover dunkler sein muss als der Grund, bekommt Rot hier seine
     dritte Stufe (7.42:1). */
  --ad-red-800: #A32328;
  /* Helle Stufe fuer Rot-Text auf dunklem Grund: --ad-red-700 kommt dort nur auf 3.07:1
     und faellt unter AA. Stand bereits dreimal als Literal #FF8A8F im Dark-Zweig. */
  --ad-red-300: #FF8A8F;
  --ad-orange: #FF9868;
  --ad-orange-700: #E07842;
  /* RD1.13 #336 Reparatur — Textstufen fuer die hellen Faecherfarben AUF ihrem eigenen
     Tint. Die -700-Stufen sind dafuer zu hell: --ad-orange-700 auf --tint-orange ergibt
     2.59:1, --ad-turq-700 auf --tint-turq 2.82:1. Beide Badges fuehren normalen Text in
     11.5px, es gilt also 4.5:1. Die neuen Stufen kommen auf 5.32:1 bzw. 6.40:1.
     Bewusst NICHT die Grundtoene aendern — die sind die Marke. */
  --ad-orange-900: #9A4A1E;
  --ad-green: #76C800;
  --ad-green-700: #5DA000;
  --ad-turq: #28DCAA;
  --ad-turq-700: #14A37C;
  --ad-turq-900: #0B6349;
  --ad-grey: #887D75;
  --ad-grey-20: #E7E5E3;
  --ad-grey-40: #CFCBC8;

  /* Soft tints (light) */
  --tint-blue: #E5F0FA;
  --tint-violet: #ECE6FB;
  --tint-orange: #FFE9DC;
  /* PR1.324 #533 — Pythia-Terrakotta, nur fuers Medaillon; aus der Orange-Rampe
     abgeleitet (-900 auf Hell, AA; -700 waere unter 3:1). */
  --pythia-terra: var(--ad-orange-900);
  --pythia-terra-grund: var(--tint-orange);
  --tint-green: #E8F6CF;
  --tint-turq: #D6F8EE;
  --tint-warn: #FFF1E5;
  /* RD1.13 #336 Reparatur — der Rot-Tint fehlte als einziger in dieser Reihe und stand
     dreimal als Literal #FBE8E9 (NKV-Heat, Konfidenz, Ablehnen-Knopf), sein Dark-Pendant
     dreimal als #3A1F20. Einmal benannt spart sechs Rohwerte und macht die drei
     Dark-Overrides ueberfluessig — der Tint schaltet jetzt selbst um. */
  --tint-red: #FBE8E9;

  /* Light theme */
  --bg-shell: #003F75;            /* contrast-rich app frame */
  --bg-app: #F4F6F9;
  --bg-surface: #FFFFFF;
  --bg-surface-2: #F7F8FA;
  --bg-surface-3: #EEF1F5;
  --bg-hover: #EEF3F9;
  --border: #E0E4EA;
  --border-strong: #C8CFD9;
  --text-1: #0E1726;
  --text-2: #4B5666;
  --text-3: #68707F;            /* PR4.17 P6 — AA: 3.78→4.98:1 auf --bg-surface (kleine Labels) */
  --text-inv: #FFFFFF;
  --focus: #006EC7;
  --shadow-1: 0 1px 0 rgba(15, 23, 38, 0.04), 0 1px 2px rgba(15, 23, 38, 0.06);
  --shadow-2: 0 6px 16px -8px rgba(15, 23, 38, 0.18), 0 2px 4px rgba(15, 23, 38, 0.06);
  --shadow-3: 0 24px 60px -28px rgba(15, 23, 38, 0.30), 0 8px 18px -10px rgba(15, 23, 38, 0.12);

  /* ── Legacy-Kompatibilitaet (PR1.229 #399) ─────────────────────────────────
     style.css ist die gemeinsame Basis beider Shells. Es konsumiert sieben
     Flaechen- und Textnamen, die die Redesign-Shell bisher nur in drei engen
     Komponenten-Scopes belegt hat (.fb-form/.fb-foot, .ms/.ms-list, .fw — je
     eingefuehrt von PR1.189/190/191). Alles ausserhalb dieser Scopes erbte
     weiter aus dem Legacy-:root und war damit vom Attribut html[data-theme]
     abhaengig, das die Redesign-Shell nicht kontrolliert: ohne data-theme traf
     helle Redesign-Schrift auf dunklen Legacy-Grund (Team-Tabelle der
     Projektmaske: 1,03:1). Die Belegung an der Wurzel macht die Shell davon
     unabhaengig und beendet das wiederholte lokale Nachflicken.

     Kein Dark-Pendant noetig: die Zieltokens sind selbst themenabhaengig
     (Block ab .crm.dark), die var()-Indirektion traegt Dark automatisch mit.
     Eine zweite Deklaration waere eine Dublette, die beim naechsten
     Wertwechsel auseinanderlaeuft. Der Ratchet in
     test/pr1-229-crm-token-mapping.test.mjs haelt beides fest. */
  --bg-base: var(--bg-app);
  --bg-card: var(--bg-surface);
  --bg-card2: var(--bg-surface-2);
  --bg-input: var(--bg-surface);
  --border-light: var(--border);
  --text-primary: var(--text-1);
  --text-secondary: var(--text-2);

  /* Radii */
  --r-xs: 4px;
  --r-sm: 6px;
  --r-md: 8px;
  --r-lg: 10px;
  --r-xl: 14px;

  /* Spacing scale */
  --s-1: 4px; --s-2: 8px; --s-3: 12px; --s-4: 16px;
  --s-5: 20px; --s-6: 24px; --s-8: 32px; --s-10: 40px;

  /* Type */
  --f-sans: 'Fira Sans', system-ui, sans-serif;
  --f-cond: 'Fira Sans Condensed', 'Fira Sans', sans-serif;
  --f-mono: 'Fira Mono', ui-monospace, monospace;

  /* Motion */
  --t-fast: 120ms cubic-bezier(.2,.6,.2,1);
  --t-med:  160ms cubic-bezier(.2,.6,.2,1);
  --t-slow: 220ms cubic-bezier(.2,.6,.2,1);
  --ease-out: cubic-bezier(.2,.7,.3,1);
}

.crm.dark , html[data-theme="dark"] .crm {
  --bg-shell: #06121F;
  --bg-app: #0B1828;
  --bg-surface: #0F2033;
  --bg-surface-2: #132A42;
  --bg-surface-3: #18334F;
  --bg-hover: #163049;
  --border: #1F3A57;
  --border-strong: #2C547D;
  --text-1: #E9EEF5;
  --text-2: #A6B3C4;
  --text-3: #8497AC;            /* PR4.17 P6 — AA: 3.78→5.49:1 auf --bg-surface (Dark) */
  --tint-blue: #0E2C49;
  --tint-violet: #1F1640;
  --tint-orange: #3A2418;
  --pythia-terra: var(--ad-orange);
  --pythia-terra-grund: var(--tint-orange);
  --tint-green: #1B2D0A;
  --tint-turq: #0E2E26;
  --tint-warn: #3A2A1B;
  --tint-red: #3A1F20;
  --shadow-1: 0 1px 0 rgba(0,0,0,.5);
  --shadow-2: 0 6px 16px -8px rgba(0,0,0,.6);
  --shadow-3: 0 24px 60px -28px rgba(0,0,0,.7);
  /* RD1.11 #334 — Dark-Pendant fuer den Fokus-Ring. Der Light-Wert --focus (#006EC7)
     liegt auf --bg-app (#0B1828) bei 1.7:1 und waere praktisch unsichtbar. --ad-blue-300
     ist derselbe Blauton, den Tabellen-Link, Badge, Chip und aktiver Tab im Dark-Modus
     bereits tragen — ein weiterer Ton waere unnoetige Streuung. */
  --focus: var(--ad-blue-300);
  /* PR1.296 #503 — der geerbte Legacy-Wert (#ef4444) kommt auf --bg-surface nur
     auf 4.37:1; die Ampel-Beschriftung "zu langsam" in der Antwortzeiten-Tabelle
     verfehlte AA damit knapp. --ad-red-300 ist derselbe Ton, den Badge, Chip und
     KB-Status im Dark-Modus bereits tragen (s. .bdg-danger) — ein weiterer waere
     unnoetige Streuung. Keine Flaeche im .crm-Scope traegt Text auf --danger:
     geprueft sind alle neun CSS- und zweiundzwanzig Inline-Verwendungen; sie
     setzen color, border-color oder einen Punkt ohne Beschriftung. */
  --danger: var(--ad-red-300);
}

/* Reset within .crm */
.crm, .crm * { box-sizing: border-box; }
.crm { font-family: var(--f-sans); color: var(--text-1); -webkit-font-smoothing: antialiased; }
.crm button { font-family: inherit; }

@media (prefers-reduced-motion: reduce) {
  .crm *, .crm *::before, .crm *::after { transition: none !important; animation: none !important; }
}

/* ===================================================================
   COMPONENTS
   =================================================================== */
/* ──────────────────────────────────────────────────────────────
   Apollon Redesign — Components & Layout (shared across variants)
   ────────────────────────────────────────────────────────────── */

/* ============== APP SHELL ============== */
.crm .app-shell {
  display: grid;
  grid-template-columns: minmax(0, 240px) 1fr;
  background: var(--bg-shell);
  padding: 12px;
  gap: 0;
  border-radius: var(--r-xl);
  height: 100%;
  width: 100%;
  overflow: hidden;
}
.crm .app-shell.shell-attio { grid-template-columns: minmax(0, 232px) 1fr; padding: 8px 8px 8px 8px; background: var(--bg-app); }
.crm .app-shell.shell-sf    { grid-template-columns: 1fr; padding: 0; background: var(--bg-surface); }
.crm .app-shell.shell-hybrid { grid-template-columns: minmax(0, 240px) 1fr; padding: 10px; background: var(--bg-shell); }

.crm .app-canvas {
  background: var(--bg-app);
  border-radius: var(--r-lg);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  min-width: 0;
}
.crm .shell-attio .app-canvas { background: var(--bg-surface); border-radius: var(--r-md); box-shadow: var(--shadow-2); }
.crm .shell-sf .app-canvas { border-radius: 0; }

/* RD1.11 #334 — Scroll-Fundament. #crm-content ist der Container, in den JEDE Redesign-View
   rendert, und hatte bis hier keine einzige Regel: ein display:block-Div, dessen Kinder mit
   flex:1;overflow:auto rechnen. Das ging nie auf — die Scrollboxen wuchsen mit dem Inhalt,
   ihr overflow griff nie, und .app-canvas{overflow:hidden} kappte alles unterhalb der
   Viewporthoehe. Diese vier Properties sind die Ursache-Reparatur; min-height:0 ist der Teil,
   ohne den ein Flex-Kind nicht unter seine Inhaltshoehe schrumpfen darf.
   Bewusst KEIN overflow hier: gescrollt wird genau eine Ebene tiefer, in der View
   (Pruefung 4 aus RD1.10 verlangt genau einen Scroll-Bereich je Ansicht). */
.crm #crm-content {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
}

/* ============== SIDEBAR ============== */
.crm .sidebar {
  display: flex;
  flex-direction: column;
  padding: 14px 12px 10px;
  color: var(--text-inv);
  font-family: var(--f-sans);
  min-width: 0;
  /* RD1.11 #334 — ohne min-height:0 wird .sb-foot (margin-top:auto) bei kurzem Fenster
     aus dem overflow:hidden der Shell herausgedrueckt: der Benutzer-Chip und damit das
     Abmelden waeren unerreichbar. Gescrollt wird die Nav-Liste, siehe .sb-list.
     BEWUSST KEIN overflow:hidden hier — das Benutzermenue ist ein absolut positioniertes
     Popover im .sb-foot und wuerde daran abgeschnitten. Das Begrenzen uebernimmt die
     schrumpfende Nav-Liste. */
  min-height: 0;
}
.crm .shell-attio .sidebar { color: var(--text-1); padding: 12px 10px; background: var(--bg-surface-2); border-radius: var(--r-md); margin-right: 8px; border: 1px solid var(--border); }

.crm .sb-brand {
  display: flex; align-items: center; gap: 10px;
  padding: 6px 8px 14px; font-family: var(--f-cond); font-weight: 700;
}
.crm .sb-brand img { width: 22px; height: 22px; flex: 0 0 auto; }
.crm .sb-brand-text { display: flex; flex-direction: column; line-height: 1.05; }
.crm .sb-brand-text b { font-size: 16px; letter-spacing: .2px; }
.crm .sb-brand-text small { font-size: 10.5px; opacity: .65; font-weight: 500; letter-spacing: .8px; text-transform: uppercase; }

.crm .sb-search {
  display: flex; align-items: center; gap: var(--s-2);
  margin: 0 4px 14px;
  padding: 7px 10px;
  background: rgba(255,255,255,.08);
  border: 1px solid rgba(255,255,255,.10);
  border-radius: var(--r-md);
  font-size: 12.5px; color: rgba(255,255,255,.85);
  cursor: text;
  transition: background var(--t-fast), border-color var(--t-fast);
}
.crm .sb-search:hover { background: rgba(255,255,255,.13); }
.crm .sb-search kbd {
  margin-left: auto;
  font-family: var(--f-mono);
  font-size: 10.5px;
  padding: 2px 6px;
  background: rgba(255,255,255,.10);
  border-radius: var(--r-xs);
  color: rgba(255,255,255,.7);
}
.crm .shell-attio .sb-search {
  background: var(--bg-surface);
  border: 1px solid var(--border);
  color: var(--text-2);
}
.crm .shell-attio .sb-search kbd { background: var(--bg-surface-3); color: var(--text-2); }

.crm .sb-section {
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  opacity: .55;
  padding: 12px 8px 6px;
}
/* RD1.11 #334 — bewusst KEIN flex:1: die Liste darf schrumpfen und dann selbst scrollen,
   soll aber nicht wachsen, sonst rutschen „Listen"-Ueberschrift und Pills vom Nav-Block weg
   an den Fuss. min-height:0 ist das, was das Schrumpfen ueberhaupt erlaubt. */
.crm .sb-list { display: flex; flex-direction: column; gap: 1px; min-height: 0; overflow-y: auto; }
.crm .sb-item {
  display: flex; align-items: center; gap: 10px;
  padding: 7px 10px;
  border-radius: var(--r-sm);
  font-size: 13px;
  font-weight: 500;
  color: rgba(255,255,255,.78);
  background: transparent;
  border: 0;
  font-family: inherit;
  text-align: left;
  cursor: pointer;
  transition: background var(--t-fast), color var(--t-fast);
}
.crm .sb-item:hover { background: rgba(255,255,255,.07); color: white; }
.crm .sb-item.active { background: rgba(255,255,255,.14); color: white; }
.crm .sb-item .sb-ic {
  width: 16px; height: 16px;
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center; justify-content: center;
  opacity: .85;
}
.crm .sb-item .sb-cnt {
  margin-left: auto;
  font-family: var(--f-mono);
  font-size: 11px;
  padding: 1px 6px;
  background: rgba(255,255,255,.10);
  border-radius: 999px;
  opacity: .85;
}
.crm .shell-attio .sb-item { color: var(--text-2); }
.crm .shell-attio .sb-item:hover { background: var(--bg-hover); color: var(--text-1); }
.crm .shell-attio .sb-item.active { background: var(--tint-blue); color: var(--ad-blue); }
.crm .shell-attio .sb-item.active .sb-ic { color: var(--ad-blue); opacity: 1; }
.crm .shell-attio .sb-item .sb-cnt { background: var(--bg-surface-3); color: var(--text-2); }

/* PR1.223 #383 — Unterebene „Aktuell | Archiv" unter Opportunities und Projekte.
   Dauerhaft sichtbar statt aufklappbar: das Archiv ist damit EIN Klick, und es entsteht
   keine Aufklapp-Semantik, die hier nur Aufwand ohne Gegenwert waere. Bewusst ohne
   eigene Bewegung — taegliche Navigation, Motion-Budget null; die Farbblende erbt sie
   von .sb-item.

   Die Masse stehen bewusst in `rem`/`em` statt in rohen px: in einer Seitenleiste soll
   die Unterebene mit der Schriftgroesse des Nutzers mitwachsen, und der ui-craft-Ratchet
   (`raw-px`, Baseline 683) darf durch neue Regeln nicht steigen. */
.crm .sb-sub-list {
  display: flex; flex-direction: column;
  padding: 0 0 .25rem;
}
.crm .sb-sub {
  padding: .25rem .625rem .25rem 2.25rem;
  border-radius: var(--r-sm);
  font-size: .75rem;
  font-weight: 500;
  color: rgba(255,255,255,.62);
  background: transparent;
  border: 0;
  font-family: inherit;
  text-align: left;
  cursor: pointer;
  transition: background var(--t-fast), color var(--t-fast);
}
.crm .sb-sub:hover { background: rgba(255,255,255,.07); color: white; }
.crm .sb-sub.active { color: white; font-weight: 600; }
.crm .shell-attio .sb-sub { color: var(--text-2); }
.crm .shell-attio .sb-sub:hover { background: var(--bg-hover); color: var(--text-1); }
.crm .shell-attio .sb-sub.active { color: var(--ad-blue); }

.crm .sb-pill-list {
  display: flex; flex-direction: column; gap: 1px;
  padding: 4px 0 0;
}
.crm .sb-pill {
  display: flex; align-items: center; gap: var(--s-2);
  padding: 6px 10px;
  border-radius: var(--r-sm);
  font-size: 12.5px;
  color: rgba(255,255,255,.66);
  background: transparent;
  border: 0;
  font-family: inherit;
  text-align: left;
  cursor: pointer;
  transition: background var(--t-fast), color var(--t-fast);
}
.crm .sb-pill:hover { background: rgba(255,255,255,.06); color: white; }
.crm .sb-pill .dot { width: 6px; height: 6px; border-radius: 50%; flex: 0 0 auto; }
.crm .shell-attio .sb-pill { color: var(--text-2); }
.crm .shell-attio .sb-pill:hover { background: var(--bg-hover); color: var(--text-1); }

.crm .sb-foot {
  margin-top: auto;
  padding: 10px 8px 4px;
  border-top: 1px solid rgba(255,255,255,.08);
  display: flex; align-items: center; gap: 10px;
}
.crm .shell-attio .sb-foot { border-top: 1px solid var(--border); }
.crm .sb-avatar {
  width: 28px; height: 28px;
  border-radius: 50%;
  background: var(--ad-violet);
  color: white;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 11px; font-weight: 700;
  font-family: var(--f-cond);
  letter-spacing: .3px;
}
.crm .sb-user { display: flex; flex-direction: column; line-height: 1.15; min-width: 0; }
.crm .sb-user b { font-size: 12.5px; font-weight: 600; color: rgba(255,255,255,.95); }
.crm .sb-user small { font-size: 10.5px; color: rgba(255,255,255,.55); }
.crm .shell-attio .sb-user b { color: var(--text-1); }
.crm .shell-attio .sb-user small { color: var(--text-3); }
.crm .sb-foot .sb-cog {
  margin-left: auto;
  width: 26px; height: 26px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: var(--r-sm);
  color: rgba(255,255,255,.65);
  cursor: pointer;
  transition: background var(--t-fast), color var(--t-fast);
}
.crm .sb-foot .sb-cog:hover { background: rgba(255,255,255,.10); color: white; }
.crm .shell-attio .sb-foot .sb-cog { color: var(--text-3); }
.crm .shell-attio .sb-foot .sb-cog:hover { background: var(--bg-hover); color: var(--text-1); }

/* ============== TOPBAR ============== */
.crm .topbar {
  display: flex; align-items: center; gap: var(--s-3);
  padding: 10px 18px;
  border-bottom: 1px solid var(--border);
  background: var(--bg-surface);
  min-height: 56px;
}
.crm .topbar.tb-sf {
  background: var(--ad-blue-900);
  border-bottom: 3px solid var(--ad-blue);
  color: white;
}
.crm .tb-crumbs {
  display: flex; align-items: center; gap: 6px;
  font-size: 13px; color: var(--text-2);
  font-weight: 500;
}
.crm .tb-crumbs b { color: var(--text-1); font-weight: 600; }
.crm .tb-crumbs .sep { color: var(--text-3); opacity: .6; }
.crm .tb-sf .tb-crumbs { color: rgba(255,255,255,.75); }
.crm .tb-sf .tb-crumbs b { color: white; }

.crm .tb-spacer { flex: 1; }

.crm .tb-search {
  flex: 1; max-width: 520px;
  display: flex; align-items: center; gap: var(--s-2);
  padding: 8px 12px;
  background: var(--bg-surface-2);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  color: var(--text-2);
  font-size: 13px;
  cursor: text;
  transition: border-color var(--t-fast), background var(--t-fast);
}
.crm .tb-search:hover { border-color: var(--border-strong); background: var(--bg-surface); }
.crm .tb-search kbd {
  margin-left: auto; font-family: var(--f-mono); font-size: 11px;
  padding: 1px 6px; background: var(--bg-surface-3);
  border: 1px solid var(--border); border-radius: var(--r-xs);
}
.crm .tb-sf .tb-search { background: rgba(255,255,255,.10); border-color: rgba(255,255,255,.15); color: rgba(255,255,255,.85); }
.crm .tb-sf .tb-search kbd { background: rgba(255,255,255,.12); border-color: rgba(255,255,255,.18); color: rgba(255,255,255,.85); }

.crm .tb-nav { display: flex; align-items: center; gap: var(--s-1); }
.crm .tb-nav-item {
  padding: 7px 12px; border-radius: var(--r-sm);
  font-size: 13px; font-weight: 500;
  color: var(--text-2); cursor: pointer;
  transition: background var(--t-fast), color var(--t-fast);
}
.crm .tb-nav-item:hover { background: var(--bg-hover); color: var(--text-1); }
.crm .tb-nav-item.active { color: var(--ad-blue); background: var(--tint-blue); }
.crm .tb-sf .tb-nav-item { color: rgba(255,255,255,.75); }
.crm .tb-sf .tb-nav-item:hover { background: rgba(255,255,255,.10); color: white; }
.crm .tb-sf .tb-nav-item.active { background: white; color: var(--ad-blue-900); font-weight: 600; }

.crm .theme-toggle {
  display: inline-flex; align-items: center; gap: var(--s-2);
  padding: 6px 10px 6px 6px;
  background: var(--bg-surface-2);
  border: 1px solid var(--border);
  border-radius: 999px;
  font-size: 12px; font-weight: 600; color: var(--text-2);
  cursor: pointer; min-width: 78px;
  transition: background var(--t-fast), border-color var(--t-fast);
}
.crm .theme-toggle .knob {
  width: 22px; height: 22px; border-radius: 50%;
  background: var(--bg-surface);
  border: 1px solid var(--border);
  transition: transform var(--t-med);
}
.crm .theme-toggle.is-dark { background: var(--ad-blue-900); color: white; border-color: var(--ad-blue-800); }
.crm .theme-toggle.is-dark .knob { background: var(--ad-orange); border-color: var(--ad-orange-700); transform: translateX(0); }
.crm .tb-sf .theme-toggle { background: rgba(255,255,255,.10); border-color: rgba(255,255,255,.15); color: white; }

/* ============== BUTTONS ============== */
.crm .btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 7px 13px;
  border-radius: var(--r-sm);
  font-family: var(--f-sans);
  font-size: 13px; font-weight: 600;
  border: 1px solid transparent;
  background: transparent; color: var(--text-1);
  cursor: pointer; white-space: nowrap;
  transition: background var(--t-fast), border-color var(--t-fast), color var(--t-fast), transform var(--t-fast);
}
.crm .btn:hover { transform: translateY(-1px); }
.crm .btn-primary { background: var(--ad-blue); color: white; border-color: var(--ad-blue); }
.crm .btn-primary:hover { background: var(--ad-blue-700); border-color: var(--ad-blue-700); }
.crm .btn-violet { background: var(--ad-violet); color: white; border-color: var(--ad-violet); }
.crm .btn-violet:hover { background: var(--ad-violet-600); border-color: var(--ad-violet-600); }
.crm .btn-secondary { background: var(--bg-surface); color: var(--text-1); border-color: var(--border-strong); }
.crm .btn-secondary:hover { background: var(--bg-surface-2); border-color: var(--text-3); }
.crm .btn-ghost { background: transparent; color: var(--text-2); }
.crm .btn-ghost:hover { background: var(--bg-hover); color: var(--text-1); }
/* RD1.13 #336 — Bestaetigungs-Ton fuer folgenschwere Aktionen (crmConfirm dangerLevel:'high',
   z.B. Nutzer deaktivieren). Bewusst nur Tokens: raw-hex/raw-px stehen unter Ratchet. */
/* RD1.13 #336 Reparatur (Coordinator-Befund 03.08.) — weiss auf --ad-red ergab 3.91:1.
   Eine Stufe dunkler traegt (5.36:1); der Hover rueckt entsprechend nach (7.42:1). */
.crm .btn-danger { background: var(--ad-red-700); color: white; border-color: var(--ad-red-700); }
.crm .btn-danger:hover { background: var(--ad-red-800); border-color: var(--ad-red-800); }
.crm .btn-sm { padding: 4px 9px; font-size: 12px; border-radius: 5px; }

.crm .icon-btn {
  width: 32px; height: 32px; display: inline-flex;
  align-items: center; justify-content: center;
  border-radius: var(--r-sm);
  border: 1px solid var(--border);
  background: var(--bg-surface);
  color: var(--text-2);
  cursor: pointer;
  transition: background var(--t-fast), color var(--t-fast), border-color var(--t-fast);
}
.crm .icon-btn:hover { background: var(--bg-surface-2); color: var(--text-1); border-color: var(--border-strong); }

/* ============== SEGMENTED ============== */
.crm .seg {
  display: inline-flex; align-items: stretch;
  padding: 3px;
  background: var(--bg-surface-2);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  /* RD1.13 #336 Phase 5 — schmale Fenster: die fuenfteilige Preset-Leiste der Kundenliste
     ist breiter als ein schmales Fenster. Statt die Seite waagerecht scrollen zu lassen
     (Konvention 20) bricht die Leiste um. Bei ausreichender Breite aendert sich nichts. */
  flex-wrap: wrap;
  max-width: 100%;
}
.crm .seg button {
  padding: 5px 12px;
  border: none; background: transparent;
  border-radius: 5px;
  font-size: 12.5px; font-weight: 600; color: var(--text-2);
  cursor: pointer;
  transition: background var(--t-fast), color var(--t-fast);
}
.crm .seg button:hover { color: var(--text-1); }
.crm .seg button.is-active {
  background: var(--bg-surface);
  color: var(--ad-blue);
  box-shadow: var(--shadow-1);
}
.crm .seg.seg-dark button.is-active { background: var(--ad-blue-900); color: white; }

/* ============== CARDS ============== */
.crm .card {
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-1);
}
.crm .card-pad { padding: 18px; }

/* ============== KPI ============== */
.crm .kpi-row {
  display: grid; grid-template-columns: repeat(4, 1fr);
  gap: var(--s-3);
}
.crm .kpi {
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  padding: 14px 16px 12px;
  display: flex; flex-direction: column; gap: var(--s-1);
  position: relative;
  overflow: hidden;
}
.crm .kpi::before {
  content: '';
  position: absolute; left: 0; top: 0; bottom: 0;
  width: 3px; background: var(--ad-blue);
}
.crm .kpi.k-violet::before { background: var(--ad-violet); }
.crm .kpi.k-orange::before { background: var(--ad-orange); }
.crm .kpi.k-turq::before { background: var(--ad-turq); }
.crm .kpi.k-green::before { background: var(--ad-green); }
.crm .kpi-label {
  font-size: 11.5px; font-weight: 600; color: var(--text-3);
  text-transform: uppercase; letter-spacing: .6px;
}
.crm .kpi-value {
  font-family: var(--f-cond);
  font-weight: 700;
  font-size: 30px;
  letter-spacing: -.5px;
  line-height: 1.1;
  color: var(--text-1);
}
.crm .kpi-meta {
  font-size: 12px; color: var(--text-2);
  display: flex; align-items: center; gap: 6px;
}
.crm .kpi-meta .delta-pos { color: var(--ad-green-700); font-weight: 600; }
.crm .kpi-meta .delta-warn { color: var(--ad-orange-700); font-weight: 600; }
.crm.dark .kpi-meta .delta-pos , html[data-theme="dark"] .crm .kpi-meta .delta-pos { color: var(--ad-green); }
.crm.dark .kpi-meta .delta-warn , html[data-theme="dark"] .crm .kpi-meta .delta-warn { color: var(--ad-orange); }

/* ============== BADGES (Status) ============== */
/* BF-15 #394 — .kb-doc-status (Ingestion-Status eines KB-Dokuments) teilt sich die
   Badge-Basis, statt eine zweite Pillen-Geometrie zu erfinden. Gerendert wird es von
   public/js/components/kb-doc-status.js, das beide Shells mit demselben Markup
   bedient; die Farbrollen unten sind das Redesign-Gesicht dazu. */
.crm .bdg,
.crm .kb-doc-status {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 2px 9px;
  font-family: var(--f-cond);
  font-size: 11.5px; font-weight: 600;
  letter-spacing: .3px;
  border-radius: 999px;
  border: 1px solid transparent;
}
.crm .bdg .pip { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
/* RD1.13 #336 Reparatur (Coordinator-Befund 03.08.) — die Badge-Schrift lag auf ihrem
   eigenen Tint unter AA: bdg-lead 4.48:1, bdg-won 2.82:1, bdg-running 2.59:1,
   bdg-warn 2.73:1. Alle vier fuehren normalen Text in 11.5px, es gilt also 4.5:1.
   Geaendert wird ausschliesslich die SCHRIFT — Tint und Rahmen bleiben, damit die
   Farbcodierung der Status unveraendert bleibt. Neue Werte: 6.08 · 6.40 · 5.32 · 5.62. */
.crm .bdg-lead    { background: var(--tint-blue);   color: var(--ad-blue-700);   border-color: rgba(0,110,199,.18); }
.crm .bdg-prop    { background: var(--tint-violet); color: var(--ad-violet); border-color: rgba(70,30,190,.18); }
.crm .bdg-running { background: var(--tint-orange); color: var(--ad-orange-900); border-color: rgba(255,152,104,.25); }
.crm .bdg-won     { background: var(--tint-turq);   color: var(--ad-turq-900); border-color: rgba(40,220,170,.25); }
.crm .bdg-warn    { background: var(--tint-warn);   color: var(--ad-orange-900); border-color: rgba(255,152,104,.25); }
.crm .bdg-neut    { background: var(--bg-surface-3); color: var(--text-2); border-color: var(--border); }
.crm.dark .bdg-lead    , html[data-theme="dark"] .crm .bdg-lead    { color: var(--ad-blue-300); }
.crm.dark .bdg-prop    , html[data-theme="dark"] .crm .bdg-prop    { color: #B49CFF; }
.crm.dark .bdg-running , html[data-theme="dark"] .crm .bdg-running { color: var(--ad-orange); }
.crm.dark .bdg-won     , html[data-theme="dark"] .crm .bdg-won     { color: var(--ad-turq); }
/* bdg-warn hatte als einziges Warn-Badge KEINEN Dark-Zweig und lebte davon, dass
   --ad-orange-700 auf dem dunklen Tint zufaellig 4.54:1 traf. Mit der dunkleren
   Light-Schrift faellt das weg (2.21:1) — der Zweig ist jetzt Pflicht, nicht Kosmetik. */
.crm.dark .bdg-warn    , html[data-theme="dark"] .crm .bdg-warn    { color: var(--ad-orange); }

/* PR1.261 (#455) — rote Etiketten-Rolle. Bis hierher bildete die Nutzertabelle
   BEIDE dringenden Toene (`red`) und den warnenden (`orange`) auf `.bdg-warn` ab
   — im Redesign sahen "Stillgelegt" und "Eingeladen" damit identisch aus, obwohl
   das eine ein gesperrter Zugang und das andere der Normalfall ist. In der
   klassischen Shell war der Unterschied die ganze Zeit sichtbar
   (`.status-ton-red` vs `.status-ton-orange`, style.css:15871-15874).
   Werte und Dark-Zweig sind die bereits AA-geprueften Rot-Rollen von
   `.nkv-high` / `.conf-lo` / `.kb-doc-status-failed` — keine neue Farbe. */
.crm .bdg-danger { background: var(--tint-red); color: var(--ad-red-700); border-color: rgba(229,72,77,.4); }
.crm.dark .bdg-danger , html[data-theme="dark"] .crm .bdg-danger { color: var(--ad-red-300); }

/* BF-15 #394 — KB-Doc-Ingestion-Status. Zwei Rollen genuegen: „laeuft noch" erbt die
   Warn-Farben von .bdg-warn, „fehlgeschlagen" die Rot-Rollen von .nkv-high/.conf-lo
   (beide dort bereits AA-geprueft). Bewusst KEINE Rolle fuer `ready` — der Normalfall
   bleibt stumm, sonst geht die eine kaputte Zeile im Etiketten-Rauschen unter. */
.crm .kb-doc-status-pending { background: var(--tint-warn); color: var(--ad-orange-900); border-color: rgba(255,152,104,.25); }
.crm .kb-doc-status-failed  { background: var(--tint-red);  color: var(--ad-red-700);    border-color: rgba(229,72,77,.4); }
.crm.dark .kb-doc-status-pending , html[data-theme="dark"] .crm .kb-doc-status-pending { color: var(--ad-orange); }
.crm.dark .kb-doc-status-failed  , html[data-theme="dark"] .crm .kb-doc-status-failed  { color: var(--ad-red-300); }

/* ============== TABLES ============== */
.crm .tbl {
  width: 100%; border-collapse: separate; border-spacing: 0;
  font-size: 13px;
}
.crm .tbl thead th {
  text-align: left; font-weight: 600;
  font-size: 11.5px; letter-spacing: .4px; text-transform: uppercase;
  color: var(--text-3);
  background: var(--bg-surface-2);
  padding: 9px 14px;
  border-bottom: 1px solid var(--border);
  border-top: 1px solid var(--border);
}
.crm .tbl thead th:first-child { border-top-left-radius: 8px; border-left: 1px solid var(--border); }
.crm .tbl thead th:last-child  { border-top-right-radius: 8px; border-right: 1px solid var(--border); }
.crm .tbl tbody td {
  padding: 11px 14px;
  border-bottom: 1px solid var(--border);
  color: var(--text-1);
  vertical-align: middle;
  background: var(--bg-surface);
}
.crm .tbl tbody td:first-child { border-left: 1px solid var(--border); }
.crm .tbl tbody td:last-child  { border-right: 1px solid var(--border); }
.crm .tbl tbody tr:last-child td:first-child { border-bottom-left-radius: 8px; }
.crm .tbl tbody tr:last-child td:last-child  { border-bottom-right-radius: 8px; }
.crm .tbl tbody tr:hover td { background: var(--bg-hover); }
.crm .tbl .num { font-family: var(--f-mono); font-size: 12.5px; font-variant-numeric: tabular-nums; }
.crm .tbl .strong { font-weight: 600; color: var(--text-1); }
.crm .tbl .muted { color: var(--text-3); }

/* RD1.13 #336 Phase 3 — Leer-, Lade- und Fehlerzustand der Redesign-Views.
   Bewusst OHNE px und ohne rohe Hex-Farben: die Ratchets raw-px/raw-hex zaehlen
   ausschliesslich in dieser Datei, und diese Phase darf sie nicht gegenfinanzieren.
   Nur Tokens, rem und Prozent. Ebenso kein px-Raster (Pruefung breakpoints) und
   kein zweites overflow:auto (Pruefung scroll-container). */
.crm .crm-empty { text-align: center; }
.crm .crm-empty-title { font-weight: 600; color: var(--text-1); }
.crm .crm-empty-hint { margin-top: .35rem; color: var(--text-3); font-size: .85rem; }
.crm .crm-skeleton-label { display: block; margin-bottom: .6rem; color: var(--text-3); font-size: .8rem; }
.crm .skel-row {
  height: 1.6rem; margin-bottom: .5rem;
  border-radius: .35rem;
  background: var(--bg-surface-3);
  animation: skel-pulse 1.4s ease-in-out infinite;
}
.crm .skel-row:last-child { margin-bottom: 0; }
@keyframes skel-pulse { 0%, 100% { opacity: .35; } 50% { opacity: .7; } }
/* Wer Bewegung reduziert haben will, bekommt einen ruhigen Platzhalter statt Gepulse. */
@media (prefers-reduced-motion: reduce) {
  .crm .skel-row { animation: none; opacity: .5; }
}
.crm .crm-error-body { flex: 1; padding: 1rem 1.4rem; }

/* RD1.13 #336 Phase 4 — Mitarbeiter-Ansicht: Filterleiste, Auswahl, erweiterte Karte.
   Wie in Phase 3 buchstaeblich OHNE px und ohne rohe Hex-Farben — nur Tokens, rem,
   Prozent. Kein zusaetzliches overflow:auto (Pruefung scroll-container) und kein
   px-Raster (Pruefung breakpoints): die Timeline ist Flex, kein Grid. */
.crm .emp-filter-bar { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; }
.crm .crm-input {
  font: inherit; font-size: .82rem;
  padding: .32rem .6rem;
  color: var(--text-1);
  background: var(--bg-surface);
  /* `thin` statt 1px: semantisch dasselbe Haarlinien-Raster, aber ohne den raw-px-Ratchet
     zu heben — diese Phase soll ihn nicht gegenfinanzieren. */
  border: thin solid var(--border);
  border-radius: .4rem;
  min-width: 0;
}
.crm .emp-filter-bar input[type="search"] { flex: 1 1 14rem; max-width: 22rem; }

.crm .emp-bulk-bar { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; }
.crm .emp-bulk-bar .clsf-progress-host { flex: 1 1 100%; }

/* Karte */
.crm .emp-card-head { display: flex; gap: .75rem; align-items: center; min-width: 0; }
/* RD1.13 #336 Reparatur (Coordinator-Befund 03.08.) — der Name ist der Tastaturweg in
   das Profil und deshalb ein echter `<button>`. Er soll aber aussehen wie die
   Überschrift, die er vorher war: gleiche Stärke, gleiche Farbe, gleiche Kappung.
   Der Fokusring kommt aus der generischen `.crm :focus-visible`-Regel am Dateiende. */
.crm .emp-card-open , .crm .emp-card-name {
  display: block; width: 100%;
  font: inherit; font-weight: 600; color: var(--text-1); text-align: left;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.crm .emp-card-open { padding: 0; border: 0; background: none; cursor: pointer; }
.crm .emp-avatar {
  position: relative;
  flex: 0 0 auto; width: 2.5rem; height: 2.5rem;
  border-radius: .7rem;
  display: flex; align-items: center; justify-content: center;
  color: white;
  font-family: var(--f-cond); font-weight: 700; font-size: .87rem; letter-spacing: .03em;
  overflow: visible;
}
.crm .emp-photo { width: 100%; height: 100%; object-fit: cover; border-radius: .7rem; }
/* Verfuegbarkeits-Punkt: Zustand als Farbe UND als title/aria-label — Farbe allein waere
   fuer Farbfehlsichtige keine Auskunft. */
.crm .emp-dot {
  position: absolute; right: -.15rem; bottom: -.15rem;
  width: .65rem; height: .65rem; border-radius: 50%;
  border: .12rem solid var(--bg-surface);
}
.crm .emp-dot-success { background: var(--ad-turq); }
.crm .emp-dot-warning { background: var(--ad-orange); }
.crm .emp-dot-neutral { background: var(--text-3); }

.crm .emp-cert-row { display: flex; flex-wrap: wrap; gap: .35rem; margin-top: .6rem; }
.crm .chip-cert { border-style: dashed; }
.crm .emp-link-row { display: flex; flex-wrap: wrap; gap: .75rem; margin-top: .7rem; }
.crm .lnk {
  font: inherit; font-size: .76rem;
  color: var(--ad-blue); background: none; border: 0; padding: 0;
  cursor: pointer; text-decoration: underline;
}

/* Mini-Timeline: sechs gleich breite Zellen je Zeile, Flex statt Raster. */
.crm .emp-mtl { margin-top: .7rem; display: flex; flex-direction: column; gap: .18rem; }
.crm .mtl-row { display: flex; align-items: center; gap: .18rem; }
.crm .mtl-l {
  flex: 0 0 4.5rem; min-width: 0;
  font-size: .62rem; color: var(--text-3);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.crm .mtl-h { flex: 1 1 0; text-align: center; font-size: .58rem; color: var(--text-3); }
.crm .mtl-h.is-now { color: var(--text-1); font-weight: 600; }
.crm .mtl-c { flex: 1 1 0; height: .55rem; border-radius: .15rem; background: var(--bg-surface-3); }
.crm .mtl-c.is-on { background: var(--ad-blue); }
/* Pre-Staffing ist sichtbar unterschieden — eine nur vorgemerkte Buchung darf nicht wie
   eine feste aussehen. */
.crm .mtl-c.is-on.is-tentative {
  background: repeating-linear-gradient(45deg, var(--ad-blue) 0 .2rem, transparent .2rem .4rem);
  opacity: .75;
}

/* Shoring-Slots: eigener, zusammenklappbarer Block — anonyme Slots sind keine Personen. */
.crm .emp-shoring { border-top: thin solid var(--border); padding-top: .7rem; }
.crm .emp-shoring-head {
  display: flex; align-items: center; gap: .5rem;
  font: inherit; font-size: .78rem; font-weight: 600; color: var(--text-2);
  background: none; border: 0; padding: 0; cursor: pointer;
}
.crm .emp-shoring-body { display: flex; flex-wrap: wrap; gap: .35rem; margin-top: .5rem; }
.crm .tbl .lnk { color: var(--ad-blue); font-weight: 600; cursor: pointer; }
.crm .tbl .lnk:hover { text-decoration: underline; }
.crm.dark .tbl .lnk , html[data-theme="dark"] .crm .tbl .lnk { color: var(--ad-blue-300); }

/* row mini-avatar */
.crm .mini-av {
  width: 22px; height: 22px;
  border-radius: 50%;
  background: var(--ad-violet);
  color: white;
  font-family: var(--f-cond); font-size: 10px; font-weight: 700;
  display: inline-flex; align-items: center; justify-content: center;
  margin-right: 8px; vertical-align: -6px;
  letter-spacing: .2px;
}
.crm .mini-av.av2 { background: var(--ad-turq-700); }
.crm .mini-av.av3 { background: var(--ad-orange-700); }
.crm .mini-av.av4 { background: var(--ad-blue); }

/* ============== KANBAN ============== */
.crm .kanban {
  display: grid;
  /* PR1.327 (#537) — bis hierher hart auf 4 Spalten. Das ging gut, solange selten mehr
     als vier Spalten Karten trugen; mit der festen Lost-Spalte und einer moeglichen
     Waisen-Spalte (PR1.87) rutschte die fuenfte lautlos in eine zweite Reihe.
     `auto-fit` statt einer festen Zahl, und die Mindestbreite in `rem` — ein neuer
     px-Wert in dieser Datei blockt den ui-craft-Ratchet. */
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  gap: 10px;
}
.crm .kan-col {
  background: var(--bg-surface-2);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: 10px 10px 12px;
  display: flex; flex-direction: column; gap: var(--s-2);
  min-height: 320px;
}
.crm .kan-head {
  display: flex; align-items: center; gap: var(--s-2);
  padding: 4px 4px 8px;
  border-bottom: 1px dashed var(--border);
}
.crm .kan-head .name {
  font-family: var(--f-cond); font-weight: 700;
  font-size: 13px; letter-spacing: .3px; text-transform: uppercase;
}
.crm .kan-head .cnt {
  margin-left: auto; font-family: var(--f-mono); font-size: 11px;
  color: var(--text-3);
  padding: 1px 7px; background: var(--bg-surface); border: 1px solid var(--border); border-radius: 999px;
}
.crm .kan-head .led { width: 8px; height: 8px; border-radius: 50%; }
.crm .kan-card {
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-left: 3px solid var(--ad-blue);
  border-radius: var(--r-md);
  padding: 10px 12px;
  display: flex; flex-direction: column; gap: 6px;
  font-size: 12.5px;
  cursor: grab;
  transition: box-shadow var(--t-fast), transform var(--t-fast);
  box-shadow: var(--shadow-1);
}
.crm .kan-card:hover { transform: translateY(-1px); box-shadow: var(--shadow-2); }
.crm .kan-card.k-prop    { border-left-color: var(--ad-violet); }
.crm .kan-card.k-running { border-left-color: var(--ad-orange); }
.crm .kan-card.k-won     { border-left-color: var(--ad-turq); }
/* PR1.327 (#537) — verloren bekommt einen eigenen Rand. Bis hierher war der
   Lost-Zweig im Kartenbauer ein toter Ternaer (`: '' : ''`): verloren und irrelevant
   sahen identisch aus, obwohl das eine ein ERGEBNIS ist und das andere eine
   Aussortierung. Klassisch war der Unterschied die ganze Zeit sichtbar
   (`colors.Lost = --danger`, views/opportunities.js).
   `--ad-red-700` statt `--danger`: letzteres ist im .crm-Scope NUR im Dark-Block
   belegt und erbt im Light-Modus aus dem Legacy-:root — eine Farbe, die diese Shell
   nicht kontrolliert. Die Status-Pille bleibt neutral (components/status-pill.js,
   Palette-Rollen-Lock PR4.15); unterschieden wird nur im Brett. */
.crm .kan-card.k-lost    { border-left-color: var(--ad-red-700); }

/* PR1.327 (#537) — der Pflicht-Stern im Verlustgrund-Dialog. Die gemeinsame Basis
   bindet ihn an `--danger`; im .crm-Scope ist das aber der geerbte Legacy-Wert
   (#ef4444, gemessen) — im Redesign weder der richtige Rotton noch kontraststark
   genug auf weissem Dialoggrund. Eine Zeile, kein neuer Rohwert. */
.crm .lost-reason-overlay .lr-pflicht { color: var(--ad-red-700); }
.crm.dark .lost-reason-overlay .lr-pflicht ,
html[data-theme="dark"] .crm .lost-reason-overlay .lr-pflicht { color: var(--ad-red-300); }
/* Der Verlustgrund auf der Karte. Ohne rohe Werte — die Zahlen sind Tokens, weil der
   ui-craft-Ratchet (RD1.10) jeden neuen Rohwert in dieser Datei blockt. */
.crm .kan-card .kan-lost-grund {
  font-size: .92em;
  line-height: 1.4;
  color: var(--ad-red-700);
}
/* ⚠️ GEMESSEN, nicht geschaetzt: --ad-red-700 auf dem dunklen Kartengrund ergibt
   3.07:1 und faellt unter AA — exakt der Wert, den der Palette-Kommentar oben fuer
   diesen Fall nennt. Die helle Stufe ist genau dafuer da. Ohne diesen Zweig waere der
   Verlustgrund im Dunkelmodus schlechter lesbar als der Hinweis „nicht erfasst"
   daneben, und das Ticket haette sein eigenes Ziel verfehlt. */
.crm.dark .kan-card .kan-lost-grund ,
html[data-theme="dark"] .crm .kan-card .kan-lost-grund { color: var(--ad-red-300); }
/* „Grund nicht erfasst" — die sechs Bestandsvorgaenge. Auf dem WEISSEN Kartengrund
   (--bg-surface) kommt --text-3 auf 4.98:1 und haelt AA; auf --bg-surface-3 waeren es
   4.40:1 gewesen, deshalb hier bewusst keine Flaeche, nur Text. */
.crm .kan-card .kan-lost-grund.leer { color: var(--text-3); font-style: italic; }
/* Leere Spalte. Sie ist kein Makel: das Ablageziel fuer die Absage, die gerade
   hereinkam, und die Aussage „diese Woche nichts verloren". */
.crm .kan-col-leer {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: var(--s-4) var(--s-3);
  font-size: .92em;
  line-height: 1.45;
  color: var(--text-3);
}
.crm .kan-card .title { font-weight: 600; color: var(--text-1); font-size: 13px; }
.crm .kan-card .sub { color: var(--text-2); font-size: 12px; }
/* BF-27 #421 — Portfolio-Chips auf der Kanban-Karte. Bewusst ohne rohe Pixelwerte: der
   raw-px-Ratchet aus RD1.10 (scripts/ui-craft-baseline.json) hat keinen Spielraum, jeder
   neue px-Wert in dieser Datei blockt die Pipeline. --s-1 ist der vorhandene 4px-Token.
   overflow-wrap, weil .bdg display:inline-flex ist und lange Portfolio-Namen sonst
   unteilbar bleiben und aus der Karte ragen. */
.crm .kan-card .tags { display: flex; flex-wrap: wrap; gap: var(--s-1); min-width: 0; }
.crm .kan-card .tags .bdg { max-width: 100%; overflow-wrap: anywhere; }
.crm .kan-card .row {
  display: flex; align-items: center; gap: 6px;
  font-family: var(--f-mono); font-size: 11.5px;
  color: var(--text-3);
}
.crm .kan-card .row .vol { color: var(--text-1); font-weight: 600; }

.crm .progress {
  width: 100%; height: 5px; background: var(--bg-surface-3);
  border-radius: 999px; overflow: hidden;
}
.crm .progress > span { display: block; height: 100%; background: var(--ad-green); border-radius: 999px; }
.crm .progress.warn > span { background: var(--ad-orange); }
.crm .progress.violet > span { background: var(--ad-violet); }

/* ============== CONTENT HEADER ============== */
/* RD1.14 #337 — `flex-wrap` nachgetragen. Erster Befund der neuen Layout-Zusicherungen:
   ohne Umbruch ragten die Kopfzeilen-Knöpfe der Kapazitäts-Ansicht bei 768px Fensterbreite
   71px aus dem Fenster und 81px aus `.app-canvas`, die `.app-canvas` kappte sie — „Export"
   war dort schlicht nicht erreichbar. Betroffen ist jede Ansicht mit mehr als einem Knopf
   in der Kopfzeile; aufgefallen ist es an `capacity`, weil sie zwei hat.
   Kein neuer px- oder Hex-Wert, die neun Ratchet-Zahlen bleiben unverändert. */
.crm .page-head {
  display: flex; flex-wrap: wrap; align-items: flex-end; gap: 18px;
  padding: 18px 22px 14px;
  background: var(--bg-app);
  border-bottom: 1px solid var(--border);
}
.crm .page-head h1 {
  font-family: var(--f-cond); font-weight: 700;
  font-size: 26px; letter-spacing: -.4px; line-height: 1.1;
  margin: 0; color: var(--text-1);
}
.crm .page-head .sub { font-size: 13px; color: var(--text-2); margin-top: 4px; }
/* RD1.13 #336 Phase 6 — schmale Fenster: das Admin-Panel fuehrt bis zu drei Kopf-Aktionen
   (Einladen, KB Command Center, Matching-Rollout). Ohne Umbruch schoben sie die Seite auf
   waagerechtes Scrollen (Konvention 20). `wrap` greift nur im Ueberlauf. */
/* Gleicher Grund wie oben: die Knopfgruppe selbst muss ebenfalls umbrechen dürfen, sonst
   verschiebt sich der Überstand nur eine Ebene tiefer. */
.crm .page-head .actions { margin-left: auto; display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2); }

/* ============== TOOLBAR (List view controls) ============== */
.crm .toolbar {
  display: flex; align-items: center; gap: 10px;
  /* RD1.13 #336 Phase 5 — schmale Fenster: ohne Umbruch schob die Preset-Leiste der
     Kundenliste die Toolbar bei 375 rem-Aequivalent auf 586 Breite und erzeugte
     waagerechtes Seiten-Scrollen (Konvention 20: „funktioniert schmal wie breit").
     Der Befund ist aelter als diese Phase und betrifft jede Redesign-Liste; `wrap`
     greift ausschliesslich im Ueberlauf und laesst breite Fenster unveraendert. */
  flex-wrap: wrap;
  padding: 10px 22px;
  border-bottom: 1px solid var(--border);
  background: var(--bg-surface);
}
.crm .toolbar .grow { flex: 1; }
.crm .chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 10px;
  background: var(--bg-surface-2);
  border: 1px solid var(--border);
  border-radius: 999px;
  font-size: 12px; color: var(--text-2);
  cursor: pointer;
  transition: background var(--t-fast), border-color var(--t-fast);
}
.crm .chip:hover { border-color: var(--border-strong); color: var(--text-1); }
.crm .chip.is-on { background: var(--tint-blue); border-color: rgba(0,110,199,.4); color: var(--ad-blue); }
.crm.dark .chip.is-on , html[data-theme="dark"] .crm .chip.is-on { color: var(--ad-blue-300); }

/* ============== TABS ============== */
.crm .tabs {
  display: flex; align-items: center; gap: 0;
  /* Fuenf Reiter passen schmal nicht nebeneinander — sie brechen um, statt die Seite
     waagerecht scrollen zu lassen (RD1.13 #336 Phase 6). */
  flex-wrap: wrap;
  padding: 0 22px;
  border-bottom: 1px solid var(--border);
  background: var(--bg-surface);
}
.crm .tab {
  padding: 12px 14px 11px;
  border-bottom: 2px solid transparent;
  font-size: 13px; font-weight: 600; color: var(--text-2);
  cursor: pointer;
  transition: color var(--t-fast), border-color var(--t-fast);
}
.crm .tab:hover { color: var(--text-1); }
.crm .tab.active { color: var(--ad-blue); border-bottom-color: var(--ad-blue); }
.crm.dark .tab.active , html[data-theme="dark"] .crm .tab.active { color: var(--ad-blue-300); border-bottom-color: var(--ad-blue-300); }

/* ============== HIGHLIGHTS PANEL (Salesforce) ============== */
.crm .highlights {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr 1fr 1fr;
  gap: 0;
  background: var(--bg-surface);
  border-bottom: 1px solid var(--border);
}
.crm .hl-cell {
  padding: 14px 18px;
  border-right: 1px solid var(--border);
  display: flex; flex-direction: column; gap: 2px;
}
.crm .hl-cell:last-child { border-right: none; }
.crm .hl-label {
  font-size: 10.5px; font-weight: 600; color: var(--text-3);
  text-transform: uppercase; letter-spacing: .8px;
}
.crm .hl-value {
  font-family: var(--f-cond); font-weight: 700; font-size: 17px; color: var(--text-1);
  letter-spacing: -.2px;
}
.crm .hl-cell.identity .hl-value { font-size: 22px; }
.crm .hl-cell.identity .hl-sub { font-size: 12.5px; color: var(--text-2); }

/* ============== ACTIVITY TIMELINE ============== */
.crm .timeline { position: relative; padding-left: 22px; }
.crm .timeline::before {
  content: '';
  position: absolute; left: 8px; top: 6px; bottom: 6px;
  width: 1px; background: var(--border);
}
.crm .tl-item {
  position: relative;
  padding: 0 0 14px 0;
  display: flex; flex-direction: column; gap: 2px;
}
.crm .tl-item::before {
  content: ''; position: absolute; left: -19px; top: 4px;
  width: 11px; height: 11px; border-radius: 50%;
  background: var(--bg-surface);
  border: 2px solid var(--ad-blue);
}
.crm .tl-item.warn::before { border-color: var(--ad-orange); }
.crm .tl-item.ok::before   { border-color: var(--ad-turq-700); }
.crm .tl-item .when { font-size: 11px; color: var(--text-3); font-family: var(--f-mono); }
.crm .tl-item .what { font-size: 13px; color: var(--text-1); font-weight: 500; }
.crm .tl-item .who  { font-size: 12px; color: var(--text-2); }

/* ============== UTILITY BAR (Salesforce-style) ============== */
.crm .utility {
  display: flex; align-items: center; gap: 0;
  padding: 0 18px;
  background: var(--bg-surface-2);
  border-top: 1px solid var(--border);
  height: 34px;
}
.crm .util-tab {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 0 14px; height: 100%;
  font-size: 12px; color: var(--text-2);
  cursor: pointer;
  border-right: 1px solid var(--border);
  transition: background var(--t-fast), color var(--t-fast);
}
.crm .util-tab:first-child { border-left: 1px solid var(--border); }
.crm .util-tab:hover { background: var(--bg-hover); color: var(--text-1); }
.crm .util-tab .ic {
  width: 14px; height: 14px;
  display: inline-flex; align-items: center; justify-content: center;
}
.crm .util-tab .cnt {
  font-family: var(--f-mono); font-size: 10.5px;
  background: var(--ad-blue); color: white;
  padding: 1px 6px; border-radius: 999px;
  margin-left: 2px;
}

/* ============== FILTER PILLS ============== */
.crm .filter-row {
  display: flex; align-items: center; gap: var(--s-2);
  /* PR1.243 (#420): umbrechen statt ueberlaufen. Bis hierher hatte keine Filterzeile genug
     Pillen, um anzustossen; die CC-Zeile der Opportunity-Liste hat acht, darunter Namen wie
     „Cloud Advisory & Transformation" — ohne Umbruch schob sie den rechten Rand aus dem
     Container und die letzten Competence Center waren nicht mehr lesbar. */
  flex-wrap: wrap;
  padding: 8px 0;
  font-size: 12px;
}
.crm .filter-row .lbl { color: var(--text-3); font-weight: 600; text-transform: uppercase; letter-spacing: .4px; font-size: 11px; }
.crm .fpill {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 10px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--bg-surface);
  color: var(--text-2);
  font-size: 12px; font-weight: 500;
  cursor: pointer;
  transition: background var(--t-fast), border-color var(--t-fast), color var(--t-fast);
}
.crm .fpill:hover { border-color: var(--border-strong); color: var(--text-1); }
.crm .fpill.is-on { background: var(--tint-blue); border-color: rgba(0,110,199,.35); color: var(--ad-blue); }
.crm .fpill.violet.is-on { background: var(--tint-violet); border-color: rgba(70,30,190,.35); color: var(--ad-violet); }
.crm .fpill.orange.is-on { background: var(--tint-orange); border-color: rgba(255,152,104,.4); color: var(--ad-orange-700); }

/* ============== SOFT-WARNING ============== */
.crm .warn-box {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 10px 12px;
  background: var(--tint-warn);
  border: 1px solid rgba(255,152,104,.4);
  border-left: 3px solid var(--ad-orange);
  border-radius: var(--r-sm);
  font-size: 12.5px; color: var(--text-1);
}
/* Gleicher Befund wie bei den Badges: --ad-orange-700 auf --tint-warn ergibt 2.73:1.
   Nicht vom Coordinator gemeldet (die Warnbox steht nur in bestimmten Zustaenden), aber
   derselbe Fehler eine Zeile weiter — mitkorrigiert statt liegengelassen. Jetzt 5.62:1. */
.crm .warn-box b { color: var(--ad-orange-900); }
.crm.dark .warn-box b , html[data-theme="dark"] .crm .warn-box b { color: var(--ad-orange); }

/* ============== WON-NUDGE-BAND ============== */
/* RD1.13 #336 Reparatur (Coordinator-Befund 03.08.) — der Nebentext im Won-Nudge-Band.
   Das Band ist ein geteiltes Bauteil (components/won-nudge-banner.js). Es faerbte sich
   in style.css ueber `var(--text-tertiary, #6b7280)`; --text-tertiary war NIRGENDS
   definiert, also griff immer der Rueckfallwert — auf dem hellen Bandgrund 4.27:1.
   PR1.219 (#379) hat die klassische Seite auf --text-secondary umgestellt, der Fehler
   ist damit auch dort weg. Diese Zeile bleibt als ausdrueckliche Festlegung stehen
   (6.57:1) — seit PR1.229 mappt der .crm-Wurzelblock --text-secondary ohnehin auf
   --text-2, sie ist also bestaetigend, nicht mehr rettend. */
.crm .won-nudge-banner__days { color: var(--text-2); }

/* PR1.219 #379 — Der Vorgangsname in der Zeile. `--text-primary` mit Rueckfall auf ein
   helles Grau steht in style.css; auf dem hellen Bandgrund des Redesigns waere das
   unlesbar, deshalb hier ueber das Token gestellt (gleiches Muster wie eine Zeile
   darueber, siehe auch die Token-Luecke aus #399). */
.crm .won-nudge-banner__name { color: var(--text-1); }

/* ============== BAND „TESTDATENSATZ" ============== */
/* PR1.224 #384 — geteiltes Bauteil (components/test-records.js), Layout steht in
   style.css. Hier nur die Token-Uebersetzung, gleiches Muster wie beim Won-Nudge-Band
   darueber: der Bandgrund der Redesign-Shell ist hell, die klassischen Werte waeren
   darauf zu blass. Dieselben Token wie .crm .warn-box eine Handvoll Zeilen weiter oben —
   `--tint-warn` als Flaechenton, `--ad-orange` als Warnfarbe. Beide sind fuer hell UND
   dunkel belegt (Zeilen 99 und 188), das Band traegt also in beiden Themes. */
.crm .test-record-band {
  background: var(--tint-warn);
  border-color: var(--border);
  border-left-color: var(--ad-orange);
  color: var(--text-2);
}
/* Derselbe Befund wie bei `.crm .warn-box b` weiter oben: --ad-orange auf --tint-warn
   ergibt 1.91:1 und das Zeichen verschwindet auf dem hellen Grund fast. Es ist zwar
   aria-hidden und traegt keine Information — der Text daneben sagt „Testdatensatz" —
   aber ein Warnzeichen, das man nicht sieht, ist kein Warnzeichen. Der 900er-Ton bringt
   es auf 5.6:1; im dunklen Modus waere er zu dunkel, dort bleibt es beim Grundton.
   Gemessen an der Pruefseite test/ui-harness/test-records.html. */
.crm .test-record-band__mark { color: var(--ad-orange-900); }
.crm.dark .test-record-band__mark,
html[data-theme="dark"] .crm .test-record-band__mark { color: var(--ad-orange); }
.crm .test-record-band__text strong { color: var(--text-1); }
.crm .test-record-band__hint { color: var(--text-2); }

/* PR1.239 (#414) — Der Suchlauf. Layout kommt aus style.css; hier nur die Toene, die auf
   dem hellen Redesign-Grund anders liegen muessen. Die Begruendungsmarken sassen mit
   --bg-hover auf --bg-card fast unsichtbar; --tint-blue gibt ihnen eine eigene Flaeche,
   ohne sie zu einem Warnhinweis zu machen — eine Beobachtung ist keine Warnung, und
   --tint-warn wuerde genau das behaupten. */
.crm .testrec-scan-reason {
  background: var(--tint-blue);
  border-color: var(--border);
  color: var(--text-2);
}
/* --danger ist im .crm-Scope belegt (Z. 2494/2550, hell wie dunkel) — kein Sonderton noetig. */

/* ============== SAVE PULSE ============== */
@keyframes save-pulse {
  0%   { box-shadow: 0 0 0 0 rgba(40,220,170,.55); }
  60%  { box-shadow: 0 0 0 8px rgba(40,220,170,0); }
  100% { box-shadow: 0 0 0 0 rgba(40,220,170,0); }
}
.crm .save-pulse { animation: save-pulse 900ms ease-out 1; }

/* ============== KPI MICRO-CHART ============== */
.crm .spark { display: flex; align-items: flex-end; gap: 2px; height: 28px; margin-top: 4px; }
.crm .spark span {
  flex: 1; background: var(--ad-blue); opacity: .35; border-radius: 1px;
  transition: opacity var(--t-fast);
}
.crm .spark span:last-child { opacity: 1; }

/* ============== RECORD-PAGE LAYOUT ============== */
.crm .record-grid {
  display: grid;
  grid-template-columns: 1fr minmax(0, 320px);
  gap: 14px;
  padding: 16px 22px 22px;
}
.crm .record-stack { display: flex; flex-direction: column; gap: 14px; }
.crm .section-h {
  display: flex; align-items: center; gap: 10px;
  margin-bottom: 10px;
}
.crm .section-h h3 {
  font-family: var(--f-cond); font-weight: 700;
  font-size: 14px; letter-spacing: .3px; text-transform: uppercase;
  margin: 0; color: var(--text-1);
}
.crm .section-h .meta { font-size: 11.5px; color: var(--text-3); margin-left: auto; font-family: var(--f-mono); }

.crm .field-grid {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px 18px;
}
.crm .field { display: flex; flex-direction: column; gap: 2px; }
.crm .field .lbl { font-size: 11px; color: var(--text-3); text-transform: uppercase; letter-spacing: .5px; font-weight: 600; }
.crm .field .val { font-size: 13.5px; color: var(--text-1); font-weight: 500; }
.crm .field .val.lnk { color: var(--ad-blue); cursor: pointer; }

/* PR1.326 (#536) — Auslastungs-Steckbrief. Das Layout steht ungescopt in style.css;
   hier nur, was der `.crm`-Scope anders faerbt. Bewusst token-basiert und ohne rohe
   Pixelwerte: `scripts/check-ui-craft.mjs` ratcht beides in dieser Datei. */
.crm .wl-caption { color: var(--text-3); }
.crm .wl-month { color: var(--text-2); }
/* `.crm .muted`-Falle umgekehrt gedacht: die Zahlenspalten sollen im hellen Redesign
   nicht auf die volle Textfarbe springen, sondern gedaempft bleiben wie in `.tbl`. */
.crm .wl-num { color: var(--text-2); }
.crm .wl-load { color: var(--text-1); }
/* Der Auslastungs-Block traegt ZWEI Kacheln; `.crm .deal-quality` ist fest dreispaltig
   und liesse rechts eine leere Spalte stehen. Das Ausweichraster `.project-quality`
   (auto-fill) taugt hier nicht — es wuerde die beiden Kacheln schmal an den linken Rand
   druecken. Zwei gleiche Haelften sind die richtige Antwort auf zwei Kacheln. */
.crm .deal-quality:has(> .dq:nth-child(2):last-child) { grid-template-columns: repeat(2, 1fr); }
/* Untertitel der Kennzahl-Kacheln — `.dq` bringt nur `lbl` und `val` mit. */
.crm .dq .dq-sub { display: block; font-size: .75rem; color: var(--text-3); }

.crm .deal-quality {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px;
}
.crm .dq {
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  padding: 10px 12px;
  display: flex; flex-direction: column; gap: 2px;
  background: var(--bg-surface-2);
}
.crm .dq .lbl { font-size: 11px; color: var(--text-3); text-transform: uppercase; letter-spacing: .4px; font-weight: 600; }
.crm .dq .val { font-family: var(--f-cond); font-size: 20px; font-weight: 700; color: var(--text-1); }
.crm .dq.warn { border-color: rgba(255,152,104,.45); background: var(--tint-warn); }
.crm .dq.warn .val { color: var(--ad-orange-700); }
.crm.dark .dq.warn .val , html[data-theme="dark"] .crm .dq.warn .val { color: var(--ad-orange); }

/* PR1.227 #387 — Qualitätskarte des Projekts: zwölf Kacheln.
   Eigene Grid-Klasse, weil `.deal-quality` fest dreispaltig ist; `auto-fill` mit `minmax`
   statt eines px-Rasters, sonst schlägt der `breakpoints`-Prüfer aus RD1.10 an.
   Kein Motion: die Karte wird täglich gelesen (PRODUCT.md, Prinzip 2). */
.crm .project-quality {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
  gap: var(--s-2);
}
/* Die Kachel ist ein echter <button> (RD1.10-Falle: kein role="button"), soll aber wie
   eine Kachel aussehen. Nur die Button-Eigenheiten werden abgeräumt — Rahmen, Radius,
   Polster und Grund kommen unverändert aus `.dq`. */
.crm .pq-tile {
  -webkit-appearance: none; appearance: none;
  font: inherit; color: inherit; text-align: left;
  cursor: pointer;
  border-left-width: 0.2rem;
}
.crm .pq-tile .val {
  font-family: var(--f-sans); font-size: 0.82rem; font-weight: 600;
  display: inline-flex; align-items: center; gap: var(--s-1); flex-wrap: wrap;
}
.crm .pq-tile:hover { border-color: var(--ad-blue); }
/* Farbe trägt die Aussage nie allein: jede Kachel nennt ihren Zustand zusätzlich im Text
   und im aria-label. Der Punkt ist die schnelle Zweitcodierung. */
.crm .pq-dot {
  width: 0.5rem; height: 0.5rem; border-radius: 50%;
  flex: 0 0 auto; display: inline-block; background: var(--text-3);
}
.crm .pq-tile.is-ok .pq-dot { background: var(--success); }
.crm .pq-tile.is-warn .pq-dot { background: var(--warning); }
.crm .pq-tile.is-bad .pq-dot { background: var(--danger); }
.crm .pq-tile.is-ok { border-left-color: var(--success); }
.crm .pq-tile.is-warn { border-left-color: var(--warning); }
.crm .pq-tile.is-bad { border-left-color: var(--danger); }
/* Ladezustand — gleiche Geometrie wie die fertige Kachel, damit nichts springt. */
.crm .pq-skeleton { min-height: 3rem; opacity: .4; }
.crm .pq-note { font-size: 0.82rem; color: var(--text-3); }

/* ============== UTILITIES ============== */
.crm .row-flex { display: flex; align-items: center; gap: 10px; }
.crm .col-flex { display: flex; flex-direction: column; gap: 10px; }
.crm .divider { height: 1px; background: var(--border); }
.crm .note {
  font-size: 11px; color: var(--text-3); font-family: var(--f-mono);
  letter-spacing: .2px;
}
.crm .illustr-tag {
  display: inline-flex; align-items: center; gap: var(--s-1);
  font-size: 10px; color: var(--text-3);
  font-family: var(--f-mono); letter-spacing: .4px;
  text-transform: uppercase;
  padding: 1px 6px; border: 1px dashed var(--border-strong);
  border-radius: 999px;
}

.crm .olympus-event {
  display: grid;
  grid-template-columns: minmax(0, 12px) 1fr auto;
  gap: 10px; align-items: flex-start;
  padding: 10px 12px;
  background: var(--bg-surface-2);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  transition: background var(--t-fast), border-color var(--t-fast);
}
.crm .olympus-event:hover { background: var(--bg-hover); border-color: var(--border-strong); }
.crm .olympus-event .pip {
  width: 8px; height: 8px; border-radius: 50%; margin-top: 5px;
  background: var(--ad-blue);
}
.crm .olympus-event.v .pip { background: var(--ad-violet); }
.crm .olympus-event.o .pip { background: var(--ad-orange); }
.crm .olympus-event.t .pip { background: var(--ad-turq-700); }
.crm .olympus-event b { font-size: 13px; color: var(--text-1); display: block; margin-bottom: 2px; }
.crm .olympus-event small { font-size: 11.5px; color: var(--text-2); }
.crm .olympus-event .when { font-family: var(--f-mono); font-size: 11px; color: var(--text-3); white-space: nowrap; }

/* ============== PALETTE STRIP ============== */
.crm .palette-grid {
  display: grid;
  grid-template-columns: repeat(8, 1fr);
  gap: var(--s-2);
}
.crm .swatch {
  display: flex; flex-direction: column;
  border-radius: var(--r-md);
  overflow: hidden;
  border: 1px solid var(--border);
  background: var(--bg-surface);
}
.crm .swatch .chip {
  height: 56px;
}
.crm .swatch .meta { padding: 6px 8px; font-size: 11px; color: var(--text-2); font-family: var(--f-mono); }
.crm .swatch .meta b { color: var(--text-1); display: block; font-family: var(--f-sans); font-size: 11.5px; }

/* ===================================================================
   FLOW (interactive layer)
   =================================================================== */
/* flow.css — interactive prototype additions on top of components.css */

/* ───────── MOTION SYSTEM ───────── */
/* Page-mount fade-up for routes */
.crm .app-canvas > * { animation: routeIn .35s var(--ease-out); }
@keyframes routeIn { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }

/* Stagger children of common containers */
.crm .section-card { animation: routeIn .4s var(--ease-out) both; }
.crm .kanban-col .kanban-card { animation: cardIn .45s var(--ease-out) both; }
.crm .kanban-col .kanban-card:nth-child(2) { animation-delay: .05s; }
.crm .kanban-col .kanban-card:nth-child(3) { animation-delay: .10s; }
.crm .kanban-col .kanban-card:nth-child(4) { animation-delay: .15s; }
.crm .kanban-col .kanban-card:nth-child(5) { animation-delay: .20s; }
@keyframes cardIn { from { opacity: 0; transform: translateY(10px) scale(.98); } to { opacity: 1; transform: none; } }
.crm .kanban-card { transition: transform .18s var(--ease-out), box-shadow .18s ease, border-color .18s ease; cursor: grab; }
.crm .kanban-card:hover { transform: translateY(-3px); box-shadow: 0 10px 24px rgba(0,0,0,.10), 0 1px 2px rgba(0,0,0,.04); border-color: var(--border-strong); }
.crm .kanban-card:active { cursor: grabbing; transform: translateY(-1px) scale(.985); }

/* Table-row stagger + hover lift */
.crm .tbl tbody tr { animation: rowIn .35s var(--ease-out) both; }
.crm .tbl tbody tr:nth-child(2) { animation-delay: .04s; }
.crm .tbl tbody tr:nth-child(3) { animation-delay: .08s; }
.crm .tbl tbody tr:nth-child(4) { animation-delay: .12s; }
.crm .tbl tbody tr:nth-child(5) { animation-delay: .16s; }
.crm .tbl tbody tr:nth-child(6) { animation-delay: .20s; }
.crm .tbl tbody tr:nth-child(7) { animation-delay: .24s; }
.crm .tbl tbody tr:nth-child(8) { animation-delay: .28s; }
.crm .tbl tbody tr:nth-child(9) { animation-delay: .32s; }
@keyframes rowIn { from { opacity: 0; transform: translateX(-6px); } to { opacity: 1; transform: none; } }
.crm .tbl.tbl-clickable tbody tr { transition: background var(--t-fast), transform var(--t-fast); }
.crm .tbl.tbl-clickable tbody tr:hover { transform: translateX(3px); }

/* Sidebar item — slide-in active indicator */
.crm .sb-item { position: relative; transition: background var(--t-fast), color var(--t-fast); }
.crm .sb-item::before {
  content: ''; position: absolute; left: 0; top: 8px; bottom: 8px; width: 3px; border-radius: 0 3px 3px 0;
  background: currentColor; opacity: 0; transform: scaleY(0); transform-origin: center;
  transition: transform .25s var(--ease-out), opacity .2s ease;
}
.crm .sb-item.active::before { opacity: .9; transform: scaleY(1); }
.crm .sb-item:hover { transform: translateX(2px); }
.crm .sb-item,.crm .sb-pill { transition: transform .15s var(--ease-out), background var(--t-fast); }
.crm .sb-pill:hover { transform: translateX(2px); }

/* KPI numbers — gentle count-in via opacity/translate */
.crm .kpi-value,.crm .kpi-num,.crm .stat-value,.crm .big-num {
  animation: kpiIn .55s var(--ease-out) both;
}
@keyframes kpiIn { from { opacity: 0; transform: translateY(6px); letter-spacing: -.04em; } to { opacity: 1; transform: none; letter-spacing: normal; } }

/* Status badge — pulse on hover/edit */
.crm .badge,.crm .stage-badge { transition: transform .15s var(--ease-out), background var(--t-fast); }
.crm .badge:hover,.crm .stage-badge:hover { transform: scale(1.04); }

/* Dot indicators — gentle breathing */
.crm .dot { transition: transform .2s var(--ease-out); }
.crm .sb-pill:hover .dot { transform: scale(1.3); }

/* Buttons — press feedback */
.crm .btn { transition: transform .12s var(--ease-out), background var(--t-fast), border-color var(--t-fast), box-shadow var(--t-fast); }
.crm .btn:hover:not(:disabled) { transform: translateY(-1px); }
.crm .btn:active:not(:disabled) { transform: translateY(0) scale(.985); }
.crm .btn-violet:hover { box-shadow: 0 8px 20px rgba(122,84,255,.22); }
.crm .btn-primary:hover { box-shadow: 0 8px 20px rgba(0,110,199,.22); }

/* Tabs — sliding underline */
.crm .tabs { position: relative; }
.crm .tab { transition: color .18s ease; position: relative; }
.crm .tab::after {
  content: ''; position: absolute; left: 12px; right: 12px; bottom: -1px; height: 2px;
  background: currentColor; border-radius: 2px;
  transform: scaleX(0); transform-origin: center;
  transition: transform .28s var(--ease-out);
}
.crm .tab.active::after,.crm .tab[aria-selected="true"]::after { transform: scaleX(1); }

/* Olympus events — slide-in stream */
.crm .event-row,.crm .olympus-row,.crm .ol-event {
  animation: evtIn .4s var(--ease-out) both;
}
.crm .event-row:nth-child(2),.crm .olympus-row:nth-child(2),.crm .ol-event:nth-child(2) { animation-delay: .04s; }
.crm .event-row:nth-child(3),.crm .olympus-row:nth-child(3),.crm .ol-event:nth-child(3) { animation-delay: .08s; }
.crm .event-row:nth-child(4),.crm .olympus-row:nth-child(4),.crm .ol-event:nth-child(4) { animation-delay: .12s; }
.crm .event-row:nth-child(5),.crm .olympus-row:nth-child(5),.crm .ol-event:nth-child(5) { animation-delay: .16s; }
.crm .event-row:nth-child(6),.crm .olympus-row:nth-child(6),.crm .ol-event:nth-child(6) { animation-delay: .20s; }
.crm .event-row:nth-child(7),.crm .olympus-row:nth-child(7),.crm .ol-event:nth-child(7) { animation-delay: .24s; }
@keyframes evtIn { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }

/* Card hover lift (generic cards) */
.crm .card { transition: box-shadow .2s ease, border-color .2s ease, transform .2s var(--ease-out); }

/* PR1.236 (#408) — Drop-Ziel beim Ziehen sichtbar machen.
   Die globale Regel dafür steht in style.css (`.staffing-dropzone-over`, dort :7366) und
   greift auf einer Redesign-Karte NICHT: `.crm .card` ist spezifischer und gewinnt den
   Rahmen zurück. Gemessen am 17.08.2026 — die Zone blieb beim Drüberziehen unverändert.
   Betrifft beide Redesign-Gesichter: die Team-Karte der Opportunity-Seite trägt dieselbe
   Klasse seit PR1.127/RD1.08, der Hinweis war dort ebenso unsichtbar.
   Keine Animation, nur ein Zustand: die Karte ist ein Arbeitsgerät, kein Schaufenster. */
.crm .card.staffing-dropzone-over {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 12%, var(--bg-surface));
}

/* Avatar — subtle wiggle on hover */
.crm .avatar { transition: transform .2s var(--ease-out); }
.crm .avatar:hover { transform: scale(1.08) rotate(-3deg); }

/* Subtle gradient shimmer on the "save-pulse" save state */
.crm .save-pulse::after {
  content: ''; position: absolute; inset: 0; border-radius: inherit;
  background: linear-gradient(120deg, transparent 30%, rgba(255,255,255,.55) 50%, transparent 70%);
  animation: shimmer 2.4s ease-in-out infinite; pointer-events: none; mix-blend-mode: overlay;
}
@keyframes shimmer { 0% { transform: translateX(-100%); } 100% { transform: translateX(100%); } }
.crm .save-pulse { position: relative; overflow: hidden; }
/* ───────── /MOTION SYSTEM ───────── */

/* ===================================================================
   RD1.11 #334 — Staffing-Pool (geteilt von Multi-Opp- und Multi-Projekt-Staffing)
   ===================================================================
   Stand bis RD1.11 als 200-Zeichen-Inline-String wortgleich in beiden Modulen. Der
   Grund dafuer war die Legacy-Regel `.mos-pool-panel` (style.css:11138), die sonst
   zurueckblutet — deshalb eine EIGENE Klasse statt der bestehenden: `.crm .staffing-pool`
   schlaegt sie ueber die Spezifitaet, ohne dass wir uns auf die Ladereihenfolge verlassen.

   Repariert wird dabei `max-height: calc(100vh - 130px)`: die 130px waren gegen den
   Viewport gerechnet, obwohl das Panel in einem Scroll-Container sitzt — der existierte
   bis RD1.11 gar nicht. `100%` bezieht sich auf genau diesen Container und ist damit auch
   dann richtig, wenn Topbar oder Kopfbereich ihre Hoehe aendern. */
.crm .staffing-pool {
  position: sticky;
  top: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
  background: var(--bg-surface);
  border: 1px solid var(--border);
  /* 12px hat kein Token (--r-lg ist 10, --r-xl ist 14) — Literal bleibt, damit sich das
     Aussehen nicht still verschiebt. padding dagegen trifft --s-3 exakt. */
  border-radius: 12px;
  padding: var(--s-3);
  max-height: 100%;
  overflow-y: auto;
}


/* topbar overflow safety — keep all actions visible at narrow widths */
.crm .topbar { flex-wrap: nowrap; }
.crm .tb-crumbs { flex: 0 1 auto; min-width: 0; overflow: hidden; }
.crm .tb-crumbs > * { flex: 0 0 auto; }
.crm .tb-search.tb-search-flex {
  flex: 1 1 0;
  min-width: 0;
  max-width: 520px;
}
.crm .tb-search.tb-search-flex .tb-search-label {
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; flex: 1;
}
.crm .tb-export,.crm .tb-primary { flex: 0 0 auto; white-space: nowrap; }

@media (max-width: 1180px) {
  .crm .tb-brand-cluster + .sep { display: none; }
  .crm .tb-crumbs .tb-brand-cluster { display: none !important; }
}
@media (max-width: 1024px) {
  .crm .tb-export { display: none; }
  .crm .tb-crumbs span:not(.sep):not(.tb-brand-cluster) { display: none; }
  .crm .tb-crumbs .sep:not(:last-of-type) { display: none; }

}
@media (max-width: 880px) {
  .crm .tb-search.tb-search-flex { max-width: 220px; }
  .crm .tb-search.tb-search-flex kbd { display: none; }
}

/* clickable rows */
.crm .tbl.tbl-clickable tbody tr { transition: background var(--t-fast); }
.crm .tbl.tbl-clickable tbody tr:hover { background: var(--bg-hover); }
.crm .tbl.tbl-clickable tbody tr:hover .lnk { text-decoration: underline; }

/* status trigger on record */
.crm .status-trigger {
  display: inline-flex; align-items: center; gap: 6px;
  background: transparent; border: 1px dashed transparent;
  padding: 4px 8px; border-radius: var(--r-sm); cursor: pointer;
  transition: background var(--t-fast), border-color var(--t-fast);
  font: inherit; color: inherit;
}
.crm .status-trigger:hover { background: var(--bg-hover); border-color: var(--border); }
.crm .popover {
  position: absolute; top: calc(100% + 6px); left: 0;
  min-width: 220px; background: var(--bg-surface);
  border: 1px solid var(--border); border-radius: var(--r-md);
  box-shadow: 0 12px 36px rgba(0,0,0,.16), 0 1px 2px rgba(0,0,0,.05);
  padding: 6px; z-index: 50;
  animation: popIn .14s ease-out;
}
@keyframes popIn { from { transform: translateY(-4px); opacity: 0; } to { transform: translateY(0); opacity: 1; } }
.crm .po-head { font-size: 10.5px; text-transform: uppercase; letter-spacing: .5px; color: var(--text-3); padding: 6px 8px 2px; font-weight: 600; }
.crm .po-item {
  display: flex; align-items: center; gap: 10px;
  width: 100%; padding: 7px 10px; border-radius: 5px;
  background: transparent; border: none; cursor: pointer;
  font: inherit; color: var(--text-1); text-align: left;
}
.crm .po-item:hover { background: var(--bg-hover); }
.crm .po-item.is-current { background: var(--bg-surface-2); }
.crm .po-item .led { width: 8px; height: 8px; border-radius: 50%; }

/* inline-edit probability */
.crm .inline-edit {
  background: transparent; border: 1px dashed transparent;
  padding: 2px 8px; border-radius: 5px; cursor: text;
  font: inherit; color: inherit;
  display: inline-flex; align-items: center; gap: var(--s-2);
}
.crm .inline-edit:hover { background: var(--bg-hover); border-color: var(--border-strong); }
.crm .inline-edit .ie-hint { font-size: 11px; color: var(--text-3); opacity: 0; transition: opacity var(--t-fast); }
.crm .inline-edit:hover .ie-hint { opacity: 1; }
.crm .pct-input {
  width: 90px; padding: 4px 8px;
  font: inherit; font-family: var(--f-cond); font-weight: 700; font-size: 22px;
  background: var(--bg-surface);
  border: 2px solid var(--ad-blue);
  border-radius: var(--r-sm); outline: none;
  color: var(--text-1);
}

/* kanban drop targets */
.crm .kan-col.drop-hot { background: var(--tint-blue); border-color: var(--ad-blue); }
.crm .kan-card.is-dragging { opacity: .55; transform: rotate(-1deg); }

/* warn-card */
.crm .warn-card { border-color: rgba(255,152,104,.5); background: var(--tint-orange); }
.crm .warn-card .warn-box b { color: var(--text-1); }

/* save-pulse */
.crm .save-pulse { box-shadow: 0 0 0 0 rgba(0,110,199,.45); animation: pulse 2.4s ease-out infinite; }
@keyframes pulse {
  0%   { box-shadow: 0 0 0 0 rgba(0,110,199,.4); }
  60%  { box-shadow: 0 0 0 12px rgba(0,110,199,0); }
  100% { box-shadow: 0 0 0 0 rgba(0,110,199,0); }
}

/* command palette */
/* BF-26 #416 — MUSS vor/mit der display:flex-Regel stehen: closeCommandPalette() setzt das
   hidden-Attribut, und ein explizites `display:flex` schlaegt das UA-`display:none` von
   [hidden]. Ohne diese Gegenregel waere die Palette nach dem Umzug in .crm dauerhaft sichtbar.
   Gleiches Muster wie `.crm .popover[hidden]` weiter unten. */
.crm .cmdk-overlay[hidden] { display: none; }
.crm .cmdk-overlay {
  position: fixed; inset: 0; z-index: 100;
  background: rgba(15,20,30,.45);
  display: flex; align-items: flex-start; justify-content: center;
  padding-top: 12vh;
  animation: fadeIn .12s ease-out;
}
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
.crm .cmdk {
  width: min(640px, 92vw);
  background: var(--bg-surface);
  border: 1px solid var(--border-strong);
  border-radius: 12px;
  box-shadow: 0 24px 60px rgba(0,0,0,.28), 0 2px 4px rgba(0,0,0,.06);
  overflow: hidden;
  animation: cmdkIn .18s cubic-bezier(.2,.7,.3,1);
}
@keyframes cmdkIn { from { transform: translateY(-12px) scale(.98); opacity: 0; } to { transform: none; opacity: 1; } }
.crm .cmdk-search { display: flex; align-items: center; gap: 10px; padding: 14px 16px; border-bottom: 1px solid var(--border); }
.crm .cmdk-search input { flex: 1; border: none; outline: none; background: transparent; font: inherit; font-size: 15px; color: var(--text-1); }
.crm .cmdk-search kbd { font-family: var(--f-mono); font-size: 11px; padding: 2px 6px; background: var(--bg-surface-3); border: 1px solid var(--border); border-radius: var(--r-xs); color: var(--text-2); }
.crm .cmdk-list { max-height: 380px; overflow-y: auto; padding: 6px; }
.crm .cmdk-item {
  display: flex; align-items: center; gap: var(--s-3);
  width: 100%; padding: 10px 12px; border-radius: 7px;
  background: transparent; border: none; cursor: pointer;
  font: inherit; color: var(--text-1); text-align: left;
}
.crm .cmdk-item.is-hover,.crm .cmdk-item:hover { background: var(--bg-hover); }
/* BF-26 #416 — die Tastaturauswahl (↑↓) setzt `is-active`; ohne Regel bewegte sie sich
   unsichtbar. Deutlicher als der Hover-Ton, damit beides unterscheidbar bleibt. --tint-blue
   hat ein Dark-Pendant, also traegt die Auswahl in beiden Erscheinungsbildern. */
.crm .cmdk-item.is-active { background: var(--tint-blue); }
/* BF-26 #416 — Label nimmt den Rest, der Typ-Chip sitzt rechts. Vorher klebte der Chip am
   Text und sass in jeder Zeile auf einer anderen X-Position; sichtbar wurde das erst, seit
   die Regeln ueberhaupt greifen. Lange Opp-Namen kuerzen statt die Zeile zu sprengen. */
.crm .cmdk-item > span:first-child {
  flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.crm .cmdk-kind {
  margin-left: auto;
  font-family: var(--f-cond); font-size: 10px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .8px;
  padding: 3px 7px; background: var(--bg-surface-3);
  /* BF-26 #416 — --text-3 lag hier bei 4.40:1 (hell) / 4.31:1 (dunkel) gegen --bg-surface-3
     und riss damit WCAG AA; 10px/700 zaehlt nicht als Grosstext. --text-2: 6.57 / 6.07. */
  color: var(--text-2); border-radius: var(--r-xs); flex: 0 0 auto; min-width: 86px; text-align: center;
}
.crm .cmdk-empty { padding: 28px 12px; text-align: center; color: var(--text-3); font-size: 13px; }
.crm .cmdk-foot { padding: 10px 16px; border-top: 1px solid var(--border); font-size: 11px; color: var(--text-3); display: flex; gap: 14px; align-items: center; background: var(--bg-surface-2); }
.crm .cmdk-foot kbd { font-family: var(--f-mono); padding: 1px 5px; background: var(--bg-surface); border: 1px solid var(--border); border-radius: 3px; }

/* drawer */
.crm .drawer-veil { position: fixed; inset: 0; background: rgba(15,20,30,.32); z-index: 80; animation: fadeIn .14s ease-out; }
.crm .drawer {
  position: fixed; top: 0; right: 0; bottom: 0;
  width: min(480px, 92vw);
  background: var(--bg-surface);
  border-left: 1px solid var(--border-strong);
  box-shadow: -16px 0 40px rgba(0,0,0,.18);
  z-index: 81;
  display: flex; flex-direction: column;
  animation: drawerIn .22s cubic-bezier(.2,.7,.3,1);
}
@keyframes drawerIn { from { transform: translateX(40px); opacity: 0; } to { transform: none; opacity: 1; } }
.crm .drawer-head { padding: 20px 22px 16px; border-bottom: 1px solid var(--border); display: flex; align-items: flex-start; gap: var(--s-3); }
.crm .drawer-head .icon-btn { margin-left: auto; }
.crm .drawer-body { flex: 1; overflow-y: auto; padding: 18px 22px; display: flex; flex-direction: column; gap: 14px; }
.crm .drawer-foot { padding: 14px 22px; border-top: 1px solid var(--border); display: flex; gap: 10px; justify-content: flex-end; background: var(--bg-surface-2); }

.crm .lineage-step { padding: 12px 14px; border: 1px solid var(--border); border-radius: var(--r-md); background: var(--bg-surface-2); }
.crm .ls-head { display: flex; align-items: center; gap: 10px; margin-bottom: 6px; }
.crm .ls-num {
  width: 22px; height: 22px; border-radius: 50%;
  background: var(--ad-blue); color: white;
  display: inline-flex; align-items: center; justify-content: center;
  font-family: var(--f-cond); font-weight: 700; font-size: 12px;
}
.crm .ls-body { padding-left: 32px; }

/* modal */
.crm .modal-veil {
  position: fixed; inset: 0; z-index: 90;
  background: rgba(15,20,30,.42);
  display: flex; align-items: center; justify-content: center;
  padding: 24px;
  animation: fadeIn .14s ease-out;
}
.crm .modal {
  width: min(820px, 96vw); max-height: 86vh;
  background: var(--bg-surface);
  border: 1px solid var(--border-strong); border-radius: 12px;
  box-shadow: 0 28px 64px rgba(0,0,0,.28);
  display: flex; flex-direction: column; overflow: hidden;
  animation: cmdkIn .2s cubic-bezier(.2,.7,.3,1);
}
.crm .modal-head { padding: 20px 22px; border-bottom: 1px solid var(--border); display: flex; align-items: flex-start; gap: var(--s-3); }
.crm .modal-head .icon-btn { margin-left: auto; }
.crm .modal-body { flex: 1; overflow-y: auto; }
.crm .modal-foot { padding: 14px 22px; border-top: 1px solid var(--border); display: flex; align-items: center; background: var(--bg-surface-2); }

/* toast */
.crm .toast {
  position: fixed; bottom: 22px; left: 50%; transform: translateX(-50%);
  z-index: 200;
  display: inline-flex; align-items: center; gap: 10px;
  padding: 10px 16px;
  background: var(--text-1); color: var(--bg-surface);
  border-radius: var(--r-md); box-shadow: 0 10px 30px rgba(0,0,0,.25);
  font-size: 13px; font-weight: 500;
  animation: toastIn .22s cubic-bezier(.2,.7,.3,1);
}
@keyframes toastIn { from { transform: translate(-50%, 18px); opacity: 0; } to { transform: translate(-50%, 0); opacity: 1; } }
.crm .toast-pip { width: 8px; height: 8px; border-radius: 50%; background: var(--ad-green); }
.crm .toast-warn .toast-pip { background: var(--ad-orange); }

/* coachmarks */
.crm .coachmarks {
  position: fixed; bottom: 22px; right: 22px; z-index: 60;
  width: 320px;
  background: var(--ad-blue-900); color: white;
  border-radius: 12px;
  box-shadow: 0 16px 40px rgba(0,0,0,.28);
  padding: 16px 18px 14px;
  font-size: 12.5px; line-height: 1.5;
  animation: drawerIn .26s cubic-bezier(.2,.7,.3,1);
}
.crm .coachmarks .coach-head { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; font-family: var(--f-cond); font-size: 14px; }
.crm .coachmarks .coach-head .icon-btn { margin-left: auto; color: rgba(255,255,255,.7); border-color: rgba(255,255,255,.2); background: transparent; }
.crm .coachmarks ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.crm .coachmarks li { display: flex; gap: var(--s-2); color: rgba(255,255,255,.85); }
.crm .coachmarks li span:first-child { flex: 0 0 14px; color: var(--ad-orange); font-family: var(--f-cond); font-weight: 700; }
.crm .coachmarks b { color: white; font-weight: 600; }
.crm .coachmarks kbd { font-family: var(--f-mono); font-size: 10.5px; background: rgba(255,255,255,.12); padding: 1px 5px; border-radius: 3px; border: 1px solid rgba(255,255,255,.16); }
.crm .coach-toggle {
  position: fixed; bottom: 22px; right: 22px; z-index: 60;
  width: 42px; height: 42px; border-radius: 50%;
  background: var(--ad-blue-900); color: white;
  border: none; cursor: pointer;
  font-family: var(--f-cond); font-size: 18px; font-weight: 700;
  box-shadow: 0 10px 26px rgba(0,0,0,.24);
}

/* dq tone */
.crm .dq.ok .val { color: var(--ad-green-700); }

/* ===================================================================
   FLOW-MODULES (heat / nkv / kb-graph / matrix / conf)
   =================================================================== */
/* flow-modules.css — styles for the added routes + dialogs */

/* shared bits */
.crm .card-hd { padding:12px 16px; border-bottom:1px solid var(--border); display:flex; align-items:center; }
.crm .card-hd h3 { margin:0; font-family:var(--f-cond); font-size:14px; text-transform:uppercase; letter-spacing:.4px; }
.crm .card-hd .note { margin-left:auto; }
.crm .kan-empty { padding:18px 8px; text-align:center; color:var(--text-3); font-size:12px; border:1px dashed var(--border); border-radius: var(--r-md); }
.crm .tb-inline-search { display:flex; align-items:center; gap: var(--s-2); padding:6px 12px; background:var(--bg-surface-2); border:1px solid var(--border); border-radius: var(--r-md); color:var(--text-3); }
.crm .tb-inline-search input { border:0; background:transparent; outline:none; font:inherit; font-size:13px; color:var(--text-1); width:200px; }

/* NKV heatmap */
.crm .heat { height:8px; background:var(--bg-surface-3); border-radius:999px; overflow:hidden; }
.crm .heat > span { display:block; height:100%; border-radius:999px; }
.crm .heat-ok > span { background:var(--ad-green); }
.crm .heat-mid > span { background:var(--ad-orange); }
.crm .heat-high > span { background:var(--ad-red); }
.crm .nkv-chip { font-family:var(--f-mono); font-size:11.5px; font-weight:600; padding:2px 8px; border-radius:999px; }
.crm .nkv-ok { background:var(--tint-green); color:var(--ad-green-700); }
.crm .nkv-mid { background:var(--tint-warn); color:var(--ad-orange-700); }
.crm .nkv-high { background:var(--tint-red); color:var(--ad-red-700); }

/* PR1.253 (#447) — Kapazitäts-Angabe in den Staffing-Auswahlpunkten.
   `--warning` schlug hier im hellen Zustand mit dem Grundton der klassischen Datei durch
   (#f59e0b auf weiss = 2,14:1). Deshalb eigene Belegung: auf hellem Grund die dunkle
   Orangestufe, auf dunklem der Grundton — dieselbe Zweiteilung wie bei `.nkv-high` und
   `.conf-lo` nebenan. Kein Gruen fuer „frei": Gruen ist im Redesign keine Textfarbe. */
.crm .cap-tag-ok { color:var(--text-2); }
.crm .cap-tag-none { color:var(--ad-orange-900); }
.crm .cap-tag-unknown { color:var(--text-3); }
.crm.dark .cap-tag-none , html[data-theme="dark"] .crm .cap-tag-none { color:var(--ad-orange); }
.crm.dark .nkv-high , html[data-theme="dark"] .crm .nkv-high { color:var(--ad-red-300); }
.crm .pivot-row { display:flex; align-items:center; gap:10px; padding:7px 0; border-bottom:1px solid var(--border); font-size:12.5px; }
.crm .pivot-row:last-child { border-bottom:0; }
.crm .pivot-row .pv-label { flex:1; min-width:0; }
.crm .pivot-row .num { color:var(--text-2); }

/* employee */
.crm .hs-mini { font-family:var(--f-mono); font-size:12px; color:var(--text-2); }
.crm .hs-mini b { color:var(--text-1); }
.crm .cert-chip { display:flex; flex-direction:column; padding:8px 12px; background:var(--bg-surface-2); border:1px solid var(--border); border-radius: var(--r-md); color:var(--text-1); }
/* PR1.279 — color ausdruecklich: die Legacy-Regel .cert-chip setzt --success als Textfarbe
   (gruener Chip auf gruenem Tint). Hier ist der Grund neutral, die geerbte gruene Schrift
   kam auf 2.39:1. Mit --text-1 sind es 16.90:1. Vgl. Konvention 21: Gruen ist im Redesign
   keine Textfarbe. */
.crm .cert-chip b { font-size:12.5px; }
.crm .cert-chip small { font-size:11px; color:var(--text-3); }
.crm .team-chip { display:inline-flex; align-items:center; gap:6px; padding:5px 10px 5px 6px; background:var(--bg-surface-2); border:1px solid var(--border); border-radius:999px; font-size:12.5px; }

/* projects health */
.crm .health-dots { display:flex; gap: var(--s-1); }
.crm .hd { width:9px; height:9px; border-radius:50%; display:inline-block; }
.crm .hd-lg { width:12px; height:12px; }

/* KB graph */
.crm .kb-node { position:absolute; border-radius:50%; color:#fff; display:flex; flex-direction:column; align-items:center; justify-content:center; text-align:center; box-shadow:var(--shadow-2); cursor:pointer; transition:transform .18s var(--ease-out,cubic-bezier(.2,.7,.3,1)); animation:kbFloat 4s ease-in-out infinite; }
.crm .kb-node:hover { transform:scale(1.08); z-index:3; }
.crm .kb-node b { font-size:11px; font-family:var(--f-cond); line-height:1.1; }
.crm .kb-node small { font-size:9px; opacity:.85; }
@keyframes kbFloat { 0%,100%{ transform:translateY(0);} 50%{ transform:translateY(-4px);} }

/* admin matrix */
.crm .tbl.matrix td,.crm .tbl.matrix th { border-right:1px solid var(--border); }
.crm .perm.on { color:var(--ad-green-700); font-weight:700; }
.crm .perm.off { color:var(--text-3); }

/* extraction review */
.crm .kb-src-banner { display:flex; align-items:center; gap:10px; padding:10px 22px; background:var(--tint-blue); border-bottom:1px solid var(--border); font-size:12.5px; }
.crm .kb-src-banner .muted { color:var(--text-2); }
.crm .kb-pill,.crm .kb-src-banner .kb-pill { font-family:var(--f-cond); font-size:10px; font-weight:700; letter-spacing:.5px; text-transform:uppercase; padding:2px 8px; background:var(--ad-blue); color:#fff; border-radius: var(--r-xs); }
.crm .conf { font-family:var(--f-mono); font-size:11px; font-weight:600; padding:2px 8px; border-radius:999px; }
.crm .conf-hi { background:var(--tint-green); color:var(--ad-green-700); }
.crm .conf-mid { background:var(--tint-warn); color:var(--ad-orange-900); }  /* PR1.279 — AA: 2.73->5.62:1; -700 ist auf dem Tint zu hell (siehe Kommentar an --ad-orange-700), .bdg-warn nutzt -900 bereits */
/* Dark braucht die Gegenrichtung: --ad-orange-900 ist dort eine dunkle Schrift auf dunklem
   Tint (1.51:1). Dieselbe Loesung wie bei .bdg-warn eine Datei weiter oben — die helle
   Markenstufe. Ohne diesen Zweig repariert man Hell und zerstoert Dunkel. */
.crm.dark .conf-mid , html[data-theme="dark"] .crm .conf-mid { color: var(--ad-orange); }
.crm .conf-lo { background:var(--tint-red); color:var(--ad-red-700); }
.crm.dark .conf-lo , html[data-theme="dark"] .crm .conf-lo { color:var(--ad-red-300); }
/* PR1.128 (KI-only) F: „nicht bewertet" — neutraler Ton, KEIN Ampel-Rot/Grün. */
.crm .conf-unrated { background:rgba(120,130,140,.14); color:var(--text-3,#64748b); }
.crm .decide { display:inline-flex; gap:6px; }
.crm .dc-btn { font:inherit; font-size:11.5px; padding:4px 9px; border-radius:5px; border:1px solid var(--border); background:var(--bg-surface); color:var(--text-2); cursor:pointer; transition:all var(--t-fast,.14s); }
.crm .dc-btn:hover { border-color:var(--border-strong); }
.crm .dc-btn.is-accept { background:var(--tint-green); color:var(--ad-green-700); border-color:rgba(118,200,0,.4); }
.crm .dc-btn.is-reject { background:var(--tint-red); color:var(--ad-red-700); border-color:rgba(229,72,77,.4); }
.crm.dark .dc-btn.is-reject , html[data-theme="dark"] .crm .dc-btn.is-reject { color:var(--ad-red-300); }
.crm .row-rejected td { opacity:.6; }
.crm .honesty-note { display:flex; align-items:flex-start; gap:10px; padding:10px 22px; font-size:12px; color:var(--text-2); background:var(--bg-surface-2); border-top:1px solid var(--border); }

/* score review */
.crm .score-lineage,.crm .convert-flow { display:flex; flex-direction:column; gap:10px; }
.crm .sl-step,.crm .cv-step { display:flex; align-items:center; gap: var(--s-3); padding:10px 12px; background:var(--bg-surface-2); border:1px solid var(--border); border-radius: var(--r-md); position:relative; }
.crm .sl-num,.crm .cv-num { flex:0 0 auto; width:24px; height:24px; border-radius:50%; background:var(--ad-violet); color:#fff; display:inline-flex; align-items:center; justify-content:center; font-family:var(--f-cond); font-weight:700; font-size:12px; }
.crm .cv-num { background:var(--ad-blue); }
.crm .sl-step b,.crm .cv-step b { font-size:13px; display:block; }
.crm .sl-step small,.crm .cv-step small { font-size:11.5px; color:var(--text-2); }
.crm .cv-arrow { margin-left:auto; color:var(--text-3); }
.crm .cv-step:last-child .cv-arrow { display:none; }
.crm .score-range { width:100%; accent-color:var(--ad-violet); }

/* ===================================================================
   PR4.15 OVERRIDES — collision-reset über Legacy-Globals
   =================================================================== */
.crm .sidebar { background: transparent; border: 0; box-shadow: none;
  /* RD1.11 #334 — hier fehlte overflow. style.css Zeile 397 setzt auf `.sidebar` ein
     `overflow-y: auto` und blutete durch: die Seitenleiste bekam einen ZWEITEN
     Scrollbereich neben der Nav-Liste, und weil `auto` einen Clipping-Kontext aufspannt,
     waere das Benutzermenue (absolutes Popover im .sb-foot) an ihrem Rand abgeschnitten
     worden. Gescrollt wird ausschliesslich .sb-list.
     (Keine geschweiften Klammern in CSS-Kommentaren — sie brechen jede naive
     Regel-Regex, die nicht vorher Kommentare entfernt.) */
  overflow: visible; }

/* ===================================================================
   RD1.11 #334 — SICHTBARER TASTATUR-FOKUS
   ===================================================================
   Bis hier stand `:focus-visible` NULL Mal in dieser Datei (Legacy-style.css: 9x),
   dafuer dreimal `outline:none` ohne jeden Ersatz. Die Tastaturbedienung selbst ist
   gut gebaut — 11 `tabindex="0"`, 72 aria-Attribute — nur sehen konnte man den Fokus
   nicht. Das ist der Regelsatz, der Pruefung 1 aus RD1.10 gruen zieht.

   Bewusst EINE generische Regel statt Einzelregeln je Komponente: sie deckt Buttons,
   Eingaben, Links, `tr[tabindex]`, .kan-card, .emp-card, .th-sort und alles kuenftige
   `[role=button]` in einem Zug ab. Kommt dieser Block ans Dateiende, gewinnt er gegen
   die drei `outline:none` weiter oben (gleiche Spezifitaet, spaeter im Dokument) —
   ohne dass irgendwo `!important` noetig waere.

   Kanon uebernommen aus dem Legacy-Stylesheet (style.css:6734 u.a.):
   2px durchgezogen in der Akzentfarbe, 2px Abstand nach aussen.
   =================================================================== */
.crm :focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
  border-radius: inherit;
}

/* Buendige Zeilen und Karten: der Ring gehoert nach INNEN, sonst ueberlappt er die
   Nachbarzeile bzw. wird vom Scroll-Container abgeschnitten. */
.crm tbody tr:focus-visible ,
.crm .kan-card:focus-visible ,
.crm .emp-card:focus-visible {
  outline-offset: -2px;
}

/* Die drei Stellen, die den Fokus bisher ersatzlos unterdrueckt haben. Das `outline:none`
   dort bleibt richtig fuer den Maus-Fokus (die Felder tragen ihren eigenen Rahmen) —
   fehlte nur der Tastatur-Fall. Der Ring sitzt innen, weil beide Felder randlos in einer
   umgebenden Flaeche liegen. */
.crm .sb-search:focus-visible ,
.crm .cmdk-search input:focus-visible ,
.crm .tb-inline-search input:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: -2px;
}

/* Auf der dunklen Seitenleiste traegt --focus zu wenig Kontrast gegen das Marine-Blau
   (Light-Shell: dunkle Sidebar, heller Canvas). Dort ist Weiss der einzige Ton, der auf
   BEIDEN Themes sicher steht. */
.crm .sidebar :focus-visible {
  outline-color: var(--text-inv);
}

/* ===================================================================
   RD1.11 #334 — ERREICHBARE CHROME (Benutzermenue, Glocke, Nav-Schalter)
   ===================================================================
   Bis hier gab es im neuen Design keinen Abmelde-Weg: das Zahnrad im Benutzer-Chip war
   ein aria-hidden-Span ohne Handler, Glocke und E-Mail-Praeferenzen existierten nur in
   der Alt-Kopfzeile, die unter data-ui="new" ausgeblendet ist. Wer sich abmelden wollte,
   musste erst in die klassische Ansicht wechseln.

   Das Popover-Aussehen (.popover/.po-head/.po-item) lag bereits fertig in dieser Datei
   und wurde von keiner einzigen JS-Datei benutzt — es ist offensichtlich genau dafuer
   gedacht gewesen. Hier kommen nur die Oeffnungsrichtungen und die zwei neuen
   Bedienelemente dazu. */

/* Anker fuer das Benutzermenue (das Popover ist absolut positioniert). */
.crm .sb-foot { position: relative; }

/* .sb-cog war ein <span>, ist jetzt ein <button> — UA-Stile zuruecknehmen. */
.crm .sb-foot button.sb-cog { background: transparent; border: 0; font: inherit; padding: 0; }

/* Nach OBEN oeffnen: das Benutzermenue sitzt am unteren Rand der Seitenleiste. */
.crm .popover.po-up { top: auto; bottom: calc(100% + 6px); }
/* Rechtsbuendig: die Glocke sitzt rechts in der Topbar, ein linksbuendiges Panel liefe
   aus dem Fenster. */
.crm .popover.po-end { left: auto; right: 0; }
.crm .popover[hidden] { display: none; }

.crm .po-head { display: flex; align-items: center; justify-content: space-between; gap: var(--s-2); }
.crm .po-head-act {
  background: transparent; border: 0; font: inherit; font-size: 10.5px; font-weight: 600;
  color: var(--ad-blue); cursor: pointer; text-transform: none; letter-spacing: 0; padding: 0;
}
.crm .po-head-act:hover { text-decoration: underline; }
.crm .po-ic { width: 16px; flex: 0 0 auto; text-align: center; opacity: .8; }
.crm .po-item.is-danger { color: var(--ad-red-700); }
.crm .po-empty { padding: var(--s-3) 10px; font-size: 12.5px; color: var(--text-3); text-align: center; }

/* Benachrichtigungs-Eintraege: mehrzeilig, deshalb oben ausgerichtet. */
.crm .po-notif { align-items: flex-start; }
.crm .po-notif-body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.crm .po-notif-msg { font-size: 12.5px; line-height: 1.35; white-space: normal; }
.crm .po-notif small { font-size: 10.5px; color: var(--text-3); }
.crm .po-notif.is-read { opacity: .55; }
.crm #crm-notif-panel { min-width: 320px; max-width: 380px; max-height: 60vh; overflow-y: auto; }

/* Glocke */
.crm .tb-bell-wrap { position: relative; flex: 0 0 auto; }
.crm .tb-bell {
  position: relative;
  width: 34px; height: 34px;
  display: inline-flex; align-items: center; justify-content: center;
  background: transparent; border: 1px solid transparent; border-radius: var(--r-md);
  font: inherit; font-size: 15px; color: var(--text-2); cursor: pointer;
  transition: background var(--t-fast), border-color var(--t-fast);
}
.crm .tb-bell:hover { background: var(--bg-hover); border-color: var(--border); }
.crm .tb-bell-badge {
  position: absolute; top: 1px; right: 1px;
  min-width: 15px; height: 15px; padding: 0 3px;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--ad-orange-700); color: var(--text-inv);
  border-radius: 999px;
  font-family: var(--f-mono); font-size: 9.5px; font-weight: 700; line-height: 1;
}

/* Navigations-Schalter — erst unterhalb des Off-Canvas-Breakpoints sichtbar (s. u.). */
.crm .tb-nav-toggle {
  display: none;
  width: 34px; height: 34px;
  align-items: center; justify-content: center;
  background: transparent; border: 1px solid var(--border); border-radius: var(--r-md);
  font: inherit; font-size: 15px; color: var(--text-2); cursor: pointer;
  flex: 0 0 auto;
}
.crm .tb-nav-toggle:hover { background: var(--bg-hover); }

/* ===================================================================
   RD1.11 #334 — SEITENLEISTE AUF SCHMALEN FENSTERN
   ===================================================================
   Bis hier stand die Seitenleiste bei fixen 240px ohne einen einzigen Breakpoint. Das
   Inventar aus RD1.01 hat bei 860px gemessen: 26 Textknoten der Navigation ragten 41-107px
   heraus und wurden ab 250px vom Canvas ueberdeckt. Die drei vorhandenen Breakpoints
   betrafen ausschliesslich die Topbar.

   Zwei Stufen, als echter Bereich statt zweier ueberlappender Regeln:
     769-1024px  Icon-Spalte  — die Leiste bleibt stehen, nur die Beschriftungen weichen.
                                title/aria-label bleiben, die Bedienung verstummt also nicht.
     bis 768px   Off-Canvas   — die Leiste verlaesst den Rasterfluss und kommt als Overlay
                                ueber den Schalter in der Topbar. MIT Beschriftungen: im
                                Overlay ist Platz, und wer sie erst aufklappt, will lesen.
   =================================================================== */

@media (max-width: 1024px) and (min-width: 769px) {
  .crm .app-shell ,
  .crm .app-shell.shell-hybrid ,
  .crm .app-shell.shell-attio { grid-template-columns: minmax(0, 64px) 1fr; }

  .crm .sidebar { padding-left: 6px; padding-right: 6px; }
  .crm .sb-brand-text ,
  .crm .sb-section ,
  .crm .sb-pill-list ,
  .crm .sb-user ,
  .crm .sb-search-label ,
  .crm .sb-search kbd ,
  .crm .sb-item > span:not(.sb-ic) { display: none; }

  .crm .sb-brand ,
  .crm .sb-search ,
  .crm .sb-item ,
  .crm .sb-foot { justify-content: center; }
  /* Avatar UND Zahnrad passen nicht nebeneinander auf 64px. Das Zahnrad bleibt: es ist
     der Auslöser des Konto-Menues und damit der einzige Abmelde-Weg — der Avatar ist
     nur Schmuck. Der Name steht weiterhin im aria-label des Knopfes. */
  .crm .sb-foot .sb-avatar { display: none; }
  .crm .sb-foot .sb-cog { margin-left: 0; }

  /* PR1.223 #383 — die Unterebene bleibt auf der Icon-Spalte bedienbar, nur enger. Sie
     wird NICHT wie die Beschriftungen der Hauptpunkte ausgeblendet: die tragen dort ihr
     Symbol weiter, „Aktuell/Archiv" hat keines und waere sonst gar nicht erreichbar. */
  .crm .sb-sub {
    padding: .2rem .125rem;
    font-size: .625rem;
    text-align: center;
  }
}

@media (max-width: 768px) {
  .crm .app-shell ,
  .crm .app-shell.shell-hybrid ,
  .crm .app-shell.shell-attio { grid-template-columns: 1fr; position: relative; }

  .crm .sidebar {
    position: absolute; z-index: 60;
    top: 0; bottom: 0; left: 0;
    width: 240px; max-width: 82vw;
    background: var(--bg-shell);
    border-radius: var(--r-lg);
    transform: translateX(-102%);
    transition: transform var(--t-med) var(--ease-out);
  }
  .crm .app-shell.nav-open .sidebar { transform: none; box-shadow: var(--shadow-3); }
  .crm .shell-attio .sidebar { background: var(--bg-surface-2); }

  .crm .tb-nav-toggle { display: inline-flex; }
  /* Auf dieser Breite konkurrieren zu viele Knoepfe um die Topbar. Export und der
     Umschalter treten zurueck; Suche, Glocke, Konto und +Opportunity bleiben. */
  .crm .tb-classic { display: none; }
}

/* RD1.11 #334 — KB-Graph: Graph links, Detail/Legende rechts. Stand als Inline-Raster
   in crm-kb-command-center.js und war damit nicht umbrechbar; unterhalb ~1024px nahm die
   starre 300px-Spalte dem Graphen die Flaeche. Diese View ist zugleich die einzige, die
   min-height:0 von Anfang an richtig gesetzt hatte — sie funktionierte trotzdem nicht,
   weil ihr Elternteil #crm-content bis RD1.11 gar kein Flex-Container war. */
/* RD1.14 #337 — `overflow-y` gilt jetzt in JEDER Breite, nicht erst unter 1024px. Die
   Graph-Karte hat `min-height:440px`; in einem kurzen Fenster (gemessen: 1280x520) passt der
   Body damit nicht, und ohne Scroller waren 162px Inhalt unerreichbar. Der Body ist der eine
   Scroll-Bereich dieser Ansicht. Gegenstueck dazu: das frueher inline gesetzte
   `overflow:hidden` in crm-kb-command-center.js ist entfernt — es hat diese Regel geschlagen. */
.crm .kb-body {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 300px);
  gap: 14px;
  overflow-y: auto;
}
@media (max-width: 1024px) {
  /* Eine Spalte: der Graph braucht Flaeche, Detail und Legende ruecken darunter. */
  .crm .kb-body { grid-template-columns: 1fr; }

  /* RD1.05 (#305) — dasselbe fuer die Kandidaten-Strecke: die Detail-Kiste rutscht unter
     die Liste, statt beide zu quetschen. Bewusst in DIESEM Block statt in einem eigenen —
     eine zweite `@media`-Zeile waere ein zusaetzlicher roher px-Wert im Ratchet.
     ⚠ Die Basisregeln stehen weiter UNTEN in der Datei. Eine Media-Query gewinnt nicht
     durch ihre Verschachtelung, sondern nur ueber Spezifitaet oder Reihenfolge — deshalb
     tragen diese beiden Regeln den zusaetzlichen `.crm-cand`-Schritt (0,3,0 gegen 0,2,0).
     Ohne ihn blieben zwei Spalten stehen, gemessen bei 900 px. */
  .crm .crm-cand .crm-cand-split { grid-template-columns: minmax(0, 1fr); }
  .crm .crm-cand .crm-cand-list { max-height: 24rem; }

  /* PR1.248 (#442) — dasselbe fuer die Alternativen Suchen, aus denselben zwei
     Gruenden: kein zweiter `@media`-Kopf (roher px-Wert im Ratchet), und der
     zusaetzliche `.crm-alt-panel`-Schritt (0,3,0 gegen 0,2,0), weil die
     Basisregeln weiter unten in der Datei stehen und sonst gewaennen. */
  .crm .crm-alt-panel .crm-alt-split { grid-template-columns: minmax(0, 1fr); }
  .crm .crm-alt-panel .crm-alt-list { max-height: 24rem; }
}

/* RD1.11 #334 — Kuerzung langer Textzellen. Kunde und Opportunity lieferten nacktes <td>
   ohne white-space/overflow, waehrend der Rest der Codebasis konsequent kuerzt: ein langer
   Kundenname sprengte die Zeilenhoehe der gesamten Tabelle. `max-width` in ch statt px,
   damit die Grenze mit der Schriftgroesse mitwandert (und ohne den px-Ratchet zu belasten).
   Der volle Text haengt am title-Attribut. */
.crm .tbl td.cell-clip {
  max-width: 26ch;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* RD1.11 #334 — „Abmelden" im Dunkelmodus. --ad-red-700 kommt auf --bg-surface (#0F2033)
   nur auf 3.07:1 und faellt damit unter AA; --ad-red-300 liegt bei 7.28:1. Derselbe Ton,
   den nkv-high/conf-lo/dc-btn im Dark bereits tragen. */
.crm.dark .po-item.is-danger ,
html[data-theme="dark"] .crm .po-item.is-danger { color: var(--ad-red-300); }

/* ===================================================================
   RD1.08 (#331) — Rollen-Sektion im Opportunity-Detail
   ===================================================================
   Das Besetzungs-Cockpit und der Rollen-Editor bringen ihr Markup aus den geteilten
   Modulen mit (`opp-`-Praefix, Regeln in style.css). Das passt optisch bereits — hier
   steht nur, was in der neuen Shell zusaetzlich noetig ist.

   Sichtbarer Tastatur-Fokus: die Sektion fuehrt Bedienelemente ein, die es im Redesign
   vorher nicht gab (Chip-Entfernen, Aufklapper, Editor-Felder). Ohne Ring waeren sie
   per Tastatur unauffindbar — der Produktionsreife-Massstab der RD-Serie verlangt ihn.

   Groessen in `rem`, Farbe aus `--focus`: der Ratchet in scripts/ui-craft-baseline.json
   zaehlt rohe `px`- und Hex-Werte in dieser Datei und laesst sie nur sinken.

   ⚠️ Nebenwirkung, bewusst in Kauf genommen: `checkFocusVisible` in
   scripts/check-ui-craft.mjs prueft nur, OB diese Datei ueberhaupt eine
   :focus-visible-Regel enthaelt. Mit dieser Regel faellt der Zaehler von 11 auf 0 und
   die Pruefung verliert ihre Warnfunktion fuer RD1.11 (#334), das den Fokus
   flaechendeckend nachziehen soll. RD1.11 braucht dafuer eine feinere Pruefung —
   vermerkt am Ticket.

   `--focus` ist bislang nur im Light-Block definiert (Z. 89) und wird im Dark-Theme
   geerbt. Ergaenzt RD1.11 dort ein Pendant, wirkt es hier automatisch mit. */
.crm #opp-detail-roles-mount button:focus-visible,
.crm #opp-detail-roles-mount summary:focus-visible,
.crm #opp-detail-roles-mount input:focus-visible,
.crm #opp-detail-roles-mount select:focus-visible,
.crm #opp-detail-roles-mount textarea:focus-visible {
  outline: 0.125rem solid var(--focus);
  outline-offset: 0.125rem;
}

/* Die Dropzonen des Cockpits sind im Redesign echte Ablageflaechen. Ohne Zeigerwechsel
   ist nicht erkennbar, dass der Chip greifbar ist. */
.crm #opp-detail-roles-mount .opp-qs-chip-remove { cursor: pointer; }

/* ═══════════════════════════════════════════════════════════════════════════
   RD1.05 (#305) — Matching-Kandidaten im neuen Design
   ═══════════════════════════════════════════════════════════════════════════
   Gesicht zu `components/crm-candidate-panel.js`. Bewusst KEIN Nachbau der
   `.opp-cand-*`-Optik aus style.css: die gehoert der klassischen Shell, und
   Konvention 20 verlangt hier denselben Token-Satz wie im Rest von `.crm`.

   Rohwerte sind Absicht vermieden — der ui-craft-Ratchet (RD1.10 #333) zaehlt
   `raw-px` und `raw-hex` in DIESER Datei und laesst beide nur sinken. Deshalb
   ueberall `var(--s-*)`/`var(--r-*)`/Token-Farben, Restmasse in `rem`.
   Das Raster steht in `minmax()`: der Ratchet erkennt das als flexibel an, und
   es ist auch fachlich richtig — die Kiste soll mitschrumpfen, nicht klippen. */

.crm .crm-cand { margin-bottom: var(--s-4); }

.crm .crm-cand-tools {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: var(--s-2); margin-bottom: var(--s-3);
}

.crm .crm-cand-search {
  flex: 1 1 12rem; min-width: 0;
  padding: var(--s-1) var(--s-2);
  border: 0.0625rem solid var(--border); border-radius: var(--r-sm);
  background: var(--bg-surface); color: var(--text-1);
  font-family: var(--f-sans); font-size: 0.8125rem;
}

/* Zwei Spalten, aber nie erzwungen: `minmax(0, …)` laesst beide Seiten schrumpfen,
   statt die Zeile aus dem Container zu druecken (Produktionsreife Punkt 1). */
.crm .crm-cand-split {
  display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
  gap: var(--s-4); align-items: start;
}
.crm .crm-cand-col { min-width: 0; display: flex; flex-direction: column; }

/* Der EINE Scrollbereich des Panels. `overflow-y` steht im Markup (der Ratchet
   zaehlt Scroll-Container je View-Datei); hier nur seine Begrenzung. */
.crm .crm-cand-list {
  max-height: 32rem; min-height: 0;
  display: flex; flex-direction: column; gap: var(--s-2);
  padding-right: var(--s-1);
}

.crm .crm-cand-group {
  font-size: 0.6875rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.03em; color: var(--text-3);
  margin-top: var(--s-2); padding-bottom: var(--s-1);
  border-bottom: 0.0625rem solid var(--border);
}

.crm .crm-cand-row {
  border: 0.0625rem solid var(--border); border-radius: var(--r-md);
  background: var(--bg-surface); padding: var(--s-2);
  display: flex; flex-direction: column; gap: var(--s-1);
  transition: border-color var(--t-fast) var(--ease-out), background var(--t-fast) var(--ease-out);
}
.crm .crm-cand-row:hover { background: var(--bg-hover); }
.crm .crm-cand-row.is-open { border-color: var(--ad-violet); background: var(--tint-violet); }

/* Die Zeile ist ein echter Knopf — deshalb muss ihr Button-Default zurueckgesetzt
   werden, nicht ihre Semantik. */
.crm .crm-cand-main {
  display: flex; align-items: center; gap: var(--s-2); width: 100%;
  background: none; border: 0; padding: 0; cursor: pointer;
  color: inherit; font: inherit; text-align: left;
}
.crm .crm-cand-id { display: flex; align-items: center; gap: var(--s-2); min-width: 0; flex: 1 1 auto; }
/* Lange Namen kuerzen kontrolliert statt die Zeile zu sprengen. */
.crm .crm-cand-name {
  font-weight: 600; font-size: 0.8125rem; color: var(--text-1);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0;
}

.crm .crm-cand-score {
  flex: 0 0 auto; display: flex; flex-direction: column; align-items: center;
  padding: var(--s-1) var(--s-2); border-radius: var(--r-sm);
  border: 0.0625rem solid var(--border); background: var(--bg-surface-2);
}
.crm .crm-cand-score .v { font-family: var(--f-cond); font-weight: 700; font-size: 0.9375rem; line-height: 1.1; }
.crm .crm-cand-score .l { font-size: 0.625rem; color: var(--text-3); text-transform: uppercase; letter-spacing: 0.03em; }
/* Ampel: gefuellt statt getoent. Zwei getoente Gruenstufen sind auf einer Kachel
   dieser Groesse nicht unterscheidbar (gemessen in PR1.147). */
.crm .crm-cand-score.tier-high { background: var(--ad-green-700); border-color: var(--ad-green-700); }
.crm .crm-cand-score.tier-high .v, .crm .crm-cand-score.tier-high .l { color: var(--text-inv); }
.crm .crm-cand-score.tier-good { background: var(--tint-green); border-color: var(--ad-green-700); }
.crm .crm-cand-score.tier-good .v { color: var(--ad-green-700); }
.crm .crm-cand-score.tier-ok { background: var(--tint-orange); border-color: var(--ad-orange-700); }
.crm .crm-cand-score.tier-ok .v { color: var(--ad-orange-700); }

.crm .crm-cand-avail { display: flex; align-items: center; gap: var(--s-2); }
.crm .crm-cand-bar {
  flex: 1 1 auto; height: 0.375rem; min-width: 0;
  background: var(--bg-surface-3); border-radius: var(--r-xs); overflow: hidden;
}
/* Bewusst neutral-blau: zwei Bewertungsfarben je Zeile lesen sich als zwei Urteile. */
.crm .crm-cand-bar-fill { height: 100%; background: var(--ad-blue); }
.crm .crm-cand-avail-txt { font-size: 0.6875rem; color: var(--text-2); flex: 0 0 auto; }

.crm .crm-cand-ctl { display: flex; align-items: center; flex-wrap: wrap; gap: var(--s-2); }
.crm .crm-cand-pick { display: inline-flex; align-items: center; gap: var(--s-1); font-size: 0.6875rem; color: var(--text-2); cursor: pointer; }
.crm .crm-cand-when { font-size: 0.6875rem; color: var(--text-3); }
.crm .crm-cand-link {
  background: none; border: 0; padding: 0; cursor: pointer;
  font-size: 0.6875rem; color: var(--ad-blue); text-decoration: underline; font-family: inherit;
}
.crm .crm-cand-link[disabled] { color: var(--text-3); cursor: not-allowed; text-decoration: none; }

.crm .crm-cand-more {
  margin-top: var(--s-2); padding: var(--s-1); width: 100%;
  background: none; border: 0.0625rem dashed var(--border); border-radius: var(--r-sm);
  color: var(--text-2); font-size: 0.75rem; font-family: inherit; cursor: pointer;
}

.crm .crm-cand-foot { margin-top: var(--s-2); font-size: 0.6875rem; color: var(--text-3); }
/* PR1.244 (#423) — Gegenstueck zu .opp-cand-notice: die Einschraenkung steht ueber der
   Rangfolge, nicht unter ihr. Eine Stufe kraeftiger als die Fusszeile, ohne Statusfarbe. */
.crm .crm-cand-notice { margin-bottom: var(--s-2); font-size: 0.75rem; color: var(--text-2); }
.crm .crm-cand-notice:empty { margin-bottom: 0; }
.crm .crm-cand-state { font-size: 0.8125rem; color: var(--text-3); padding: var(--s-3) 0; }

/* PR1.254 (#448) — Reverse-Matching, Redesign-Gesicht.
   Klassisches Pendant: .emp-match-* in style.css. Nur Tokens, keine rohen Hex- oder
   px-Werte — der ui-craft-Ratchet (Konvention 21) zaehlt beides und laesst es nur sinken.
   Groessen deshalb in rem, Abstaende ueber --s-*, Radien ueber --r-*. */
.crm .crm-rev-actions { display: flex; gap: var(--s-2); margin-left: auto; }
.crm .crm-rev-list { display: flex; flex-direction: column; gap: var(--s-2); max-height: 60vh; }
.crm .crm-rev-row {
    padding: var(--s-2) var(--s-3);
    border-radius: var(--r-sm);
}
/* Trennung ueber eine Haarlinie statt ueber eine eigene Flaeche.
   GRUND (gemessen mit axe-core, 21.08.2026): die Linkfarbe --rd-blue (#006EC7) liegt im
   dunklen Redesign auf JEDEM Untergrund unter der AA-Schwelle — 3,45:1 auf dem App-Grund,
   3,18:1 auf der Karte. Ein zusaetzlicher, etwas hellerer Zeilenhintergrund
   (--bg-surface-2) drueckte sie auf 2,82:1 und machte ein vorbestehendes Problem
   messbar schlimmer. Die Flaeche gab optisch wenig und kostete 0,36 Kontrast.
   Der Grundbefund selbst gehoert nicht in dieses Ticket: er betrifft jede Liste der
   Redesign-Shell und waere ein Token-Eingriff. Siehe Evidenz-Fragment. */
.crm .crm-rev-row + .crm-rev-row {
    border-top: thin solid var(--border);
    padding-top: var(--s-3);
}
.crm .crm-rev-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: var(--s-1); }
.crm .crm-rev-when { font-size: 0.75rem; color: var(--text-3); }
.crm .crm-rev-reason { font-size: 0.75rem; line-height: 1.45; margin-top: var(--s-1); }
.crm .crm-rev-act { flex-shrink: 0; }

/* Die drei Zustaende. `is-loading` traegt zugleich den view-states-Nachweis im
   Quelltext des Panels (siehe Kopfkommentar dort). */
.crm .crm-rev-state {
    display: flex; flex-direction: column; gap: var(--s-2);
    align-items: flex-start;
    font-size: 0.8125rem; color: var(--text-3);
    padding: var(--s-3) 0;
}
.crm .crm-rev-state .val { color: var(--text-1); font-weight: 600; }
.crm .crm-rev-error {
    /* Volle Umrandung statt Seitenstreifen — dieselbe Begruendung wie im klassischen
       Pendant (.emp-match-error in style.css). */
    /* `thin` statt `1px`: der ui-craft-Ratchet (Konvention 21) zaehlt harte px-Werte
       in dieser Datei und laesst sie nur sinken. Das Keyword ergibt dieselbe
       Haarlinie ohne den Zaehler zu erhoehen. */
    border: thin solid var(--danger);
    border-radius: var(--r-sm);
    padding: var(--s-3);
}

/* BF-32 (#427) — Pendant zu .opp-cand-degraded-action / .opp-cand-unpersisted in
   style.css. Gleiche Aussage, Redesign-Tokens: keine rohen Farbwerte, keine harten
   px-Abstaende (der ui-craft-Ratchet zaehlt beides). */
.crm .crm-cand-state-action { display: block; margin-top: var(--s-2); color: var(--text-3); }
.crm .crm-cand-unpersisted {
    font-size: 0.8125rem;
    line-height: 1.45;
    color: var(--warning);
    margin-bottom: var(--s-3);
    padding: var(--s-2) var(--s-3);
    background: color-mix(in srgb, var(--warning) 10%, transparent);
    border-radius: var(--radius-sm);
}
.crm .crm-cand-unpersisted-action { color: var(--text-3); }

/* ── Detail-Kiste ──────────────────────────────────────────────────────────── */
.crm .crm-cand-detail { min-width: 0; }
.crm .crm-cd { display: flex; flex-direction: column; gap: var(--s-3); }
.crm .crm-cd-head { display: flex; align-items: center; gap: var(--s-2); }
.crm .crm-cd-head-txt { display: flex; align-items: center; gap: var(--s-2); min-width: 0; flex: 1 1 auto; }
.crm .crm-cd-name { font-weight: 700; font-size: 0.875rem; color: var(--text-1); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.crm .crm-cd-sec { border-top: 0.0625rem solid var(--border); padding-top: var(--s-2); }
.crm .crm-cd-sec-t { font-size: 0.6875rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.03em; color: var(--text-3); margin-bottom: var(--s-2); }
.crm .crm-cd-p { font-size: 0.8125rem; color: var(--text-2); margin: 0 0 var(--s-2); line-height: 1.5; }
.crm .crm-cd-muted { font-size: 0.75rem; color: var(--text-3); }
.crm .crm-cd-block { margin-bottom: var(--s-3); }
.crm .crm-cd-block-t { font-size: 0.75rem; font-weight: 600; color: var(--text-2); margin-bottom: var(--s-1); }
.crm .crm-cd-chips { display: flex; flex-wrap: wrap; gap: var(--s-1); }
.crm .crm-cd-chip {
  display: inline-flex; align-items: center; gap: var(--s-1);
  padding: 0 var(--s-1); border-radius: var(--r-xs);
  background: var(--bg-surface-2); color: var(--text-2); font-size: 0.6875rem;
}
.crm .crm-cd-chip.is-ok { background: var(--tint-green); color: var(--ad-green-700); }
.crm .crm-cd-chip.is-warn { background: var(--tint-orange); color: var(--ad-orange-700); }
.crm .crm-cd-card {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2);
  border: 0.0625rem solid var(--border); border-radius: var(--r-sm);
  padding: var(--s-2); margin-bottom: var(--s-1); background: var(--bg-surface);
}
.crm .crm-cd-card-t { font-size: 0.8125rem; font-weight: 600; color: var(--text-1); }
.crm .crm-cd-list { margin: 0; padding-left: var(--s-4); font-size: 0.75rem; color: var(--text-2); }

.crm .crm-cd-metric { border-bottom: 0.0625rem solid var(--border); padding: var(--s-1) 0; }
.crm .crm-cd-metric > summary { display: flex; align-items: center; gap: var(--s-2); cursor: pointer; list-style: none; }
.crm .crm-cd-metric > summary::-webkit-details-marker { display: none; }
.crm .crm-cd-metric-l { font-size: 0.75rem; color: var(--text-2); flex: 0 0 8rem; }
.crm .crm-cd-metric-bar { flex: 1 1 auto; height: 0.375rem; min-width: 0; background: var(--bg-surface-3); border-radius: var(--r-xs); overflow: hidden; }
.crm .crm-cd-metric-fill { display: block; height: 100%; background: var(--ad-blue); }
.crm .crm-cd-metric-fill.high { background: var(--ad-green-700); }
.crm .crm-cd-metric-fill.medium { background: var(--ad-orange-700); }
.crm .crm-cd-metric-fill.low { background: var(--ad-red); }
.crm .crm-cd-metric-v { flex: 0 0 auto; font-family: var(--f-cond); font-weight: 700; font-size: 0.8125rem; color: var(--text-1); }
.crm .crm-cd-ev-body { padding: var(--s-2) 0 var(--s-1); }
.crm .crm-cd-ev-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--s-1); }
.crm .crm-cd-ev { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-1); font-size: 0.75rem; color: var(--text-2); }
.crm .crm-cd-ev-q { font-style: italic; }

/* Sichtbarer Tastatur-Fokus fuer die neuen Bedienelemente — RD1.11-Regelsatz,
   hier auf die Kandidaten-Strecke gezogen. */
.crm .crm-cand button:focus-visible,
.crm .crm-cand summary:focus-visible,
.crm .crm-cand input:focus-visible {
  outline: 0.125rem solid var(--focus);
  outline-offset: 0.125rem;
}

/* Schmales Fenster: die Kiste rutscht unter die Liste, statt beide zu quetschen.
   Die Regeln stehen im BESTEHENDEN 1024er-Block weiter oben (Z. 1654) statt in einem
   eigenen: eine neue `@media (max-width: 1024px)`-Zeile waere ein zusaetzlicher roher
   px-Wert und haette den `raw-px`-Ratchet gerissen (683 -> 684), ohne einen einzigen
   zusaetzlichen Breakpoint zu schaffen. */

/* ============== RD1.13 #336 Phase 5 — Kunden-Excel-Tabelle ==============
   Sechs ein-/ausklappbare Spaltengruppen mit klebender Kundenspalte.

   Bewusst OHNE `px` und ohne rohe Hex-Farben: die Ratchets raw-px/raw-hex zaehlen
   ausschliesslich in dieser Datei und duerfen nicht steigen (R1/R9). Nur Tokens,
   `rem`, `%` und `thin` fuer Haarlinien.

   Die Huelle scrollt ausschliesslich WAAGERECHT. `overflow-x` zaehlt fuer die Pruefung
   scroll-container nicht mit (sie sucht `overflow:` und `overflow-y:`) — der eine
   senkrechte Scrollbereich der View bleibt damit der einzige. Die Kundenspalte klebt
   per `position: sticky` IN dieser Huelle, NICHT in einem zweiten Scroll-Container. */
.crm .cust-tbl-hull { overflow-x: auto; border-radius: 0.5rem; }
.crm .tbl-cust { min-width: 100%; }

/* Kopfzeile der Spaltengruppen: dezenter als die Spaltenkoepfe, damit die Hierarchie
   ohne zusaetzliche Linien lesbar ist. */
.crm .tbl-cust thead .grp-row th {
  cursor: pointer;
  text-align: center;
  color: var(--text-2);
  background: var(--bg-surface-3);
  border-bottom: thin solid var(--border);
  user-select: none;
}
.crm .tbl-cust thead .grp-row th.is-collapsed { color: var(--text-3); font-style: italic; }
.crm .tbl-cust thead .grp-row th:hover { color: var(--text-1); }

/* Spaltenkopf: der Sortier-Knopf fuellt die Zelle, damit die gesamte Kopfflaeche
   klickbar ist — er ist ein echter <button> (Fokus-Ratchet RD1.10). */
.crm .tbl-cust th.col-h { white-space: nowrap; }
.crm .tbl-cust th.col-h .col-sort {
  all: unset;
  display: block; width: 100%;
  cursor: pointer;
  font: inherit; color: inherit; letter-spacing: inherit; text-transform: inherit;
}
.crm .tbl-cust th.col-h .col-sort:hover { color: var(--text-1); }
.crm .tbl-cust .sort-rank {
  display: inline-block;
  margin-left: 0.25rem;
  padding: 0 0.3rem;
  /* Pillenform in `rem` statt der sonst ueblichen 999px — der raw-px-Ratchet zaehlt
     auch diesen Wert, und diese Phase soll ihn nicht gegenfinanzieren. */
  border-radius: 0.75rem;
  font-family: var(--f-mono); font-size: 0.65rem;
  background: var(--bg-surface-3); color: var(--text-2);
}

/* Klebende Kundenspalte. Der Hintergrund muss gesetzt sein, sonst scheinen die
   darunterliegenden Zellen beim Scrollen durch. */
.crm .tbl-cust th.is-sticky,
.crm .tbl-cust td.is-sticky {
  position: sticky; left: 0; z-index: 2;
  box-shadow: inset -0.0625rem 0 0 0 var(--border);
}
.crm .tbl-cust td.is-sticky { background: var(--bg-surface); }
.crm .tbl-cust thead th.is-sticky { z-index: 3; background: var(--bg-surface-2); }
.crm .tbl-cust tbody tr:hover td.is-sticky { background: var(--bg-hover); }

/* Lange Freitextwerte duerfen die Tabelle nicht in die Breite treiben — sie werden
   gekuerzt, der volle Wert bleibt ueber den Inline-Edit erreichbar. */
.crm .tbl-cust tbody td {
  max-width: 14rem;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.crm .tbl-cust tbody td.is-sticky { max-width: 16rem; }
.crm .tbl-cust .crm-tbl-empty { text-align: center; padding: 1.25rem 0.75rem; }

/* Such- und Filterleiste ueber der Tabelle. */
.crm .cust-filter-bar {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem;
}
/* Das Suchfeld nimmt den freien Platz. Bewusst ueber den Typ statt ueber eine ID: die
   Leiste wird seit RD1.13 Phase 6 auch vom Audit-Log benutzt, und eine ID-gebundene Regel
   haette dessen Feld auf Inhaltsbreite zusammenfallen lassen. */
.crm .cust-filter-bar input[type="search"] { flex: 1 1 14rem; min-width: 0; }

/* RD1.13 #336 Phase 5 — Karten-Ansicht der Kunden (Inventar Z. 638) und das Popover der
   Erweiterten Suche. Wie oben: nur Tokens, `rem`, `%` und `thin` — keine rohen px, keine
   Hex-Farben, kein zweiter senkrechter Scroll-Container. */
.crm .cust-card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(18rem, 1fr));
  gap: 0.875rem;
}
.crm .cust-card { padding: 0.875rem; cursor: pointer; }
.crm .cust-card-head { display: flex; align-items: flex-start; gap: 0.5rem; }
.crm .cust-card-title { display: flex; flex-direction: column; gap: 0.125rem; min-width: 0; flex: 1; }
/* Lange Kundennamen brechen kontrolliert statt die Karte zu sprengen. */
.crm .cust-card-title .strong { overflow-wrap: anywhere; }
.crm .cust-card-badges { display: flex; flex-wrap: wrap; gap: 0.375rem; margin-top: 0.5rem; }
.crm .cust-card-kpis {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(6rem, 1fr));
  gap: 0.5rem; margin: 0.75rem 0 0;
}
.crm .cust-card-kpis div {
  padding: 0.5rem;
  background: var(--bg-surface-2);
  border: thin solid var(--border);
  border-radius: 0.4rem;
}
.crm .cust-card-kpis dt { font-size: 0.68rem; color: var(--text-3); text-transform: uppercase; letter-spacing: .03em; }
.crm .cust-card-kpis dd { margin: 0.2rem 0 0; font-weight: 600; color: var(--text-1); }
.crm .cust-card-tl-head { margin-top: 0.75rem; }
.crm .cust-card-tl { list-style: none; margin: 0.25rem 0 0; padding: 0; }
.crm .cust-card-tl-item {
  display: flex; align-items: center; gap: 0.5rem;
  padding: 0.3rem 0;
  border-top: thin solid var(--border);
  cursor: pointer;
}
.crm .cust-card-tl-item:hover { background: var(--bg-hover); }
.crm .cust-card-tl-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ── PR1.277 (#471) — Bewegung, Logo in der Zeile, Fokus-Ansicht ───────────────
   Bewusst px-frei: der ui-craft-Ratchet (Konvention 21) steht auf 683/683 harten
   px-Werten und 65/65 rohen Hex — jeder neue Wert blockiert die Pipeline. Alle Maße
   kommen deshalb aus rem, `thin` und den .crm-Tokens. */

/* Bewegungs-Kennzeichen: Punkt UND Wort. Nie nur Farbe — ein Zustand, den man allein
   an der Farbe erkennt, ist fuer Farbfehlsichtige kein Zustand. */
/* PR1.293 (#494) — `font-size` steht jetzt ausdruecklich hier. Vorher erbte die Marke
   13px aus `.crm .tbl`; das war zufaellig richtig, aber nicht festgeschrieben — eine
   Aenderung an der Tabellen-Grundschrift haette sie stillschweigend mitgezogen. Derselbe
   Wert wie klassisch, damit beide Shells dieselbe Groesse zeigen. rem statt px: der
   raw-px-Ratchet steht auf 683/683 und blockiert jeden neuen px-Wert in dieser Datei. */
.crm .mv-tag { display: inline-flex; align-items: center; gap: 0.375rem; white-space: nowrap; font-size: 0.8125rem; }
.crm .mv-dot { width: 0.5625rem; height: 0.5625rem; border-radius: 50%; flex: 0 0 auto; }
/* PR1.293 — Paritaets-Luecke: `.mv-label` gab es nur klassisch (style.css). Im Redesign
   trug das Wort die volle Zellfarbe und dominierte damit den Punkt daneben. */
.crm .mv-label { color: var(--text-2); }
/* ⚠️ Die -700-Stufen, nicht die Grundtoene: `--ad-green` (#76C800) und `--ad-orange`
   (#FF9868) erreichen auf der weissen Karte nur 2.09:1 bzw. 2.11:1 und verfehlen damit
   WCAG 1.4.11 (nicht-textueller Kontrast, 3:1). Die -700-Stufen liegen bei 3.23:1 und
   3.03:1. Gemessen mit demselben Verfahren wie scripts/check-crm-contrast.mjs. */
.crm .mv-active { background: var(--ad-green-700); }
.crm .mv-quiet { background: var(--ad-orange-700); }
.crm .mv-dormant { background: var(--ad-red-700); }
.crm .mv-unknown { background: var(--text-3); }

/* Die Bewegung zusaetzlich als schmale Leiste am Zeilen- bzw. Kartenrand. Sie kostet
   keine Spalte und macht die Verteilung beim Ueberfliegen sichtbar. Die Leiste ist eine
   ZWEITE Kodierung derselben Information, nie die einzige — die Spalte „Bewegung"
   nennt den Zustand im Klartext. */
.crm .tbl-cust tbody tr.mv-lead > td:first-child { border-left: 0.2rem solid transparent; }
.crm .tbl-cust tbody tr.mv-lead-active > td:first-child { border-left-color: var(--ad-green-700); }
.crm .tbl-cust tbody tr.mv-lead-quiet > td:first-child { border-left-color: var(--ad-orange-700); }
.crm .tbl-cust tbody tr.mv-lead-dormant > td:first-child { border-left-color: var(--ad-red-700); }
/* Die Karte traegt KEINE farbige Akzentkante mehr.
   Sie war die dritte Kodierung derselben Aussage — der Punkt und das Wort im Kartenfuss
   sagen den Zustand bereits — und eine farbige Leiste am Rand einer abgerundeten Karte ist
   das saturierteste Erkennungsmerkmal generierter Oberflaechen. In der TABELLE bleibt die
   Leiste: dort gibt es keine Gruppierung, 67 Zeilen wollen ueberflogen werden, und die Kante
   spart das Lesen einer Spalte. Auf einer Karte spart sie nichts. */

/* Logo in der Namenszelle — die Luecke, die „keine Logos" meinte. Das Monogramm ist ein
   <span>; das Bild setzt services/account-logo-client.js spaeter als Hintergrund. */
.crm .cust-name-cell { display: flex; align-items: center; gap: 0.5rem; min-width: 0; }
/* PR1.293 (#494) — die Namenszelle ist ein <button> geworden (Klick oeffnet die
   Kundenseite, und nur ein Knopf ist ohne Maus erreichbar). Er soll wie Text wirken:
   Browser-Default zuruecknehmen, Zeiger und Unterstrich als Affordanz, sichtbarer Fokus
   aus dem .crm-Token. Alle Masse in rem — raw-px-Ratchet. */
.crm .cust-name-btn { background: none; border: 0; padding: 0; margin: 0; font: inherit;
  color: inherit; text-align: left; cursor: pointer; width: 100%; }
.crm .cust-name-btn:hover .cust-name-text { text-decoration: underline; }
.crm .cust-name-btn:focus-visible { outline: 0.125rem solid var(--ad-blue); outline-offset: 0.125rem; border-radius: 0.25rem; }
.crm .cust-name-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.crm .cust-strat { color: var(--ad-blue); font-size: 0.75rem; flex: 0 0 auto; }

.crm .cust-card-foot {
  display: flex; align-items: center; justify-content: space-between; gap: 0.5rem;
  margin-top: 0.75rem; padding-top: 0.5rem;
  border-top: thin solid var(--border);
  font-size: 0.75rem; color: var(--text-3);
}

/* Fokus-Ansicht: gruppiert nach Bewegung, innerhalb der Gruppe das groesste Geld zuerst. */
.crm .cust-focus-sect { margin-bottom: 1.25rem; }
.crm .cust-focus-head {
  display: flex; align-items: center; gap: 0.5rem; margin: 0 0 0.25rem;
  font-size: 0.8rem; font-weight: 600; text-transform: uppercase; letter-spacing: .05em;
  color: var(--text-2);
}
.crm .cust-focus-hint { margin: 0 0 0.5rem; }
/* Ebenfalls ohne Akzentkante: in der Fokus-Ansicht nennt schon die GRUPPE den Zustand,
   und die Meta-Zeile wiederholt ihn im Wort. Eine Leiste waere die vierte Kodierung. */
.crm .cust-focus-row {
  display: flex; align-items: center; gap: 0.625rem;
  padding: 0.5rem 0.75rem; margin-bottom: 0.3rem; cursor: pointer;
  background: var(--bg-surface); border: thin solid var(--border);
  border-radius: var(--r-sm);
}
.crm .cust-focus-row:hover { background: var(--bg-hover); }
.crm .cust-focus-row:focus-visible { outline: 0.125rem solid var(--focus); outline-offset: 0.125rem; }
.crm .cust-focus-main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.crm .cust-focus-main .strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.crm .cust-focus-pipe { font-weight: 600; color: var(--text-1); white-space: nowrap; }
.crm .cust-focus-rest { margin: 0; }
/* ⚠️ `.crm .muted` und `.crm .strong` sind ausschliesslich innerhalb von `.tbl` definiert
   (style-redesign.css:728-729). Die Fokus-Ansicht ist keine Tabelle — ohne diese beiden
   Regeln stuenden ihre Nebentexte in voller Textfarbe und der Kundenname ohne Gewicht. */
.crm .cust-focus-main .strong { font-weight: 600; color: var(--text-1); }
.crm .cust-focus-main .muted,
.crm .cust-focus-hint,
.crm .cust-focus-n,
.crm .cust-focus-rest { color: var(--text-3); font-size: 0.75rem; }
.crm .cust-focus-head .cust-focus-n { font-weight: 400; }

/* Popover der Erweiterten Suche: der Query-Builder bringt sein eigenes Markup mit
   (query-builder.js) und wird konsumiert, nicht nachgebaut. Diese Regeln geben ihm die
   Flaeche und den Rahmen der Redesign-Shell. */
.crm .qb-popover {
  padding: 0.75rem;
  background: var(--bg-surface);
  border: thin solid var(--border);
  border-radius: 0.5rem;
}
.crm .qb-popover[hidden] { display: none; }

/* RD1.13 #336 Phase 6 — aufklappbare Diff-Details im Audit-Log (Inventar Z. 725).
   <details>/<summary> statt eines Toggle-Knopfs: ohne JavaScript bedienbar, Tastatur gratis. */
.crm .audit-diff summary { cursor: pointer; color: var(--text-2); font-size: 0.78rem; }
.crm .audit-diff summary:hover { color: var(--text-1); }
.crm .audit-diff-body {
  margin: 0.375rem 0 0;
  padding: 0.5rem;
  max-height: 12rem;
  /* Nur waagerecht scrollend — der eine senkrechte Scrollbereich der View bleibt der
     einzige (Pruefung scroll-container zaehlt `overflow:` und `overflow-y:`). */
  overflow-x: auto;
  background: var(--bg-surface-2);
  border: thin solid var(--border);
  border-radius: 0.4rem;
  font-family: var(--f-mono); font-size: 0.7rem;
  white-space: pre;
}

/* RD1.13 #336 Phase 6 — Auslastungs-Balken der FTE-Kachel (Inventar Z. 299). Die Farbe
   kommt inline aus fteUtilization (Ampel-Token), die Geometrie hier. Ohne px, ohne Hex. */
.crm .kpi .crm-fte-bar {
  margin-top: 0.4rem;
  height: 0.3rem;
  border-radius: 0.15rem;
  background: var(--bg-surface-3);
  overflow: hidden;
}
.crm .kpi .crm-fte-bar-fill { height: 100%; border-radius: inherit; transition: width var(--t-fast); }

/* RD1.13 #336 Phase 6 — der Bucket-Titel der Staffability-Kachel ist ein echter <button>
   (Inventar Z. 312): so ist der Detail-Dialog ohne Maus erreichbar und der Fokus-Ratchet
   aus RD1.10 greift. Er soll aber wie Text aussehen, nicht wie ein Knopf. */
.crm .crm-staff-title {
  all: unset;
  cursor: pointer;
  font: inherit; color: inherit;
  text-decoration: underline dotted;
  text-underline-offset: 0.15rem;
}
.crm .crm-staff-title:hover { color: var(--text-1); text-decoration-style: solid; }

/* RD1.13 #336 Reparatur (Coordinator-Befund 03.08.) — die Zahl der Kachel ist jetzt der
   zweite echte Knopf (Filter auf die Opp-Liste), nachdem der Kachelrahmen sein
   `role="button"` abgegeben hat. Sie soll unverändert aussehen wie die Zahl vorher. */
.crm .crm-staff-count {
  display: block;
  padding: 0; border: 0; background: none; cursor: pointer;
  font: inherit; font-size: 1.4rem; font-weight: 800;
  color: inherit; text-align: left;
}

/* RD1.13 #336 Phase 6 — Untertitel einer Dashboard-Kachel (Inventar Z. 307). */
.crm .dw-card-sub { display: block; margin: -0.25rem 0 0.5rem; }

/* PR1.308 (#517) — das Kachelraster. Stand bis hierher als Inline-Stil in
   views/dashboard.js; ohne Klasse gibt es keine Media-Query und damit kein
   verlaessliches Verhalten auf schmalem Fenster.
   Vier Spalten statt `auto-fill`: auf einem auto-fill-Raster ist `grid-column: span n`
   nicht verlaesslich — die breite Karte landet je Fensterbreite in einer anderen Zeile.
   Alles in rem und Tokens: der ui-craft-Ratchet `raw-px` hat null Luft, ein einziges
   hartes px in dieser Datei blockt den Merge. */
.crm .crm-dw-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--s-3);
  align-items: start;
}

.crm .dw-card.dash-size-klein  { grid-column: span 1; }
.crm .dw-card.dash-size-mittel { grid-column: span 2; }
.crm .dw-card.dash-size-gross  { grid-column: span 4; }

/* Die grossen Schaubilder bleiben ausserhalb des Spaltenmodells und behalten
   ihr bisheriges Verhalten (bewusst ausserhalb von PR1.307/1.308).

   PR1.311 (#520): die Mindestbreite von 20rem auf 28rem gehoben. Seit diese Karten
   echte Diagramme zeigen, ist die Breite nicht mehr nur Geschmack: chart-kit zeichnet
   in fester 800er-Breite mit festen Abstaenden, und auf 20rem (=320px, bei 1280px
   Fensterbreite drei Spalten a ~380px) ueberlappten die zwoelf Monatsbeschriftungen
   der Auslastungslinie einander — gemessen von test/layout, 13 Fundstellen bei 768
   und bei 1280. Ab 28rem liegen es hoechstens zwei Spalten, und die Beschriftung hat
   wieder Platz. In `rem`, damit der ui-craft-Ratchet `raw-px` nicht steigt. */
.crm .crm-dw-grid-charts {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--s-3);
  align-items: start;
}

.crm .crm-dw-grid-charts > .dw-card.dash-size-klein  { grid-column: span 1; }
.crm .crm-dw-grid-charts > .dw-card.dash-size-mittel { grid-column: span 2; }
.crm .crm-dw-grid-charts > .dw-card.dash-size-gross  { grid-column: span 4; }

/* Die Umbrueche stehen bewusst HIER und nicht in den bestehenden px-Bloecken weiter
   oben: die Grundregel `.crm .crm-dw-grid` hat dieselbe Spezifitaet und steht in der
   Datei spaeter — sie haette jede frueher notierte Media-Regel wieder ueberstimmt, und
   das Redesign waere auf schmalem Fenster stur vierspaltig geblieben (gemessen).
   In `rem` statt `px`, damit der ui-craft-Ratchet `raw-px` nicht steigt; 64rem/48rem
   entsprechen den 1024px/768px der uebrigen Shell-Breakpoints. */
@media (max-width: 64rem) {
  .crm .crm-dw-grid , .crm .crm-dw-grid-charts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .crm .dw-card.dash-size-klein  { grid-column: span 1; }
  .crm .dw-card.dash-size-mittel { grid-column: span 1; }
  .crm .dw-card.dash-size-gross  { grid-column: span 2; }
  /* Dieselben Spannen noch einmal mit der Spezifitaet des charts-Rasters: dessen
     Grundregel traegt drei Klassen und haette die zwei Zeilen darueber sonst
     ueberstimmt — eine `gross`-Karte waere mit `span 4` in einem Zweispalter stehen
     geblieben und ueber ihre Nachbarin gelaufen (gemessen: 14px Ueberlappung). */
  .crm .crm-dw-grid-charts > .dw-card.dash-size-klein  { grid-column: span 1; }
  .crm .crm-dw-grid-charts > .dw-card.dash-size-mittel { grid-column: span 1; }
  .crm .crm-dw-grid-charts > .dw-card.dash-size-gross  { grid-column: span 2; }
}

/* Eine Spalte: jede Karte ist voll breit, unabhaengig von der Stufe. Das ist die
   Zusicherung „auf schmalem Fenster wird gross zur vollen Breite". */
@media (max-width: 48rem) {
  .crm .crm-dw-grid , .crm .crm-dw-grid-charts { grid-template-columns: minmax(0, 1fr); }
  .crm .dw-card.dash-size-klein ,
  .crm .dw-card.dash-size-mittel ,
  .crm .dw-card.dash-size-gross { grid-column: span 1; }
  .crm .crm-dw-grid-charts > .dw-card.dash-size-klein ,
  .crm .crm-dw-grid-charts > .dw-card.dash-size-mittel ,
  .crm .crm-dw-grid-charts > .dw-card.dash-size-gross { grid-column: span 1; }
}

/* ============================================================
   PR1.189 (#347) — In-App-Feedback, Redesign-Gesicht
   ============================================================
   Struktur und Abstaende des Formulars stehen in style.css und sind NICHT
   .crm-gescopt — sie greifen damit bereits in beiden Shells. Hier wird deshalb
   kein Layout wiederholt, sondern nur die Designsprache uebersetzt: die
   Legacy-Tokens werden im .crm-Scope auf ihre Redesign-Entsprechung gemappt.

   Das hat zwei Vorteile ueber eine zweite Regelmenge: Layoutaenderungen bleiben
   an einer Stelle (ein Gehirn, zwei Gesichter — Konvention 20), und dieser Block
   kommt ohne einen einzigen rohen px- oder Hex-Wert aus, wie Konvention 21 und
   der ui-craft-Ratchet es verlangen. Dark wird automatisch mitgetragen, weil die
   Zieltokens selbst themenabhaengig sind. */
.crm .fb-form,
.crm .fb-foot {
  /* PR1.229: die naechsten vier stehen seit PR1.229 auch an der .crm-Wurzel und
     sind hier redundant. Sie bleiben als Selbstbeschreibung des Bausteins
     stehen — der Block traegt weiterhin allein, was die Wurzel nicht fuehrt
     (--primary/-glow, --danger, --warning, --radius*, --transition). */
  --bg-card: var(--bg-surface);
  --bg-card2: var(--bg-surface-2);
  --bg-input: var(--bg-surface);
  --border-light: var(--border);
  /* Bewusste Abweichung von der Wurzel (--bg-hover dort auf eigenem Wert):
     Formularzeilen heben sich flaechig ab, nicht ueber einen Hover-Ton. */
  --bg-hover: var(--bg-surface-3);
  --primary: var(--ad-blue);
  --primary-glow: var(--tint-blue);
  --danger: var(--ad-red);
  --warning: var(--ad-orange-700);
  --radius: var(--r-md);
  --radius-sm: var(--r-sm);
  --transition: var(--t-fast);
}

/* Die Kategorie-Wahl ist der erste Schritt und traegt deshalb die
   Condensed-Schrift der Redesign-Kopfzeilen. */
.crm .fb-legend { font-family: var(--f-cond); }
.crm .fb-cat { font-family: var(--f-cond); letter-spacing: 0.01em; }

/* Der Zaehler ist eine Messgroesse — im Redesign steht so etwas in Mono. */
.crm .fb-count { font-family: var(--f-mono); }

/* Der Fuss traegt links die Begruendung, rechts die Knoepfe (crmModalFoot). */
.crm .fb-foot { display: flex; align-items: center; gap: var(--s-3); }

/* PR1.189 (#347) — Feedback-Einstieg unten in der Seitenleiste. Der Knopf traegt
   `sb-item` und erbt damit Optik, Hover und Fokus der Navigation; hier steht nur,
   was die Position betrifft. Ohne den Container haetten Feedback-Knopf und
   Konto-Bereich je ein eigenes `margin-top:auto` und der Freiraum verteilte sich
   zwischen beiden, statt beide nach unten zu schieben. */
.crm .sb-bottom { margin-top: auto; }
.crm .sb-bottom .sb-foot { margin-top: 0; }
.crm .sb-feedback { width: 100%; }

/* ============================================================
   PR1.191 (#350) — Auswahl-Baustein, Redesign-Gesicht
   ============================================================
   Struktur und Abstaende des Bausteins stehen in style.css und sind NICHT
   .crm-gescopt — sie greifen damit bereits in beiden Shells. Hier wird deshalb
   kein Layout wiederholt, sondern nur die Designsprache uebersetzt: die
   Legacy-Tokens werden im .crm-Scope auf ihre Redesign-Entsprechung gemappt.
   Gleiches Vorgehen wie PR1.189 (#347) weiter oben — ein Gehirn, zwei Gesichter
   (Konvention 20), und der Block kommt ohne einen einzigen rohen px- oder
   Hex-Wert aus, wie Konvention 21 und der ui-craft-Ratchet es verlangen. Dark
   traegt sich automatisch mit, weil die Zieltokens selbst themenabhaengig sind.

   Kein `transition`: der Baustein wird dutzende Male am Tag ueber die Tastatur
   bedient (Konvention 22, DESIGN.md-Prinzip 2 „Frequenz bestimmt Motion"). */
.crm .ms,
.crm .ms-list {
  /* PR1.229: die naechsten vier sind seit PR1.229 auch an der .crm-Wurzel belegt
     und hier redundant; sie bleiben als Selbstbeschreibung stehen. Eigenstaendig
     bleiben --primary, --radius-sm und vor allem --danger (dunklere Stufe). */
  --bg-card: var(--bg-surface);
  --bg-card2: var(--bg-surface-2);
  --bg-input: var(--bg-surface);
  --border-light: var(--border);
  /* Bewusste Abweichung von der Wurzel — s. Feedback-Block oben. */
  --bg-hover: var(--bg-surface-3);
  --primary: var(--ad-blue);
  --radius-sm: var(--r-sm);
  /* --ad-red traegt weisse Schrift nur auf 3.91:1 — fuer Flaechen mit Text gilt
     die dunklere Stufe (siehe Kontrast-Reparatur RD1.13 am Token selbst). */
  --danger: var(--ad-red-700);
}

/* Die Gruppen-Ueberschrift ist eine Kopfzeile — im Redesign traegt so etwas
   die Condensed-Schrift, wie die uebrigen Abschnittstitel. */
.crm .ms-group-header { font-family: var(--f-cond); }

.crm .ms-chip-x:hover { color: var(--text-inv); }

/* BF-40 (#439) — Der markierte Chip (siehe style.css). Im Redesign traegt `--danger`
   bereits die dunklere Rotstufe (--ad-red-700, Kontrast-Reparatur RD1.13), die Regel
   oben greift also schon richtig. Hier steht nur, was darueber hinaus noetig ist: der
   getoente Grund folgt der Filter-Pillen-Sprache dieser Shell statt dem grauen
   Hover-Ton der klassischen. */
/* Rahmen und Textfarbe muessen HIER mitstehen, nicht nur in style.css: die
   `.crm .chip`-Regeln dieser Datei haben dieselbe Spezifitaet und kommen spaeter in der
   Kaskade — im Browser gemessen kam sonst nur der Innenrahmen durch, waehrend der
   aeussere Rand grau blieb. */
.crm .ms-chip.is-armed {
  background: var(--tint-red, var(--bg-surface-2));
  border-color: var(--ms-armed);
  color: var(--text-1);
}

/* Im Dunkeln liegt derselbe Rahmen (--danger = --ad-red-700, #C4353A) auf dem dunklen
   Marken-Grund (--tint-red, #3A1F20) bei nur 2.80:1 und verfehlt damit die 3:1, die
   WCAG 1.4.11 fuer nicht-textuelle Bedienelemente verlangt. Eine Stufe heller loest das
   (#E5484D: 3.84:1 auf dem Chip, 4.47:1 gegen den App-Grund daneben) — dieselbe
   Zwei-Stufen-Logik wie beim Fokus-Ring (RD1.11) und beim --danger-Token selbst.
   Nur die Farbe, nicht die Form: den Innenrahmen setzt style.css einmal. */
.crm.dark .ms-chip.is-armed,
html[data-theme="dark"] .crm .ms-chip.is-armed { --ms-armed: var(--ad-red); }

/* Aktive Pillen folgen der Filter-Pillen-Sprache des Redesigns (.fpill.is-on):
   getoenter Grund mit farbigem Text, nicht Weiss auf Vollton. */
.crm .ms-pill { background: var(--bg-surface); }
.crm .ms-pill:hover:not(:disabled) { border-color: var(--border-strong); }
.crm .ms-pill.is-on {
  background: var(--tint-blue);
  border-color: var(--ad-blue-300);
  color: var(--ad-blue);
}

/* Fokusring ist im Redesign ein eigenes Token, kein Primaerton. */
.crm .ms-chip-x:focus-visible,
.crm .ms-option:focus-visible,
.crm .ms-pill:focus-visible,
.crm .ms-retry:focus-visible { outline-color: var(--focus); }

/* ============================================================
   PR1.190 (#349) — Schritt-Huelle, Redesign-Gesicht
   ============================================================
   Struktur, Abstaende und Verhalten stehen in style.css und sind nicht
   .crm-gescopt — sie greifen damit bereits in beiden Shells. Hier wird deshalb
   kein Layout wiederholt, sondern nur die Designsprache uebersetzt: die von der
   Huelle benutzten Legacy-Tokens werden im .crm-Scope auf ihre
   Redesign-Entsprechung gemappt (Muster PR1.189, Block oben).

   Damit bleibt das Layout an einer Stelle (Konvention 20), Dark wird automatisch
   mitgetragen, weil die Zieltokens selbst themenabhaengig sind, und dieser Block
   kommt ohne einen einzigen rohen px- oder Hex-Wert aus, wie Konvention 21 und
   der ui-craft-Ratchet es verlangen. */
.crm .fw {
  /* PR1.229: die naechsten vier sind seit PR1.229 auch an der .crm-Wurzel belegt
     und hier redundant; sie bleiben als Selbstbeschreibung stehen. Eigenstaendig
     bleiben --text-muted, --primary, --success, --radius-sm und --transition. */
  --bg-card2: var(--bg-surface-2);
  --border-light: var(--border);
  --text-primary: var(--text-1);
  --text-secondary: var(--text-2);
  /* Bewusste Abweichung von der Wurzel — s. Feedback-Block oben. */
  --bg-hover: var(--bg-surface-3);
  --text-muted: var(--text-3);
  --primary: var(--ad-blue);
  --success: var(--ad-green-700);
  --radius-sm: var(--r-sm);
  --transition: var(--t-fast);
}

/* Schrittbeschriftungen sind Kopfzeilen der Maske und tragen deshalb die
   Condensed-Schrift der Redesign-Ueberschriften. */
.crm .fw-step-label { font-family: var(--f-cond); }

/* „3 von 8" ist eine Messgroesse — so etwas steht im Redesign in Mono. */
.crm .fw-progress-num { font-family: var(--f-mono); }

/* ── PR1.198 #357 — Der ⓘ neben einem Formular-Label ────────────────────────
   Geometrie und Verhalten stehen in style.css; hier nur die Redesign-Optik.
   Der Fokusring kommt aus der generischen `.crm :focus-visible`-Regel oben —
   eine eigene Regel waere Doppelung und wuerde den focus-visible-Zaehler
   verwaessern. Nur Tokens, rem und Prozent (Pruefungen raw-px, raw-hex). */
.crm .fh-btn { color: var(--text-2); }
.crm .fh-btn > span { border-color: var(--border-strong); }
.crm .fh-btn:hover,
.crm .fh-btn[aria-expanded="true"] { color: var(--focus); }
.crm .fh-btn:hover > span,
.crm .fh-btn[aria-expanded="true"] > span { border-color: var(--focus); }
/* Der Hinweis schwebt ueber dem Feld und muss sich klar davon abheben — in
   `--bg-surface-2` mit `--text-2` sah er in der Sichtpruefung 07.08.2026 aus wie der
   Placeholder des Feldes darunter. Kraeftigere Flaeche, voller Text, grosser Schatten
   und die Interaktivfarbe als Rahmen: er liegt sichtbar DAVOR. */
.crm .fh-pop {
  background: var(--bg-surface-3);
  border-color: var(--focus);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-3);
  color: var(--text-1);
  font-family: var(--f-sans);
}

/* PR1.213 #373 — Externen-Tabelle der Projekt-Detailseite. Der waagerechte Scroll-Rahmen
   steht hier und nicht inline in `crm-project-detail.js`: die Datei darf genau einen
   Scroll-Container tragen (Ratchet `scroll-container`), und ein zweiter inline haette die
   Baseline gebrochen. Nur `overflow-x` — keine px, keine Hex (raw-px, raw-hex). */
.crm .ext-table-scroll { overflow-x: auto; }

/* ────────────────────────────────────────────────────────────────────────────
   PR1.240 (#417) — KB-Status: Bestand und Verdrahtung (Redesign-Shell)

   Die Landeansicht des KB Command Center ist eine Status-Seite: Kennzahlen, eine
   Tabelle je Datensatztyp, aufklappbare Befundlisten. Keine Animation — das Auf-
   und Zuklappen laeuft ueber <summary> und ist tastaturinitiiert.

   Zwei Dinge stehen hier bewusst NICHT:
   • Kein eigener Fokusring — die generische `.crm :focus-visible`-Regel (:1836)
     greift auf <summary> und <button> von selbst.
   • Kein eigener Rahmen fuer `.kb-finding` — der Befund traegt im Markup `card`
     und bekommt Rahmen, Radius und Schatten von dort.
   Beides waeren zusaetzliche rohe px-Werte, und der Ratchet `raw-px` (Konvention 21)
   laesst die Zahl nur sinken.

   Die Overflow-Regeln stehen hier statt inline in `crm-kb-command-center.js`: die
   Datei traegt bereits ihren einen Scroll-Container (Ratchet `scroll-container`) —
   dieselbe Ueberlegung wie bei `.ext-table-scroll` (PR1.213 #373).
   ──────────────────────────────────────────────────────────────────────────── */

.crm .kb-status-body { padding: var(--s-4) var(--s-6); overflow-y: auto; }

/* Erklaerender Fliesstext.
   NICHT `.note` verwenden: die Klasse ist Fira Mono (:—) und damit fuer Zahlenkolonnen
   und IDs gedacht, nicht fuer Saetze. Auf dieser Seite steht viel erklaerender Text
   („Das Feld ist gefuellt, das Ziel existiert nicht mehr …") — in Mono liest sich das
   wie ein Log-Auszug. Schriftgroesse in em statt px: die Skala bleibt relativ und der
   Ratchet `raw-px` sieht keinen neuen harten Wert. */
.crm .kb-prose { color: var(--text-2); max-width: 70ch; font-size: .92em; }

.crm .kb-kpi-label { color: var(--text-3); font-size: .82em; margin-top: var(--s-1); }

/* Breite Tabellen scrollen in sich, die Seite selbst nie waagerecht. */
.crm .kb-status-scroll { overflow-x: auto; }

.crm .kb-events-toggle {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  margin-top: var(--s-3);
  color: var(--text-2);
  cursor: pointer;
}

/* ── Befunde ── */
.crm .kb-finding { margin-bottom: var(--s-2); }

.crm .kb-finding-summary {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  padding: var(--s-3) var(--s-4);
  cursor: pointer;
  list-style: none;
  color: var(--text-1);
}

.crm .kb-finding-summary::-webkit-details-marker { display: none; }

.crm .kb-finding-summary::before { content: '▸'; color: var(--text-3); }

.crm .kb-finding[open] > .kb-finding-summary::before { content: '▾'; }

.crm .kb-finding-count {
  background: var(--bg-surface-3);
  border-radius: var(--r-xl);
  padding-inline: var(--s-2);
  font-variant-numeric: tabular-nums;
  color: var(--text-2);
}

/* Nur die Stufe „kaputt" traegt Farbe, und zwar an der Zahl statt am Rand: eine
   Randlinie waere ein weiterer roher px-Wert, und der Zaehler ist ohnehin die
   Stelle, auf die das Auge zuerst faellt. Tint + dunkle Schrift ist die Sprache
   der Statusfelder dieser Shell (AA auf hellem Grund). */
.crm .kb-finding.is-broken .kb-finding-count {
  background: var(--tint-red);
  color: var(--ad-red-800);
  font-weight: 600;
}

.crm .kb-finding-hint { margin: 0; padding: 0 var(--s-4) var(--s-2); }

.crm .kb-finding-list {
  margin: 0;
  padding: 0 var(--s-4) var(--s-3);
  list-style: none;
  max-height: 20rem;
  overflow-y: auto;
}

.crm .kb-finding-item {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--s-2);
  padding-block: var(--s-1);
}

.crm .kb-finding-link {
  appearance: none;
  background: none;
  border: none;
  padding: 0;
  font: inherit;
  color: var(--ad-blue);
  text-align: left;
  cursor: pointer;
}

.crm .kb-finding-link:hover { text-decoration: underline; }

/* PR1.241 (#418) — zweiter Weg pro Befund: „wie hängt DAS hier zusammen".
   Zurückhaltender gesetzt als der Name: der Sprung in die Detailansicht ist der
   häufigere Weg und behält die stärkere Farbe.
   BEWUSST OHNE px — `raw-px` ist eine Ratchet-Kennzahl des Gates `ui-craft`
   (Konvention 21) und liegt auf ihrer Baseline. */
.crm .kb-finding-graph {
  margin-left: auto;
  padding: 0.1em 0.6em;
  border-radius: var(--r-sm);
  border: none;
  background: none;
  color: var(--text-3);
  font: inherit;
  font-size: 0.82em;
  font-weight: 600;
  cursor: pointer;
}

.crm .kb-finding-graph:hover {
  color: var(--ad-blue);
  text-decoration: underline;
}

/* ── BF-33 #428 · Outbox-Anzeige in der Redesign-Topbar ────────────────────── */
/* Basis (Farbtoene, Einblenden, Zustandsklassen) steht in style.css und traegt
   hier durch — `--primary`, `--warning` und `--danger` sind im .crm-Scope oben
   auf die adesso-Palette gemappt, die Toene stimmen also von selbst.
   Hier steht nur die Geometrie, die zur Redesign-Topbar passt.

   BEWUSST OHNE px: `raw-px` ist eine Ratchet-Kennzahl des Gates `ui-craft`
   (Konvention 21) und liegt exakt auf ihrer Baseline — jeder harte Wert hier
   wuerde die Pipeline blockieren. Radien kommen aus den Tokens, Abstaende in
   em, damit sie mit der Schriftgroesse mitwandern. */
.crm .outbox-indicator {
  border-radius: var(--r-xl);
  font-size: 0.75rem;
  padding: 0.3em 0.85em;
  gap: 0.35em;
  white-space: nowrap;
}

/* Enge Topbar: der Zaehler ist die Information, der Satz darf weichen. */
.crm .outbox-indicator {
  max-width: 22em;
  overflow: hidden;
  text-overflow: ellipsis;
}

.crm .outbox-indicator:focus-visible {
  outline: 0.125rem solid var(--primary);
  outline-offset: 0.125rem;
}

/* ════════════════════════════════════════════════════════════════════════════
   PR1.248 (#442) — Alternative Suchen (Redesign-Gesicht)
   ────────────────────────────────────────────────────────────────────────────
   Die dritte Kiste gab es bisher nur in der klassischen Shell. Bewusst KEIN
   Nachbau der `.opp-alt-*`-Optik aus style.css: beide Stylesheets sind
   gleichzeitig geladen, die alten Regeln griffen also technisch — aber sie
   tragen das Vokabular der Legacy-Shell. Konvention 20 verlangt hier denselben
   Token-Satz wie der Rest des Redesigns.

   Alle Masse als Token oder `rem`. Der ui-craft-Ratchet zaehlt jedes rohe
   px-Literal und jede Hex-Farbe in dieser Datei; beides blockt die CI.
   ════════════════════════════════════════════════════════════════════════════ */

.crm .crm-alt-panel { margin-bottom: var(--s-4); }

.crm .crm-alt-intro { font-size: 0.8125rem; color: var(--text-2); line-height: 1.5; }

/* Leer-, Lade- und Fehlerzustand teilen sich eine Grundform — sie stehen an
   derselben Stelle und sollen sich nicht gegenseitig verspringen lassen. */
.crm .crm-alt-state {
  font-size: 0.8125rem; color: var(--text-3); padding: var(--s-3) 0;
}
/* Fehlerfarbe theme-abhaengig: `--ad-red` (#E5484D) traegt auf hellem Grund nur
   3.91:1 und reisst AA fuer Text dieser Groesse. Die dunkle Variante waere im
   Dark-Theme umgekehrt zu dunkel — deshalb dasselbe Paar-Muster wie `.warn-box b`. */
.crm .crm-alt-state.is-error {
  color: var(--ad-red-700); display: flex; flex-wrap: wrap;
  align-items: center; gap: var(--s-2);
}
.crm.dark .crm-alt-state.is-error,
html[data-theme="dark"] .crm .crm-alt-state.is-error { color: var(--ad-red-300); }

.crm .crm-alt-spec {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: var(--s-2); margin-bottom: var(--s-3);
}
.crm .crm-alt-spec-why { font-size: 0.75rem; color: var(--text-3); }

.crm .crm-alt-split {
  display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
  gap: var(--s-4); align-items: start;
}

/* Der EINE Scrollbereich dieser View. `overflow-y` steht im Markup (der Ratchet
   zaehlt Scroll-Container je View-Datei); hier nur seine Begrenzung. */
.crm .crm-alt-list {
  max-height: 32rem; min-height: 0;
  display: flex; flex-direction: column; gap: var(--s-2);
  padding-right: var(--s-1);
}

.crm .crm-alt-row {
  border: 0.0625rem solid var(--border); border-radius: var(--r-md);
  background: var(--bg-surface); padding: var(--s-2);
  display: flex; flex-direction: column; gap: var(--s-1);
  transition: border-color var(--t-fast) var(--ease-out), background var(--t-fast) var(--ease-out);
}
.crm .crm-alt-row:hover { background: var(--bg-hover); }
.crm .crm-alt-row.is-open { border-color: var(--ad-violet); background: var(--tint-violet); }
/* Uebernommen: ruhiger Zustand, kein Erfolgs-Jubel. Die Zeile bleibt lesbar und
   sagt nur, dass sie erledigt ist. */
.crm .crm-alt-row.is-taken { border-color: var(--ad-green); background: var(--tint-green); }

/* Die Zeile ist ein echter Knopf — zurueckgesetzt wird sein Aussehen, nicht seine
   Semantik. */
.crm .crm-alt-main {
  appearance: none; background: none; border: 0; padding: 0;
  font: inherit; color: inherit; text-align: left; cursor: pointer;
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2);
  min-width: 0; width: 100%;
}
.crm .crm-alt-name { font-weight: 600; min-width: 0; }
.crm .crm-alt-score {
  margin-left: auto; font-family: var(--f-mono); font-size: 0.8125rem;
  font-weight: 700; padding: 0 var(--s-2); border-radius: var(--r-sm);
}

.crm .crm-alt-meta {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: var(--s-2); font-size: 0.75rem; color: var(--text-3);
}
.crm .crm-alt-avail { min-width: 0; }
.crm .crm-alt-take { margin-left: auto; }
/* Bewusst KEINE gruene Schrift: `--ad-green` (#76C800) kommt auf hellem Grund auf
   2.09:1, `--ad-green-700` auf 3.23:1 — beides reisst AA fuer Text dieser Groesse.
   Den Zustand traegt der Zeilenrahmen (`.is-taken`) plus das Haekchen im Wortlaut. */
.crm .crm-alt-done {
  margin-left: auto; color: var(--text-2); font-weight: 600; white-space: nowrap;
}

.crm .crm-alt-detail {
  border: 0.0625rem solid var(--border); border-radius: var(--r-md);
  background: var(--bg-surface-2); padding: var(--s-3);
  display: flex; flex-direction: column; gap: var(--s-3); min-width: 0;
}
.crm .crm-alt-detail-head {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: var(--s-2); justify-content: space-between;
}
.crm .crm-alt-detail-sec { font-size: 0.8125rem; line-height: 1.5; }
.crm .crm-alt-detail-t {
  font-size: 0.6875rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.03em; color: var(--text-3); margin-bottom: var(--s-1);
}
.crm .crm-alt-muted { color: var(--text-3); }

.crm .crm-alt-foot {
  margin-top: var(--s-3); font-size: 0.75rem; color: var(--text-3);
  font-family: var(--f-mono);
}

/* ─────────────────────────────────────────────────────────────
   PR1.275 (#469) — Kundenlogo im Redesign.
   Konvention 21: keine rohen px, keine Hex-Literale. Groessen kommen aus
   dem style-Attribut (size-Option von accountLogoHtml), nicht von hier —
   deshalb steht unten keine einzige Laengenangabe in px.
   `white` ist ein CSS-Keyword und kein Hex-Literal; der Ratchet-Pruefer
   matcht /#[0-9a-fA-F]{3,8}/.
   ───────────────────────────────────────────────────────────── */

.crm .acc-logo {
  border-radius: .55rem;
  font-family: var(--f-cond);
  font-weight: 700;
  letter-spacing: .03em;
}

.crm .acc-logo.is-loaded {
  background-color: white;
  box-shadow: inset 0 0 0 .06rem rgba(0, 0, 0, .14);
  padding: 6%;
}

.crm .acc-logo-drop {
  border-radius: .55rem;
  font-family: var(--f-cond);
  font-size: .85rem;
}

/* ═══════════════════════════════════════════════════════════════════
   PR1.276 (#470) — Kunden-Dossier als Full-Page (Redesign-Shell).
   Pendant in der klassischen Shell: .cd-* in style.css.
   Bewusst px-frei (rem/%/Tokens) — Konvention 21, Ratchet raw-px.
   ═══════════════════════════════════════════════════════════════════ */

/* .card ist als flex-row definiert (Kachel-Karten der Listen). Das Dossier stapelt
   seine Abschnitte - ohne display:block laufen die Statusgruppen nebeneinander statt
   untereinander (Befund der Optik-Abnahme auf der Pruefseite). */
.crm .crm-cd-card {
  display: block;
  margin-bottom: 1rem;
}


.crm .crm-cd-row {
  display: flex;
  gap: .75rem;
  padding: .3rem 0;
  border-bottom: .0625rem dashed var(--border);
  font-size: .85rem;
}
.crm .crm-cd-row-label { flex: 0 0 40%; color: var(--text-3); }
.crm .crm-cd-row-value { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.crm .crm-dash { color: var(--text-3); }

.crm .crm-cd-empty,
.crm .crm-cd-locked {
  color: var(--text-3);
  font-size: .85rem;
  padding: .625rem 0;
}
.crm .crm-cd-note,
.crm .crm-cd-legend { margin-bottom: .5rem; }

.crm .crm-cd-group { margin-bottom: .875rem; }
.crm .crm-cd-group-title {
  font-family: var(--f-cond);
  font-weight: 600;
  font-size: .85rem;
  margin-bottom: .375rem;
}
.crm .crm-cd-list { list-style: none; margin: 0; padding: 0; }
.crm .crm-cd-list li {
  display: flex;
  gap: .625rem;
  justify-content: space-between;
  padding: .25rem 0;
  font-size: .85rem;
}

.crm .crm-cd-team { width: 100%; font-size: .85rem; }

/* Der Betrag ist in der Pipeline die Kernaussage, keine Fussnote - .note (--text-3)
   war dafuer zu leise (Befund der Optik-Abnahme). */
.crm .crm-cd-amount {
  color: var(--text-2);
  font-family: var(--f-mono);
  font-size: .8rem;
  font-variant-numeric: tabular-nums;
}

.crm .crm-cd-portfolio {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
  gap: .25rem 1rem;
}
.crm .crm-cd-pf {
  display: flex;
  align-items: center;
  gap: .5rem;
  padding: .3rem 0;
  font-size: .85rem;
}
.crm .crm-cd-pf-dot {
  width: .55rem;
  height: .55rem;
  border-radius: 50%;
  flex: 0 0 auto;
  background: var(--text-3);
}
/* „bezogen" traegt zusaetzlich zur Farbe einen gefuellten Punkt, „nicht bezogen"
   einen leeren Ring — die Unterscheidung darf nicht allein an der Farbe haengen. */
.crm .crm-cd-pf-bezogen .crm-cd-pf-dot { background: var(--ad-violet); }
.crm .crm-cd-pf-nicht-bezogen .crm-cd-pf-dot {
  background: transparent;
  border: .125rem solid var(--text-2);
}
.crm .crm-cd-pf-label { flex: 1; min-width: 0; }
.crm .crm-cd-pf-state { font-size: .72rem; color: var(--text-3); }
.crm .crm-cd-pf-driftmark {
  font-size: .65rem;
  padding: .0625rem .375rem;
  border-radius: .5rem;
  border: .0625rem solid var(--ad-violet);
  color: var(--ad-violet);
}

.crm .crm-cd-timeline { list-style: none; margin: 0; padding: 0; }
.crm .crm-cd-tl {
  display: flex;
  gap: .75rem;
  padding: .3rem 0;
  border-bottom: .0625rem dashed var(--border);
  font-size: .85rem;
}
.crm .crm-cd-tl-date { flex: 0 0 5.5rem; color: var(--text-3); }
.crm .crm-cd-tl-label { flex: 1; min-width: 0; }

@media (max-width: 45rem) {
  .crm .crm-cd-row { flex-direction: column; gap: .125rem; }
  .crm .crm-cd-row-label { flex: none; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   PR1.269 (#463) — Daten-Cockpit (Redesign-Gesicht)

   Ausschliesslich Tokens und rem: die Ratchet-Pruefungen `raw-px` und `raw-hex`
   zaehlen ueber die GANZE Datei, ein einzelner harter Wert hier laesst den CI-Job
   kippen. Die Raster arbeiten mit auto-fit/minmax statt fester Spaltenbreiten
   (Pruefung `breakpoints`).
   ═══════════════════════════════════════════════════════════════════════════ */

.crm .dcp-body > * + * { margin-top: 0.875rem; }

.crm .dcp-label {
  display: block;
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--text-2);
  margin-bottom: 0.375rem;
}

.crm .dcp-frage-zeile {
  display: flex;
  gap: 0.625rem;
  align-items: flex-start;
}

.crm .dcp-input {
  flex: 1;
  min-width: 0;
  padding: 0.5rem 0.75rem;
  font: inherit;
  font-size: 0.875rem;
  color: var(--text-1);
  background: var(--bg-input);
  border: 0.0625rem solid var(--border-strong);
  border-radius: var(--radius-sm);
  resize: vertical;
}

.crm .dcp-hint {
  margin-top: 0.5rem;
  font-size: 0.75rem;
  color: var(--text-3);
}

.crm .dcp-beispiele {
  display: flex;
  flex-wrap: wrap;
  gap: 0.375rem;
  margin-top: 0.625rem;
}

.crm .dcp-h2 {
  margin: 0;
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--text-1);
}

.crm .dcp-abfrage-kopf,
.crm .dcp-ergebnis-kopf {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  margin-bottom: 0.75rem;
}

.crm .dcp-meta { font-size: 0.75rem; color: var(--text-3); }

/* Eine Zeile je Gruppe: Titel links, Merkzettel rechts. auto-fit statt fester
   Spalten — auf schmalen Fenstern rutscht der Titel ueber die Zettel. */
.crm .dcp-zeile {
  display: grid;
  grid-template-columns: minmax(7rem, max-content) 1fr;
  gap: 0.5rem 0.75rem;
  align-items: start;
  padding: 0.4375rem 0;
  border-top: 0.0625rem solid var(--border);
}
.crm .dcp-zeile:first-of-type { border-top: 0; }

.crm .dcp-zeile-titel {
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--text-3);
  text-transform: uppercase;
  letter-spacing: 0.03em;
  padding-top: 0.3125rem;
}

.crm .dcp-zeile-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.375rem;
  align-items: center;
}

.crm .dcp-chip-wrap { display: inline-flex; align-items: center; gap: 0.125rem; }

.crm .dcp-chip {
  display: inline-flex;
  align-items: baseline;
  gap: 0.375rem;
  padding: 0.3125rem 0.625rem;
  font: inherit;
  font-size: 0.8125rem;
  color: var(--text-1);
  background: var(--bg-surface-2);
  border: 0.0625rem solid var(--border-strong);
  border-radius: var(--radius-sm);
  cursor: pointer;
}
.crm .dcp-chip:hover { background: var(--bg-hover); }
.crm .dcp-chip.is-open { border-color: var(--ad-violet); }
.crm .dcp-chip.is-missing { border-color: var(--warning); }
.crm .dcp-chip.is-invalid { border-color: var(--danger); }

.crm .dcp-chip-label { font-size: 0.6875rem; color: var(--text-3); }
.crm .dcp-chip-value { font-weight: 600; }

.crm .dcp-chip-x {
  padding: 0.125rem 0.3125rem;
  font: inherit;
  line-height: 1;
  color: var(--text-3);
  background: transparent;
  border: 0;
  border-radius: var(--radius-sm);
  cursor: pointer;
}
.crm .dcp-chip-x:hover { color: var(--danger); background: var(--bg-hover); }

.crm .dcp-add {
  padding: 0.3125rem 0.625rem;
  font: inherit;
  font-size: 0.8125rem;
  color: var(--text-2);
  background: transparent;
  border: 0.0625rem dashed var(--border-strong);
  border-radius: var(--radius-sm);
  cursor: pointer;
}
.crm .dcp-add:hover:not(:disabled) { color: var(--text-1); border-color: var(--text-3); }
.crm .dcp-add:disabled { opacity: 0.45; cursor: not-allowed; }

.crm .dcp-issue {
  flex-basis: 100%;
  font-size: 0.75rem;
  color: var(--danger);
}

/* Bearbeiten geschieht in einer Zeile UNTER den Merkzetteln — kein schwebendes
   Fenster, also auch keine Positionsrechnerei und keine Fokusfalle. */
.crm .dcp-editor {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  gap: 0.5rem 0.75rem;
  align-items: end;
  margin-top: 0.625rem;
  padding: 0.75rem;
  background: var(--bg-surface-2);
  border: 0.0625rem solid var(--border-strong);
  border-radius: var(--radius-sm);
}

.crm .dcp-control {
  width: 100%;
  padding: 0.375rem 0.5rem;
  font: inherit;
  font-size: 0.8125rem;
  color: var(--text-1);
  background: var(--bg-input);
  border: 0.0625rem solid var(--border-strong);
  border-radius: var(--radius-sm);
}

.crm .dcp-check {
  display: flex;
  align-items: center;
  gap: 0.375rem;
  font-size: 0.8125rem;
  color: var(--text-2);
}

.crm .dcp-band {
  display: inline-block;
  padding: 0.1875rem 0.5rem;
  font-size: 0.75rem;
  font-weight: 600;
  border-radius: var(--radius-sm);
  background: var(--bg-surface-2);
  color: var(--text-2);
}
.crm .dcp-band-hoch { color: var(--success); }
.crm .dcp-band-mittel { color: var(--warning); }
.crm .dcp-band-niedrig { color: var(--danger); }

.crm .dcp-missing-note { margin-left: 0.625rem; font-size: 0.8125rem; color: var(--text-3); }

.crm .dcp-missing-list {
  margin: 0.5rem 0 0;
  padding-left: 1.125rem;
  font-size: 0.8125rem;
  color: var(--text-2);
}

.crm .dcp-rueckfrage-titel,
.crm .dcp-fehler-titel {
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--text-1);
  margin-bottom: 0.375rem;
}
.crm .dcp-rueckfrage-text,
.crm .dcp-fehler-text { margin: 0 0 0.625rem; font-size: 0.875rem; color: var(--text-2); }

.crm .dcp-fehler-wege { display: flex; flex-wrap: wrap; gap: 0.375rem; }
.crm .dcp-request { margin-top: 0.5rem; font-size: 0.75rem; color: var(--text-3); }

/* Die Ergebnistabelle scrollt WAAGERECHT in ihrem eigenen Kasten. Senkrecht scrollt
   die Ansicht als Ganzes — zwei senkrechte Scroll-Zonen uebereinander sind
   unvorhersagbar zu bedienen. */
.crm .dcp-tabelle { overflow-x: auto; }
.crm .dcp-tabelle table { width: 100%; }

.crm .dcp-leer-titel { font-weight: 600; color: var(--text-1); }
.crm .dcp-leer-hinweis { margin-top: 0.25rem; font-size: 0.8125rem; color: var(--text-3); }

/* ── PR1.270 (#464) — Diagramm-Baukasten, Redesign-Fassung ──────────────────
   Die Umgebung des Baukastens steht in style.css und traegt hier ueber die
   .crm-Aliase (--bg-card2 -> --bg-surface-2 usw.) schon fast richtig. Hier steht
   nur, was die Redesign-Formensprache anders will: die Marke fuer das aktive Bild,
   der Fokusring in --ad-blue und die ruhigeren Trennlinien.

   Keine rohen Farbwerte, keine px-Werte — der ui-craft-Ratchet zaehlt beides. */

.crm .ck-typ {
    padding: 0.3125rem 0.75rem;
    border: 0.0625rem solid var(--border);
    border-radius: var(--radius-sm, 0.375rem);
    background: var(--bg-surface);
    color: var(--text-2);
    font-size: 0.8125rem;
    cursor: pointer;
}

.crm .ck-typ:hover {
    background: var(--bg-hover);
    color: var(--text-1);
}

.crm .ck-typ.is-active {
    background: var(--ad-blue);
    border-color: var(--ad-blue);
    color: var(--text-inv);
}

/* --focus traegt im dunklen Zustand bereits die hellere Stufe (Zeile 197). */
.crm .ck-el:focus-visible,
.crm .ck-sort:focus-visible,
.crm .ck-drill-link:focus-visible {
    outline: 0.125rem solid var(--focus, var(--ad-blue));
    outline-offset: 0.125rem;
}

.crm .ck-kachel-wert {
    color: var(--text-1);
}

.crm .ck-kachel-label {
    color: var(--text-3);
    opacity: 1;
}

.crm .ck-leer {
    color: var(--text-3);
    opacity: 1;
}

.crm .ck-legend {
    color: var(--text-2);
}

.crm .ck-drill {
    border-top-color: var(--border);
}

.crm .ck-drill-titel {
    color: var(--text-1);
}

.crm .ck-drill-link {
    color: var(--ad-blue-700);
}

/* Dasselbe Muster wie bei den Tabellen-Links (Zeile 846): --ad-blue-700 liegt auf dem
   dunklen Grund bei rund 1,7:1 und waere praktisch unlesbar. */
.crm.dark .ck-drill-link,
html[data-theme="dark"] .crm .ck-drill-link {
    color: var(--ad-blue-300);
}

.crm .ck-drill-leer,
.crm .ck-drill-hinweis {
    color: var(--text-3);
    opacity: 1;
}

/* ── PR1.286 (#484) — Freigabe-Rueckfrage: Token-Bruecke ────────────────────
   Das Fenster selbst liegt in style.css (ein Layout fuer beide Shells,
   Konvention 20). Was dort fehlt, ist die Uebersetzung zweier Legacy-Namen in
   die Redesign-Palette: --primary und --danger stehen NICHT an der .crm-Wurzel
   (siehe .crm .fb-form weiter oben — dort steht dieselbe Begruendung). Ohne
   diesen Block bekaeme das Fenster in der Redesign-Shell das indigo --primary
   und das grelle --danger aus :root und saehe damit aus wie ein
   Alt-Design-Einsprengsel.

   Kein roher px- oder Hex-Wert, wie Konvention 21 und der ui-craft-Ratchet es
   verlangen; Dark wird automatisch mitgetragen, weil die Zieltokens selbst
   themenabhaengig sind. --ad-red-700 statt --ad-red: der Fehlertext muss als
   TEXT lesbar sein, nicht nur als Flaeche. */
.crm .website-consent-veil .modal {
  --primary: var(--ad-blue);
  --primary-glow: var(--tint-blue);
  --danger: var(--ad-red-700);
  --radius: var(--r-md);
}

/* ── PR1.286 (#484) — Nutzerverwaltung: Token-Bruecke ───────────────────────
   Das Layout liegt in style.css (ein Regelsatz fuer beide Shells, Konvention 20).
   Was dort fehlt, ist die Uebersetzung der Legacy-Namen in die Redesign-Palette:
   --primary, --danger, --warning und --success stehen NICHT an der .crm-Wurzel
   (dieselbe Lage wie bei .crm .fb-form weiter oben, dort steht die Begruendung).
   Ohne diesen Block truege die Nutzertabelle das indigo --primary und das grelle
   --danger aus :root — sichtbare Alt-Design-Einsprengsel mitten im Redesign.

   Die -700-Stufen sind Absicht: --ad-green und --ad-orange bleiben unter 3:1 und
   taugen als Flaeche, nicht als Schriftfarbe. Kein roher px- oder Hex-Wert, wie
   Konvention 21 und der ui-craft-Ratchet es verlangen. */
.crm .admin-users-erklaerung,
.crm .admin-users-suche input,
.crm .admin-users-select,
.crm .admin-users-bulk select,
.crm .admin-sort,
.crm .admin-users-status,
.crm .admin-users-warnung,
.crm .admin-users-speichern,
.crm .admin-section-erklaerung,
.crm .status-pill {
  --primary: var(--ad-blue);
  --danger: var(--ad-red-700);
  --warning: var(--ad-orange-700);
  --success: var(--ad-green-700);
  --radius: var(--r-md);
}

/* ═══════════════════════════════════════════════════════════════════════════
   PR1.273 (#467) — KB-Chat im Daten-Cockpit
   ───────────────────────────────────────────────────────────────────────────
   Motion-Budget: der Chat wird mehrmals taeglich benutzt (Vertrieb, CC-Leitung).
   Nach der Frequenz-Regel aus DESIGN.md heisst das: keine Tipp-Animation, keine
   Einblend-Choreografie, nichts ueber --t-fast. Die einzige Bewegung ist der
   wartende Punkt — und der hoert auf, sobald die Antwort da ist.

   Zwei Entscheidungen, die man sonst fuer Nachlaessigkeit halten koennte:

   1. Die Sprechblasen sind `.card` — die vorhandene Karte, nicht ein zweiter,
      fast gleicher Kasten. DESIGN.md: keine neuen Werte erfinden, wenn eine
      Skala existiert; dasselbe gilt fuer Bausteine.
   2. Linienstaerken kommen als rem, nicht als px. Der ui-craft-Ratchet zaehlt
      rohe px-Werte und blockt Rueckschritte — und nebenbei skaliert eine
      rem-Linie beim Zoom mit, statt duenner zu wirken.
   ═══════════════════════════════════════════════════════════════════════════ */

.crm .chat-panel,
.crm .dcp-reiter {
  --chat-linie: 0.0625rem;
  --chat-linie-aktiv: 0.125rem;
}

.crm .dcp-reiter {
  display: flex;
  gap: var(--s-1);
  border-bottom: var(--chat-linie) solid var(--border);
  margin-bottom: var(--s-4);
}

.crm .dcp-reiter-btn {
  appearance: none;
  background: none;
  border: none;
  border-bottom: var(--chat-linie-aktiv) solid transparent;
  color: var(--text-2);
  padding: var(--s-2) var(--s-4);
  font: inherit;
  cursor: pointer;
  transition: color var(--t-fast), border-color var(--t-fast);
}

.crm .dcp-reiter-btn:hover { color: var(--text-1); }

.crm .dcp-reiter-btn.is-aktiv {
  color: var(--text-1);
  border-bottom-color: var(--primary);
  font-weight: 600;
}

.crm .chat-panel {
  display: flex;
  flex-direction: column;
  gap: var(--s-4);
}

.crm .chat-verlauf {
  display: flex;
  flex-direction: column;
  gap: var(--s-4);
}

/* Die eigene Frage rechts und schmal, die Antwort ueber die volle Breite: eine
   Antwort mit Belegen und Diagramm braucht Platz, eine Frage nicht. */
.crm .chat-zeile.chat-ich {
  align-self: flex-end;
  max-width: 80%;
  background: var(--bg-card2);
  padding: var(--s-2) var(--s-4);
}

.crm .chat-zeile.chat-apollon { padding: var(--s-4); }

.crm .chat-zeile p { margin: 0; }

.crm .chat-hinweis {
  margin-top: var(--s-2) !important;
  color: var(--text-3);
  font-size: 0.875rem;
}

.crm .chat-quellen {
  margin-top: var(--s-3);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-2);
}

.crm .chat-quellen-titel {
  color: var(--text-3);
  font-size: 0.8125rem;
}

.crm .chat-quelle {
  display: inline-block;
  border: var(--chat-linie) solid var(--border);
  border-radius: var(--r-sm);
  padding: var(--s-1) var(--s-2);
  font-size: 0.8125rem;
  color: var(--text-2);
  background: var(--bg-card2);
  max-width: 22rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.crm button.chat-quelle-doc {
  cursor: pointer;
  font-family: inherit;
  transition: border-color var(--t-fast), color var(--t-fast);
}

.crm button.chat-quelle-doc:hover {
  border-color: var(--primary);
  color: var(--text-1);
}

/* Kein Beleg ist eine Auskunft, kein Fehler — deshalb ruhig statt rot. */
.crm .chat-ohne-beleg {
  margin-top: var(--s-3) !important;
  color: var(--text-3);
  font-size: 0.875rem;
  font-style: italic;
}

.crm .chat-offen {
  margin-top: var(--s-3);
  font-size: 0.875rem;
  color: var(--text-2);
}

.crm .chat-offen summary { cursor: pointer; }
.crm .chat-offen ul { margin: var(--s-2) 0 0; padding-left: var(--s-5); }

.crm .chat-diagramm {
  margin-top: var(--s-4);
  padding-top: var(--s-4);
  border-top: var(--chat-linie) solid var(--border);
}

.crm .chat-uebernehmen { margin-top: var(--s-3); }

/* Leerzustand: aktives Verb, anklickbare Startpunkte. */
.crm .chat-leer {
  padding: var(--s-8) var(--s-4);
  text-align: center;
  color: var(--text-2);
}

.crm .chat-leer-titel {
  color: var(--text-1);
  font-weight: 600;
  margin: 0 0 var(--s-2);
}

.crm .chat-leer-sub { margin: 0 0 var(--s-6); font-size: 0.875rem; color: var(--text-3); }

.crm .chat-beispiele {
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
  align-items: center;
}

.crm .chat-beispiel {
  appearance: none;
  background: var(--bg-card2);
  border: var(--chat-linie) solid var(--border);
  border-radius: var(--r-md);
  color: var(--text-2);
  padding: var(--s-2) var(--s-4);
  font: inherit;
  font-size: 0.875rem;
  cursor: pointer;
  max-width: 100%;
  transition: border-color var(--t-fast), color var(--t-fast);
}

.crm .chat-beispiel:hover { border-color: var(--primary); color: var(--text-1); }

/* Ladezustand: was gerade passiert, und wie weit es noch gehen kann. */
.crm .chat-laeuft {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  color: var(--text-2);
  font-size: 0.875rem;
  padding: var(--s-2) 0;
}

.crm .chat-punkt {
  width: var(--s-2);
  height: var(--s-2);
  border-radius: 50%;
  background: var(--primary);
  animation: chat-puls 1.4s ease-in-out infinite;
}

/* Die einzige Bewegung im Panel — und sie zeigt etwas an, statt zu schmuecken. */
@keyframes chat-puls {
  0%, 100% { opacity: 0.35; }
  50%      { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .crm .chat-punkt { animation: none; opacity: 0.7; }
}

.crm .chat-runde { color: var(--text-3); margin-left: auto; }

.crm .chat-fehler {
  border: var(--chat-linie) solid var(--danger);
  border-radius: var(--r-md);
  padding: var(--s-3) var(--s-4);
  color: var(--text-1);
}

.crm .chat-fehler p { margin: 0; }
.crm .chat-fehler-code { margin-top: var(--s-1) !important; color: var(--text-3); font-size: 0.75rem; }

.crm .chat-form {
  display: flex;
  gap: var(--s-2);
  align-items: flex-end;
}

.crm .chat-eingabe {
  flex: 1;
  resize: vertical;
  min-height: var(--s-10);
  font: inherit;
}

.crm .chat-rest {
  margin: 0;
  text-align: right;
  color: var(--text-3);
  font-size: 0.75rem;
}

/* ═══════════════════════════════════════════════════════════════════════════
   PR1.319 (#528) — Pythia bekommt ein Gesicht: Bereich, Seitenleiste, Protokoll,
   Fund-Karten, Belegmarken, Suchweg, Gespraechsliste, Wegweiser.
   Motion-Budget wie beim Chat: keine Einblend-Choreografie, keine neue Animation —
   Protokollzeilen und Karten erscheinen einfach. rem statt px, Tokens statt Hex
   (Ratchets raw-px / raw-hex bleiben, wo sie sind).
   ═══════════════════════════════════════════════════════════════════════════ */

.crm .pythia-bereich {
  display: grid;
  grid-template-columns: 16rem minmax(0, 1fr);
  gap: var(--s-4);
  align-items: start;
}

.crm .pythia-gespraeche { padding: var(--s-3); }
.crm .pythia-hauptteil { padding: var(--s-4); }
.crm .pythia-kopf { margin-bottom: var(--s-4); display: flex; align-items: center; gap: var(--s-3); }
/* PR1.324 #533 — Pythia-Zeichen: Medaillon nur im Bereichskopf (4rem = 64 px), sonst
   der Dreifuss in Textfarbe. Statisch — keine Motion auf Knopf und Menuepunkt. */
.crm .pythia-kopf-zeichen { flex: none; width: 4rem; height: 4rem; }
.crm .pythia-kopf-text { min-width: 0; }
.crm .pythia-medaillon { display: block; color: var(--pythia-terra); }
.crm .pythia-medaillon .pz-grund,
.crm .pythia-medaillon .pz-gewand { fill: var(--pythia-terra-grund); }
.crm .pythia-zeichen { flex: none; }
.crm .sb-ic .pythia-dreifuss { display: block; }
.crm .pythia-leiste-titel { display: flex; align-items: center; gap: var(--s-2); }
.crm .pythia-titel { margin: 0; font-family: var(--f-cond); font-size: 1.25rem; }
.crm .pythia-sub { margin: var(--s-1) 0 0; color: var(--text-3); font-size: 0.875rem; }

/* Linkfarbe fuer kleine Texte: adesso-Blau (#006EC7) faellt im Dunkel-Theme auf 3,2:1 —
   deshalb ein eigener Token, der dort auf die helle Stufe wechselt (AA, axe-belegt). */
.crm .pythia-bereich,
.crm .pythia-leiste,
.crm .chat-panel { --chat-link: var(--ad-blue-700); }
.crm.dark .pythia-bereich, html[data-theme="dark"] .crm .pythia-bereich,
.crm.dark .pythia-leiste, html[data-theme="dark"] .crm .pythia-leiste,
.crm.dark .chat-panel, html[data-theme="dark"] .crm .chat-panel { --chat-link: var(--ad-blue-300); }

/* Gespraechsliste — drei Zustaende, aktiver Eintrag, Knoepfe immer sichtbar (Tastatur). */
.crm .chat-gespraeche-kopf { display: flex; flex-direction: column; gap: var(--s-2); margin-bottom: var(--s-3); }
.crm .chat-gespraeche-titel { color: var(--text-3); font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.03em; }
.crm .chat-gespraeche-liste { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--s-1); }
.crm .chat-gespraech { display: flex; align-items: center; gap: var(--s-1); border-radius: var(--r-sm); }
.crm .chat-gespraech.is-aktiv { background: var(--bg-card2); }
.crm .chat-gespraech-oeffnen {
  flex: 1;
  min-width: 0;
  appearance: none;
  background: none;
  border: none;
  text-align: left;
  padding: var(--s-2);
  font: inherit;
  font-size: 0.875rem;
  color: var(--text-2);
  cursor: pointer;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  border-radius: var(--r-sm);
}
.crm .chat-gespraech-oeffnen:hover { color: var(--text-1); background: var(--bg-card2); }
.crm .chat-gespraech.is-aktiv .chat-gespraech-oeffnen { color: var(--chat-link); font-weight: 600; }
.crm .chat-gespraech-knoepfe { display: flex; gap: var(--s-1); }
.crm .chat-gespraech-umbenennen { display: flex; gap: var(--s-1); flex-wrap: wrap; width: 100%; padding: var(--s-1); }
.crm .chat-gespraech-umbenennen input { flex: 1; min-width: 8rem; }
.crm .chat-gespraeche-leer,
.crm .chat-gespraeche-laedt { color: var(--text-3); font-size: 0.875rem; margin: 0; padding: var(--s-2); }
.crm .chat-gespraeche-fehler {
  border: var(--chat-linie) solid var(--danger);
  border-radius: var(--r-md);
  padding: var(--s-2) var(--s-3);
  font-size: 0.875rem;
}
.crm .chat-gespraeche-fehler p { margin: 0 0 var(--s-2); }

/* Statuszeile + Protokoll: die Liste waechst nach unten, ohne Bewegung. */
.crm .chat-laeuft { flex-direction: column; align-items: stretch; gap: var(--s-3); }
.crm .chat-schritt { display: flex; align-items: center; gap: var(--s-2); }
.crm .chat-protokoll {
  list-style: none;
  margin: 0;
  padding: 0 0 0 var(--s-3);
  border-left: var(--chat-linie-aktiv) solid var(--border);
  display: flex;
  flex-direction: column;
  gap: var(--s-1);
  font-size: 0.8125rem;
  color: var(--text-2);
}
.crm .chat-protokoll-schritt { display: flex; align-items: center; gap: var(--s-2); }
.crm .chat-protokoll-schritt.is-fertig { color: var(--text-3); }
.crm .chat-protokoll-ok { color: var(--success); font-weight: 600; }
.crm .chat-suchweg { margin-top: var(--s-3); font-size: 0.875rem; color: var(--text-2); }
.crm .chat-suchweg summary { cursor: pointer; }
.crm .chat-suchweg .chat-protokoll { margin-top: var(--s-2); }

/* Fund-Karten: der Ort, an dem man in den Bestand hineinklickt. */
.crm .chat-funde { display: flex; flex-direction: column; gap: var(--s-2); margin-top: var(--s-3); }
.crm .chat-fund { padding: var(--s-2) var(--s-3); background: var(--bg-card2); font-size: 0.8125rem; }
.crm .chat-fund-kopf { display: flex; justify-content: space-between; gap: var(--s-2); color: var(--text-2); margin-bottom: var(--s-1); }
.crm .chat-fund-titel { font-weight: 600; color: var(--text-1); }
.crm .chat-fund-anzahl { color: var(--text-3); white-space: nowrap; }
.crm .chat-fund-tabelle { overflow-x: auto; }
.crm .chat-fund-liste { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--s-1); }
.crm .chat-fund-link {
  appearance: none;
  background: none;
  border: none;
  padding: 0;
  font: inherit;
  font-size: 0.8125rem;
  color: var(--chat-link);
  cursor: pointer;
  text-align: left;
}
.crm .chat-fund-link:hover { text-decoration: underline; }
.crm .chat-fund-auszug { color: var(--text-3); }
.crm .chat-fund-hinweis { margin: var(--s-1) 0 0; color: var(--text-3); font-size: 0.75rem; font-style: italic; }

/* Belegmarken im Satz — klein, aber ein echter Knopf mit Fokusring. */
.crm .chat-beleg {
  appearance: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.125rem;
  height: 1.125rem;
  padding: 0 var(--s-1);
  margin: 0 0.125rem;
  border: var(--chat-linie) solid var(--chat-link);
  border-radius: var(--r-sm);
  background: var(--bg-card2);
  color: var(--chat-link);
  font: inherit;
  font-size: 0.6875rem;
  font-weight: 600;
  line-height: 1;
  vertical-align: 0.125rem;
  cursor: pointer;
}
.crm .chat-beleg:hover { background: var(--primary); color: var(--bg-surface); }
.crm .chat-quelle-nr { color: var(--text-3); font-size: 0.75rem; }
.crm button.chat-quelle-datensatz,
.crm button.chat-quelle-zahl { cursor: pointer; font-family: inherit; transition: border-color var(--t-fast), color var(--t-fast); }
.crm button.chat-quelle-datensatz:hover,
.crm button.chat-quelle-zahl:hover { border-color: var(--primary); color: var(--text-1); }

/* Zusammenhang: als Chip an der Frage und abwaehlbar ueber dem Feld. */
.crm .chat-kontext {
  display: inline-flex;
  align-items: center;
  gap: var(--s-1);
  border-radius: 999rem;
  padding: var(--s-1) var(--s-3);
  background: var(--bg-card2);
  border: var(--chat-linie) solid var(--border);
  font-size: 0.8125rem;
  color: var(--text-2);
  max-width: 100%;
}
.crm .chat-kontext-titel { color: var(--text-3); }
.crm .chat-kontext-weg { appearance: none; background: none; border: none; color: var(--text-3); cursor: pointer; font: inherit; padding: 0 var(--s-1); }
.crm .chat-kontext-weg:hover { color: var(--text-1); }
.crm .chat-ich .chat-kontext { margin-bottom: var(--s-2); }

/* Dokumenttext unter der Antwort (Beleg-Klick). */
.crm .chat-dokument {
  margin-top: var(--s-3);
  border: var(--chat-linie) solid var(--border);
  border-radius: var(--r-md);
  padding: var(--s-2) var(--s-3);
  font-size: 0.8125rem;
  color: var(--text-2);
}
.crm .chat-dokument-kopf { display: flex; justify-content: space-between; align-items: center; gap: var(--s-2); margin-bottom: var(--s-2); color: var(--text-1); }
.crm .chat-dokument-text { margin: 0; white-space: pre-wrap; max-height: 20rem; overflow: auto; font: inherit; }
.crm .chat-dokument-fehler { border-color: var(--danger); }

/* Wegweiser im Cockpit + „Erneut fragen" */
.crm .chat-wegweiser { padding: var(--s-6); text-align: center; }
.crm .chat-wegweiser-titel { margin: 0 0 var(--s-2); font-weight: 600; color: var(--text-1); }
.crm .chat-wegweiser-sub { margin: 0 0 var(--s-4); color: var(--text-2); font-size: 0.875rem; }
.crm .chat-erneut { margin-top: var(--s-2); }

/* Seitenleiste = der vorhandene Drawer, etwas breiter fuer Karten und Tabellen. */
.crm .pythia-leiste { width: min(34rem, 96vw); }
.crm .pythia-leiste-body .chat-panel { flex: 1; }
.crm .tb-pythia { white-space: nowrap; display: inline-flex; align-items: center; gap: var(--s-2); }
/* Das 20-px-Zeichen darf den Knopf nicht hoeher machen als seine Nachbarn. */
.crm .tb-pythia .pythia-dreifuss { margin-block: -0.25rem; }
.crm .pythia-leiste-bereich { appearance: none; background: none; border: none; padding: 0; font: inherit; font-size: 0.8125rem; color: var(--chat-link); cursor: pointer; text-decoration: underline; }

@media (max-width: 56rem) {
  .crm .pythia-bereich { grid-template-columns: minmax(0, 1fr); }
  .crm .pythia-leiste { width: 100vw; }
}

/* Schmale Fenster: kein harter Umbruchpunkt noetig. Das Formular bricht um, sobald
   das Eingabefeld seine Mindestbreite unterschreitet, und die Sprechblase kann nie
   breiter werden als der Platz — das traegt jede Fensterbreite ohne Sprungstelle. */
.crm .chat-form { flex-wrap: wrap; }
.crm .chat-eingabe { flex: 1 1 12rem; }
/* Der Knopf behaelt seine natuerliche Breite. Mit flex-grow zog er sich ueber die halbe
   Zeile — ein Absenden-Knopf, der breiter ist als noetig, sieht nach Fehler aus. */
.crm .chat-senden { flex: 0 0 auto; }

/* Waehrend der Chat arbeitet, sind Feld und Knopf gesperrt — das muss man auch SEHEN.
   Bewusst an diesen beiden Elementen statt global an `.btn:disabled`: eine app-weite
   Regel traefe jeden Knopf der Anwendung, und genau deshalb hat sich das Projekt an
   zwei anderen Stellen schon dagegen entschieden (style.css:13231, :13456). */
.crm .chat-senden:disabled,
.crm .chat-eingabe:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}
/* ── PR1.274 (#468) — Bestaetigungskarten fuer Chat-Aktionen ─────────────────────
   Zwilling zum gleichnamigen Block in style.css.

   Alle Masse in rem, nicht in px: der ui-craft-Ratchet `raw-px` (Konvention 21) zaehlt
   harte Pixelwerte in dieser Datei, und der Chat-Block darueber ist aus demselben Grund
   schon so gebaut.

   Ebenfalls bewusst: keine Bewegung. Was in einem scrollenden Verlauf erscheint, soll
   dastehen, nicht auffahren. */
.crm .chat-aktionen { display: flex; flex-direction: column; gap: 0.625rem; margin-top: 0.75rem; }

.crm .chat-aktion {
  border-left: 0.1875rem solid var(--primary);
  padding: 0.75rem;
  background: var(--bg-surface-2);
}

.crm .chat-aktion-titel {
  margin: 0 0 0.5rem;
  font-weight: 600;
  color: var(--text-1);
}

.crm .chat-aktion-felder { margin: 0; display: grid; gap: 0.25rem 0.75rem; }
.crm .chat-aktion-feld { display: grid; grid-template-columns: minmax(7rem, 11rem) 1fr; gap: 0.25rem 0.75rem; }
.crm .chat-aktion-feld dt { color: var(--text-2); font-size: 0.8rem; }
.crm .chat-aktion-feld dd { margin: 0; color: var(--text-1); font-size: 0.85rem; overflow-wrap: anywhere; }

.crm .chat-aktion-knoepfe { display: flex; gap: 0.5rem; flex-wrap: wrap; margin-top: 0.75rem; }

.crm .chat-aktion-status { margin: 0.5rem 0 0; color: var(--text-2); font-size: 0.8rem; }

/* Der Fehlerton kommt aus der -700-Stufe: `--ad-red` liegt unter 3:1 gegen die helle
   Flaeche und taugt fuer Text nicht (dokumentierte AA-Korrektur dieser Datei). */
.crm .chat-aktion-fehler { margin: 0.5rem 0 0; color: var(--ad-red-700); font-size: 0.8rem; }

/* Gruen ist im Redesign keine Textfarbe — hier faerbt es nur den Balken, nicht Schrift. */
.crm .chat-aktion.is-erledigt { border-left-color: var(--ad-green-700); }
.crm .chat-aktion.is-fehler { border-left-color: var(--ad-red-700); }
.crm .chat-aktion.is-abgelehnt { border-left-color: var(--border); opacity: 0.7; }
.crm .chat-aktion.is-laeuft { border-left-color: var(--text-3); }

@media (max-width: 26rem) {
  .crm .chat-aktion-feld { grid-template-columns: 1fr; }
}

/* ── PR1.321 (#530) — Pythias Bestaetigungsliste ──────────────────────────────
   Bewusst OHNE px und ohne rohe Farben (Konvention 21, ui-craft-Ratchet). Ton-
   stufen nach der Kontrast-Lehre dieser Datei: Text in -900 bzw. -700, die
   Grundtoene nur fuer Balken. Keine Animation: gelegentlich genutzt, hoher
   Einsatz — Klarheit vor Effekt. */
.crm .chat-plan-zaehlung { margin: 0; color: var(--text-2); font-size: 0.85rem; }

.crm .pythia-plan-hinweise { display: flex; flex-direction: column; gap: 0.375rem; margin-bottom: 0.75rem; }
.crm .pythia-plan-hinweise:empty { display: none; }
.crm .pythia-plan-hinweise p {
  margin: 0; padding: 0.5rem 0.75rem; font-size: 0.85rem;
  border-left: 0.1875rem solid var(--border-strong);
  background: var(--bg-surface-2); color: var(--text-1);
}
.crm .pythia-plan-hinweise .pythia-plan-sperre,
.crm .pythia-plan-hinweise .pythia-plan-fehler { border-left-color: var(--ad-red-700); font-weight: 600; }
.crm .pythia-plan-hinweise .pythia-plan-hinweis.is-warnung { border-left-color: var(--ad-orange-700); }
.crm .pythia-plan-hinweise .pythia-plan-lauf { border-left-color: var(--primary); }
.crm .pythia-plan-hinweise .pythia-plan-leer { color: var(--text-2); }

.crm .pythia-plan-huelle {
  max-height: 60vh; overflow: auto;
  border: 0.0625rem solid var(--border); border-radius: var(--r-md);
}
.crm .pythia-plan-tabelle { width: 100%; min-width: 44rem; border-collapse: collapse; font-size: 0.85rem; }
.crm .pythia-plan-tabelle th {
  position: sticky; top: 0; z-index: 1;
  background: var(--bg-surface-2); text-align: left; font-weight: 600; color: var(--text-2);
  padding: 0.5rem 0.625rem; border-bottom: 0.0625rem solid var(--border);
}
.crm .pythia-plan-tabelle td {
  padding: 0.5rem 0.625rem; border-bottom: 0.0625rem solid var(--border);
  vertical-align: top; color: var(--text-1);
}
.crm .pythia-plan-tabelle tr:last-child td { border-bottom: 0; }
.crm .pythia-plan-wahl { width: 2.5rem; }
.crm .pythia-plan-wahl input { width: 1.125rem; height: 1.125rem; }
.crm .pythia-plan-name { display: block; font-weight: 600; overflow-wrap: anywhere; }
.crm .pythia-plan-art { display: block; color: var(--text-2); font-size: 0.8rem; }
.crm .pythia-plan-status { display: inline-block; margin-top: 0.25rem; font-size: 0.75rem; font-weight: 600; color: var(--text-2); }
.crm .pythia-plan-bisher { color: var(--text-2); overflow-wrap: anywhere; }
.crm .pythia-plan-felder { display: grid; gap: 0.375rem; }
.crm .pythia-plan-feld { display: grid; grid-template-columns: minmax(6rem, 9rem) 1fr; gap: 0.25rem 0.5rem; align-items: center; }
.crm .pythia-plan-feld.is-einzeln { grid-template-columns: 1fr; }
.crm .pythia-plan-feld label { color: var(--text-2); font-size: 0.8rem; }
.crm .pythia-plan-feld .form-control { padding: 0.25rem 0.5rem; font-size: 0.85rem; }
.crm .pythia-plan-feldfehler { grid-column: 1 / -1; color: var(--ad-red-700); font-size: 0.8rem; }
.crm .pythia-plan-weg { color: var(--ad-red-700); font-weight: 600; }
.crm .pythia-plan-maske { margin-top: 0.375rem; }
.crm .pythia-plan-meldung { margin: 0.375rem 0 0; font-size: 0.8rem; color: var(--text-2); }

.crm .pythia-plan-zeile.is-ab td:not(.pythia-plan-wahl),
.crm .pythia-plan-zeile.is-unmoeglich td:not(.pythia-plan-wahl) { color: var(--text-3); }
.crm .pythia-plan-zeile.is-ab .pythia-plan-bisher,
.crm .pythia-plan-zeile.is-ab .pythia-plan-art { color: var(--text-3); }
.crm .pythia-plan-zeile.is-geaendert td:first-child { box-shadow: inset 0.1875rem 0 0 var(--ad-orange-700); }
.crm .pythia-plan-zeile.is-geaendert .pythia-plan-status,
.crm .pythia-plan-zeile.is-geaendert .pythia-plan-meldung { color: var(--ad-orange-900); }
.crm .pythia-plan-zeile.is-fehler td:first-child { box-shadow: inset 0.1875rem 0 0 var(--ad-red-700); }
.crm .pythia-plan-zeile.is-fehler .pythia-plan-status,
.crm .pythia-plan-zeile.is-fehler .pythia-plan-meldung { color: var(--ad-red-700); }
.crm .pythia-plan-zeile.is-erledigt td:first-child { box-shadow: inset 0.1875rem 0 0 var(--ad-green-700); }
.crm .pythia-plan-knoepfe { display: flex; gap: 0.5rem; }
/* Gesperrt MUSS gesperrt aussehen: bei einer Sperre (mehr als drei Loeschungen, leere
   Pflichtangabe) und waehrend der Ausfuehrung. Nur an dieser Liste, nicht global an
   `.btn:disabled` — dieselbe Abwaegung wie bei .chat-senden:disabled oben. */
.crm .pythia-plan-knoepfe .btn:disabled,
.crm .pythia-plan-maske:disabled { opacity: 0.55; cursor: not-allowed; }

/* Dunkelmodus: --ad-red-700 kommt auf dem dunklen Grund nur auf 3.07:1 (Palette-
   Kommentar oben) — Rot-TEXT nimmt dort die helle Stufe, Orange-Text den Grundton.
   Die Balken bleiben, wie sie sind; sie sind Markierung, kein Text. */
.crm.dark .pythia-plan-weg , html[data-theme="dark"] .crm .pythia-plan-weg ,
.crm.dark .pythia-plan-feldfehler , html[data-theme="dark"] .crm .pythia-plan-feldfehler ,
.crm.dark .pythia-plan-zeile.is-fehler .pythia-plan-status ,
html[data-theme="dark"] .crm .pythia-plan-zeile.is-fehler .pythia-plan-status ,
.crm.dark .pythia-plan-zeile.is-fehler .pythia-plan-meldung ,
html[data-theme="dark"] .crm .pythia-plan-zeile.is-fehler .pythia-plan-meldung { color: var(--ad-red-300); }
.crm.dark .pythia-plan-zeile.is-geaendert .pythia-plan-status ,
html[data-theme="dark"] .crm .pythia-plan-zeile.is-geaendert .pythia-plan-status ,
.crm.dark .pythia-plan-zeile.is-geaendert .pythia-plan-meldung ,
html[data-theme="dark"] .crm .pythia-plan-zeile.is-geaendert .pythia-plan-meldung { color: var(--ad-orange); }

/* ── PR1.265 (#459) — Org-Struktur (BL → CC → MA) ───────────────────────────
   Bewusst OHNE px und ohne rohe Farben: der ui-craft-Ratchet zaehlt beide ueber
   die ganze Datei, ein einziger harter Wert kippt den Job (Konvention 21).
   Kein overflow hier — die Ansicht scrollt ueber #crm-content, genau wie die
   Status-Seite. Keine transition: der Aufklapp-Weg ist tastaturinitiiert. */
.crm .kb-eyebrow { font-size:0.6875rem; color:var(--text-3); letter-spacing:0.0375rem;
  text-transform:uppercase; font-weight:600; }
.crm .org-tbl { width:100%; }
.crm .org-tbl th.num , .crm .org-tbl td.org-num { text-align:right; white-space:nowrap; }
.crm .org-name { display:flex; align-items:baseline; gap:0.5rem; }
.crm .org-lvl-1 .org-name { padding-left:1.25rem; }
.crm .org-lvl-2 .org-name { padding-left:2.75rem; }
.crm .org-glyph { color:var(--text-3); width:0.875rem; flex:0 0 auto; text-align:center; }
.crm .org-toggle { background:none; border:0; color:var(--text-3); cursor:pointer;
  font:inherit; padding:0; line-height:1; width:0.875rem; flex:0 0 auto; }
.crm .org-bl { font-family:var(--f-cond); font-weight:700; }
.crm .org-cc-wrap { display:flex; align-items:baseline; gap:0.375rem; flex-wrap:wrap; min-width:0; }
.crm .org-cc { font-weight:600; color:var(--text-1); }
.crm .org-count { color:var(--text-3); font-size:0.71875rem; }
.crm .org-sub { flex-basis:100%; color:var(--text-3); font-size:0.75rem; }
/* „Ohne Zuordnung" ist ein Datenqualitaets-Befund, kein normales Center. Der Hinweis
   traegt den Warnton als TEXTfarbe — eine Flaeche haette einen Farbwert gebraucht,
   den es als AA-gepruefter Token nicht gibt. */
.crm .org-sub-warn { color:var(--ad-orange-900); }
.crm.dark .org-sub-warn , html[data-theme="dark"] .crm .org-sub-warn { color:var(--ad-orange); }
.crm .org-link { background:none; border:0; padding:0; font:inherit; cursor:pointer;
  color:var(--text-1); text-align:left; }
.crm .org-link:hover { text-decoration:underline; }
.crm .org-ma { font-weight:500; color:var(--text-2); }
.crm .org-proj , .crm .org-sep { color:var(--text-3); font-size:0.78125rem; }
.crm .org-proj.org-link { color:var(--text-3); }
.crm .org-note { color:var(--text-3); font-size:0.75rem; margin-left:0.375rem; }
/* PR1.265 — in der halbierten Pruefspalte brach „Kai Peters" ueber zwei Zeilen.
   Der Name bleibt jetzt zusammen; umbrochen wird der Projektname dahinter. */
.crm .org-name { flex-wrap: wrap; }
.crm .org-bl , .crm .org-cc , .crm .org-ma { white-space: nowrap; }
.crm .org-retry { padding: 0.75rem 1rem 0; }

/* ── PR1.264 (#458) — Kunden-Baum (Kunde → Vorgang → Projekt → Team) ────────
   Vier Ebenen statt drei, sonst dieselben Regeln wie die Org-Struktur oben.
   Wieder OHNE px und ohne rohe Farben — der raw-px-Ratchet stand beim Bau
   exakt auf seiner Grenze (683/683), ein einziger harter Wert kippt den Job.
   Kein overflow: die Ansicht scrollt ueber #crm-content, wie die Status-Seite.
   Keine transition: der Aufklapp-Weg ist tastaturinitiiert (Konvention 22). */
.crm .ctree-tbl { width:100%; }
.crm .ctree-tbl th.num , .crm .ctree-tbl td.ctree-num { text-align:right; white-space:nowrap; }
.crm .ctree-name { display:flex; align-items:baseline; gap:var(--s-2); flex-wrap:wrap; }
/* Die Einrueckung ist die einzige Tiefenanzeige — ohne sie waere ein Projekt
   unter einem Vorgang von einem Vorgang nicht zu unterscheiden. */
.crm .ctree-lvl-1 .ctree-name { padding-left:1.25rem; }
.crm .ctree-lvl-2 .ctree-name { padding-left:2.75rem; }
.crm .ctree-lvl-3 .ctree-name { padding-left:4.25rem; }
.crm .ctree-glyph { color:var(--text-3); width:0.875rem; flex:0 0 auto; text-align:center; }
.crm .ctree-toggle { background:none; border:0; color:var(--text-3); cursor:pointer;
  font:inherit; padding:0; line-height:1; width:0.875rem; flex:0 0 auto; }
/* flex:1 1 0 ist hier kein Feinschliff: ohne die Angabe waehlt der Browser die
   Inhaltsbreite als Basis, die Zelle bricht um — und der Aufklapp-Pfeil stand in
   einer eigenen Zeile UEBER dem Namen, zu dem er gehoert. */
.crm .ctree-wrap { display:flex; align-items:baseline; gap:var(--s-2); flex-wrap:wrap;
  min-width:0; flex:1 1 0; }
.crm .ctree-sub { flex-basis:100%; color:var(--text-3); font-size:0.75rem; }
.crm .ctree-link { background:none; border:0; padding:0; font:inherit; cursor:pointer;
  color:var(--text-1); text-align:left; white-space:nowrap; }
.crm .ctree-link:hover { text-decoration:underline; }
.crm .ctree-cust { font-weight:600; }
.crm .ctree-person .ctree-link { color:var(--text-2); font-weight:500; }
/* Platzhalter fuer das Kundenlogo: die Flaeche steht sofort, das Bild kommt ueber
   die authentifizierte Route nach (resolveAccountLogos). Ohne feste Flaeche
   ruckelte die Zeile beim Nachladen. */
/* Nur Groesse und Ausrichtung: Farbe, Radius und das Ausblenden der Initialen bei
   geladenem Logo kommen aus .acc-logo in style.css, die sich beide Shells teilen. */
.crm .ctree-logo { width:1.25rem; height:1.25rem; font-size:0.5625rem; align-self:center; }
.crm .ctree-zeit { color:var(--text-3); font-size:0.75rem; white-space:nowrap; }
.crm .ctree-bar { display:flex; align-items:center; gap:var(--s-3); flex-wrap:wrap;
  padding:var(--s-3) var(--s-4); }
.crm .ctree-bar .grow { flex:1 1 auto; }
.crm .ctree-opt { display:inline-flex; align-items:center; gap:var(--s-2);
  color:var(--text-2); font-size:0.8125rem; white-space:nowrap; }
/* Die Kundenzeile ist der Blockanfang — bei 40+ Kunden findet das Auge ihn sonst
   nicht wieder. Tonung statt zweiter Linienstaerke, sonst wird das Raster unruhig. */
.crm .ctree-customer > td { background:var(--bg-surface-2); }
.crm .ctree-more .ctree-link { color:var(--text-3); font-size:0.8125rem; white-space:normal; }
.crm .ctree-retry { padding:var(--s-3) var(--s-4) 0; }
/* Hoehenkette (RD1.11): #crm-content ist der Flex-KONTEXT, gescrollt wird eine Ebene
   tiefer. Die Karte fuellt die Hoehe, die Tabelle darin scrollt. Live gemessen lief
   ohne das #crm-content um 3543px ueber — die Org-Sicht faellt nur deshalb nicht auf,
   weil sie kuerzer ist. */
.crm .ctree-card { display:flex; flex-direction:column; flex:1 1 auto; min-height:0; }
.crm .ctree-scroll { overflow-y:auto; flex:1 1 auto; min-height:0; }

/* ── PR1.267 (#461) — Sicht „Datenqualitaet" ────────────────────────────────
   Bewusst ohne rohe Pixel- und Farbwerte: der ui-craft-Ratchet zaehlt beides ueber
   die ganze Datei und stand bei raw-px exakt an der Grenze (683/683). Alle Groessen
   in rem, alle Farben aus Tokens.

   Die Regelzeilen sind natives <details>/<summary> — tastaturbedienbar, mit
   sichtbarem Fokus und korrekter Zustandsmeldung, ohne eine Zeile Skript. Und sie
   animieren nicht: die Sicht liegt auf einem Aufraeum-Weg, nicht auf einem
   Hochfrequenz-Pfad, aber ein Aufklappen mit Bewegung waere hier reine Dekoration. */
.crm .dq-head { display:flex; align-items:center; justify-content:space-between;
  gap:var(--s-3); flex-wrap:wrap; margin-bottom:var(--s-3); }
.crm .dq-rules { display:flex; flex-direction:column; gap:var(--s-1); }
/* Trennung ueber Flaechenwechsel statt Trennlinien — das ist die Redesign-Sprache
   fuer Karten (DESIGN.md, „Cards/Containers") und spart zugleich rohe px-Werte, die
   der Ratchet zaehlt. */
.crm .dq-rule { border-radius:var(--r-md); background:var(--bg-surface-2); }
.crm .dq-rule + .dq-rule { margin-top:0; }
.crm .dq-summary { display:flex; align-items:baseline; gap:var(--s-3);
  padding:var(--s-2) var(--s-3); cursor:pointer; flex-wrap:wrap; }
.crm .dq-summary::-webkit-details-marker { display:none; }
/* Eigenes Dreieck statt des Browser-Markers: das Standardglyph sitzt je nach
   Plattform anders und bricht die Grundlinie der Zeile. */
.crm .dq-summary::before { content:"\25B8"; color:var(--text-3); flex:0 0 auto;
  width:0.875rem; transition:none; }
.crm .dq-rule[open] > .dq-summary::before { content:"\25BE"; }
.crm .dq-count { font-family:var(--f-cond); font-weight:700; font-size:1.125rem;
  min-width:2rem; text-align:right; flex:0 0 auto; }
.crm .dq-label { font-weight:600; color:var(--text-1); }
/* Nur im Zeilen-Kontext: `flex-basis` wird in einem Spalten-Container zur HOEHE,
   und der Hinweis im Dubletten-Block stand dadurch 12rem hoch statt einzeilig.
   Auf der Pruefseite im Leerzustand als klaffende Luecke aufgefallen. */
.crm .dq-summary .dq-hint { flex:1 1 12rem; min-width:0; }
.crm .dq-muted { flex:0 0 auto; }
.crm .dq-list { list-style:none; margin:0; padding:0 var(--s-3) var(--s-3);
  display:flex; flex-direction:column; gap:var(--s-1); }
.crm .dq-list-empty { padding:0 var(--s-3) var(--s-3); }
.crm .dq-item { display:flex; align-items:baseline; gap:var(--s-2); flex-wrap:wrap;
  padding:var(--s-2); border-radius:var(--r-sm); background:var(--bg-surface); }
.crm .dq-link { background:none; border:0; padding:0; font:inherit; cursor:pointer;
  color:var(--text-1); font-weight:600; text-align:left; text-decoration:underline;
  text-underline-offset:0.125rem; }
.crm .dq-grund { flex:1 1 14rem; min-width:0; }
/* Das Urteilswort teilt die Farbstufen der Zaehlspalte, aber NICHT ihre Groesse:
   „Verschieden" in Zaehlgroesse draengt sich vor die Namen, um die es geht. Bei der
   Abnahme auf der Pruefseite genau so aufgefallen. */
.crm .dq-verdict { font-size:0.75rem; font-weight:700; text-transform:uppercase;
  letter-spacing:0.03em; min-width:5.5rem; flex:0 0 auto; }
.crm .dq-pair-names { flex:1 1 16rem; min-width:0; color:var(--text-1); }
.crm .dq-vs { color:var(--text-3); }
.crm .dq-mute-wrap { display:flex; align-items:baseline; gap:var(--s-2);
  flex-wrap:wrap; flex:0 0 auto; }
.crm .dq-mute { background:var(--bg-surface-3); border:0; border-radius:var(--r-sm);
  padding:0.125rem var(--s-2); font:inherit; font-size:0.75rem; cursor:pointer;
  color:var(--text-2); }
.crm .dq-mute:hover { background:var(--bg-hover); color:var(--text-1); }
.crm .dq-reason { display:flex; align-items:center; gap:var(--s-2); flex-wrap:wrap; }
/* `display:flex` aus der Zeile darueber schlaegt das UA-Stylesheet fuer [hidden] —
   ohne diese Regel stehen ALLE Begruendungsfelder dauerhaft offen und die Trefferliste
   ist zugemuellt. Beim ersten Blick auf die Pruefseite genau so aufgefallen. */
.crm .dq-reason[hidden] { display:none; }
/* Das Label ist sichtbar und mit dem Feld verbunden — ein Platzhalter allein
   verschwindet beim Tippen und ist kein Ersatz. */
.crm .dq-reason-lbl { font-size:0.75rem; color:var(--text-3); }
/* Groesse und Mindestbreite hier, alles Uebrige aus .crm-input — ein zweiter
   Eingabefeld-Stil waere genau die Designsprachen-Mischung, die Konvention 21 meint. */
.crm .dq-reason-in { font-size:0.8125rem; min-width:12rem; }
.crm .dq-actions { margin-top:var(--s-2); }
.crm .dq-dupes-hd { margin-top:var(--s-5); }
.crm .dq-dupes-idle { display:flex; flex-direction:column; gap:var(--s-2); }
.crm .dq-trunc , .crm .dq-nomerge { margin-top:var(--s-2); }
/* ── PR1.294 (#499) — KB-Graph: Legende mit Zeichen + Ladehinweis ─────────────
   Ausschliesslich rem und Tokens: der ui-craft-Ratchet zaehlt jeden rohen
   px- und Hex-Wert in dieser Datei, und beide Zaehler stehen exakt auf ihrer
   Grenze (683 bzw. 65). Ein einziger harter Wert hier blockt den CI-Job. */
.crm .kbg-legend { display: flex; flex-direction: column; gap: 0.4375rem; margin-top: 0.375rem; }
.crm .kbg-legend-row { gap: 0.5rem; }
/* Das Zeichen sitzt weiss auf der Typfarbe — dieselbe Kombination wie im Graphen,
   damit Legende und Bild als dasselbe gelesen werden. */
.crm .kbg-legend-mark {
  width: 1.125rem;
  height: 1.125rem;
  flex: 0 0 auto;
  border-radius: 50%;
  color: var(--bg-surface);
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
/* Ordnungsbegriffe eckig — dieselbe Unterscheidung wie im Graphen, und sie
   traegt auch dann, wenn Farben nicht unterscheidbar sind. */
.crm .kbg-legend-mark--hub { border-radius: var(--r-sm); }
.crm .kbg-legend-name { flex: 1; min-width: 0; }
/* Der dritte Zustand des Graphen: waehrend das Layout rechnet. */
.crm .kbg-busy {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  color: var(--text-3);
  font-size: 0.8125rem;
  background: var(--bg-surface);
  pointer-events: none;
}
.crm .kbg-busy[hidden] { display: none; }

/* ── PR1.305 (#513) — Linienarten-Legende + Verbindungen in der Karte ─────────
   Wie der Block darueber: ausschliesslich rem und Tokens. Die Linienfarben kommen
   als Inline-Stil aus kb-graph-icons.js, nicht von hier — der ui-craft-Ratchet steht
   auf 65/65 (raw-hex) und 683/683 (raw-px), ein einziger harter Wert blockt den
   CI-Job. Genau deshalb ist die Vorschau ein SVG aus dem geteilten Modul. */
.crm .kbg-legend-sub {
  margin-top: 0.625rem;
  margin-bottom: 0.25rem;
  color: var(--text-3);
  font-size: 0.75rem;
  font-weight: 600;
}
/* Traeger der Linienvorschau. `color` gilt der Art „gehoert zu": sie traegt keine
   eigene Farbe und folgt per currentColor dem Rahmen-Token — wie im Bild. */
.crm .kbg-legend-line {
  display: inline-flex;
  align-items: center;
  flex: 0 0 auto;
  width: 1.375rem;
  /* Folgt der Kantenfarbe im Graphen — dort `--text-3` seit PR1.305. */
  color: var(--text-3);
}
/* Eine Verbindungszeile: Linie, Beziehungswort, Gegenueber. Das Gegenueber darf
   kuerzen statt die Zeile zu sprengen — Namen sind hier beliebig lang. */
.crm .kbg-edgerow {
  gap: 0.5rem;
  min-height: 1.375rem;
}
.crm .kbg-edgerow .lbl {
  flex: 0 0 auto;
}
.crm .kbg-edgerow-other {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--text-2);
}
/* PR1.302 (#510) — Vollständigkeit des Startpunkts, direkt über dem Bild.
   Feststellend gesetzt, nicht alarmierend: keine Signalfarbe, kein Rahmen, kein
   Zeichen. Die Zahl steht in der Vordergrundfarbe, die Aufzählung eine Stufe
   zurückgenommen. Ausschließlich rem + Tokens — die Ratchets `raw-px` und `raw-hex`
   dieser Datei sind ausgereizt.

   Die Aufzählung trägt bewusst NICHT `.lbl`: die Regel `.crm .filter-row .lbl` setzt
   `text-transform: uppercase`, und der Satz stünde dann in Großbuchstaben — geschrien
   statt festgestellt. */
.crm .kbg-expect {
  align-items: baseline;
  gap: 0.5rem;
  flex-wrap: wrap;
  padding: 0.5rem 1.375rem;
  border-bottom: 0.0625rem solid var(--border);
  font-size: 0.8125rem;
}
.crm .kbg-expect b {
  color: var(--text-1);
  font-variant-numeric: tabular-nums;
}
.crm .kbg-expect-missing { color: var(--text-3); }
/* Die Zeichenfläche ist seit PR1.294 per Tastatur anspringbar. Den Ring selbst zieht
   schon die generische `.crm :focus-visible`-Regel oben; korrigiert wird hier nur der
   Versatz: die Graph-Karte trägt `overflow:hidden`, ein nach außen gesetzter Ring
   würde an ihrer Kante abgeschnitten. Farbe und Stärke bleiben bewusst geerbt —
   ein eigener Rington wäre ein zweiter Fokus-Stil in derselben Shell. */
.crm #kb-cy:focus-visible {
  outline-offset: -0.25rem;
  border-radius: var(--r-md);
}
/* ============== PR1.303 (#511) — NAMENSSCHILDER ==============
   Die Beschriftung eines Knotens liegt seit PR1.303 nicht mehr auf der Zeichenfläche,
   sondern als echtes Textkästchen darüber. Grund: eine Cytoscape-Beschriftung trägt
   genau EINE Schriftgröße, Entscheid A21 will aber den Namen groß und Kennung plus
   Art klein darunter.

   Die Maße hier sind die Sicht-Entsprechung der Rechnung in kb-graph-labels.js
   (LABEL_HEIGHT, LABEL_PAD_X, Schriftgrößen 11/9 px). Wer hier Schrift oder
   Innenabstand ändert, muss sie dort nachziehen — sonst schiebt der Mindestabstand
   nach einem Schild auseinander, das es so nicht gibt.

   Bewusst ohne rohe px und ohne Hex: der ui-craft-Ratchet steht bei raw-px 683/683
   und raw-hex 65/65, also exakt an der Grenze — ein einziger roher Wert hier blockt
   den Job. */
.crm .kbg-labels {
  position: absolute;
  inset: 0;
  overflow: hidden;
  /* Die Ebene fängt NICHTS ab: Klicken, Doppeltippen und Ziehen gehen unverändert an
     die Zeichenfläche darunter. Ohne das wäre der Graph nicht mehr bedienbar. */
  pointer-events: none;
  z-index: 1;
}
.crm .kbg-labels[hidden] { display: none; }
.crm .kbg-label {
  position: absolute;
  transform-origin: top center;
  display: flex;
  flex-direction: column;
  gap: 0.0625rem;
  padding: 0.125rem 0.375rem;
  border: 0.0625rem solid var(--border-strong);
  border-radius: var(--r-sm);
  background: var(--bg-surface);
  box-shadow: var(--shadow-1);
  text-align: center;
  pointer-events: none;
  /* Der Name steht einzeilig — die Kürzung passiert in kb-graph-labels.js, das hier
     ist der zweite Gürtel für den Fall, dass ein Zeichen breiter ausfällt als
     gerechnet. */
  white-space: nowrap;
  overflow: hidden;
}
.crm .kbg-label-name {
  font-size: 0.6875rem;
  line-height: 1.25;
  font-weight: 600;
  color: var(--text-1);
  overflow: hidden;
  text-overflow: ellipsis;
}
.crm .kbg-label-meta {
  font-size: 0.5625rem;
  line-height: 1.25;
  color: var(--text-3);
  overflow: hidden;
  text-overflow: ellipsis;
}
/* Überfahren oder ausgewählt: der volle Name. Die Kürzung ist eine Platzentscheidung,
   keine Auskunftsverweigerung. Kein Übergang — das Schild sitzt auf einer Fläche, die
   sich beim Zoomen ohnehin bewegt, und zwei Bewegungen übereinander sind nicht mehr
   zu lesen (Motion-Budget, Konvention 22). */
.crm .kbg-label.is-open {
  max-width: 20rem !important;
  white-space: normal;
  z-index: 2;
}
.crm .kbg-label.is-open .kbg-label-name { white-space: normal; overflow: visible; }
/* ============== PR1.266 (#460) — KONVERSIONEN ==============
   Fuenfte Sicht der Wissens-Zentrale. Der Zwilling steht in style.css als
   .kbcc-conv-*. Bewusst ohne rohe px und ohne Hex: der ui-craft-Ratchet steht bei
   raw-px 683/683 und raw-hex 65/65, also exakt an der Grenze — ein einziger roher
   Wert hier blockt den Job. */

/* Hoehenkette (RD1.11) wie bei .ctree-card: #crm-content ist der Flex-KONTEXT, die
   Karte fuellt die Hoehe, gescrollt wird eine Ebene tiefer. */
.crm .conv-card { display:flex; flex-direction:column; flex:1 1 auto; min-height:0; }
/* Der EINZIGE Scroll-Bereich dieser Sicht: Kacheln, Bild und beide Tabellen liegen
   darin. Zwei Scroll-Bereiche uebereinander sind nicht vorhersagbar bedienbar
   (Konvention 20, Punkt 2). */
.crm .conv-scroll { overflow-y:auto; flex:1 1 auto; min-height:0; padding:0 var(--s-4) var(--s-4); }

.crm .conv-bar { display:flex; align-items:center; gap:var(--s-3); flex-wrap:wrap;
  padding:var(--s-3) var(--s-4); }
.crm .conv-bar .grow { flex:1 1 auto; }

.crm .conv-kpis { margin-bottom:var(--s-3); }

/* Die Auffaelligkeitszeile: eine Zeile mit Zahl und Sprung, keine zweite Liste —
   die vollstaendige Aufarbeitung baut die Datenqualitaets-Sicht (#461). */
.crm .conv-hint { display:flex; align-items:center; gap:var(--s-3); flex-wrap:wrap;
  padding:var(--s-3); margin-bottom:var(--s-4);
  background:var(--tint-warn); border-radius:var(--r-sm);
  border-left:0.1875rem solid var(--ad-orange);
  font-size:0.8125rem; color:var(--text-1); }
/* --ad-orange auf --tint-warn ergibt 2.73:1 — fuer Text zu wenig. Dieselbe
   Korrektur wie bei .crm .warn-box b. */
.crm .conv-hint b { color:var(--ad-orange-900); }
.crm.dark .conv-hint b , html[data-theme="dark"] .crm .conv-hint b { color:var(--ad-orange); }
.crm .conv-hint-more { color:var(--text-2); }
.crm .conv-hint .conv-jump { margin-left:auto; }
.crm .conv-hint-ok { background:var(--tint-green); border-left-color:var(--ad-green); }
/* Gruen ist im Redesign KEINE Textfarbe: --ad-green-700 auf --tint-green ergibt im
   hellen Theme 2.85:1. Es gibt keine -900-Stufe, also traegt der Balken links die
   Farbe und der Text die Primaerfarbe — dieselbe Entscheidung wie im Zwilling. */
.crm .conv-hint-ok b { color:var(--text-1); }

.crm .conv-block { margin-bottom:var(--s-5); }
.crm .conv-h { margin:0 0 var(--s-3); font-size:0.875rem; font-weight:600; color:var(--text-1);
  display:flex; align-items:baseline; gap:var(--s-2); }
.crm .conv-chart { margin-bottom:var(--s-2); }
.crm .conv-note { margin:var(--s-2) 0 0; color:var(--text-3); font-size:0.75rem; }

.crm .conv-tbl { width:100%; }
/* Nur die ZAHLEN bleiben ungebrochen. Die Kopfzeilen duerfen umbrechen — sonst
   hielt allein "davon mit Projekt" eine Spalte auf 162 px und die Tabelle sprengte
   bei 900 px Fensterbreite ihre Spalte. */
/* Der Tabellen-Grundstil haelt Kopfzellen in EINER Zeile. Bei sechs bzw. sieben
   Spalten hielten allein "Konvertiert am" und "Wert Vorgang" je 123 px besetzt, und
   die Liste lief 37 px aus ihrem Bereich heraus. Die Koepfe duerfen umbrechen —
   die ZAHLEN darunter nicht. */
.crm .conv-tbl thead th { white-space:normal; }
.crm .conv-tbl th.num { text-align:right; }
.crm .conv-tbl td.num { text-align:right; white-space:nowrap; }
/* Zeilenkoepfe tragen lange Kundennamen: ohne diese Regel erbt die Zelle ein
   white-space:nowrap aus dem Tabellen-Grundstil und bricht nie um. */
.crm .conv-tbl tbody th { white-space:normal; }
/* Dieselbe Absicherung wie im Zwilling: `anywhere` senkt auch die intrinsische
   MINDESTbreite, damit ein sehr langer Projektname die Tabelle nicht aufspannt. */
/* `break-word` statt `anywhere`: letzteres bricht MITTEN im Wort und machte aus
   "Containerplattform" ein "Containerplattf orm". Gebrochen wird nur, wenn ein
   einzelnes Wort allein nicht in die Spalte passt. */
.crm .conv-liste td:first-child , .crm .conv-liste td:nth-child(2) ,
.crm .conv-tbl tbody th { overflow-wrap:break-word; }
/* Ohne Breitenvorgabe raeumt der Tabellenalgorithmus den Zahlenspalten so viel Platz
   ein, dass Vorgangs- und Projektname auf vier Zeilen umbrechen und jede Zeile ueber
   100 px hoch wird. Prozent statt px — der ui-craft-Ratchet zaehlt rohe px. */
.crm .conv-liste th:first-child , .crm .conv-liste th:nth-child(2) { width:24%; }
/* KEIN display:flex auf einer Tabellenzelle: das ersetzt `table-cell` vollstaendig,
   der Browser schiebt eine anonyme Zelle darunter — die zweite Spalte rutschte unter
   die erste und alle Folgespalten waren um eins verschoben. Die Zelle bleibt eine
   Zelle; gestapelt wird ueber den Block-Umbruch der Unterzeile. */
.crm .conv-name { font-weight:inherit; text-align:left; }
.crm .conv-sub { display:block; color:var(--text-3); font-size:0.75rem; }
.crm .conv-link { background:none; border:0; padding:0; font:inherit; cursor:pointer;
  color:var(--text-1); text-align:left; }
.crm .conv-link:hover { text-decoration:underline; }
.crm .conv-glyph { display:inline-block; color:var(--text-3); width:0.875rem; text-align:center; }
.crm .conv-toggle { display:inline-block; background:none; border:0; color:var(--text-3);
  cursor:pointer; font:inherit; padding:0; line-height:1; width:0.875rem; }

/* Die Gruppenzeile ist der Blockanfang — dieselbe Tonung wie bei der Kundenzeile
   im Kunden-Baum, damit beide Sichten dieselbe Sprache sprechen. */
/* Zeilenkoepfe tragen DATEN (den Statusnamen, den Kundennamen), keine
   Spaltenueberschrift: die geerbte Grossschreibung der Kopfzellen machte aus
   `Lead` ein `LEAD`. Nur thead bleibt in Versalien. */
.crm .conv-tbl tbody th , .crm .conv-tbl tfoot th { text-transform:none; letter-spacing:normal; }
.crm .conv-grp > th { background:var(--bg-surface-2); font-weight:600; }
.crm .conv-kind > td { color:var(--text-2); }
/* Die Einrueckung ist die einzige Tiefenanzeige. */
.crm .conv-kind .conv-name { padding-left:1.25rem; }
.crm .conv-sum > th , .crm .conv-sum > td { border-top:0.125rem solid var(--border-strong);
  font-weight:600; }
.crm .conv-warn { color:var(--ad-orange-900); font-weight:600; }
.crm.dark .conv-warn , html[data-theme="dark"] .crm .conv-warn { color:var(--ad-orange); }
/* Archivierte Zeilen bleiben lesbar: die Deckkraft sitzt bewusst NICHT am Kind,
   sonst laesst sie sich fuer den Text nicht mehr zuruecknehmen. */
.crm .conv-archiv > td { color:var(--text-3); }
.crm .conv-retry { padding:var(--s-3) var(--s-4) 0; }
/* ── PR1.271 (#465) — Gespeicherte Auswertungen ───────────────────────────────
   Dritter Reiter des Daten-Cockpits: eine Kachel je Auswertung.

   Bewusst ohne Bewegung. Das Cockpit ist ein Werkzeug fuer wenige Leute, die es
   taeglich oeffnen — eine Einblend-Animation, die man zweimal sieht, ist Charme;
   dieselbe Animation beim zwanzigsten Mal am Tag ist Wartezeit.

   "Freigegeben" ist eine Flaeche, keine gruene Schrift: --ad-green traegt als
   Textfarbe keine 3:1 gegen den Kartengrund, und Gruen ist im Redesign ohnehin
   kein Textfarb-Token. */

.crm .sv-kopf {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem;
  margin-bottom: 0.75rem;
  flex-wrap: wrap;
}

/* auto-fill statt fester Spaltenzahl: die Galerie steht neben dem Baukasten in
   derselben Breite und muss von einer Kachel bis zu einer vollen Reihe tragen. */
.crm .sv-raster {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
  gap: 0.75rem;
}

.crm .sv-kachel {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 0.875rem;
  background: var(--bg-card);
  border: 0.0625rem solid var(--border);
  border-radius: var(--radius-sm);
}

.crm .sv-kachel.is-frei { border-color: var(--ad-violet); }

/* Die ganze Kachelflaeche oeffnet — aber als echter Knopf, nicht als Klickflaeche
   mit Zeigefinger-Cursor. Ohne das gibt es keinen Tastaturweg zur Auswertung. */
.crm .sv-oeffnen {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.25rem;
  width: 100%;
  padding: 0;
  background: none;
  border: 0;
  cursor: pointer;
  text-align: left;
  color: inherit;
  font: inherit;
}

.crm .sv-name {
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--text-1);
  line-height: 1.3;
}

.crm .sv-oeffnen:hover .sv-name { text-decoration: underline; }

.crm .sv-art { font-size: 0.75rem; color: var(--text-3); }

.crm .sv-fuss {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.375rem 0.5rem;
  font-size: 0.75rem;
  color: var(--text-3);
}

.crm .sv-marke {
  padding: 0.0625rem 0.375rem;
  border-radius: var(--radius-sm);
  font-size: 0.6875rem;
  font-weight: 600;
  border: 0.0625rem solid var(--border);
}

.crm .sv-marke-frei {
  background: var(--ad-violet);
  border-color: var(--ad-violet);
  color: white;
}

.crm .sv-marke-privat { color: var(--text-2); }

.crm .sv-besitzer { color: var(--text-2); }

.crm .sv-aktionen {
  display: flex;
  flex-wrap: wrap;
  gap: 0.375rem;
  padding-top: 0.5rem;
  border-top: 0.0625rem solid var(--border);
}

/* Der Loeschknopf, nachdem er einmal gedrueckt wurde. Die Farbe ist die Warnung —
   ein zweiter Klick loescht wirklich. */
.crm .sv-loeschen.is-scharf { font-weight: 600; }

/* Ladezustand: das Raster der echten Kacheln, damit beim Eintreffen nichts springt. */
.crm .sv-skelett { gap: 0.625rem; }

.crm .sv-skelett-zeile {
  display: block;
  height: 0.75rem;
  border-radius: var(--radius-sm);
  background: var(--bg-hover);
}

.crm .sv-skelett-kurz { width: 45%; }

.crm .sv-leer-titel {
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--text-1);
  margin-bottom: 0.375rem;
}

.crm .sv-leer-text {
  margin: 0 0 0.75rem;
  font-size: 0.8125rem;
  color: var(--text-2);
  line-height: 1.5;
}

/* ── Speichern-Dialog ──────────────────────────────────────────────────────── */

.crm .sv-dialog-huelle {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1rem;
  background: rgba(14, 23, 38, 0.55);
}

.crm .sv-dialog {
  width: min(28rem, 94vw);
  display: flex;
  flex-direction: column;
  gap: 0.625rem;
}

.crm .sv-dialog-titel {
  margin: 0;
  font-size: 1rem;
  font-weight: 600;
  color: var(--text-1);
}

.crm .sv-dialog-hinweis {
  margin: 0;
  font-size: 0.75rem;
  color: var(--text-3);
  line-height: 1.5;
}

.crm .sv-dialog-fehler {
  margin: 0;
  font-size: 0.8125rem;
  color: var(--danger);
}

.crm .sv-schalter {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.8125rem;
  color: var(--text-1);
  cursor: pointer;
}

.crm .sv-dialog-fuss {
  display: flex;
  justify-content: flex-end;
  gap: 0.5rem;
  margin-top: 0.25rem;
}

/* ── BF-52 (#501) — Hinweisstreifen im Redesign ─────────────────────────────
   Das Element traegt die Klasse `crm` selbst, weil es ausserhalb von `#app-crm`
   haengen kann (klassische Shell: direkt an `body`). Ohne diese Regeln griffen dort
   die Redesign-Marken nicht, und der Streifen saehe aus wie ein Fremdkoerper aus
   dem alten Design. Werte kommen aus Marken, nicht aus rohen Pixeln. */
.crm.session-banner {
  background: var(--bg-surface);
  color: var(--text-1);
  /* Rahmenbreite erbt aus style.css — hier nur die Farbe des Redesigns. */
  border-bottom-color: var(--warning);
  font-family: var(--f-sans);
  padding: var(--s-3) var(--s-5);
  gap: var(--s-4);
}

.crm.session-banner .session-banner-btn {
  border-radius: var(--r-sm);
}
/* ===================================================================
   PR1.250 (#444) — MA-Übersicht: drei Darstellungen, Frei-Kennzeichen
   ===================================================================
   Wie die Phasen davor buchstaeblich OHNE px und ohne rohe Hex-Farben — nur Tokens,
   rem und Prozent (Ratchet raw-px/raw-hex, scripts/check-ui-craft.mjs). Kein zweiter
   overflow:auto-Container (Pruefung scroll-container): die Tabelle scrollt waagerecht
   ueber `overflow-x`, was die Pruefung nicht zaehlt, und senkrecht ueber den bereits
   bestehenden Container der View.
   Farbpaare fuer Text auf Tint sind die AA-geprueften aus dem Badge-Block darueber
   (RD1.13-Reparatur) — Dark bekommt wie dort die helle Stufe, sonst faellt die Schrift
   auf dem dunklen Tint unter AA. */

/* ── Darstellungs-Umschalter ── */
.crm .emp-mode-bar { display: inline-flex; border: thin solid var(--border-strong); border-radius: var(--r-sm); overflow: hidden; }
.crm .emp-mode-btn {
  font: inherit; font-size: .78rem; font-weight: 600;
  padding: .3rem .75rem;
  border: 0; background: var(--bg-surface); color: var(--text-2);
  cursor: pointer;
  transition: background var(--t-fast), color var(--t-fast);
}
.crm .emp-mode-btn + .emp-mode-btn { border-left: thin solid var(--border); }
.crm .emp-mode-btn:hover { background: var(--bg-hover); color: var(--text-1); }
.crm .emp-mode-btn.is-on { background: var(--ad-blue); color: var(--text-inv); }

/* ── Filterleiste: Zusaetze der Staffing-Achse ── */
.crm .emp-filter-lbl { font-size: .74rem; color: var(--text-3); white-space: nowrap; }
.crm .emp-filter-spacer { flex: 1 1 auto; }
.crm .emp-filter-bar .emp-filter-skill { flex: 0 1 9rem; }

/* ── Frei-Kennzeichen ── */
.crm .emp-free {
  margin-top: .75rem; padding: .7rem .8rem;
  border-radius: var(--r-md);
  border: thin solid transparent;
}
.crm .emp-free-head { display: flex; align-items: baseline; gap: .5rem; flex-wrap: wrap; }
.crm .emp-free-num { font-family: var(--f-mono); font-size: 1.6rem; font-weight: 700; line-height: 1; font-variant-numeric: tabular-nums; }
.crm .emp-free-unit { font-size: .8rem; font-weight: 600; }
.crm .emp-free-off { font-size: .92rem; font-weight: 600; }
.crm .emp-free-hint { margin-top: .3rem; font-size: .74rem; opacity: .92; }
.crm .emp-free-tent { margin-left: auto; }

.crm .emp-free-frei  { background: var(--tint-turq);   color: var(--ad-turq-900);   border-color: rgba(40, 220, 170, .25); }
.crm .emp-free-teil  { background: var(--tint-warn);   color: var(--ad-orange-900); border-color: rgba(255, 152, 104, .25); }
.crm .emp-free-voll  { background: var(--bg-surface-3); color: var(--text-2);       border-color: var(--border); }
.crm .emp-free-nicht { background: var(--bg-surface-3); color: var(--text-2);       border-color: var(--border); }
.crm.dark .emp-free-frei , html[data-theme="dark"] .crm .emp-free-frei { color: var(--ad-turq); }
.crm.dark .emp-free-teil , html[data-theme="dark"] .crm .emp-free-teil { color: var(--ad-orange); }

/* Kompakte Form fuer Tabellen- und Verfuegbarkeits-Zeilen: dieselben Farbrollen, aber als
   Pille in der Zeile statt als Block auf der Karte. */
.crm .emp-free.is-compact {
  display: inline-flex; align-items: baseline; gap: .35rem;
  margin-top: 0; padding: .15rem .5rem;
  border-radius: 99rem;
}
.crm .emp-free.is-compact .emp-free-num { font-size: .95rem; }
.crm .emp-free.is-compact .emp-free-unit { font-size: .68rem; }
.crm .emp-free.is-compact .emp-free-off { font-size: .72rem; }
.crm .emp-free-cell { display: inline-flex; align-items: center; gap: .35rem; flex-wrap: wrap; }
/* Die Pille selbst bricht nie um — nur die Vormerkung daneben darf in die zweite Zeile. */
.crm .emp-free.is-compact { white-space: nowrap; }
.crm .emp-free-cell .emp-free-tent { margin-left: 0; }

/* ── Gemeinsame Zeilenbausteine (Tabelle + Verfuegbarkeit) ── */
.crm .emp-row-name { display: inline-flex; align-items: center; gap: .55rem; min-width: 0; }
.crm .emp-row-ident { display: flex; flex-direction: column; min-width: 0; }
.crm .emp-row-sub { font-size: .68rem; color: var(--text-3); }
.crm .emp-row-load { display: inline-flex; align-items: center; gap: .5rem; }
.crm .emp-row-load .progress { width: 4rem; }
.crm .avatar.is-sm { width: 1.75rem; height: 1.75rem; font-size: .62rem; }
/* Voll verplante und nicht verfuegbare Zeilen treten zurueck — sie bleiben lesbar, ziehen
   aber den Blick nicht auf sich. Bewusst am ELTERN-Element: `opacity` auf einem Kind laesst
   sich weiter innen nicht zuruecknehmen, und das Frei-Kennzeichen soll seinen Ton behalten. */
.crm .emp-row.is-dim td .emp-row-name,
.crm .emp-row.is-dim td.muted,
.crm .emp-av-row.is-dim .emp-row-name,
.crm .emp-av-row.is-dim .emp-av-cc { opacity: .62; }

/* ── Darstellung 2: Tabelle ── */
.crm .emp-table-wrap { overflow-x: auto; }
.crm .emp-tbl thead th { white-space: nowrap; }
.crm .emp-tbl thead th.is-sorted { color: var(--ad-blue-700); border-bottom-color: var(--ad-blue); }
.crm.dark .emp-tbl thead th.is-sorted , html[data-theme="dark"] .crm .emp-tbl thead th.is-sorted { color: var(--ad-blue-300); }
.crm .emp-th-sort {
  font: inherit; color: inherit; letter-spacing: inherit; text-transform: inherit;
  display: inline-flex; align-items: center; gap: .3rem;
  background: none; border: 0; padding: 0; cursor: pointer;
}
.crm .emp-th-sort:hover { color: var(--text-1); }
.crm .emp-sort-caret { font-size: .6rem; }
.crm .emp-tbl tbody tr { cursor: pointer; }
.crm .emp-tbl .emp-td-free { padding-top: .4rem; padding-bottom: .4rem; }

/* ── Darstellung 3: nach Verfuegbarkeit ── */
.crm .emp-av { display: flex; flex-direction: column; gap: .75rem; }
.crm .emp-av-group {
  background: var(--bg-surface);
  border: thin solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-1);
  overflow: hidden;
}
.crm .emp-av-head { display: flex; align-items: center; gap: .6rem; padding: .6rem .85rem; flex-wrap: wrap; }
.crm .emp-av-title { font-family: var(--f-cond); font-size: .88rem; font-weight: 700; letter-spacing: .02em; text-transform: uppercase; }
.crm .emp-av-count { padding: .05rem .45rem; border-radius: 99rem; background: var(--bg-surface); font-size: .7rem; font-weight: 700; }
.crm .emp-av-sub { font-size: .74rem; opacity: .85; }
.crm .emp-av-spacer { flex: 1 1 auto; }
.crm .emp-av-now   { --av-ink: var(--ad-turq-900); }
.crm .emp-av-soon  { --av-ink: var(--ad-orange-900); }
.crm .emp-av-later { --av-ink: var(--text-2); }
.crm .emp-av-now  .emp-av-head { background: var(--tint-turq); color: var(--av-ink); }
.crm .emp-av-soon .emp-av-head { background: var(--tint-warn); color: var(--av-ink); }
.crm .emp-av-later .emp-av-head { background: var(--bg-surface-3); color: var(--av-ink); }
.crm.dark .emp-av-now  , html[data-theme="dark"] .crm .emp-av-now  { --av-ink: var(--ad-turq); }
.crm.dark .emp-av-soon , html[data-theme="dark"] .crm .emp-av-soon { --av-ink: var(--ad-orange); }

.crm .emp-av-row {
  display: flex; align-items: center; gap: .9rem;
  padding: .55rem .85rem;
  border-top: thin solid var(--border);
  cursor: pointer;
}
.crm .emp-av-row:hover { background: var(--bg-hover); }
.crm .emp-av-row .emp-row-name { flex: 0 0 13rem; }
.crm .emp-av-cc { flex: 0 0 11rem; font-size: .76rem; }
.crm .emp-av-free { flex: 0 0 10rem; display: flex; flex-direction: column; gap: .15rem; align-items: flex-start; }
.crm .emp-av-note { font-size: .68rem; color: var(--text-3); }
.crm .emp-av-date { flex: 1 1 auto; text-align: right; font-size: .76rem; color: var(--text-2); }

/* ── Belegungsstreifen: sechs Monate ── */
.crm .emp-strip { display: flex; gap: .18rem; flex: 0 0 auto; }
.crm .emp-strip-cell {
  position: relative; display: block;
  width: 1.6rem; height: 1.4rem;
  border-radius: var(--r-xs);
  background: var(--bg-surface-3);
  overflow: hidden;
}
/* Fest verplant und vorgemerkt sind sichtbar unterschieden — eine Vormerkung darf nicht
   wie eine Buchung aussehen (HF3.11). */
.crm .emp-strip-fest { position: absolute; left: 0; right: 0; bottom: 0; background: var(--ad-blue); opacity: .85; }
.crm .emp-strip-vor  { position: absolute; left: 0; right: 0; background: var(--ad-orange); opacity: .75; }
.crm .emp-strip.is-head { align-items: flex-end; }
.crm .emp-strip-lbl {
  width: 1.6rem; text-align: center;
  font-family: var(--f-cond); font-size: .62rem; font-weight: 600;
  letter-spacing: .02em; text-transform: uppercase;
  color: var(--text-3);
}
.crm .emp-strip-lbl.is-now { color: var(--ad-blue-700); }
.crm.dark .emp-strip-lbl.is-now , html[data-theme="dark"] .crm .emp-strip-lbl.is-now { color: var(--ad-blue-300); }
/* PR1.295 (#500) — Nebentexte im Reiter „Funktionen" (Zwilling zu style.css).
   Die Redesign-Regel fuer graue Nebentexte lautet `.crm .tbl .muted`; die
   Tabelle hier heisst aber `crm-table`, der Selektor greift also nicht. */
.crm .crm-table .muted { color: var(--text-3); }
.crm .funk-hinweis { margin-top: 0.25rem; font-size: 0.85em; color: var(--text-3); }
.crm .funk-tabelle-rahmen { overflow-x: auto; }
/* Zwei Stufen wie bei Rot (--ad-red-700/-300): --ad-orange-700 kommt auf hellem
   Grund nur auf 3,4:1 und faellt fuer 12px-Text unter AA; auf dunklem Grund ist die
   -900-Stufe zu dunkel. Deshalb je Grund die passende Stufe. */
.crm .funk-aus { color: var(--ad-orange-900); }
.crm.dark .funk-aus , html[data-theme="dark"] .crm .funk-aus { color: var(--ad-orange); }

/* ═══ PR1.307 (#516) — geheftete Auswertungen: Farben der Redesign-Shell ════════
   Struktur und Abstaende kommen aus style.css. Hier stehen nur die Toene, deren
   Legacy-Token im `.crm`-Scope gar nicht existiert (--warning, --danger, --accent)
   und die sonst ihren Dunkel-Wert auf hellen Grund erbten. */

/* --ad-orange kommt auf hellem Grund nur auf 2,6:1; fuer 11px-Grossbuchstaben gilt
   4,5:1. Auf dunklem Grund ist die -900-Stufe umgekehrt zu dunkel — deshalb zwei. */
.crm .dash-pin-marke { color: var(--ad-orange-900); }
.crm.dark .dash-pin-marke , html[data-theme="dark"] .crm .dash-pin-marke { color: var(--ad-orange); }

.crm .dash-pin-entfernen {
  border-color: var(--ad-red-700);
  color: var(--ad-red-700);
}
.crm.dark .dash-pin-entfernen , html[data-theme="dark"] .crm .dash-pin-entfernen {
  border-color: var(--ad-red-300);
  color: var(--ad-red-300);
}

.crm .dash-pin-skelett-label , .crm .dash-pin-skelett-balken { background: var(--bg-surface-3); }

.crm .sv-kachel.is-geheftet { border-color: var(--ad-blue); }
.crm.dark .sv-kachel.is-geheftet , html[data-theme="dark"] .crm .sv-kachel.is-geheftet {
  border-color: var(--ad-blue-300);
}

.crm .dash-cfg-weg:hover { border-color: var(--ad-red-700); color: var(--ad-red-700); }
.crm.dark .dash-cfg-weg:hover , html[data-theme="dark"] .crm .dash-cfg-weg:hover {
  border-color: var(--ad-red-300);
  color: var(--ad-red-300);
}

/* PR1.299 (#506) — Einzelfall-Knopf im Betriebs-Reiter.
   Zwillingsregel zu `style.css`. Unter `.crm` gescoped wie alles hier; der
   Fokusring kommt aus der generischen `.crm :focus-visible`-Regel weiter oben,
   diese Regel liefert nur den Zeigerzustand. */
.crm .ops-fall-btn:hover {
    background: var(--bg-hover) !important;
}

/* PR1.299 (#506) — gesperrter Knopf im Einzelfall-Fenster.
   „Bring mich hin" bleibt auch ohne Ziel stehen (User-Entscheid 12.09.2026) —
   dann MUSS man ihm ansehen, dass er nicht klickt. Ohne diese Regel trug er
   volle Farbe und sah aus wie jeder andere.

   Bewusst an DIESEM Knopf statt global auf `.btn:disabled`: dieselbe Abwaegung,
   die in dieser Datei schon dreimal getroffen wurde (siehe die Regeln beim
   Konvertier- und beim Freigabe-Dialog). Eine app-weite Regel wuerde jeden
   deaktivierten Knopf im Bestand umfaerben — das ist ein eigenes Ticket wert,
   nicht ein Nebeneffekt von diesem. */
.crm .ops-ef-btn:disabled {
    opacity: .5;
    cursor: not-allowed;
}
