/* ============================================================
   Alpha Power Tool — Main Stylesheet
   ============================================================ */

/* Die Schriften stehen als @font-face in variables.css — selbst gehostet.
   Hier stand bis 08/2026 ein `@import` auf fonts.googleapis.com, das die
   benutzten Schnitte 700/800 gar nicht mitlud (siehe dort). */
@import url('variables.css');

/* Reset */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
/* ⚠️ KEIN Token. Das ist die rem-Basis der Anwendung, keine Textgröße —
   `1rem` heißt hier 14px. Als `var(--text-md)` geschrieben hinge die Basis
   an einer Schriftstufe: wer die Formularschrift anpasst, skalierte
   ungewollt jeden rem-Wert mit. Die Größenmigration vom 28.08. hatte die
   Zeile mit erwischt; hier steht sie bewusst wieder fest. */
html { font-size: 14px; }
body {
  font-family: var(--font-sans);
  background: var(--color-bg);
  color: var(--color-text);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  /* ⚠️ Riegel gegen den Fehler, der bis 08/2026 auf 373 Stellen bestand:
     werden 700/800 angefordert, ohne dass es sie gibt, rechnet der Browser
     sie sich aus und schmiert die Buchstaben. Hier wird das verboten — ein
     fehlender Schnitt fällt dann sofort auf, statt still hässlich zu sein.
     Bewusst NUR die Strichstärke: Kursiv darf weiter synthetisiert werden,
     dafür gibt es an vier Stellen Bedarf und keine eigene Schriftdatei. */
  font-synthesis-weight: none;
}
a { color: inherit; text-decoration: none; }

/* ── Überschriften ────────────────────────────────────────────────────────
   Die eine Stelle, an der die Anwendung aufhört, nach Standardvorlage
   auszusehen. main.css hatte bis 08/2026 überhaupt keine h1–h6-Regel; die
   312 Überschriften der Anwendung liefen in derselben Schrift wie der
   Fließtext. Größen bleiben absichtlich ungesetzt — die stehen in den
   Vorlagen und gehören in einen eigenen Durchgang (Größenskala). */
h1, h2, h3, h4, h5, h6 { font-family: var(--font-display); }
/* Große Grade laufen sonst zu luftig. Nur h1/h2 — ab h3 sind es hier
   meist 13–15px, und da schadet Unterschneidung der Lesbarkeit. */
h1, h2 { letter-spacing: -0.011em; }

/* ⚠️ Die h1–h6-Regel allein reicht in dieser Anwendung NICHT. Sie trifft 312
   Stellen, aber viele Seiten zeichnen ihre Überschrift als <div> mit eigener
   Klasse aus — das Dashboard hat kein einziges Überschriften-Element. Eine
   einheitliche Konvention dafür ist ein eigener Durchgang; bis dahin sind
   hier die beiden app-weiten Bauteile ergänzt und `.apt-display` steht als
   Auszeichnung für alles Weitere bereit. */
.card-title { font-family: var(--font-display); }
.apt-display { font-family: var(--font-display); }
/* ⚠️ Bedienelemente erben die Schriftgröße NICHT — sie fallen sonst auf die
   Vorgabe des Browsers zurück (in Chromium 13,333px). Hier stand bis 08/2026
   nur die Familie, weshalb jeder Knopf ohne eigene Größenangabe knapp neben
   der Skala lag. Gefunden beim Nachmessen im Browser, nicht im Markup: im
   Quelltext steht an diesen Stellen gar nichts. */
button { cursor: pointer; font-family: var(--font-sans); font-size: var(--text-base); }
input, select, textarea { font-family: var(--font-sans); font-size: var(--text-base); }

/* ============================================================
   Layout
   ============================================================ */
.apt-layout {
  display: flex;
  height: 100vh;
  overflow: hidden;
}

/* ============================================================
   Sidebar — ausklappbar mit Pin-Funktion
   ============================================================ */
.apt-sidebar {
  width: var(--sidebar-width);
  background: var(--color-sidebar);
  border-right: 0.5px solid var(--color-border);
  display: flex;
  flex-direction: column;
  flex-shrink: 0;
  overflow-y: auto;
  overflow-x: hidden;
  transition: transform 0.25s ease, width 0.25s ease;
  z-index: 200;
  /* --sb-text-2/3/4 kommen aus variables.css (je Palette definiert) */
}

/* Overlay (Mobile) */
.sb-overlay {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.55);
  z-index: 199;
}
.sb-overlay.active { display: block; }

/* Mobile/Desktop-Modus wird per JS über die kleinere Bildschirmseite bestimmt
   (Klasse html.viewport-mobile, siehe base.html <head>) statt reiner Breite —
   ein Handy im Querformat bleibt so zuverlässig im Mobile-Drawer-Modus. */

/* Mobile: Sidebar als Drawer von links */
html.viewport-mobile .apt-sidebar {
  position: fixed;
  top: 0; left: 0; bottom: 0;
  width: var(--sidebar-width) !important;
  transform: translateX(-100%);
  box-shadow: 4px 0 20px rgba(0,0,0,0.5);
  /* Aus dem Flex-Flow nehmen */
  flex-shrink: 0;
  margin-right: -220px;
}
html.viewport-mobile .apt-layout.sb-open .apt-sidebar {
  transform: translateX(0);
}
html.viewport-mobile .apt-layout.sb-open .sb-overlay {
  display: block;
}
html.viewport-mobile .apt-main {
  width: 100%;
  min-width: 0;
}
/* Topbar auf Mobile: genug Platz für Hamburger */
html.viewport-mobile .apt-topbar {
  padding: 0 12px;
  gap: 8px;
}

/* Desktop/Tablet: Sidebar kollabierbar, aber kein Overlay */
html:not(.viewport-mobile) .apt-layout.sb-collapsed .apt-sidebar {
  width: 0;
  border-right: none;
  overflow: hidden;
}
/* Pinned = immer sichtbar, kein Collapse */
html:not(.viewport-mobile) .apt-layout.sb-pinned .apt-sidebar {
  transform: none !important;
  width: var(--sidebar-width) !important;
}

.apt-sidebar::-webkit-scrollbar { width: 3px; }
.apt-sidebar::-webkit-scrollbar-track { background: transparent; }
.apt-sidebar::-webkit-scrollbar-thumb { background: var(--tint-4); border-radius: var(--radius-sm); }

.sidebar-logo {
  padding: 18px 18px 14px;
  border-bottom: 0.5px solid var(--color-border);
  flex-shrink: 0;
  text-align: center;
}
.sidebar-logo-text {
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--color-accent);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.sidebar-logo-sub {
  font-size: var(--text-2xs);
  color: var(--sb-text-4);
  margin-top: 2px;
}

/* ── Suche (⌘K / Strg+K) ──────────────────────────────────────── */
.sb-search {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 12px 10px 4px;
  padding: 7px 9px;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  color: var(--sb-text-3);
  font-size: var(--text-sm);
  cursor: pointer;
  transition: var(--transition);
}
.sb-search:hover { border-color: var(--color-border-hover); color: var(--sb-text-2); }
.sb-search i { font-size: var(--text-base); flex-shrink: 0; }
.sb-search span { flex: 1; }
.sb-kbd {
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  color: var(--sb-text-4);
  background: var(--color-surface-2);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  padding: 1px 5px;
  flex-shrink: 0;
}

/* ── Favoriten (jetzt Teil von "Übersicht & Favoriten", kein eigener Block mehr) ── */
.sb-fav-empty {
  font-size: var(--text-xs);
  color: var(--sb-text-4);
  padding: 6px 8px;
  font-style: italic;
}

.sidebar-section {
  padding: 10px 10px 4px;
}
.sidebar-section-label {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--sb-text-3);
  padding: 5px 8px;
  margin-bottom: 2px;
  border-radius: var(--radius-md);
  cursor: pointer;
  user-select: none;
  transition: var(--transition);
}
.sidebar-section-label:hover { background: var(--tint-1); color: var(--sb-text-2); }
.sidebar-item {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 6px 8px;
  border-radius: var(--radius-md);
  color: var(--sb-text-3);
  font-size: var(--text-base);
  margin-bottom: 1px;
  transition: all var(--transition);
  cursor: pointer;
  position: relative;
}
.sidebar-item:hover {
  background: var(--tint-2);
  color: var(--sb-text-2);
}
.sidebar-item.active {
  background: var(--color-accent-dim);
  /* ⚠️ Schrift, nicht Fläche: --color-accent auf der eigenen Tönung ergibt im
     Hellmodus 1,48:1. --color-accent-text ist im Dunkeln derselbe Wert. */
  color: var(--color-accent-text);
}
.sidebar-item i { font-size: var(--text-lg); flex-shrink: 0; }
.sidebar-item .itemtext { flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* Farbige Icon-Chips je Modul — nutzt die längst vorhandenen --color-mod-*-Töne,
   die vorher im Menü gar nicht verwendet wurden. Farbe kommt als Inline-Style
   (style="--chip:...") direkt am .sb-chip-Element in base.html. */
.sb-chip {
  width: 21px;
  height: 21px;
  border-radius: var(--radius-md);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  background: var(--chip-bg, var(--tint-3));
}
.sb-chip i { font-size: var(--text-base); color: var(--chip-fg, var(--sb-text-2)); }
.sidebar-item.active .sb-chip { background: var(--color-accent-mid) !important; }
.sidebar-item.active .sb-chip i { color: var(--color-accent-text) !important; }

/* Anpinnen-Stern je Menüpunkt (Favoriten) */
.sb-star {
  opacity: 0;
  font-size: var(--text-base) !important;
  color: var(--sb-text-4) !important;
  flex-shrink: 0;
  transition: var(--transition);
  padding: 2px;
}
.sidebar-item:hover .sb-star { opacity: .7; }
.sb-star:hover { opacity: 1 !important; color: var(--color-accent) !important; }
.sb-star.pinned { opacity: 1; color: var(--color-accent) !important; }

/* Sichtbarer, aber noch nicht verlinkter Menüpunkt (z.B. "Verträge" — bewusst nicht
   ausgeblendet, Umsetzung folgt). Kein <a>, daher kein hover/active-Zustand nötig. */
.sidebar-item-soon { opacity: .62; cursor: default; }
.sb-soon-badge {
  font-size: var(--text-2xs);
  font-weight: 700;
  letter-spacing: .03em;
  text-transform: uppercase;
  /* ⚠️ --color-warning ist im Dunkeln #BA7517 und ergab auf der eigenen
     Tönung nur 2,96:1 bei 9,5px Schriftgröße. --color-warn-text ist genau für
     diesen Fall da: im Dunkeln hell, im Hellen dunkel. */
  color: var(--color-warn-text);
  background: var(--color-warn-dim);
  border-radius: var(--radius-full);
  padding: 1px 7px;
  flex-shrink: 0;
}

/* Einklappbares Menü */
.sb-chev {
  font-size: var(--text-sm);
  color: var(--sb-text-4);
  transition: transform 0.2s ease;
  flex-shrink: 0;
}
.sidebar-section[data-sb].sb-collapsed .sb-chev {
  transform: rotate(-90deg);
}
/* ⚠️ Hier stand `max-height: 500px`. Das schneidet einen Block ohne jede
   Warnung hart ab, sobald er höher wird — der Superadmin-Block lag mit elf
   Einträgen knapp darunter. `grid-template-rows: 1fr → 0fr` klappt dieselbe
   Animation, aber ohne Deckel und ohne JavaScript. */
.sb-items {
  display: grid;
  grid-template-rows: 1fr;
  transition: grid-template-rows 0.25s ease, opacity 0.2s ease;
  opacity: 1;
}
.sb-items > * { min-height: 0; }
.sidebar-section[data-sb].sb-collapsed .sb-items {
  grid-template-rows: 0fr;
  opacity: 0;
  pointer-events: none;
}

/* ── Ebenen des Menüs ──────────────────────────────────────────────────────
   Module / Einstellungen / Admin liegen im selben Menü und werden getauscht,
   statt ein zweites Navigationsband aufzumachen. Welche Ebene offen ist,
   entscheidet der Server (siehe base.html) — der Klick schaltet nur um. */
.sb-ebene { display: none; }
.sb-ebene.aktiv { display: block; }

.sb-ebene-zurueck {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 10px 10px 2px;
  padding: 7px 8px;
  border-radius: var(--radius-md);
  font-size: var(--text-sm);
  color: var(--sb-text-3);
  cursor: pointer;
  user-select: none;
  transition: var(--transition);
}
.sb-ebene-zurueck:hover { background: var(--tint-1); color: var(--sb-text-2); }

.sb-fuss-punkt {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 8px 10px;
  margin-top: 2px;
  border-radius: var(--radius-md);
  font-size: var(--text-base);
  color: var(--sb-text-2);
  cursor: pointer;
  user-select: none;
  transition: var(--transition);
}
.sb-fuss-punkt:hover { background: var(--tint-2); }
.sb-fuss-punkt.aktiv { background: var(--color-accent-dim); color: var(--color-accent-text); }
.sb-fuss-chev { margin-left: auto; font-size: var(--text-base); opacity: 0.4; }
.sb-fuss-punkt.aktiv .sb-fuss-chev { opacity: 0.8; }

/* Der Standard-Chip für Verwaltungspunkte — ersetzt den bis 08/2026
   wiederholten Inline-Stil `--chip-bg:var(--color-surface-3)`. */
.sb-chip-neutral { --chip-bg: var(--color-surface-3); }

/* Handy: Touch-Ziele ≥44px */
@media (max-width: 768px) {
  .sb-fuss-punkt, .sb-ebene-zurueck { min-height: 44px; }
  /* ⚠️ Gemessen 25.08.2026: auf dem Handy ist die Seitenleiste eine Schublade
     und ihre Einträge waren mit 33px (Menüpunkt), 26,5px (Kategorie), 28px
     (Sprachauswahl) und 40px (Umschalter) unter der Projektvorgabe von 44px.
     Nur hier angehoben — auf dem Desktop bleibt die Dichte, wie sie ist. */
  .sidebar-item, .sidebar-section-label { min-height: 44px; box-sizing: border-box; }
  .lang-select, .theme-btn, .sb-toggle-btn { min-height: 44px; }
}

.sidebar-divider {
  height: 0.5px;
  background: var(--color-border);
  margin: 8px 14px;
}

.sidebar-bottom {
  margin-top: auto;
  padding: 10px;
  border-top: 0.5px solid var(--color-border);
  flex-shrink: 0;
}
.sidebar-user {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 8px 10px;
  border-radius: var(--radius-md);
  cursor: pointer;
  transition: background var(--transition);
}
.sidebar-user:hover { background: var(--tint-2); }
.user-avatar {
  width: 28px;
  height: 28px;
  border-radius: var(--radius-full);
  background: var(--color-accent-dim);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--color-accent-text);
  flex-shrink: 0;
}
.user-name { font-size: var(--text-sm); color: var(--sb-text-2); }
.user-role { font-size: var(--text-2xs); color: var(--sb-text-4); }

/* ── Kommandopalette (⌘K / Strg+K) ───────────────────────────────
   App-weites Overlay, durchsucht alle aktuell im Menü gerenderten
   .sidebar-item-Links (rollenabhängig — zeigt also nur, was der
   jeweilige Benutzer ohnehin sehen darf). */
.cmdk-overlay {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.55);
  z-index: 500;
  align-items: flex-start;
  justify-content: center;
  padding-top: 12vh;
}
.cmdk-overlay.open { display: flex; }
.cmdk-box {
  width: 480px;
  max-width: 90vw;
  background: var(--color-surface);
  border: 1px solid var(--color-border-hover);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
}
.cmdk-box input {
  width: 100%;
  background: transparent;
  border: none;
  border-bottom: 1px solid var(--color-border);
  padding: 14px 16px;
  color: var(--color-text);
  font-size: var(--text-md);
  font-family: var(--font-sans);
  outline: none;
}
.cmdk-box input::placeholder { color: var(--color-text-4); }
.cmdk-results { max-height: 320px; overflow-y: auto; padding: 6px; }
.cmdk-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  border-radius: var(--radius-md);
  font-size: var(--text-base);
  color: var(--color-text-2);
  cursor: pointer;
}
.cmdk-item i { font-size: var(--text-md); opacity: .85; flex-shrink: 0; }
.cmdk-item:hover, .cmdk-item.sel { background: var(--color-accent-dim); color: var(--color-accent); }
.cmdk-item .cmdk-grp { margin-left: auto; font-size: var(--text-2xs); color: var(--color-text-4); }
.cmdk-empty { padding: 18px; font-size: var(--text-sm); color: var(--color-text-4); text-align: center; }

/* ============================================================
   Main Content Area
   ============================================================ */
.apt-main {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

/* Hamburger-Button */
.sb-toggle-btn {
  background: none;
  border: none;
  color: var(--color-text-2);
  cursor: pointer;
  padding: 6px 8px;
  border-radius: var(--radius-sm);
  font-size: var(--text-2xl);
  display: flex;
  align-items: center;
  flex-shrink: 0;
  transition: color var(--transition), background var(--transition);
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}
.sb-toggle-btn:hover { color: var(--color-accent); background: var(--tint-3); }
html.viewport-mobile .sb-toggle-btn {
  font-size: var(--text-3xl);
  padding: 8px 10px;
  color: var(--color-text);
  min-width: 40px;
  min-height: 40px;
  justify-content: center;
}

/* Pin-Button in Sidebar-Logo */
.sidebar-logo { position: relative; }
.sb-pin-btn {
  position: absolute;
  top: 8px; right: 8px;
  background: none;
  border: none;
  color: var(--color-text-4);
  cursor: pointer;
  padding: 4px;
  border-radius: var(--radius-sm);
  font-size: var(--text-md);
  display: none; /* nur Desktop */
  transition: color var(--transition);
}
.sb-pin-btn:hover { color: var(--color-accent); }
.sb-pin-btn.pinned { color: var(--color-accent); }
html:not(.viewport-mobile) .sb-pin-btn { display: flex; align-items: center; }

/* ============================================================
   Topbar
   ============================================================ */
.apt-topbar {
  height: var(--topbar-height);
  background: var(--color-surface);
  border-bottom: 0.5px solid var(--color-border);
  display: flex;
  align-items: center;
  padding: 0 var(--space-6);
  gap: var(--space-3);
  flex-shrink: 0;
}
.topbar-title {
  font-size: var(--text-base);
  font-weight: 500;
  color: var(--color-text);
}
.topbar-right {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: var(--space-2);
}
.lang-select {
  background: var(--color-surface-2);
  border: 0.5px solid var(--color-border);
  color: var(--color-accent);
  font-size: var(--text-xs);
  font-family: var(--font-sans);
  padding: 5px 10px;
  border-radius: var(--radius-md);
  cursor: pointer;
  outline: none;
  transition: border-color var(--transition);
}
.lang-select:hover { border-color: var(--color-accent-mid); }

/* Farbschema-Schalter — steht links neben der Sprachauswahl */
.theme-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 26px; padding: 0;
  background: var(--color-surface-2);
  border: 0.5px solid var(--color-border);
  color: var(--color-accent-text);
  border-radius: var(--radius-md);
  cursor: pointer; flex-shrink: 0;
  transition: border-color var(--transition), color var(--transition);
}
.theme-btn i { font-size: var(--text-lg); }
.theme-btn:hover { border-color: var(--color-accent-mid); }
.theme-btn:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 2px; }
/* Auf dem Handy das Touch-Mindestmaß des Projekts einhalten */
html.viewport-mobile .theme-btn { width: 44px; height: 40px; }

/* ============================================================
   Content
   ============================================================ */
.apt-content {
  flex: 1;
  padding: var(--space-6);
  overflow-y: auto;
  background: var(--color-surface);
}
.apt-content::-webkit-scrollbar { width: 4px; }
.apt-content::-webkit-scrollbar-thumb { background: var(--tint-4); border-radius: var(--radius-sm); }

/* ============================================================
   Section Labels
   ============================================================ */
.section-label {
  font-size: var(--text-2xs);
  color: var(--color-text-4);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  margin-bottom: var(--space-3);
}

/* ============================================================
   App Cards / Kacheln
   ============================================================ */
.app-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: var(--space-3);
  margin-bottom: var(--space-6);
}
.app-card {
  background: var(--color-surface-2);
  border: 0.5px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
  cursor: pointer;
  transition: all var(--transition);
  text-decoration: none;
  display: block;
}
.app-card:hover {
  border-color: var(--color-border-hover);
  background: var(--color-surface-3);
  transform: translateY(-1px);
  box-shadow: var(--shadow-md);
}
.app-card.disabled {
  opacity: 0.5;
  cursor: not-allowed;
  pointer-events: none;
}
.app-icon {
  width: 34px;
  height: 34px;
  border-radius: var(--radius-md);
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: var(--space-3);
  font-size: var(--text-xl);
}
.app-name {
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--color-text);
  margin-bottom: 2px;
}
.app-desc {
  font-size: var(--text-2xs);
  color: var(--color-text-4);
  line-height: 1.4;
}
.app-badge {
  display: inline-block;
  font-size: var(--text-2xs);
  padding: 2px 7px;
  border-radius: var(--radius-sm);
  margin-top: var(--space-2);
}
.badge-active { background: var(--color-accent-dim); color: var(--color-accent); }
.badge-soon   { background: var(--tint-2); color: var(--color-text-4); }
.badge-beta   { background: var(--color-info-dim); color: var(--color-info); }

/* ============================================================
   Stats Cards
   ============================================================ */
.stats-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
  gap: var(--space-3);
  margin-bottom: var(--space-6);
}
.stat-card {
  background: var(--color-surface-2);
  border: 0.5px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-4);
}
.stat-label {
  font-size: var(--text-2xs);
  color: var(--color-text-4);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  margin-bottom: var(--space-1);
}
.stat-value {
  font-size: var(--text-3xl);
  font-weight: 500;
  color: var(--color-text);
  line-height: 1.2;
}
.stat-sub {
  font-size: var(--text-2xs);
  color: var(--color-accent);
  margin-top: 3px;
  opacity: 0.8;
}

/* ============================================================
   Buttons
   ============================================================ */
.btn {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: 7px 14px;
  border-radius: var(--radius-md);
  font-size: var(--text-sm);
  font-weight: 500;
  border: none;
  transition: all var(--transition);
  cursor: pointer;
  white-space: nowrap;
}
.btn-primary {
  background: var(--color-accent);
  color: #000000;
}
.btn-primary:hover { background: #d4df00; box-shadow: 0 0 12px rgba(200,211,0,0.3); }
.btn-secondary {
  background: var(--color-surface-2);
  color: var(--color-text-2);
  border: 0.5px solid var(--color-border);
}
.btn-secondary:hover { background: var(--color-surface-3); color: var(--color-text); }
.btn-danger {
  background: var(--color-danger-dim);
  color: var(--color-danger);
  border: 0.5px solid rgba(216,90,48,0.2);
}
.btn-danger:hover { background: rgba(216,90,48,0.2); }
.btn-sm { padding: 5px 10px; font-size: var(--text-xs); }
.btn-lg { padding: 10px 20px; font-size: var(--text-base); }
.btn-icon { width: 32px; height: 32px; padding: 0; justify-content: center; }

/* ============================================================
   Forms
   ============================================================ */
.form-group { margin-bottom: var(--space-4); }
.form-label {
  display: block;
  font-size: var(--text-xs);
  color: var(--color-text-3);
  margin-bottom: var(--space-2);
  font-weight: 500;
}
.form-input {
  width: 100%;
  background: var(--color-surface-2);
  border: 0.5px solid var(--color-border);
  border-radius: var(--radius-md);
  color: var(--color-text);
  font-size: var(--text-base);
  font-family: var(--font-sans);
  padding: 9px 12px;
  transition: border-color var(--transition);
  outline: none;
}
.form-input:focus { border-color: var(--color-accent-mid); }
.form-input::placeholder { color: var(--color-text-4); }
.form-select {
  width: 100%;
  background: var(--color-surface-2);
  border: 0.5px solid var(--color-border);
  border-radius: var(--radius-md);
  color: var(--color-text);
  font-size: var(--text-base);
  font-family: var(--font-sans);
  padding: 9px 12px;
  outline: none;
  cursor: pointer;
}
.form-select:focus { border-color: var(--color-accent-mid); }

/* ============================================================
   Tables
   ============================================================ */
.apt-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--text-sm);
}
.apt-table th {
  text-align: left;
  padding: 8px 12px;
  font-size: var(--text-2xs);
  font-weight: 500;
  color: var(--color-text-4);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  border-bottom: 0.5px solid var(--color-border);
}
.apt-table td {
  padding: 10px 12px;
  border-bottom: 0.5px solid var(--color-border);
  color: var(--color-text-2);
}
.apt-table tr:hover td { background: var(--tint-1); }
.apt-table tr:last-child td { border-bottom: none; }

/* ============================================================
   Cards
   ============================================================ */
.card {
  background: var(--color-surface-2);
  border: 0.5px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
}
.card-title {
  font-size: var(--text-base);
  font-weight: 500;
  color: var(--color-text);
  margin-bottom: var(--space-4);
}

/* ============================================================
   Badges / Status
   ============================================================ */
.status { display: inline-flex; align-items: center; gap: 5px; font-size: var(--text-xs); padding: 3px 8px; border-radius: var(--radius-sm); }
.status-dot { width: 5px; height: 5px; border-radius: var(--radius-full); }
.status-active  { background: var(--color-success-dim); color: var(--color-success); }
.status-pending { background: var(--color-warning-dim); color: var(--color-warning); }
.status-error   { background: var(--color-danger-dim);  color: var(--color-danger);  }

/* ============================================================
   KI Chat Widget (Global)
   ============================================================ */
.ai-chat-btn {
  position: fixed;
  bottom: 24px;
  right: 24px;
  width: 46px;
  height: 46px;
  background: var(--color-accent);
  border: none;
  border-radius: var(--radius-full);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  box-shadow: 0 4px 16px rgba(200,211,0,0.4);
  transition: all var(--transition);
  z-index: 100;
  font-size: var(--text-2xl);
  color: #000;
}
.ai-chat-btn:hover {
  transform: scale(1.08);
  box-shadow: 0 6px 20px rgba(200,211,0,0.5);
}
.ai-chat-panel {
  position: fixed;
  bottom: 82px;
  right: 24px;
  width: 340px;
  height: 440px;
  background: var(--color-sidebar);
  border: 0.5px solid var(--color-border);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-lg);
  display: flex;
  flex-direction: column;
  z-index: 100;
  overflow: hidden;
  display: none;
}
.ai-chat-panel.open { display: flex; }
.ai-chat-header {
  padding: 14px 16px;
  border-bottom: 0.5px solid var(--color-border);
  display: flex;
  align-items: center;
  gap: 10px;
}
.ai-chat-avatar {
  width: 28px;
  height: 28px;
  background: var(--color-accent-dim);
  border-radius: var(--radius-full);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--text-md);
  color: var(--color-accent);
}
.ai-chat-title { font-size: var(--text-sm); font-weight: 500; color: var(--color-text); }
.ai-chat-sub { font-size: var(--text-2xs); color: var(--color-text-4); }
.ai-chat-close { margin-left: auto; background: none; border: none; color: var(--color-text-3); font-size: var(--text-xl); cursor: pointer; }
.ai-chat-messages {
  flex: 1;
  padding: 14px;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.ai-msg { max-width: 85%; font-size: var(--text-sm); line-height: 1.5; padding: 9px 12px; border-radius: var(--radius-lg); }
.ai-msg-user { background: var(--color-accent-dim); color: var(--color-text); align-self: flex-end; border-radius: var(--radius-lg) var(--radius-lg) 4px var(--radius-lg); }
.ai-msg-bot { background: var(--color-surface-2); color: var(--color-text-2); align-self: flex-start; border-radius: var(--radius-lg) var(--radius-lg) var(--radius-lg) 4px; }
.ai-chat-input-row {
  padding: 12px;
  border-top: 0.5px solid var(--color-border);
  display: flex;
  gap: 8px;
}
.ai-chat-input {
  flex: 1;
  background: var(--color-surface-2);
  border: 0.5px solid var(--color-border);
  border-radius: var(--radius-md);
  color: var(--color-text);
  font-size: var(--text-sm);
  font-family: var(--font-sans);
  padding: 8px 12px;
  outline: none;
  resize: none;
}
.ai-chat-input:focus { border-color: var(--color-accent-mid); }
.ai-send-btn {
  width: 32px;
  height: 32px;
  background: var(--color-accent);
  border: none;
  border-radius: var(--radius-md);
  color: #000;
  font-size: var(--text-md);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  flex-shrink: 0;
  align-self: flex-end;
}

/* ============================================================
   Alerts / Notifications
   ============================================================ */
.alert {
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  font-size: var(--text-sm);
  margin-bottom: var(--space-4);
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
}
.alert-success { background: var(--color-success-dim); color: var(--color-success); border: 0.5px solid rgba(29,158,117,0.2); }
.alert-warning { background: var(--color-warning-dim); color: var(--color-warning); border: 0.5px solid rgba(186,117,23,0.2); }
/* ⚠️ `error` und `danger` sind DASSELBE. Der Code ruft `flash(…, 'error')`
   82-mal auf, `'danger'` 94-mal — beide Schreibweisen sind gewachsen. Ohne
   diese Zeile blieb jede der 82 Fehlermeldungen ungestylt: sie stand als
   farbloser Kasten mit blauem Info-Symbol da und war von einem Hinweis nicht
   zu unterscheiden. Genau daran wirkte es, als „passiere nichts", wenn das
   Aufgabenformular das Abschließen ablehnte.
   Ein Test hält jede benutzte Kategorie gegen die hier definierten Klassen. */
.alert-danger,
.alert-error   { background: var(--color-danger-dim);  color: var(--color-danger);  border: 0.5px solid rgba(216,90,48,0.2); }
.alert-info    { background: var(--color-info-dim);    color: var(--color-info);    border: 0.5px solid rgba(55,138,221,0.2); }

/* ============================================================
   Utilities
   ============================================================ */
.flex { display: flex; }
.flex-col { flex-direction: column; }
.items-center { align-items: center; }
.justify-between { justify-content: space-between; }
.gap-2 { gap: var(--space-2); }
.gap-3 { gap: var(--space-3); }
.gap-4 { gap: var(--space-4); }
.mb-4 { margin-bottom: var(--space-4); }
.mb-6 { margin-bottom: var(--space-6); }
.mt-auto { margin-top: auto; }
.text-accent { color: var(--color-accent); }
.text-muted { color: var(--color-text-3); }
.text-sm { font-size: var(--text-xs); }
.text-xs { font-size: var(--text-2xs); }
.font-medium { font-weight: 500; }
.w-full { width: 100%; }
.hidden { display: none !important; }

/* ═══════════════════════════════════════════════════════════════════════════
   Arbeitsliste (.wl-*) — gemeinsames Bauteil für Mail-Pilot-Briefing und die
   Kästen der PM-Startseite.

   Beide zeigten dasselbe: eine nach Dringlichkeit gruppierte Liste von Dingen,
   die auf eine Entscheidung warten. Die Stile lagen doppelt inline in
   briefing.html (.mp-briefing-*) und woche.html (.pw-karte) und waren dadurch
   fürs jeweils andere Modul unerreichbar.

   Der Breakpoint ist bewusst 768px statt der früheren 600px des Briefings —
   als gemeinsames Bauteil muss es der Projektkonvention folgen.
   ═════════════════════════════════════════════════════════════════════════ */

.wl-kopf {
  display: flex; align-items: center; gap: 6px;
  font-size: var(--text-sm); font-weight: 600; text-transform: uppercase; letter-spacing: .5px;
  margin: 18px 0 8px; color: var(--color-text-2b);
}
.wl-kopf:first-child { margin-top: 0; }
.wl-kopf.warn { color: var(--color-err-text); }
.wl-count {
  background: var(--color-surface); color: var(--color-text-4b); font-size: var(--text-2xs); font-weight: 700;
  padding: 1px 6px; border-radius: var(--radius-lg); text-transform: none; letter-spacing: 0;
  margin-left: auto;
}
.wl-liste { background: var(--color-card); border: 1px solid var(--color-surface); border-radius: var(--radius-md); overflow: hidden; }
.wl-item {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 10px 14px; border-bottom: 1px solid var(--color-card-2); text-decoration: none;
  transition: background .1s;
}
.wl-item:last-child { border-bottom: none; }
.wl-item:hover { background: var(--color-sidebar); }
.wl-item-main { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }
.wl-item-main strong { color: var(--color-text-1b); font-size: var(--text-base); }
.wl-betreff { color: var(--color-text-2b); font-size: var(--text-base); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.wl-zsf { color: var(--color-text-5); font-size: var(--text-sm); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.wl-zeit { color: var(--color-text-5); font-size: var(--text-xs); white-space: nowrap; flex-shrink: 0; }
.wl-leer { text-align: center; padding: 40px 20px; }
.wl-aktionen { display: flex; gap: 6px; flex-shrink: 0; }
.wl-btn {
  background: var(--color-surface); border: 1px solid var(--color-surface-3); color: var(--color-text-3b); cursor: pointer;
  border-radius: var(--radius-md); padding: 5px 9px; font-size: var(--text-xs); line-height: 1;
  display: inline-flex; align-items: center; gap: 4px; white-space: nowrap;
}
.wl-btn:hover { border-color: var(--color-accent-text); color: var(--color-accent-text); }
.wl-btn[disabled] { opacity: .5; cursor: default; }
.wl-mehr { font-size: var(--text-xs); color: var(--color-text-5); margin-top: 6px; }

@media (max-width: 768px) {
  .wl-zeit { display: none; }
  .wl-item { flex-wrap: wrap; }
  .wl-btn { padding: 9px 12px; font-size: var(--text-sm); }   /* Touch-Ziel */
}


/* ── Logo je Farbschema ───────────────────────────────────────────────────
   Zwei Dateien statt einer Umfärbung: das Logo ist mehrfarbig (Fingerabdruck
   grau, „brand.eu" lime, Rest schwarz bzw. weiß) — ein CSS-Filter träfe alle
   Teile gleich und zerstörte die Marke. */
.sidebar-logo img { max-width: 138px; width: 100%; height: auto; display: block; margin: 0 auto 8px; }
.sidebar-logo .logo-fuer-hell { display: none; }
:root[data-theme="hell"] .sidebar-logo .logo-fuer-dunkel { display: none; }
:root[data-theme="hell"] .sidebar-logo .logo-fuer-hell   { display: block; }
@media (prefers-color-scheme: light) {
  :root[data-theme="auto"] .sidebar-logo .logo-fuer-dunkel { display: none; }
  :root[data-theme="auto"] .sidebar-logo .logo-fuer-hell   { display: block; }
}

/* ── Reklamations-Ablauf (Zeitleiste) ──────────────────────────────────────
   Genutzt von der Reklamations-Detailseite und vom Reklamations-Reiter der
   Kundenkartei — deshalb zentral hier statt in einem der beiden Templates. */
.rk-ablauf { display:flex; flex-direction:column; gap:2px; }
.rk-ablauf-zeile { display:flex; gap:12px; align-items:flex-start; padding:6px 0; position:relative; }
.rk-ablauf-zeile:not(:last-child)::before {
  content:''; position:absolute; left:13px; top:34px; bottom:-6px; width:1px;
  background:var(--color-surface-3);
}
.rk-ablauf-marke {
  width:27px; height:27px; border-radius: var(--radius-full); border:1px solid; flex:0 0 auto;
  display:flex; align-items:center; justify-content:center; font-size: var(--text-md);
  background:var(--color-card); position:relative; z-index:1;
}
.rk-ablauf-inhalt { flex:1; min-width:0; padding-top:3px; }
.rk-ablauf-kopf { display:flex; gap:10px; align-items:baseline; flex-wrap:wrap; }
.rk-ablauf-text { font-size: var(--text-base); color:var(--color-text-1b); font-weight:600; }
.rk-ablauf-zeit { font-size: var(--text-xs); color:var(--color-text-5); white-space:nowrap; }
.rk-ablauf-detail { font-size: var(--text-sm); color:var(--color-text-3b); margin-top:2px; white-space:pre-wrap; word-break:break-word; }
.rk-ablauf-user { font-size: var(--text-xs); color:var(--color-text-5); margin-top:2px; }

/* ── Art einer PM-Aufgabe: Farbe je Art ────────────────────────────────────
   Die Grundfarbe kommt als `--pm-art-farbe` aus PmBoardTyp.farbe. Fläche und
   Rahmen bleiben in beiden Designs dezent; im hellen Design wird der Text
   abgedunkelt, weil ein mittelheller Farbton auf Weiß sonst unlesbar ist
   (dieselbe Überlegung wie beim Akzent in variables.css). Ohne Farbe
   (Altbestand) greift überall der bisherige Akzent-Look. */
.pm-art-chip {
  font-size: var(--text-2xs); padding: 2px 7px; border-radius: var(--radius-md); font-weight: 600;
  display: inline-flex; align-items: center; gap: 4px;
  background: color-mix(in srgb, var(--pm-art-farbe, #c8d300) 14%, transparent);
  color: var(--pm-art-farbe, var(--color-accent-text));
  border: 1px solid color-mix(in srgb, var(--pm-art-farbe, #c8d300) 30%, transparent);
}
.pm-art-chip i { font-size: var(--text-sm); }
:root[data-theme="hell"] .pm-art-chip {
  color: color-mix(in srgb, var(--pm-art-farbe, #666d00) 62%, #000);
}
@media (prefers-color-scheme: light) {
  :root[data-theme="auto"] .pm-art-chip {
    color: color-mix(in srgb, var(--pm-art-farbe, #666d00) 62%, #000);
  }
}

/* ── Hülle des Admin-Bereichs (admin/shell.html) ───────────────────────────
   Bewusst hier und nicht in der Vorlage: Die Modul-Einstellungsseiten, die in
   die Hülle umgezogen sind, belegen `extra_css` mit ihrem eigenen CSS. Läge
   das Hüllen-CSS dort, verschwände es bei genau diesen Seiten. */
.ab-inhalt { max-width: 1100px; }

.ab-pfad { display: flex; align-items: center; gap: 6px; font-size: var(--text-sm);
           color: var(--color-text-4b); margin-bottom: var(--space-2); }
.ab-pfad a { color: var(--color-text-3b); text-decoration: none; }
.ab-pfad a:hover { color: var(--color-accent-text); }

.ab-kopf { margin-bottom: var(--space-5); padding-bottom: var(--space-4);
           border-bottom: 0.5px solid var(--color-border); }
.ab-kopf h1 { font-size: var(--text-2xl); font-weight: 600; color: var(--color-text); margin: 0 0 5px; }
.ab-kopf p { font-size: var(--text-base); color: var(--color-text-3b); margin: 0;
             max-width: 62ch; line-height: 1.5; }

@media (max-width: 768px) {
  .ab-kopf h1 { font-size: var(--text-xl); }
}


/* ══════════════════════════════════════════════════════════════════════════
   Trefferflächen am Telefon (27.08.2026)
   ══════════════════════════════════════════════════════════════════════════
   Gemessen auf 390px über 22 Modulseiten: **keine einzige lief über den
   Rand** — die Grundlagen stimmen also. Zu klein zum Antippen waren dagegen
   vier Muster, zusammen rund 190 Bedienelemente:

     50× Auswahlkästchen der Mail-Sortierung   18×18
     50× Symbolknöpfe daneben                  35×30
     24× Zeilenaktionen der Verträge           22×29
      4× KPI-Filterknöpfe der Kundenliste      22×22

   Apples und Googles Richtwert ist 44px; alles darunter trifft man mit dem
   Daumen im Auto nicht zuverlässig.

   ⚠️ Bewusst NICHT angefasst: die Bedienelemente von FullCalendar im
   Terminkalender (`.fc-*`, Tageszahlen 15–23px, Termin-Chips 8px breit) und
   die von Leaflet auf den Karten. Fremdcode — wer dort an den Maßen dreht,
   verschiebt das Raster, und der nächste Bibliotheks-Sprung macht es wieder
   zunichte. Dieselbe Entscheidung wie beim Browser-Durchgang am 26.08.
   ══════════════════════════════════════════════════════════════════════════ */
@media (max-width: 768px) {
  /* Auswahlkästchen: das Kästchen selbst wächst, sonst bleibt die
     Trefferfläche klein, egal wie viel Polster ringsum liegt. */
  .apt-content input[type="checkbox"],
  .apt-content input[type="radio"] {
    width: 22px; height: 22px;
  }
  /* Eine Beschriftung neben dem Kästchen wird zur ganzen Trefferfläche. */
  .apt-content label:has(> input[type="checkbox"]),
  .apt-content label:has(> input[type="radio"]) {
    min-height: 44px; display: inline-flex; align-items: center; gap: 8px;
  }

  /* Reine Symbolknöpfe in Zeilen — ohne Beschriftung fehlt ihnen die Breite,
     die ein Textknopf von selbst mitbringt. */
  .apt-content button:not(.btn):not([class*="tab"]),
  .mp-zeile-btn, .vt-row-action, .kn-kpi-filterbtn, .rk-row-action {
    min-height: 40px; min-width: 40px;
  }
}


/* ══════════════════════════════════════════════════════════════════════════
   Favoritenstern ohne Hover (30.08.2026)
   ══════════════════════════════════════════════════════════════════════════
   ⚠️ Am Telefon liessen sich Favoriten NICHT setzen. `.sb-star` steht auf
   `opacity: 0` und wird allein über `.sidebar-item:hover` eingeblendet — ein
   Zustand, den ein Finger nie auslöst. Auf einem Touchgerät gemessen: 0 von
   20 Sternen sichtbar, `(hover: hover)` ist `false`. Sichtbar waren nur
   bereits gesetzte Favoriten (`.sb-star.pinned`), also liess sich die Leiste
   am Telefon lesen, aber nicht pflegen.

   Die Bedingung hängt an `hover: none`, NICHT an der Bildschirmbreite: ein
   Touch-Notebook hat einen breiten Schirm und trotzdem keinen Hover, ein
   schmales Fenster am Rechner umgekehrt.                                    */
@media (hover: none) {
  .sb-star { opacity: .45; position: relative; }

  /* ⚠️ Die Trefferfläche wächst über ein Pseudoelement, nicht über die
     Maße des Sterns: `width: 44px` schöbe die Menübeschriftung zusammen.
     So bleibt das Aussehen der Zeile unverändert, und nur der antippbare
     Bereich wird gross.

     ⚠️ Die Werte sind ABGETASTET, nicht gerechnet: mit `elementFromPoint`
     vom Mittelpunkt nach aussen, bis der Stern nicht mehr getroffen wird.
     Ein erster Versuch mit -13px/-15px kam auf 40x42.

     ⚠️ Mehr als **42x42** ist hier baulich nicht zu holen: die Menüzeile ist
     selbst 44px hoch, das Polster stösst oben und unten an die Nachbarzeilen,
     und die werden später gezeichnet. Wer die vollen 44 erzwingen will,
     braucht `z-index` über den Nachbarn — das nähme dem Nachbar-Menüpunkt
     Trefferfläche weg. 42 in einer 44er-Zeile ist das Maximum. */
  .sb-star::after {
    content: ''; position: absolute; inset: -14px -16px;
  }

  /* Ohne Hover gibt es keinen Hover-Zustand, den man zurücknehmen müsste —
     gesetzte Favoriten müssen sich aber weiterhin klar abheben. */
  .sb-star.pinned { opacity: 1; }
}


/* ============================================================
   Signal-Schriftfarben als Klasse (29.08.2026)
   ============================================================
   Aus JavaScript heraus gesetzte Hinweise standen bisher als
   style="color:var(--color-err-text)" im Markup. Eine Zeichenkette in JS kann kein
   var(--…) enthalten — dort wäre es blosser Text. Mit dem Layout-Umbau
   definiert `html.ui-neu` die Statusfarben entsättigt neu; ein fester
   Hex-Wert bliebe davon unberührt und leuchtete weiter.

   Deshalb vier Klassen: sie funktionieren in einer JS-Zeichenkette genauso
   wie im Markup und ziehen mit jeder Palette mit.
   ============================================================ */
.txt-err  { color: var(--color-err-text); }
.txt-warn { color: var(--color-warn-text); }
.txt-ok   { color: var(--color-ok-text); }
.txt-hint { color: var(--color-hint-text); }

/* Zähler am Menüpunkt (nur neue Oberfläche — der Wert wird in der gewohnten
   gar nicht erst berechnet, siehe core/dashboard/zaehler.py). */
/* Roter Kreis wie eine Mitteilung am Telefon: gleiche Höhe wie Breite,
   voll rund, weiße Ziffer. ⚠️ `min-width` + `padding` statt fester Breite —
   bei dreistelligen Zahlen wird daraus eine Pille statt eines
   abgeschnittenen Kreises. */
.sb-zahl {
  margin-left: auto;
  min-width: 19px; height: 19px; padding: 0 5px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: var(--radius-full);
  font-family: var(--font-mono); font-variant-numeric: tabular-nums;
  font-size: var(--text-2xs); font-weight: 700; line-height: 1;
  background: var(--color-err); color: #ffffff;
}
/* Auch auf dem aktiven Menüpunkt bleibt der Kreis rot — er meldet etwas
   Offenes, und das hängt nicht daran, wo man gerade steht. */
.sidebar-item.active .sb-zahl { background: var(--color-err); color: #ffffff; }
/* ⚠️ Im Icon-Modus hat der Zähler keinen Platz neben dem Symbol — er sitzt
   dann als Punkt oben rechts auf dem Chip. */
html[data-menuform="schmal"] .sb-zahl {
  position: absolute; top: 4px; right: 8px; margin: 0;
  min-width: 16px; padding: 0 4px;
}
html[data-menuform="schmal"] .sidebar-item { position: relative; }

/* ── Drehende Symbole ────────────────────────────────────────────────────
   `.ti-spin` stand seit jeher im Markup (Shopify Importer, zwei
   Ladeanzeigen), war aber NIRGENDS definiert — die Symbole standen still.
   Gefunden beim Umstellen auf die selbst gehostete Symbolschrift (30.08.),
   weil dort jedes benutzte `ti-*` gegen die Schriftdatei geprüft wird und
   `.ti-spin` als einziger Name übrig blieb, den es dort nicht gibt.
   Es IST auch kein Symbol, sondern eine Zusatzklasse — deshalb hier und
   nicht in tabler-icons.css.                                              */
@keyframes apt-dreh { to { transform: rotate(360deg); } }
.ti-spin { display: inline-block; animation: apt-dreh 1s linear infinite; }
@media (prefers-reduced-motion: reduce) { .ti-spin { animation: none; } }


/* ══════════════════════════════════════════════════════════════════════════
   Kanban-Gerüst (`.kb-*`) — gemeinsames Bauteil der vier Bretter
   ══════════════════════════════════════════════════════════════════════════
   Projektmanagement, Reklamationen, Kundenanfragen und das KI-Entwicklungs-
   Brett im Superadmin hatten dieses Gerüst **viermal** — gleiche Radien,
   Farben, Abstände, gleicher 768px-Breakpoint, gleiches `82vw`, nur ein
   anderer Präfix. Es steht jetzt einmal hier, nach dem Muster von `.wl-*`.

   ⚠️ **Dieser Block trägt das Aussehen, das die Bretter am 30.08.2026 hatten,
   und darf sich nicht verändern.** Das neue Leitwerk-Aussehen liegt
   ausschliesslich in `neu.css` hinter `html.ui-neu` — dort sticht
   `html.ui-neu .kb-karte` (0,2,0) diese Regeln (0,1,0) doppelt: über die
   Spezifität und über die Ladereihenfolge. Ein Test vergleicht die tragenden
   Werte hier gegen eine Referenztabelle; wer das Aussehen ändern will, ändert
   `neu.css`.

   ⚠️ **Warum ein neuer Name und keine Sammelregel** (`.pm-karte, .rk-karte …`):
   die Vorlagen tragen ihr CSS in einem `<style>`-Block IN der Seite, also nach
   dieser Datei. Bei gleicher Spezifität gewinnt die spätere Regel — eine
   Sammelregel hier wirkte erst nach dem Löschen der lokalen Zeilen und fasste
   damit dieselben vier Dateien an.

   ⚠️ **Kein Drag & Drop.** Das Fehlen ist eine bewusste Entscheidung. Deshalb
   hier weder `cursor: grab` noch eine Hover-Hebung — eine Karte darf nicht
   aussehen, als liesse sie sich ziehen. `cursor: pointer` ist etwas anderes.

   Im Markup steht beides: `class="kb-karte pm-karte"`. Das Gerüst kommt von
   `kb-`, der Modulname bleibt Aufhänger für alles Fachliche (Timer,
   Rückläufer, Übergabezeile, Art-Chips) und für die sechs Maßabweichungen.
   ══════════════════════════════════════════════════════════════════════════ */

.kb-kanban {
  --kb-spalte: 280px;      /* Kundenanfragen setzt 270px */
  --kb-meta-gap: 8px;      /* Kundenanfragen setzt 6px  */
  display: flex; gap: 14px; overflow-x: auto; padding-bottom: 20px;
  min-height: calc(100vh - 160px); -webkit-overflow-scrolling: touch;
}
.kb-col { flex: 0 0 var(--kb-spalte); display: flex; flex-direction: column; gap: 8px; }

/* Kopf: eine Leiste, keine Karte — Umbau vom 05.08.2026. Die Spaltenfarbe
   sitzt in der 2px-Unterkante, nicht in einem Punkt davor. */
.kb-col-header {
  display: flex; align-items: center; gap: 8px; padding: 9px 12px 8px;
  border-radius: var(--radius-lg); background: var(--color-surface-2);
  border-bottom: 2px solid var(--kb-col-farbe, var(--color-line-2));
  font-weight: 700; font-size: var(--text-sm); letter-spacing: .05em;
  text-transform: uppercase; color: var(--color-text-3b);
}
.kb-col-count {
  margin-left: auto; background: var(--color-surface-3); color: var(--color-text-2b);
  border-radius: var(--radius-2xl); padding: 1px 8px;
  font-size: var(--text-xs); letter-spacing: 0; font-weight: 600;
}
.kb-col-body { display: flex; flex-direction: column; gap: 8px; flex: 1; }

.kb-karte {
  background: var(--color-card); border: 1px solid var(--color-surface-3);
  border-radius: var(--radius-xl); padding: 12px 14px; cursor: pointer;
  transition: border-color .15s; position: relative;
}
.kb-karte:hover { border-color: var(--color-accent-text); }
/* ⚠️ `kb-karte-titel` trägt den Namen eines VORGANGS, keine Rubrik — er ist
   deshalb kein Fall für die Überschriften-Rangfolge und steht in deren
   Ausschlussliste. */
.kb-karte-titel {
  font-size: var(--text-base); font-weight: 600; color: var(--color-text-1b);
  margin-bottom: 6px; line-height: 1.35;
}
.kb-karte-meta {
  font-size: var(--text-xs); color: var(--color-text-4b);
  display: flex; gap: var(--kb-meta-gap); flex-wrap: wrap; align-items: center;
}
.kb-karte-footer {
  display: flex; gap: 6px; align-items: center; margin-top: 8px; padding-top: 8px;
  border-top: 1px solid var(--color-surface);
}
/* ⚠️ Das KI-Brett hat KEINEN Fuss und seine Aktionen stehen statisch statt
   absolut — es bekommt `kb-karte-footer`/`kb-karte-actions` bewusst nicht. */
.kb-karte-actions { display: none; position: absolute; top: 8px; right: 8px; gap: 4px; }
.kb-karte:hover .kb-karte-actions { display: flex; }
.kb-status-btn {
  padding: 3px 7px; border-radius: var(--radius-md); font-size: var(--text-2xs);
  background: var(--color-surface); border: 1px solid var(--color-line-2);
  color: var(--color-text-3b); cursor: pointer; white-space: nowrap;
}
.kb-status-btn:hover {
  background: var(--color-accent); color: var(--color-card);
  border-color: var(--color-accent-text);
}
.kb-add-btn {
  display: flex; align-items: center; gap: 6px; padding: 8px 12px;
  border: 1px dashed var(--color-surface-3); border-radius: var(--radius-lg);
  color: var(--color-text-5); font-size: var(--text-sm); text-decoration: none;
  transition: all .15s;
}
.kb-add-btn:hover { border-color: var(--color-accent-text); color: var(--color-accent-text); }

/* Prioritäts-Chip — stand vorher dreimal wortgleich in PM, RK und KA. */
.kb-prio {
  display: inline-flex; align-items: center; gap: 3px; font-size: var(--text-2xs);
  font-weight: 700; padding: 2px 7px; border-radius: var(--radius-xl);
}
.kb-prio.hoch    { background: var(--color-err-dim);  color: var(--color-err-text); }
.kb-prio.mittel  { background: var(--color-warn-dim); color: var(--color-warn-text); }
.kb-prio.niedrig { background: var(--color-ok-dim);   color: var(--color-ok-text); }

.kb-karte-faellig { font-size: var(--text-xs); }
.kb-karte-faellig.ueberfaellig { color: var(--color-err-text); }
.kb-karte-faellig.heute        { color: var(--color-warn-text); }
.kb-karte-faellig.ok           { color: var(--color-text-4b); }

/* ⚠️ Ohne Zeiger gibt es kein Zeigen — und damit keinen Statusknopf.
   `.kb-karte-actions` steht auf `display:none` und erscheint nur bei
   `:hover`. Bis zum 31.08.2026 hing die Ausnahme allein an der
   Bildschirmbreite (≤768px): ein Touch-Notebook und ein Tablet im
   Querformat sind breiter und haben trotzdem keinen Hover — dort war der
   Knopf, mit dem man eine Aufgabe weiterschiebt, **überhaupt nicht
   erreichbar**. Dieselbe Falle wie bei den Favoriten-Sternen am 30.08.:
   die Bedingung gehört an `hover: none`, nicht an die Breite. */
@media (hover: none) {
  .kb-karte-actions { display: flex; position: static; margin-top: 8px; }
  .kb-status-btn { padding: 6px 10px; font-size: var(--text-xs); min-height: 32px; }
}

/* Am Telefon bleiben die Spalten nebeneinander und scrollen — gestapelt
   verlöre das Brett seinen Sinn. */
@media (max-width: 768px) {
  .kb-kanban { --kb-spalte: 82vw; }
  /* Am Finger gibt es kein Zeigen: die Aktionen stehen fest in der Karte
     statt beim Hover zu erscheinen, und die Knöpfe werden grösser.
     Stand vorher wortgleich in PM, RK und KA. */
  .kb-status-btn { padding: 6px 10px; font-size: var(--text-xs); }
  .kb-karte-actions { display: flex; position: static; margin-top: 8px; }
}


/* == Masstabelle - Reiter "Groessen" in Lieferantenkartei UND DataPilot ==
   Achtung: app-weit hier statt in einer Vorlage, weil dasselbe Bauteil
   an zwei Stellen eingebunden wird. */
.gr-lade { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; }
.gr-lade-lbl { font-size: var(--text-2xs); font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase; color: var(--color-text-5); margin-right: 2px; }
.gr-schalter { display: inline-flex; gap: 2px; background: var(--color-surface-2);
  border-radius: var(--radius-full); padding: 3px; margin: 4px 0 14px; }
.gr-s { border: 0; background: none; color: var(--color-text-3); cursor: pointer;
  padding: 7px 18px; border-radius: var(--radius-full); font-size: var(--text-base);
  font-weight: 600; min-height: 32px; }
.gr-s.aktiv { background: var(--color-accent); color: var(--color-on-accent); }
.gr-block-titel { font-size: var(--text-2xs); font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; color: var(--color-text-4); margin: 18px 0 7px; }
.gr-umriss { overflow-x: auto; border: 1px solid var(--color-line); border-radius: var(--radius-md); }
.gr-tab { width: 100%; border-collapse: collapse; font-size: var(--text-sm);
  font-variant-numeric: tabular-nums; }
.gr-tab th, .gr-tab td { padding: 7px 10px; text-align: center; border-bottom: 1px solid var(--color-line-2); }
.gr-tab th { background: var(--color-surface-2); font-size: var(--text-2xs); font-weight: 700;
  color: var(--color-text-2); vertical-align: bottom; }
.gr-tab th small { display: block; font-weight: 400; color: var(--color-text-5); font-size: var(--text-2xs); }
.gr-tab td:first-child { font-weight: 700; color: var(--color-text-1b); }
.gr-tab td.gr-gruppe { background: var(--color-surface-2b); font-weight: 700;
  border-left: 1px solid var(--color-line); }
.gr-tab tbody tr:last-child td { border-bottom: 0; }
.gr-legende { margin: 0; font-size: var(--text-sm); }
.gr-legende dt { font-weight: 700; color: var(--color-text-1b); margin-top: 8px; }
.gr-legende dd { margin: 2px 0 0 0; color: var(--color-text-3); }
.gr-hinweis { margin-top: 14px; padding: 10px 13px; font-size: var(--text-sm);
  background: var(--color-surface-2); border-left: 3px solid var(--color-line);
  border-radius: var(--radius-sm); color: var(--color-text-3); }
.gr-hinweis.hervor { background: var(--color-accent-dim); border-left-color: var(--color-accent);
  color: var(--color-text-2); }

/* Lieferantenwahl auf der DataPilot-Seite "Groessen" */
.gr-wahl { display: flex; flex-wrap: wrap; gap: 6px; margin: 0 0 16px; }
.gr-wahl-el { padding: 7px 13px; border-radius: var(--radius-full); min-height: 32px;
  display: inline-flex; align-items: center; background: var(--color-surface-2);
  color: var(--color-text-2); font-size: var(--text-sm); font-weight: 600;
  text-decoration: none; border: 1px solid var(--color-line); }
.gr-wahl-el:hover { color: var(--color-text-1b); border-color: var(--color-line-2); }
.gr-wahl-el.aktiv { background: var(--color-accent); border-color: var(--color-accent); color: var(--color-on-accent); }
.gr-ohne { margin-top: 18px; font-size: var(--text-xs); color: var(--color-text-5); }

/* Messanleitung der Masstabelle (Silhouette + Punkte) */
.gr-unter { margin: 0 0 14px; color: var(--color-text-3); font-size: var(--text-base); }
.gr-messen { display: grid; grid-template-columns: 200px 1fr; gap: 30px; align-items: start;
  margin: 0 0 22px; }
.gr-figur { width: 100%; height: auto; max-height: 420px; }
ol.gr-schritte { list-style: none; counter-reset: s; padding: 0; margin: 0; }
ol.gr-schritte li { counter-increment: s; position: relative; padding-left: 38px; margin-bottom: 14px; }
ol.gr-schritte li::before { content: counter(s); position: absolute; left: 0; top: 1px;
  width: 26px; height: 26px; border-radius: var(--radius-full); background: var(--color-accent);
  color: var(--color-on-accent); font-weight: 700; font-size: var(--text-sm); display: flex;
  align-items: center; justify-content: center; }
ol.gr-schritte li[data-nr]::before { content: attr(data-nr); font-size: var(--text-2xs); }
ol.gr-schritte.mit-doppel li[data-nr="3b"] { counter-increment: none; }
ol.gr-schritte b { display: block; font-weight: 700; color: var(--color-text-1b); }
ol.gr-schritte span { color: var(--color-text-3); font-size: var(--text-base); }
@media (max-width: 768px) {
  .gr-messen { grid-template-columns: 1fr; }
  .gr-figur { max-width: 190px; margin: 0 auto; display: block; }
}

/* Eigenstaendige Huelle der Masstabelle - das Bauteil steht in zwei Modulen
   und darf deshalb keine Modulklassen (.lf-*) voraussetzen. */
.gr-karte { background: var(--color-card); border: 1px solid var(--color-line);
  border-radius: var(--radius-lg); padding: 20px 22px; }
.gr-karte-kopf { display: flex; justify-content: space-between; align-items: flex-start;
  gap: 16px; flex-wrap: wrap; margin-bottom: 6px; }
.gr-karte-sub { display: block; font-size: var(--text-xs); color: var(--color-text-5); margin-top: 3px; }
.gr-btn { display: inline-flex; align-items: center; gap: 5px; min-height: 32px;
  padding: 6px 12px; border-radius: var(--radius-md); border: 1px solid var(--color-line);
  background: var(--color-surface-2); color: var(--color-text-2); font-size: var(--text-sm);
  font-weight: 600; text-decoration: none; }
.gr-btn:hover { color: var(--color-text-1b); border-color: var(--color-accent); }
.gr-leer { padding: 18px 0; color: var(--color-text-5); font-size: var(--text-sm); }
.gr-quelle { margin-top: 12px; font-size: var(--text-xs); color: var(--color-text-5); }
.gr-link { color: var(--color-accent-text); }
@media (max-width: 768px) {
  .gr-karte { padding: 16px 14px; }
  .gr-btn { min-height: 44px; }
}

.gr-hinweis.gr-warn { background: var(--color-warn-dim); border-left-color: var(--color-warn);
  color: var(--color-text-2); }
.gr-hinweis.gr-warn b { color: var(--color-warn-text); display: block; margin-bottom: 3px; }

/* Spiegelumgebung (core/umgebung.py): Band über jeder Seite, nur bei UMGEBUNG=dev. */
.dev-spiegel-band {
  position: sticky; top: 0; z-index: 10000;
  display: flex; align-items: center; justify-content: center; gap: 8px;
  padding: 4px 16px;
  background: var(--color-err);
  color: var(--color-on-accent);
  font-size: var(--text-sm);
  letter-spacing: .04em;
  text-align: center;
}
