/* ============================================================
   CONSOLE v3 — Sidebar-Layout + alle 7 Modul-Views
   ============================================================ */
:root {
  --bg:             #F6FAF8;
  --surface:        #FFFFFF;
  --surface-2:      #EFF6F2;
  --surface-3:      #DFEDE6;
  --sidebar-bg:     #0B2B23;
  --border:         rgba(11, 43, 35, 0.10);
  --border-strong:  rgba(10, 10, 11, 0.16);
  --text:           #0A0A0B;
  --text-muted:     #5F5F66;
  /* GEFIXT (Runde 113, N4, MITTEL): #9A9AA1 lag auf --surface (#FFFFFF) bei
     2.80:1 -- unter dem WCAG-AA-Minimum 4.5:1 fuer Fliesstext (u.a.
     .person-row-meta, .sb-group-label, .kap-note). #6E6E75 erreicht 5.06:1
     bei minimal veraendertem Grauton. */
  --text-faint:     #6E6E75;
  /* NEU (Runde 113, N4-Nachtrag, MITTEL): die Sidebar (--sidebar-bg) bleibt
     in BEIDEN Themes dunkelgruen -- ein einziges, themenabhaengiges
     --text-faint kann nie gleichzeitig auf hellem --surface UND auf der
     dauerhaft dunklen Sidebar lesbar sein (der obige, fuer --surface
     verdunkelte Wert faellt auf der Sidebar auf 3.00:1). Eigener,
     sidebar-spezifischer Token mit dem urspruenglichen (fuer dunkle
     Untergruende bereits gut lesbaren) Grauton. */
  --sidebar-faint:  #9A9AA1;
  /* NEU (Runde 139, R139-eng-1, NIEDRIG -- Restluecke/Regression des
     Runde-138-Kontrastfixes): dieselbe Ursache wie bei --sidebar-faint, nur
     eine Ebene weiter. Die HAUPT-Sidebar (aside.sidebar) sitzt wie die
     Modul-Sidebar auf --sidebar-bg (#0B2B23 hell, #0E0E10 dunkel) und ist
     damit in BEIDEN Themes dunkel. Die zwei Plaketten darin
     (.sb-item .pip.alert / .pip.beta) tragen aber halbtransparente
     Fuellungen (--brand-soft / --info-soft), die auf DIESEM dunklen Grund
     landen -- nicht auf --surface. Runde 138 hat --brand-ink (fuer weisse
     Karten verdunkelt, #17694E) bzw. --info (#2563EB -> #1D4FD8) dort
     eingesetzt und den Kontrast damit von 4.24:1 auf 1.90:1 bzw. von 2.70:1
     auf 2.10:1 GESENKT -- genau umgekehrt zur Absicht des Fixes. Wie
     --sidebar-faint deshalb eigene, sidebar-spezifische Toene: die bereits
     fuer dunkle Untergruende kalibrierten Dunkel-Themen-Werte, die in
     BEIDEN Themes passen (5.39:1 / 6.46:1 bzw. 5.48:1 / 6.22:1) und daher
     bewusst NICHT in [data-theme="dark"] ueberschrieben werden.
     Verifiziert: runde139_eng_kontrast_hauptsidebar.js */
  --sidebar-brand-ink: #2FBF8F;
  --sidebar-info-ink:  #60A5FA;
  /* NEU (Runde 140, R140-eng-1, NIEDRIG -- Nachzuegler im R139-eng-Fix):
     --sidebar-faint (R113-N4) hat den Token eingefuehrt, aber nur DREI der
     zehn betroffenen Haupt-Sidebar-Regeln umgestellt. Die uebrigen trugen
     weiter die fuer das weisse --surface kalibrierten Texttoken auf dem
     dauerhaft dunklen Sidebar-Grund -- .sb-item mit --text-muted (2.40:1 hell)
     sowie .sb-group-label/.sb-group-label .ico/.sb-collapse/.sb-user-menu
     mit --text-faint (3.00:1 hell). .sb-brand-name und .sb-user-info strong
     deklarierten ueberhaupt keine Farbe und erbten die Body-Farbe --text
     -- 1.30:1, praktisch unsichtbar. Der R139-eng-Test konnte das nicht
     sehen: er sammelt (wie der R138-Sweep) nur Regeln mit color UND
     background in DERSELBEN Regel, waehrend der Sidebar-Grund genau einmal
     am Vorfahren aside.sidebar steht. Zwei weitere sidebar-spezifische
     Toene, wie --sidebar-faint bewusst NICHT in [data-theme="dark"]
     ueberschrieben (es sind die dort ohnehin geltenden, fuer dunkle
     Untergruende kalibrierten Werte) -- so bleibt auch die Abstufung
     Titel > Eintrag > Beschriftung erhalten.
     Verifiziert: runde140_eng_kontrast_sidebar_erbfarben.js */
  --sidebar-text:   #F5F5F7;   /* 13.93:1 hell / 17.71:1 dunkel */
  --sidebar-muted:  #A1A1A8;   /*  5.91:1 hell /  7.51:1 dunkel */
  --brand:          #27A97E;
  --brand-hover:    #1E8763;
  /* NEU (Runde 138, R138-breit-1, MITTEL): --brand (#27A97E) ist als
     FLAECHEN-/Rahmenfarbe kalibriert und darf nicht veraendert werden (er
     traegt Fuellungen, Rahmen, Fortschrittsbalken und accent-color). Als
     TEXTFARBE erreicht er jedoch nur 2.63:1 auf --brand-soft, 2.97:1 auf
     --surface und 2.71:1 auf --surface-2 -- alle drei unter dem WCAG-AA-
     Minimum 4.5:1 fuer Fliesstext. Betroffen waren u.a. .chk-chip,
     .rolle-leiter ("Leitung"), .pool-pflicht, .osm-count, .wh-month-num,
     .store-badge.official, .subtab.active .count, .row-action:hover und
     .karte-locate-ctrl a. Analog zu --sidebar-faint (Runde 113, N4-Nachtrag)
     deshalb ein EIGENER Token nur fuer die Textrolle: #17694E erreicht
     5.88:1 auf --brand-soft, 6.63:1 auf --surface und 6.04:1 auf
     --surface-2, bleibt aber in derselben Farbfamilie. Im dunklen Thema ist
     --brand bereits ausreichend hell (6.11:1 auf --brand-soft) -- dort ist
     --brand-ink schlicht identisch mit --brand. NICHT ersetzt wurde
     .mod-sb-title i: dieses Icon steht auf der dauerhaft dunkelgruenen
     --sidebar-bg, wo ein dunkleres Gruen die Lesbarkeit verschlechtern
     wuerde. Verifiziert: runde138_breit_kontrast_vollsweep.js */
  --brand-ink:      #17694E;
  --brand-soft:     rgba(39, 169, 126, 0.12);
  --accent:         #27A97E;
  --accent-soft:    rgba(39, 169, 126, 0.12);
  /* GEFIXT (Runde 113, N4-Nachtrag, MITTEL): #16A34A auf seinem eigenen
     --success-soft (ueber --surface gelegt) lag bei nur 2.96:1 -- unter
     WCAG-AA 4.5:1. #0F7A37 (dieselbe Farbfamilie) erreicht 4.88:1. Alle
     Konsumstellen folgen demselben Muster color:--success + background:
     --success-soft (Pool-Typ-Tags, Zertifikat-Badges, Status-Pillen,
     Sync-Pille, Trend-Pfeile) -- eine gemeinsame, konsistente Aenderung
     statt Einzelfaelle. */
  --success:        #0F7A37;
  --success-soft:   rgba(22, 163, 74, 0.10);
  /* GEFIXT (Runde 138, R138-breit-2, MITTEL -- Luecke der Runde-113-Pruefung,
     die nur --berry/--success/--text-* abdeckte): #B45309 auf seinem EIGENEN
     --warning-soft (ueber --surface gelegt) lag bei 4.38:1, unter WCAG-AA
     4.5:1 -- betroffen .status-pill.umsetzung, .cert-badge.soon,
     .fa-tag.cert-soon, .sync-pill.pending, .feed-icon.warn. Als Klartext auf
     --surface war derselbe Wert mit 5.02:1 unauffaellig; nur die eingefaerbte
     Pille faellt durch, weshalb eine Pruefung "Token gegen --surface" das nie
     sehen konnte. #9A4A08 (dieselbe Farbfamilie) erreicht 5.46:1 auf
     --warning-soft und 6.26:1 auf --surface. --warning traegt nirgends Text
     als FLAECHE (einzige Flaechen-Nutzung ist ein textloser Punkt-Indikator,
     Z. ~547), die Aenderung ist daher gefahrlos global. */
  --warning:        #9A4A08;
  --warning-soft:   rgba(180, 83, 9, 0.10);
  /* GEFIXT (Runde 138, R138-breit-2, MITTEL): #2563EB auf seinem eigenen
     --info-soft lag bei 4.4999:1 -- rechnerisch UNTER 4.5:1, also ein
     AA-Verstoss, der bei zweistelliger Rundung ("4.50") wie eine bestandene
     Pruefung aussieht. Betroffen .status-pill.in-kraft/.processing,
     .rolle-mitarbeiter, .pool-typ.wiederkehrend, .wh-task-tag,
     .sync-pill.syncing, .feed-icon.info, .sb-item .pip.beta, .mod-pip.beta.
     #1D4FD8 erreicht 5.78:1 auf --info-soft und 6.64:1 auf --surface. */
  --info:           #1D4FD8;
  --info-soft:      rgba(37, 99, 235, 0.10);
  /* NEU (Runde 138, R138-breit-3, NIEDRIG): zwei Farben standen als
     Literal im Regelwerk statt als Token und waren deshalb nie
     themenabhaengig. `.rolle-extern` (#0891B2 auf rgba(8,145,178,.10)) lag im
     hellen Thema bei 3.27:1 -- die Rollen-Plakette "Extern" steht direkt
     neben .rolle-leiter/.rolle-mitarbeiter, die beide AA erfuellen.
     `.lern-chip` (#6D28D9 auf --surface) erreicht im hellen Thema 7.10:1,
     faellt im DUNKLEN aber auf 2.61:1, weil der Literalwert von
     [data-theme="dark"] gar nicht erst erreicht wird. */
  --extern:         #0B6280;
  --extern-soft:    rgba(8, 145, 178, 0.10);
  --lern:           #6D28D9;
  /* GEFIXT (Runde 113, R110-breit-3-Nachtrag, MITTEL): #BE185D erfuellte
     AA (6.04:1) UND unterschied sich farblich klar von --success, aber
     beide Farben hatten fast dieselbe LEUCHTDICHTE (Luminanz-Kontrast
     zwischen ihnen nur 1.11:1) -- fuer Rot-Gruen-Farbfehlsichtige, die
     primaer ueber Helligkeit statt Farbton unterscheiden, blieben
     "ueberfaellig" (--berry) und "bestanden" (--success) trotz des
     Farbtonwechsels weiterhin praktisch ununterscheidbar. #881337 (dunklerer
     Rotton derselben Familie) erreicht 1.76:1 Leuchtdichte-Unterschied zu
     --success UND 7.95:1 Eigenkontrast auf --berry-soft/--surface. */
  --berry:          #881337;
  /* NACHGEBESSERT (Runde 114, R114-eng-Notiz): stand noch auf rgb(190,24,93)
     -- dem RGB-Wert des ALTEN --berry (#BE185D) vor der obigen Verdunkelung.
     Kein Kontrastfehler (Text auf diesem Grund erreicht weiterhin 7.95:1),
     aber die Palette war seit Runde 113 intern inkonsistent. */
  --berry-soft:     rgba(136, 19, 55, 0.10);
  --font-sans:      'Inter Tight', system-ui, sans-serif;
  --font-mono:      'JetBrains Mono', ui-monospace, monospace;
  --r-sm: 6px;
  --r-md: 10px;
  --r-lg: 14px;
  --sidebar-w:      244px;
  --topbar-h:       52px;
  --ease:           cubic-bezier(0.32, 0.72, 0, 1);
  --t-fast:         140ms;
  --t-base:         220ms;
}
[data-theme="dark"] {
  --bg: #0A0A0B; --surface: #131316; --surface-2: #1B1B1F; --surface-3: #25252B;
  --sidebar-bg: #0E0E10;
  --border: rgba(255,255,255,0.08); --border-strong: rgba(255,255,255,0.16);
  /* GEFIXT (Runde 113, N4, MITTEL): #6B6B73 lag auf --surface (#131316) bei
     3.51:1 und auf --sidebar-bg (#0E0E10) bei 3.65:1 -- unter 4.5:1. #8F8F97
     erreicht 5.78:1 bzw. 6.01:1. */
  --text: #F5F5F7; --text-muted: #A1A1A8; --text-faint: #8F8F97;
  /* Runde 138: im dunklen Thema ist --brand als Textfarbe bereits
     ausreichend hell (6.11:1 auf --brand-soft, 7.33:1 auf --surface-2) --
     --brand-ink ist hier bewusst identisch mit --brand. */
  --brand: #2FBF8F; --brand-hover: #4ACD9F; --brand-soft: rgba(47,191,143,0.16);
  --brand-ink: #2FBF8F;
  /* Runde 138, R138-breit-3: dunkle Gegenstuecke der beiden bisherigen
     Literalfarben. --extern hell (#0B6280) waere auf --surface (#131316)
     unlesbar, --lern hell (#6D28D9) lag dort bei 2.61:1. */
  --extern: #67E8F9; --extern-soft: rgba(103,232,249,0.14);
  --lern: #C4B5FD;
  --accent: #2FBF8F; --accent-soft: rgba(47,191,143,0.16);
  --success: #4ADE80; --success-soft: rgba(74,222,128,0.14);
  --warning: #FBBF24; --warning-soft: rgba(251,191,36,0.14);
  --info: #60A5FA; --info-soft: rgba(96,165,250,0.14);
  --berry: #F472B6; --berry-soft: rgba(244,114,182,0.14);
}

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html, body { height: 100%; }
body {
  font-family: var(--font-sans);
  font-feature-settings: 'cv11', 'ss01', 'ss03';
  font-size: 14px; line-height: 1.5;
  color: var(--text); background: var(--bg);
  -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility;
  transition: background 240ms var(--ease), color 240ms var(--ease);
}
button { font-family: inherit; cursor: pointer; border: none; background: none; color: inherit; }
/* GEFIXT (Runde 113, N3, MITTEL): --brand (#27A97E) lag auf --surface (hell)
   bei 2.97:1 -- unter dem WCAG-1.4.11-Minimum 3:1 fuer Nicht-Text-Kontrast
   (hier: der Fokusring selbst). --brand-hover erreicht 4.47:1 (hell) bzw.
   9.29:1 (dunkel) und ist bereits ein bestehender Marken-Token. */
button:focus-visible, a:focus-visible, [tabindex]:focus-visible {
  outline: 2px solid var(--brand-hover); outline-offset: 2px; border-radius: var(--r-sm);
}
a { color: inherit; text-decoration: none; }
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0; }

/* GEFIXT (Runde 131, R131-breit-2, NIEDRIG): `text-muted` und `text-faint`
   sind die beiden Abtoenungs-Klassen, mit denen das Modul modulweit
   Nebeninformation optisch zuruecknimmt (Hinweiszeilen in Formularen,
   Leerzustaende in Modalen, Unterzeilen in Detailkarten, die Erlaeuterung an
   der Blockerleiste des Wochenprogramms). Fuer `.text-faint` gab es GAR KEINE
   Regel -- nur die gleichnamige CSS-Variable `--text-faint`, die beim Lesen
   des Stylesheets wie eine aussieht --, fuer `.text-muted` nur zwei eng
   gebundene (`.data-table .text-muted`, `.mangel-list li.text-muted`, beide
   weiter unten, beide unveraendert). Jede Verwendung ausserhalb einer
   Datentabelle oder der Maengelliste rendert damit in VOLLER Textfarbe: die
   behauptete Abtoenung fand nicht statt, Hinweis- und Leerzeilen standen
   genauso dunkel wie der Inhalt daneben. Dieselbe Klasse wie R130-eng-1
   (`disabled` ohne CSS-Wirkung). Dass die Abtoenung gewollt ist, zeigt
   templates/index.html: dort sind alle acht faint-Stellen als Inline-Stil
   `color:var(--text-faint)` geschrieben -- an der Klasse vorbei. Hier global
   und mit genau den Farben der bereits bestehenden, engeren Regeln; deren
   hoehere Spezifitaet (inkl. font-style in der Maengelliste) bleibt
   unberuehrt (verifiziert:
   runde131_breit_textmuted_textfaint_ohne_css.js). */
.text-muted { color: var(--text-muted); }
.text-faint { color: var(--text-faint); }

/* APP SHELL */
.app { display: grid; grid-template-columns: var(--sidebar-w) 1fr; height: 100vh; transition: grid-template-columns var(--t-base) var(--ease); }
.app.sb-collapsed { grid-template-columns: 64px 1fr; }

/* ============================================================
   SIDEBAR
   ============================================================ */
aside.sidebar {
  background: var(--sidebar-bg); border-right: 1px solid var(--border);
  display: flex; flex-direction: column; overflow: hidden;
}
.sb-head {
  display: flex; align-items: center; gap: 10px;
  padding: 12px 14px; height: var(--topbar-h);
  border-bottom: 1px solid var(--border);
}
.sb-brand-mark {
  width: 28px; height: 28px; border-radius: 7px;
  background: var(--brand); color: #fff;
  display: grid; place-items: center;
  font-size: 13px; font-weight: 700; letter-spacing: -0.02em; flex-shrink: 0;
}
.sb-brand-text { line-height: 1.15; flex: 1; min-width: 0; overflow: hidden; }
.sb-brand-name {
  font-size: 13px; font-weight: 600; letter-spacing: -0.01em;
  /* GEFIXT (Runde 140, R140-eng-1): ohne eigene Farbe erbte der Produktname
     die Body-Farbe --text -- im hellen Thema 1.30:1 auf --sidebar-bg. */
  color: var(--sidebar-text);
  display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.sb-brand-sub { font-size: 11px; color: var(--sidebar-faint); white-space: nowrap; }
.sb-collapse {
  width: 28px; height: 28px; border-radius: 6px;
  /* GEFIXT (Runde 140, R140-eng-1): --text-faint ist fuer --surface
     kalibriert und ergibt auf --sidebar-bg nur 3.00:1 (helles Thema). */
  display: grid; place-items: center; color: var(--sidebar-faint); flex-shrink: 0;
}
.sb-collapse:hover { background: var(--surface-2); color: var(--text); }
.sb-collapse i { font-size: 15px; }

.sb-scroll { flex: 1; overflow-y: auto; padding: 10px 8px 12px; }
.sb-scroll::-webkit-scrollbar { width: 6px; }
.sb-scroll::-webkit-scrollbar-thumb { background: var(--surface-3); border-radius: 3px; }

.sb-group { margin-bottom: 14px; }
.sb-group-label {
  font-size: 10.5px; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase;
  /* GEFIXT (Runde 140, R140-eng-1): siehe --sidebar-text/--sidebar-muted im
     :root-Block -- --text-faint ergab hier 3.00:1 (helles Thema). */
  color: var(--sidebar-faint); padding: 6px 10px;
  display: flex; align-items: center; justify-content: space-between;
}
.sb-group-label .ico {
  width: 18px; height: 18px; display: grid; place-items: center;
  border-radius: 4px; color: var(--sidebar-faint);
}
.sb-group-label .ico:hover { background: var(--surface-2); color: var(--text); }
.sb-group-label .ico i { font-size: 14px; }

.sb-item {
  display: flex; align-items: center; gap: 9px;
  padding: 6px 10px; border-radius: 6px;
  /* GEFIXT (Runde 140, R140-eng-1): der HAUPTNAVIGATIONSTEXT stand mit dem
     fuer --surface kalibrierten --text-muted auf dem dunklen --sidebar-bg --
     2.40:1 im hellen Thema, der schwerste Wert der ganzen Sidebar. */
  font-size: 13px; color: var(--sidebar-muted); font-weight: 500;
  width: 100%; text-align: left; position: relative;
  transition: all var(--t-fast) var(--ease);
}
.sb-item:hover { background: var(--surface-2); color: var(--text); }
.sb-item.active {
  background: var(--surface); color: var(--text);
  box-shadow: 0 0 0 1px var(--border);
}
.sb-item i { font-size: 16px; color: var(--sidebar-faint); flex-shrink: 0; }
.sb-item:hover i, .sb-item.active i { color: var(--text); }
.sb-item .label { flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sb-item .pip {
  font-family: var(--font-mono); font-size: 10px;
  background: var(--surface-2); color: var(--text-muted);
  padding: 1px 6px; border-radius: 4px;
}
/* GEFIXT (Runde 139, R139-eng-1, NIEDRIG): beide Plaketten sitzen auf der
   dauerhaft dunklen aside.sidebar (--sidebar-bg), nicht auf --surface --
   siehe --sidebar-brand-ink/--sidebar-info-ink im :root-Block. Die
   Runde-138-Werte (--brand-ink/--info) sind fuer HELLE Karten verdunkelt und
   fielen hier auf 1.90:1 bzw. 2.10:1. */
.sb-item .pip.beta { background: var(--info-soft); color: var(--sidebar-info-ink); }
.sb-item .pip.alert { background: var(--brand-soft); color: var(--sidebar-brand-ink); }
.sb-item.disabled { opacity: 0.45; cursor: not-allowed; pointer-events: none; }

.sb-foot {
  padding: 10px; border-top: 1px solid var(--border);
  display: flex; align-items: center; gap: 10px;
}
.sb-user-ava {
  width: 30px; height: 30px; border-radius: 50%;
  background: var(--brand); color: #fff;
  display: grid; place-items: center;
  font-size: 11px; font-weight: 600; letter-spacing: 0.03em; flex-shrink: 0;
}
.sb-user-info { line-height: 1.2; flex: 1; min-width: 0; }
/* GEFIXT (Runde 140, R140-eng-1): wie .sb-brand-name erbte der Benutzername
   ohne eigene Farbe die Body-Farbe --text -- 1.30:1 im hellen Thema. */
.sb-user-info strong { font-size: 12.5px; font-weight: 600; color: var(--sidebar-text); display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sb-user-info span { font-size: 11px; color: var(--sidebar-faint); }
.sb-user-menu {
  width: 24px; height: 24px; display: grid; place-items: center;
  /* GEFIXT (Runde 140, R140-eng-1): --text-faint auf --sidebar-bg = 3.00:1. */
  border-radius: 5px; color: var(--sidebar-faint);
}
.sb-user-menu:hover { background: var(--surface-2); color: var(--text); }
.sb-user-menu i { font-size: 14px; }

/* SIDEBAR — COLLAPSED STATE */
.app.sb-collapsed .sb-brand-text,
.app.sb-collapsed .sb-collapse,
.app.sb-collapsed .sb-group-label,
.app.sb-collapsed .sb-item .label,
.app.sb-collapsed .sb-item .pip,
.app.sb-collapsed .sb-user-info,
.app.sb-collapsed .sb-user-menu { display: none; }
.app.sb-collapsed .sb-head { justify-content: center; padding: 12px 8px; }
.app.sb-collapsed .sb-scroll { padding: 10px 6px 12px; }
.app.sb-collapsed .sb-item {
  justify-content: center; padding: 9px 6px;
  position: relative;
}
.app.sb-collapsed .sb-foot { justify-content: center; padding: 10px 6px; }
.app.sb-collapsed .sb-group { margin-bottom: 6px; }
.app.sb-collapsed .sb-group + .sb-group::before {
  content: ''; display: block;
  height: 1px; background: var(--border);
  margin: 2px 8px 8px;
}
/* Tooltip im collapsed-State */
.app.sb-collapsed .sb-item::after {
  content: attr(data-label);
  position: absolute; left: calc(100% + 8px); top: 50%;
  transform: translateY(-50%);
  background: var(--text); color: var(--bg);
  padding: 5px 10px; border-radius: 5px;
  font-size: 12px; font-weight: 500; white-space: nowrap;
  opacity: 0; pointer-events: none;
  transition: opacity var(--t-fast) var(--ease);
  z-index: 200;
}
.app.sb-collapsed .sb-item:hover::after { opacity: 1; }

/* ============================================================
   MODUL-INTERNE SIDEBAR — für "Programm im Programm"-Module
   ============================================================ */
.mod-shell {
  display: grid;
  grid-template-columns: 200px 1fr;
  height: calc(100vh - var(--topbar-h));
}
.mod-sidebar {
  background: var(--sidebar-bg);
  border-right: 1px solid var(--border);
  display: flex; flex-direction: column;
  overflow: hidden;
}
.mod-sb-head {
  padding: 16px 14px 12px;
  border-bottom: 1px solid var(--border);
}
.mod-sb-eyebrow {
  font-family: var(--font-mono); font-size: 10.5px;
  color: var(--text-faint); letter-spacing: 0.08em;
  text-transform: uppercase; margin-bottom: 4px;
}
.mod-sb-title {
  font-size: 15px; font-weight: 600;
  letter-spacing: -0.01em;
  display: flex; align-items: center; gap: 8px;
}
.mod-sb-title i { font-size: 18px; color: var(--brand); }

.mod-sb-scroll {
  flex: 1; overflow-y: auto; padding: 10px 8px;
}
.mod-sb-scroll::-webkit-scrollbar { width: 6px; }
.mod-sb-scroll::-webkit-scrollbar-thumb { background: var(--surface-3); border-radius: 3px; }

.mod-sb-group { margin-bottom: 14px; }
.mod-sb-group-label {
  font-size: 10px; font-weight: 600;
  letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--sidebar-faint); padding: 4px 10px 6px;
}
.mod-sb-item {
  display: flex; align-items: center; gap: 9px;
  padding: 7px 10px; border-radius: 6px;
  font-size: 13px; color: var(--text-muted); font-weight: 500;
  width: 100%; text-align: left;
  transition: all var(--t-fast) var(--ease);
  margin-bottom: 1px;
}
.mod-sb-item i { font-size: 15px; color: var(--sidebar-faint); flex-shrink: 0; }
.mod-sb-item:hover { background: var(--surface-2); color: var(--text); }
.mod-sb-item:hover i { color: var(--text); }
/* GEFIXT (Runde 115, R115-eng-3, NIEDRIG): die drei folgenden
   ".mod-sb-item.active..."-Deklarationen (color/background/badge) waren TOT
   -- der spaetere, unconditional "CIVARA-Design"-Block (siehe dort) hat
   gleiche Selektor-Spezifitaet und deklariert background/color sowie
   .badge bereits selbst. Entfernt statt umgestellt, analog zu R114-eng-2s
   .today-pill-Aufraeumung -- eine tote Fassung koennte sonst kuenftig
   faelschlich fuer die wirksame gehalten werden. */
.mod-sb-item .badge {
  margin-left: auto;
  font-family: var(--font-mono); font-size: 10px;
  background: var(--surface-2); color: var(--text-muted);
  padding: 1px 6px; border-radius: 4px;
}

.mod-sb-foot {
  border-top: 1px solid var(--border);
  padding: 10px 12px;
}
.mod-team-mini {
  display: flex; flex-wrap: wrap; gap: 4px;
}
.mod-team-mini .ava {
  width: 24px; height: 24px; border-radius: 50%;
  display: grid; place-items: center;
  font-size: 9.5px; font-weight: 600; color: #fff;
  letter-spacing: 0.02em;
}
.mod-team-mini-label {
  font-size: 10.5px; color: var(--text-faint);
  margin-bottom: 6px; font-family: var(--font-mono);
  letter-spacing: 0.04em; text-transform: uppercase;
}

.mod-content {
  overflow-y: auto;
  padding: 28px 28px 60px;
}
.mod-content::-webkit-scrollbar { width: 10px; }
.mod-content::-webkit-scrollbar-thumb {
  background: var(--surface-3); border-radius: 5px; border: 3px solid var(--bg);
}

/* MAIN */
.main { display: flex; flex-direction: column; overflow: hidden; background: var(--bg); }
.topbar {
  height: var(--topbar-h); display: flex; align-items: center;
  padding: 0 24px; gap: 14px; border-bottom: 1px solid var(--border);
}
.topbar-crumb { display: flex; align-items: center; gap: 6px; font-size: 13px; color: var(--text-muted); }
.topbar-crumb strong { color: var(--text); font-weight: 500; }
.cmdk {
  flex: 1; max-width: 420px; margin: 0 auto;
  display: flex; align-items: center; gap: 8px;
  padding: 6px 10px 6px 12px;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-md);
  color: var(--text-muted); font-size: 13px;
  transition: all var(--t-fast) var(--ease);
}
.cmdk:hover { border-color: var(--border-strong); }
.cmdk i { font-size: 15px; color: var(--text-faint); }
.cmdk-kbd { margin-left: auto; display: flex; gap: 3px; }
.cmdk-kbd kbd {
  font-family: var(--font-mono); font-size: 10.5px;
  padding: 1px 5px; background: var(--surface-2);
  border: 1px solid var(--border); border-radius: 4px;
  color: var(--text-muted);
}
.top-right { display: flex; align-items: center; gap: 2px; }
.top-icon {
  width: 32px; height: 32px; display: grid; place-items: center;
  border-radius: 7px; color: var(--text-muted); position: relative;
  transition: all var(--t-fast) var(--ease);
}
.top-icon:hover { background: var(--surface-2); color: var(--text); }
.top-icon i { font-size: 17px; }
.top-icon .dot {
  position: absolute; top: 7px; right: 7px;
  width: 6px; height: 6px; background: var(--brand);
  border-radius: 50%; border: 2px solid var(--bg);
}
.weather-chip {
  display: flex; align-items: center; gap: 6px;
  padding: 5px 10px; border-radius: 100px;
  background: var(--surface); border: 1px solid var(--border);
  font-size: 12.5px; color: var(--text-muted); margin-right: 4px;
}
.weather-chip i { font-size: 14px; color: var(--warning); }
.weather-chip strong { color: var(--text); font-weight: 500; }

/* CANVAS */
.canvas {
  flex: 1; overflow-y: auto; padding: 36px 36px 80px;
}
.canvas::-webkit-scrollbar { width: 10px; }
.canvas::-webkit-scrollbar-thumb { background: var(--surface-3); border-radius: 5px; border: 3px solid var(--bg); }
.shell { max-width: 1180px; margin: 0 auto; }
.view { animation: viewIn 240ms var(--ease); }
.view[hidden] { display: none; }
@keyframes viewIn { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: translateY(0); } }

/* PAGE HEAD */
.page-head {
  display: flex; align-items: flex-end; justify-content: space-between;
  margin-bottom: 32px; gap: 24px;
  /* Titel und Aktionen brechen bei Platznot untereinander. Die
     720-px-Stufe machte das schon per flex-direction: column; das hier
     greift stufenlos und damit auch dazwischen. */
  flex-wrap: wrap;
}
.page-head > * { min-width: 0; }
.page-eyebrow {
  font-family: var(--font-mono); font-size: 11px;
  color: var(--text-faint); letter-spacing: 0.06em;
  text-transform: uppercase; margin-bottom: 10px;
}
.page-title {
  font-size: 30px; font-weight: 600;
  letter-spacing: -0.025em; line-height: 1.05;
}
.page-title .accent { color: var(--brand-ink); }
.page-actions {
  display: flex; gap: 8px;
  /* Umbrechen statt ueber den Rand schieben: das Wochenprogramm hat sieben
     Knoepfe (Heute, vor/zurueck, Generieren, Teilen, A3-PDF, Wissen), die
     auf einem Handy nie nebeneinander passen. Ohne flex-wrap waren
     "A3-PDF" und "Wissen" ausserhalb des Bildes -- am Geraet gemeldet. */
  flex-wrap: wrap;
}

.btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 14px; border-radius: 8px;
  font-size: 13px; font-weight: 500; font-family: inherit;
  transition: all var(--t-fast) var(--ease);
  border: 1px solid transparent; white-space: nowrap;
}
.btn i { font-size: 15px; }
.btn.primary { background: var(--text); color: var(--bg); }
/* GEFIXT (Runde 117, R117-eng-1, NIEDRIG): diese Regel war seit dem
   CIVARA-Umbau (Runde 116) tot -- der spaetere Block ersetzt den
   Hovereffekt durch einen reinen Farbwechsel (#0E3A2F -> #145243) und
   deklariert kein `opacity`; bei gleicher Spezifitaet blieb diese fruehe
   Deklaration trotzdem LEBENDIG (opacity kommt in der spaeteren Regel gar
   nicht vor) und wirkte zusaetzlich zum Farbwechsel -- der Primaerknopf
   verblasste beim Hovern, statt sich abzusetzen. Dasselbe Vorgehen wie
   R115-eng-3 bei den toten .mod-sb-item.active-Deklarationen: entfernt,
   nicht umgestellt, da sie seit dem CIVARA-Umbau nicht mehr der gewollte
   Effekt ist. */
.btn.ghost { background: var(--surface); color: var(--text); border-color: var(--border); }
.btn.ghost:hover { background: var(--surface-2); border-color: var(--border-strong); }
.btn.small { padding: 5px 10px; font-size: 12px; }
/* GEFIXT (Runde 130, R130-eng-1, MITTEL -- Nachzuegler im eigenen
   R129-breit-2-Fix): R129-breit-2 hat die beiden toten Export-Knoepfe
   (Protokolle/Controlling) auf `disabled` gesetzt, mit der ausdruecklichen
   Begruendung "bewusst SICHTBAR deaktiviert statt stumm". Es gab dafuer aber
   keine passende Regel: die einzigen `[disabled]`-Regeln des Moduls sind
   `.lern-chip[disabled]` (Z. ~1104) und `.osm-row .btn[disabled]` (Z. ~1118),
   beide an einen anderen Kontext gebunden. Ein `<button class="btn ghost"
   disabled>` in `.page-actions` traf also KEINE davon -- und die
   UA-Stylesheet-Abschwaechung (Chrome: `color: GrayText`, grauer Grund)
   kommt nicht zum Zug, weil `button { color: inherit; background: none }`
   (Z. 97) und `.btn.ghost { background/color/border-color }` (Z. 440) als
   AUTOR-Regeln jede UA-Regel schlagen, unabhaengig von Spezifitaet.
   Ergebnis: der deaktivierte Knopf war von einem aktiven pixelgleich nicht
   zu unterscheiden -- inklusive `button { cursor: pointer }` (Z. 97) und
   weiterhin greifendem `.btn.ghost:hover` (`:hover` trifft auch deaktivierte
   Elemente). Der Knopf lud damit genauso zum Klicken ein wie vorher und tat
   genauso wenig; der `title`-Hinweis ist auf dem iPad (Zielgeraet, kein
   Hover) ohnehin unerreichbar. `pointer-events: none` statt nur
   `cursor: not-allowed`, damit der Hovereffekt gar nicht erst matcht --
   dasselbe Vokabular wie `.sb-item.disabled` (Z. 182). Bewusst generisch
   `.btn[disabled]`, nicht auf die zwei Knoepfe verengt: die spezifischere
   Regel `.osm-row .btn[disabled]` (0,3,0) behaelt ihre eigene Deckkraft. */
.btn[disabled] { opacity: 0.45; cursor: not-allowed; pointer-events: none; }

/* SECTION */
.section {
  padding-top: 32px; margin-top: 32px;
  border-top: 1px solid var(--border);
}
.section:first-of-type { border-top: none; padding-top: 0; margin-top: 0; }
.section-head {
  display: flex; align-items: baseline; justify-content: space-between;
  margin-bottom: 18px; gap: 12px;
}
.section-title-wrap { display: flex; align-items: baseline; gap: 10px; }
.section-title {
  font-size: 18px; font-weight: 600;
  letter-spacing: -0.015em; color: var(--text); line-height: 1.2;
}
.section-count {
  font-family: var(--font-mono); font-size: 12px;
  color: var(--text-faint); font-weight: 500;
}
.section-link {
  font-size: 12.5px; color: var(--text-muted);
  display: flex; align-items: center; gap: 2px; font-weight: 500;
}
.section-link:hover { color: var(--text); }
.section-link i { font-size: 13px; }

/* MODUL SUB-TABS — Sub-Navigation innerhalb eines Moduls */
.subtabs {
  display: flex; align-items: center; gap: 2px;
  border-bottom: 1px solid var(--border);
  margin: 0 0 28px 0;
  overflow-x: auto; scrollbar-width: none;
}
.subtabs::-webkit-scrollbar { display: none; }
.subtab {
  display: flex; align-items: center; gap: 7px;
  padding: 11px 14px;
  font-size: 13.5px; font-weight: 500;
  color: var(--text-muted); white-space: nowrap;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  transition: all var(--t-fast) var(--ease);
}
.subtab i { font-size: 16px; }
.subtab:hover { color: var(--text); }
.subtab.active {
  color: var(--text);
  border-bottom-color: var(--accent);
}
.subtab .count {
  font-family: var(--font-mono); font-size: 11px;
  padding: 1px 6px; border-radius: 4px;
  background: var(--surface-2); color: var(--text-muted);
  margin-left: 2px;
}
.subtab.active .count { background: var(--accent-soft); color: var(--brand-ink); }
.subtab .badge-alert {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--warning); margin-left: 4px;
}

/* FILTER-PILLS — z.B. im Inventar-Tab zum Umschalten zwischen Datentypen */
.filter-pills {
  display: inline-flex; gap: 2px;
  padding: 3px; background: var(--surface-2);
  border: 1px solid var(--border); border-radius: 8px;
  /* Umbrechen statt ueber den Rand schieben. Im Aufgaben-Pool sind es fuenf
     Reiter (Alle, Ueberfaellig, Bald, Pflicht, Ausloeser), bei den Pendenzen
     vier -- auf einem Handy passt beides nicht in eine Zeile. Ohne den
     Umbruch waren die hinteren Reiter ausserhalb des Bildes; am Geraet
     gemeldet, in der Messung als "Container scrollt" durchgerutscht. */
  flex-wrap: wrap;
  max-width: 100%;
}
.filter-pill {
  display: flex; align-items: center; gap: 6px;
  padding: 6px 12px;
  font-size: 13px; font-weight: 500;
  color: var(--text-muted);
  border-radius: 6px;
  transition: all var(--t-fast) var(--ease);
}
.filter-pill i { font-size: 15px; }
.filter-pill:hover { color: var(--text); }
.filter-pill.active {
  background: var(--surface); color: var(--text);
  box-shadow: 0 1px 2px rgba(0,0,0,0.04);
}
.filter-pill .count {
  font-family: var(--font-mono); font-size: 10.5px;
  color: var(--text-faint);
}
.filter-pill.active .count { color: var(--text-muted); }

.subview { animation: viewIn 240ms var(--ease); }
.subview[hidden] { display: none; }

/* ============================================================
   WERKHOF — Wochenraster (Mo-Fr Spalten mit Tasks)
   ============================================================ */
.wh-week {
  /* fluid: bricht selbst um, statt fuenf Spalten zu erzwingen */
  display: grid; grid-template-columns: repeat(auto-fit, minmax(min(9rem, 100%), 1fr));
  gap: 8px;
}
.wh-day {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-md); overflow: hidden;
  display: flex; flex-direction: column;
}
.wh-day.today { border-color: var(--brand); border-width: 2px; }
.wh-day-head {
  padding: 8px 10px;
  background: var(--surface-2);
  border-bottom: 1px solid var(--border);
  display: flex; align-items: center; justify-content: space-between;
}
.wh-day.today .wh-day-head { background: var(--brand-soft); }
.wh-day-label {
  font-size: 11px; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.04em;
  color: var(--text);
}
.wh-day.today .wh-day-label { color: var(--brand-ink); }
.wh-day-date {
  font-family: var(--font-mono); font-size: 10.5px;
  color: var(--text-faint);
}
.wh-task {
  display: flex; gap: 7px; align-items: flex-start;
  padding: 7px 10px; font-size: 11.5px;
  border-bottom: 1px solid var(--border);
  cursor: pointer;
  transition: background var(--t-fast) var(--ease);
}
.wh-task:hover { background: var(--surface-2); }
.wh-task:last-child { border-bottom: none; }
.wh-task .dot {
  width: 6px; height: 6px; border-radius: 50%;
  margin-top: 5px; flex-shrink: 0;
}
.wh-task-body { flex: 1; min-width: 0; }
.wh-task-name {
  font-weight: 500; line-height: 1.35;
  color: var(--text);
}
.wh-task-meta {
  display: flex; align-items: center; gap: 5px;
  margin-top: 3px;
}
.wh-task-meta .mini-ava {
  width: 16px; height: 16px; border-radius: 50%;
  display: grid; place-items: center;
  color: #fff; font-size: 8.5px; font-weight: 600;
}
.wh-task-meta .ini {
  font-size: 10px; color: var(--text-faint);
}
.wh-task-tag {
  font-size: 9.5px; font-weight: 500;
  padding: 1px 5px; border-radius: 4px;
  background: var(--info-soft); color: var(--info);
  letter-spacing: 0.02em;
}
.wh-task-tag.done { background: var(--success-soft); color: var(--success); }
.wh-day-add {
  margin: 5px 8px 8px;
  font-size: 11px; color: var(--brand-ink);
  background: none;
  border: 1px dashed var(--brand-soft);
  border-radius: 4px;
  padding: 4px;
  transition: all var(--t-fast) var(--ease);
}
.wh-day-add:hover { background: var(--brand-soft); }

/* Wetter-Karten (5-Tage Prognose, klickbar) */
.wh-wcards {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(min(6.5rem, 100%), 1fr));
  gap: 8px;
}
.wh-wcard {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-md);
  padding: 12px 10px;
  text-align: center;
  cursor: pointer;
  transition: all var(--t-fast) var(--ease);
}
.wh-wcard:hover { border-color: var(--border-strong); }
.wh-wcard.active {
  border-color: var(--brand); background: var(--brand-soft);
}
.wh-wcard-icon { font-size: 24px; line-height: 1; margin-bottom: 4px; }
.wh-wcard-day {
  font-size: 12px; font-weight: 700;
  letter-spacing: 0.02em; margin-bottom: 2px;
}
.wh-wcard-temp {
  font-family: var(--font-mono); font-size: 10.5px;
  color: var(--text-muted);
}
.wh-wcard-prec {
  font-family: var(--font-mono); font-size: 9.5px;
  color: var(--info); margin-top: 2px;
}

/* Vorschläge basierend auf Wetter */
.wh-suggest {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-md); padding: 14px 16px;
}
.wh-suggest-label {
  font-size: 10.5px; font-weight: 600;
  letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--text-faint); margin-bottom: 10px;
}
.wh-suggest-list {
  display: flex; flex-direction: column; gap: 2px;
}
.wh-suggest-item {
  display: flex; align-items: center; gap: 8px;
  font-size: 13px; color: var(--text);
  padding: 6px 0;
  border-bottom: 1px solid var(--border);
}
.wh-suggest-item:last-child { border-bottom: none; }
.wh-suggest-item::before {
  content: '→'; color: var(--brand-ink);
  font-weight: 700;
}

/* Jahresplan-Grid (12 Monate) */
.wh-year {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(min(11rem, 100%), 1fr));
  gap: 10px;
}
.wh-month {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-md); overflow: hidden;
}
.wh-month.current { border-color: var(--brand); border-width: 2px; }
.wh-month-head {
  padding: 9px 12px;
  background: var(--surface-2);
  display: flex; align-items: center; gap: 8px;
  border-bottom: 1px solid var(--border);
}
.wh-month.current .wh-month-head { background: var(--brand-soft); }
.wh-month-num {
  font-family: var(--font-mono); font-size: 10.5px;
  font-weight: 600; padding: 1px 7px;
  background: var(--brand-soft); color: var(--brand-ink);
  border-radius: 100px;
}
.wh-month-name {
  font-size: 13px; font-weight: 600;
}
.wh-month.current .wh-month-name { color: var(--brand-ink); }
.wh-month-hours {
  margin-left: auto;
  font-family: var(--font-mono); font-size: 10.5px;
  color: var(--text-faint);
}
.wh-month-tag {
  font-size: 9.5px; font-weight: 600;
  padding: 1px 5px; border-radius: 4px;
  background: var(--brand); color: #fff;
}
.wh-month-tag.security { background: #FEE2E2; color: #991B1B; }
.wh-month-task {
  display: flex; align-items: flex-start; gap: 6px;
  padding: 6px 12px;
  font-size: 11.5px;
  border-bottom: 1px solid var(--border);
}
.wh-month-task:last-child { border-bottom: none; }
.wh-month-task-name {
  flex: 1; line-height: 1.35;
  color: var(--text-muted); font-weight: 500;
}
.wh-month-task.security .wh-month-task-name {
  /* GEFIXT (Runde 138, R138-breit-3): #991B1B war ein Literal OHNE eigene
     Flaeche -- der Text sitzt auf der themenabhaengigen Monatskarte und lag
     im DUNKLEN Thema bei 2.23:1 (hell 8.86:1, deshalb nie aufgefallen).
     --berry ist der seit Runde 113/114 etablierte Token fuer "kritisch" in
     diesem Modul (9.57:1 hell / 7.00:1 dunkel) -- kein neuer Sonderton. */
  color: var(--berry); font-weight: 700;
}
.wh-month-task-meta {
  font-family: var(--font-mono); font-size: 9.5px;
  color: var(--text-faint);
}

/* Mini-Avatar */
.mini-ava {
  width: 16px; height: 16px; border-radius: 50%;
  display: inline-grid; place-items: center;
  color: #fff; font-size: 8.5px; font-weight: 600;
  flex-shrink: 0;
}

/* TODAY-Liste */
.today-card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg); overflow: hidden; }
.today-row {
  display: grid; grid-template-columns: 24px 1fr auto auto auto;
  align-items: center; gap: 14px; padding: 13px 18px;
  border-bottom: 1px solid var(--border);
  transition: background var(--t-fast) var(--ease); cursor: pointer;
}
.today-row:last-child { border-bottom: none; }
.today-row:hover { background: var(--surface-2); }
.today-check {
  width: 18px; height: 18px;
  border: 1.5px solid var(--text-faint); border-radius: 5px;
  cursor: pointer; transition: all var(--t-fast) var(--ease);
  display: grid; place-items: center;
}
.today-check:hover { border-color: var(--brand); }
.today-check.done { background: var(--success); border-color: var(--success); }
.today-check.done::after { content: '\2713'; color: #fff; font-size: 12px; font-weight: 700; }
.today-text { font-size: 14px; font-weight: 500; color: var(--text); }
.today-row.done .today-text { color: var(--text-faint); text-decoration: line-through; }
.today-sub { font-size: 12px; color: var(--text-muted); margin-top: 2px; }
.today-pill {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 8px; font-size: 11px; font-weight: 500;
  background: var(--surface-2); border-radius: 5px; color: var(--text-muted);
}
.today-pill i { font-size: 12px; }
/* GEFIXT (Runde 114, R114-eng-2, MITTEL): diese Deklaration war TOT --
   ".today-pill.high"/".today-pill.med" werden weiter unten (Abschnitt
   "TODAY-PILL Spezial-Farben fuer Status") bei GLEICHER Selektor-Spezifitaet
   ein zweites Mal deklariert; bei gleicher Spezifitaet gewinnt die SPAETERE
   Regel im Stylesheet, hier also #991B1B/#FEE2E2 bzw. #B45309/#FEF3C7 --
   niemals das hier stehende var(--brand). Die tote fruehere Fassung hatte
   trotzdem den exakten Rangfolgen-Fehler, den dieser Zyklus fuer
   .cert-badge.expired/.soon bereits gefixt hat ("hoch" gruen wie ein
   Erfolg, "mittel" korrekt orange) -- ein kuenftiger Umbau, der die
   scheinbar redundante spaetere Regel entfernt, wuerde diesen Fehler
   unbemerkt wieder sichtbar machen. Statt zwei Fassungen zu pflegen: die
   tote fruehere Deklaration entfernt, nur die spaetere (bereits korrekte)
   bleibt bestehen. */
.today-due {
  font-family: var(--font-mono); font-size: 11.5px;
  color: var(--text-muted); min-width: 56px; text-align: right;
}
/* GEFIXT (Runde 113, R110-breit-3, MITTEL): war var(--brand) -- (a) nur
   2.97:1 auf --surface (unter WCAG-AA 4.5:1), (b) --brand liegt farblich so
   nah an --success (beide gruen), dass "ueberfaellig" und "bestanden"
   praktisch ununterscheidbar waren (fuer Sehbehinderte/Farbfehlsichtige
   ohnehin, aber auch bei fluechtigem Betrachten). --berry (Pink/Rot) ist
   sowohl kontraststark als auch farblich eindeutig von --success/--warning
   getrennt -- konsistent mit .cert-badge.expired/.fa-tag.cert-expired/
   .status-pill.critical (siehe dort), die dieselbe Verwechslung trugen. */
.today-due.urgent { color: var(--berry); font-weight: 500; }
.today-assignee {
  width: 22px; height: 22px; border-radius: 50%;
  display: grid; place-items: center;
  font-size: 9.5px; font-weight: 600; color: #fff;
}

/* AUFGABEN-POOL */
.pool-row {
  display: grid; grid-template-columns: 128px 1fr auto auto auto;
  align-items: center; gap: 14px; padding: 12px 18px;
  border-bottom: 1px solid var(--border);
  transition: background var(--t-fast) var(--ease);
}
.pool-row:last-child { border-bottom: none; }
.pool-row:hover { background: var(--surface-2); }
.pool-typ {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 8px; font-size: 10.5px; font-weight: 500;
  border-radius: 5px; white-space: nowrap;
  background: var(--surface-2); color: var(--text-muted);
}
.pool-typ i { font-size: 12px; }
.pool-typ.wiederkehrend { color: var(--info);    background: var(--info-soft); }
.pool-typ.saisonal      { color: var(--success); background: var(--success-soft); }
.pool-typ.trigger       { color: var(--berry);   background: var(--berry-soft); }
.pool-quelle { font-size: 12px; color: var(--text-muted); margin-top: 2px; }
.pool-pflicht {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 10.5px; font-weight: 600;
  color: var(--brand-ink); background: var(--brand-soft);
  padding: 3px 7px; border-radius: 5px; white-space: nowrap;
}
.pool-pflicht i { font-size: 12px; }
/* „nie kontrolliert": fehlender Nachweis, kein Versäumnis — deshalb in der
   neutralen Info-Farbe und nicht im Alarm-Rot der überfälligen Fristen. */
.nie-kontrolliert {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 10.5px; font-weight: 600;
  color: var(--info); background: var(--info-soft);
  padding: 3px 7px; border-radius: 5px; white-space: nowrap;
}
.nie-kontrolliert i { font-size: 12px; }
.pool-add {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 12px; font-weight: 500; color: var(--text-muted);
  border: 1px solid var(--border); border-radius: 6px;
  padding: 6px 11px; min-height: 32px;
  transition: all var(--t-fast) var(--ease);
}
.pool-add:hover { color: var(--brand-ink); border-color: var(--brand); }
.pool-add.done { color: var(--success); border-color: var(--success-soft); background: var(--success-soft); }
.pool-add i { font-size: 14px; }

/* DOKUMENTE */
.dok-block { margin-top: 16px; border-top: 1px solid var(--border); padding-top: 12px; }
.dok-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; font-size: 13px; font-weight: 600; }
.dok-head span i { color: var(--text-faint); }
.dok-row { display: grid; grid-template-columns: 22px 1fr auto auto; align-items: center; gap: 10px; padding: 8px 10px; border: 1px solid var(--border); border-radius: var(--r-sm); margin-bottom: 6px; }
.dok-row > i { font-size: 18px; color: var(--brand-ink); }
.dok-name { font-size: 13px; font-weight: 500; word-break: break-word; }
.dok-meta { font-size: 11px; color: var(--text-faint); font-weight: 400; margin-top: 1px; }
.dok-empty { font-size: 12px; color: var(--text-faint); padding: 8px 2px; }

/* KAPAZITÄTS-MODELL */
.kap-summary { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(11rem, 100%), 1fr)); gap: 12px; margin-bottom: 16px; }
.kap-big { background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--r-md); padding: 14px 16px; }
.kap-big-num { font-size: 26px; font-weight: 600; line-height: 1; }
.kap-big-lbl { font-size: 11.5px; color: var(--text-muted); margin-top: 6px; }
.kap-bars { display: flex; flex-direction: column; gap: 8px; }
.kap-row { display: grid; grid-template-columns: 160px 1fr 64px; align-items: center; gap: 12px; }
.kap-label { font-size: 12.5px; color: var(--text); }
.kap-bar-wrap { height: 10px; background: var(--surface-2); border-radius: 6px; overflow: hidden; }
.kap-bar { height: 100%; background: linear-gradient(90deg, var(--brand-soft), var(--brand)); border-radius: 6px; }
.kap-val { font-size: 12px; text-align: right; color: var(--text-muted); }
.kap-note { margin-top: 14px; font-size: 12px; color: var(--text-faint); line-height: 1.5; }

/* MITARBEITENDE */
.cert-badge { display: inline-flex; align-items: center; gap: 4px; font-size: 10.5px; font-weight: 600; padding: 2px 7px; border-radius: 5px; vertical-align: middle; }
.cert-badge i { font-size: 12px; }
/* GEFIXT (Runde 113, R110-breit-3, MITTEL): "expired" (schwerwiegender)
   nutzte bisher --brand, waehrend das WENIGER dringliche "soon" bereits
   korrekt --warning (orange) trug -- "abgelaufen" wirkte dadurch WENIGER
   alarmierend als "laeuft bald ab". Siehe Kommentar an .today-due.urgent. */
.cert-badge.expired { color: var(--berry); background: var(--berry-soft); }
.cert-badge.soon { color: var(--warning); background: var(--warning-soft); }
.cert-badge.ok { color: var(--success); background: var(--success-soft); }
.cert-badge.inaktiv { color: var(--text-muted); background: var(--surface-2); }
.fa-tags { display: inline-flex; flex-wrap: wrap; gap: 5px; }
.fa-tag { display: inline-block; font-size: 11px; font-weight: 500; padding: 2px 8px; border-radius: 5px; background: var(--surface-2); color: var(--text-muted); }
.fa-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.fa-chip { display: inline-flex; align-items: center; gap: 5px; font-size: 12.5px; padding: 6px 11px; border: 1px solid var(--border); border-radius: 7px; cursor: pointer; user-select: none; }
.fa-chip:has(input:checked) { border-color: var(--brand); background: var(--brand-soft); color: var(--brand-ink); }
.zert-list { display: flex; flex-direction: column; gap: 6px; }
.zert-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 8px 10px; border: 1px solid var(--border); border-radius: var(--r-sm); }
.berecht-row { display: grid; grid-template-columns: 1fr 150px 32px; gap: 8px; align-items: center; margin-bottom: 6px; }

/* PROZESS-CHECKLISTEN */
.chk-chip { display: inline-flex; align-items: center; gap: 4px; font-weight: 600; color: var(--brand-ink); background: var(--brand-soft); padding: 1px 7px; border-radius: 5px; cursor: pointer; }
.chk-chip.full { color: var(--success); background: var(--success-soft); }
.chk-chip i { font-size: 13px; }
.chk-edit-row { display: grid; grid-template-columns: 22px 1fr 32px; gap: 8px; align-items: center; margin-bottom: 6px; }
.chk-num { width: 22px; height: 22px; border-radius: 50%; background: var(--surface-2); color: var(--text-muted); font-size: 11px; font-weight: 600; display: grid; place-items: center; }
.chk-progress { height: 8px; background: var(--surface-2); border-radius: 5px; overflow: hidden; margin-bottom: 6px; }
.chk-progress-bar { height: 100%; background: linear-gradient(90deg, var(--brand-soft), var(--brand)); border-radius: 5px; transition: width .2s; }
.chk-progress-lbl { font-size: 12px; color: var(--text-muted); margin-bottom: 12px; }
.chk-list { display: flex; flex-direction: column; gap: 6px; }
.chk-item { display: flex; align-items: flex-start; gap: 10px; padding: 11px 13px; border: 1px solid var(--border); border-radius: var(--r-sm); cursor: pointer; font-size: 13.5px; transition: background .12s, border-color .12s; }
.chk-item:hover { border-color: var(--brand); }
.chk-item input { margin-top: 2px; width: 17px; height: 17px; accent-color: var(--brand); flex-shrink: 0; }
.chk-item.done { background: var(--success-soft); border-color: var(--success-soft); }
.chk-item.done span { text-decoration: line-through; color: var(--text-muted); }

/* ROLLEN / LOGIN / EINSTELLUNGEN */
#login-overlay { position: fixed; inset: 0; background: var(--bg); display: flex; align-items: center; justify-content: center; z-index: 9999; padding: 20px; }
.login-box { background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg); padding: 28px; width: 100%; max-width: 460px; box-shadow: 0 24px 70px rgba(0,0,0,0.18); }
.login-head { display: flex; align-items: center; gap: 14px; margin-bottom: 20px; }
/* Bildmarke: kein eigener Hintergrund -- das PNG bringt Verlauf und
   abgerundete Ecken selbst mit, ein Grund darunter blitzt in den Ecken durch. */
.login-logo { width: 44px; height: 44px; border-radius: 11px; display: block; flex: none; }
.login-title { font-size: 17px; font-weight: 600; }
.login-sub { font-size: 13px; color: var(--text-muted); }
.login-list { display: flex; flex-direction: column; gap: 8px; margin-bottom: 8px; }
.login-person { display: flex; align-items: center; gap: 12px; width: 100%; text-align: left; padding: 11px 13px; border: 1px solid var(--border); border-radius: var(--r-md); background: var(--surface); cursor: pointer; transition: border-color .12s, background .12s; }
.login-person:hover { border-color: var(--brand); background: var(--surface-2); }
.login-person .ava { width: 36px; height: 36px; font-size: 13px; flex-shrink: 0; display: grid; place-items: center; }
.login-person-info { flex: 1; display: flex; flex-direction: column; }
.login-person-info strong { font-size: 14px; }
.login-person-info span { font-size: 12px; color: var(--text-muted); }
.login-rolle { font-size: 11px; font-weight: 600; display: inline-flex; align-items: center; gap: 4px; padding: 3px 9px; border-radius: 6px; white-space: nowrap; }
.rolle-mitarbeiter { color: var(--info); background: var(--info-soft); }
.rolle-leiter { color: var(--brand-ink); background: var(--brand-soft); }
.rolle-admin { color: #fff; background: #1F2937; }
.login-admin { margin-top: 4px; }
.login-foot { margin-top: 16px; font-size: 11.5px; color: var(--text-faint); line-height: 1.5; }
.user-chip { display: inline-flex; align-items: center; gap: 7px; padding: 3px 11px 3px 4px; border: 1px solid var(--border); border-radius: 20px; background: var(--surface); cursor: pointer; }
.user-chip:hover { border-color: var(--brand); }
.user-chip .ava { display: grid; place-items: center; }
.user-chip-role { font-size: 12px; font-weight: 500; color: var(--text-muted); }
.settings-account { display: flex; align-items: center; gap: 12px; padding: 12px; background: var(--surface-2); border-radius: var(--r-md); margin-bottom: 6px; }
.settings-account .ava { display: grid; place-items: center; }
.rollen-cards { display: flex; flex-direction: column; gap: 8px; }
.rollen-card { border: 1px solid var(--border); border-radius: var(--r-sm); padding: 10px 12px; }
.rollen-card.aktiv { border-color: var(--brand); background: var(--brand-soft); }
.rollen-card-head { font-size: 13px; font-weight: 600; display: flex; align-items: center; gap: 6px; }
.rollen-card-desc { font-size: 12px; color: var(--text-muted); margin-top: 3px; }
body[data-role="mitarbeiter"] .leiter-only { display: none !important; }
body[data-role="mitarbeiter"] .nav-leiter { display: none !important; }
.rolle-extern { color: var(--extern); background: var(--extern-soft); }
/* Extern = rein lesend: alle Bearbeitungs- und Feld-Aktionen ausblenden */
body[data-role="extern"] .leiter-only,
body[data-role="extern"] .nav-leiter,
body[data-role="extern"] .field-only { display: none !important; }

/* MITARBEITENDE — breite Zeilen */
.person-rows { display: flex; flex-direction: column; gap: 10px; }
.person-row { display: grid; grid-template-columns: 52px 1fr auto; gap: 16px; align-items: start; padding: 16px 18px; background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-md); cursor: pointer; transition: border-color .12s, background .12s; }
.person-row:hover { border-color: var(--brand); background: var(--surface-2); }
.person-row-ava { width: 48px; height: 48px; border-radius: 50%; display: grid; place-items: center; color: #fff; font-weight: 600; font-size: 16px; }
.person-row-main { min-width: 0; }
.person-row-top { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.person-row-name { font-size: 16px; font-weight: 600; }
.person-row-role { color: var(--text-muted); font-size: 13px; }
.person-row-meta { display: flex; flex-wrap: wrap; gap: 8px 16px; margin-top: 7px; font-size: 12.5px; color: var(--text-muted); }
.person-row-meta span { display: inline-flex; align-items: center; }
.person-row-meta i { font-size: 14px; margin-right: 4px; opacity: .7; }
.person-row-tags { display: flex; flex-wrap: wrap; gap: 5px; align-items: center; margin-top: 9px; }
.prt-label { font-size: 10px; color: var(--text-faint); text-transform: uppercase; letter-spacing: .05em; margin-right: 4px; }
/* GEFIXT (Runde 113, R110-breit-3, MITTEL): siehe Kommentar an .today-due.urgent. */
.fa-tag.cert-expired { color: var(--berry); background: var(--berry-soft); font-weight: 500; }
.fa-tag.cert-soon { color: var(--warning); background: var(--warning-soft); font-weight: 500; }
.person-row-side { display: flex; flex-direction: column; align-items: flex-end; gap: 8px; text-align: right; min-width: 150px; position: relative; }
.person-row-stats { display: flex; flex-direction: column; gap: 2px; font-size: 12px; color: var(--text-muted); }
.person-row-stats strong { color: var(--text); font-size: 13px; }
.person-row-edit { color: var(--text-faint); font-size: 18px; }
@media (max-width: 720px) {
  .person-row { grid-template-columns: 44px 1fr; }
  .person-row-side { grid-column: 1 / -1; align-items: flex-start; flex-direction: row; flex-wrap: wrap; min-width: 0; gap: 12px; }
  .person-row-edit { display: none; }
}

/* KARTE (Leaflet) */
.karte-divicon { background: none; border: none; }
.karte-marker {
  width: 30px; height: 30px; border-radius: 50% 50% 50% 0;
  transform: rotate(-45deg); display: grid; place-items: center;
  color: #fff; box-shadow: 0 1px 4px rgba(0,0,0,0.35); position: relative;
}
.karte-marker i { transform: rotate(45deg); font-size: 16px; }
.karte-dot {
  position: absolute; top: -3px; right: -3px;
  width: 11px; height: 11px; border-radius: 50%;
  background: #DC2626; border: 2px solid #fff; transform: rotate(45deg);
}
.karte-dot-bald { background: #F59E0B; }
.karte-dot-nie  { background: #2563EB; }
.karte-legend { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 12px; font-size: 12px; color: var(--text-muted); }
.karte-legend span { display: inline-flex; align-items: center; gap: 6px; }
.lg-dot { width: 12px; height: 12px; border-radius: 50%; display: inline-block; }
.karte-pop { min-width: 180px; font-family: var(--font-sans); }
.karte-pop strong { font-size: 13px; }
.karte-pop-sub { font-size: 11px; color: var(--text-muted); margin: 2px 0; }
.karte-pop-meta { font-size: 11px; color: var(--text-faint); margin-bottom: 8px; }
.karte-pop-btn { font-size: 12px; font-weight: 500; color: #fff; background: var(--brand); border-radius: 5px; padding: 5px 10px; width: 100%; }
.leaflet-popup-content { margin: 12px 14px; }

/* KARTE — Standort (GPS), Locate-Control, Suche */
.karte-loc-divicon { background: none; border: none; }
.karte-loc-dot {
  width: 16px; height: 16px; border-radius: 50%;
  background: #2563EB; border: 3px solid #fff;
  box-shadow: 0 0 0 2px rgba(37,99,235,0.45), 0 1px 4px rgba(0,0,0,0.4);
  animation: locPulse 1.8s ease-out infinite;
}
@keyframes locPulse { 0%{ box-shadow: 0 0 0 2px rgba(37,99,235,0.45); } 70%{ box-shadow: 0 0 0 14px rgba(37,99,235,0); } 100%{ box-shadow: 0 0 0 2px rgba(37,99,235,0); } }
.karte-locate-ctrl a { display: grid; place-items: center; font-size: 17px; color: var(--brand-ink); background: var(--surface); }
.karte-locate-ctrl a:hover { background: var(--surface-2); }
.karte-locate-ctrl a.locating { color: var(--info); animation: spin .9s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }
.karte-toolbar { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-bottom: 12px; }
.karte-search-wrap { position: relative; flex: 1 1 260px; min-width: 220px; }
.karte-search-wrap i { position: absolute; left: 10px; top: 50%; transform: translateY(-50%); color: var(--text-faint); font-size: 15px; pointer-events: none; }
.karte-search-wrap input { width: 100%; padding: 8px 12px 8px 32px; border: 1px solid var(--border); border-radius: var(--r-sm); background: var(--surface); color: var(--text); font-size: 13px; font-family: var(--font-sans); }
.karte-search-wrap input:focus { outline: none; border-color: var(--brand); }
.karte-sug-box { position: absolute; top: calc(100% + 4px); left: 0; right: 0; z-index: 500; background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-sm); box-shadow: 0 8px 24px rgba(0,0,0,0.14); overflow: hidden; }
.karte-sug { display: block; width: 100%; text-align: left; padding: 9px 12px; font-size: 13px; color: var(--text); background: none; border: none; border-bottom: 1px solid var(--border); cursor: pointer; }
.karte-sug:last-child { border-bottom: none; }
.karte-sug:hover { background: var(--brand-soft); }
.karte-sug-empty { padding: 10px 12px; font-size: 12px; color: var(--text-faint); }
.karte-gps-note { font-size: 11px; color: var(--info); font-weight: 500; }
.gps-btn { background: var(--brand); color: #fff; }
.gps-btn:hover { background: var(--brand-hover); }

/* SYNC-PILLE (Topbar) + Sync-Einstellungen */
.sync-pill { display: inline-flex; align-items: center; gap: 6px; padding: 5px 11px; border-radius: 999px; font-size: 12px; font-weight: 600; border: 1px solid var(--border); background: var(--surface-2); color: var(--text-muted); cursor: pointer; white-space: nowrap; transition: background .12s, color .12s, border-color .12s; }
.sync-pill i { font-size: 14px; }
.sync-pill:hover { border-color: var(--border-strong); }
.sync-pill.local   { color: var(--text-muted); }
.sync-pill.ok      { color: var(--success); background: var(--success-soft); border-color: transparent; }
.sync-pill.pending { color: var(--warning); background: var(--warning-soft); border-color: transparent; }
.sync-pill.offline { color: var(--berry); background: var(--berry-soft); border-color: transparent; }
.sync-pill.syncing { color: var(--info); background: var(--info-soft); border-color: transparent; }
.sync-pill.syncing i { animation: spin .9s linear infinite; }
.sync-toggle { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--text); margin: 4px 0; cursor: pointer; }
.sync-toggle input { width: 16px; height: 16px; accent-color: var(--brand); }
.sync-meta { font-size: 12px; color: var(--text-muted); background: var(--surface-2); padding: 8px 10px; border-radius: var(--r-sm); }
.sync-meta code { font-family: var(--font-mono); font-size: 11px; }
.sync-status-lg { display: flex; align-items: center; gap: 8px; font-size: 13px; font-weight: 600; padding: 8px 10px; border-radius: var(--r-sm); margin-bottom: 4px; }
.sync-contract { font-size: 12px; color: var(--text-muted); border: 1px solid var(--border); border-radius: var(--r-sm); padding: 8px 10px; }
.sync-contract summary { cursor: pointer; font-weight: 600; color: var(--text); }
.sync-contract pre { font-family: var(--font-mono); font-size: 11px; background: var(--surface-2); padding: 8px; border-radius: 5px; overflow-x: auto; margin-top: 8px; white-space: pre; }
@media (max-width: 700px) { .sync-pill span { display: none; } }

/* FOTO-DOKU (Feld) */
.foto-block { border-top: 1px solid var(--border); margin-top: 16px; padding-top: 12px; }
.foto-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px; }
.foto-head span { font-size: 13px; font-weight: 600; display: inline-flex; align-items: center; gap: 6px; }
.foto-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(92px, 1fr)); gap: 8px; }
.foto-thumb { position: relative; aspect-ratio: 1; border-radius: var(--r-sm); overflow: hidden; border: 1px solid var(--border); cursor: pointer; background: var(--surface-2); }
.foto-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.foto-thumb .foto-geo { position: absolute; left: 4px; bottom: 4px; font-size: 9px; font-weight: 600; color: #fff; background: rgba(0,0,0,0.55); border-radius: 4px; padding: 1px 5px; display: inline-flex; align-items: center; gap: 2px; }
.foto-thumb .foto-del { position: absolute; top: 3px; right: 3px; width: 22px; height: 22px; border-radius: 50%; background: rgba(0,0,0,0.55); color: #fff; display: grid; place-items: center; font-size: 13px; opacity: 0; transition: opacity .12s; }
.foto-thumb:hover .foto-del { opacity: 1; }
.foto-empty { font-size: 12px; color: var(--text-faint); padding: 4px 0; }
.foto-preview-strip { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.foto-preview-strip .foto-thumb { width: 64px; height: 64px; aspect-ratio: auto; }
.foto-lightbox img { max-width: 100%; max-height: 70vh; border-radius: var(--r-sm); display: block; margin: 0 auto; }
.foto-lightbox-meta { text-align: center; font-size: 12px; color: var(--text-muted); margin-top: 10px; }
/* QR */
.qr-wrap { display: grid; place-items: center; padding: 8px; }
.qr-wrap svg, .qr-wrap img { width: 240px; height: 240px; image-rendering: pixelated; background: #fff; border-radius: var(--r-sm); padding: 10px; border: 1px solid var(--border); }
.qr-url { font-family: var(--font-mono); font-size: 11px; color: var(--text-muted); word-break: break-all; text-align: center; margin-top: 10px; background: var(--surface-2); padding: 8px 10px; border-radius: var(--r-sm); }
.qr-note { font-size: 12px; color: var(--text-muted); margin-top: 10px; display: flex; gap: 8px; align-items: flex-start; }
.qr-note i { color: var(--brand-ink); margin-top: 1px; }
/* BENUTZERVERWALTUNG */
.user-list { display: flex; flex-direction: column; gap: 6px; }
.user-row { display: grid; grid-template-columns: 40px 1fr auto; gap: 12px; align-items: center; padding: 8px 10px; border: 1px solid var(--border); border-radius: var(--r-sm); }
.user-row .ava { width: 34px; height: 34px; font-size: 12px; }
.user-row-info strong { font-size: 14px; display: block; }
.user-row-info span { font-size: 12px; color: var(--text-muted); }
.user-row-actions { display: flex; gap: 4px; flex-wrap: wrap; }
/* AUTO-WOCHENPLAN */
.wh-plan-banner { display: flex; gap: 12px; align-items: flex-start; padding: 14px 16px; border: 1px solid var(--brand); background: var(--brand-soft); border-radius: var(--r-md); }
.wh-plan-banner-icon { width: 34px; height: 34px; border-radius: 9px; background: var(--brand); color: #fff; display: grid; place-items: center; font-size: 18px; flex-shrink: 0; }
.wh-plan-banner-title { font-size: 14px; font-weight: 700; display: flex; align-items: center; gap: 8px; }
.wh-plan-banner-text { font-size: 13px; color: var(--text); margin-top: 2px; }
.wh-plan-banner-meta { font-size: 11px; color: var(--text-muted); margin-top: 5px; display: inline-flex; align-items: center; gap: 5px; }
.wh-plan-banner-title { justify-content: flex-start; }
.wh-ai-out { display: flex; gap: 7px; align-items: flex-start; margin-top: 8px; padding: 9px 11px; background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-sm); font-size: 12.5px; color: var(--text); line-height: 1.45; }
.wh-ai-out i { color: var(--brand-ink); margin-top: 1px; flex-shrink: 0; }
.wh-ai-out .ti-loader-2 { animation: spin .9s linear infinite; }
.wh-task { position: relative; }
.wh-task-grund { font-size: 10.5px; color: var(--text-muted); margin-top: 3px; display: flex; align-items: flex-start; gap: 4px; line-height: 1.3; }
.wh-task-grund i { color: var(--warning); font-size: 12px; margin-top: 1px; flex-shrink: 0; }
.wh-task-check { background: none; border: none; color: var(--text-faint); cursor: pointer; font-size: 18px; padding: 0 2px; display: grid; place-items: center; }
.wh-task-check:hover { color: var(--success); }
.wh-task-done { opacity: 0.6; }
.wh-task-done .wh-task-name { text-decoration: line-through; }
.wh-task-done .wh-task-check { color: var(--success); }
/* Bündelungs-Umschalter + gruppierte Karten */
.wh-group-toggle { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.wh-group-label { font-size: 12px; color: var(--text-muted); font-weight: 600; display: inline-flex; align-items: center; gap: 5px; }
.wh-group-btn { font-size: 12px; font-weight: 500; padding: 5px 11px; border-radius: 999px; border: 1px solid var(--border); background: var(--surface); color: var(--text-muted); cursor: pointer; }
.wh-group-btn:hover { border-color: var(--border-strong); }
.wh-group-btn.active { background: var(--brand); color: #fff; border-color: transparent; }
.wh-bundle { border: 1px solid var(--border); border-left: 3px solid var(--text-faint); border-radius: var(--r-sm); padding: 7px 9px; margin-bottom: 6px; background: var(--surface); }
.wh-bundle.pflicht { border-left-color: var(--brand); background: var(--brand-soft); }
.wh-bundle-head { display: flex; justify-content: space-between; align-items: baseline; gap: 6px; }
.wh-bundle-name { font-size: 13px; font-weight: 600; line-height: 1.25; }
.wh-bundle-count { font-size: 12px; font-weight: 800; color: var(--brand-ink); }
.wh-bundle-detail { font-size: 11px; color: var(--text-muted); margin-top: 3px; display: flex; gap: 4px; align-items: flex-start; }
.wh-bundle-detail i { margin-top: 1px; flex-shrink: 0; }
.wh-bundle-meta { display: flex; align-items: center; gap: 4px; margin-top: 5px; flex-wrap: wrap; }
.wh-day-empty { color: var(--text-faint); font-size: 13px; text-align: center; padding: 14px 0; }
/* Lernbasis / Erfahrung */
.wh-task-lern { font-size: 10.5px; color: var(--lern); margin-top: 3px; display: flex; align-items: flex-start; gap: 4px; line-height: 1.3; }
.wh-task-lern i { margin-top: 1px; flex-shrink: 0; }
.lern-box { margin-top: 12px; border: 1px solid rgba(124,58,237,0.25); background: rgba(124,58,237,0.06); border-radius: var(--r-sm); padding: 10px 12px; }
.lern-box-h { font-size: 12px; font-weight: 600; color: var(--lern); display: flex; align-items: center; gap: 6px; margin-bottom: 8px; }
.lern-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.lern-chip { font-size: 12px; border: 1px solid rgba(124,58,237,0.35); background: var(--surface); color: var(--lern); border-radius: 999px; padding: 4px 10px; cursor: pointer; }
.lern-chip:hover { background: rgba(124,58,237,0.12); }
.lern-chip[disabled] { opacity: 0.6; pointer-events: none; }
.wissen-title { font-size: 13px; font-weight: 700; margin: 0 0 8px; }
.wissen-fn { margin-bottom: 12px; }
.wissen-fn-h { font-size: 13px; font-weight: 600; color: var(--lern); display: flex; align-items: center; gap: 6px; margin-bottom: 4px; }
.wissen-item { display: grid; grid-template-columns: 1fr auto 28px; gap: 8px; align-items: center; padding: 5px 8px; border: 1px solid var(--border); border-radius: var(--r-sm); margin-bottom: 4px; font-size: 13px; }
.wissen-meta { font-size: 11px; color: var(--text-faint); white-space: nowrap; }
/* OSM-Import */
.osm-list { display: flex; flex-direction: column; gap: 6px; }
.osm-row { display: grid; grid-template-columns: 22px 1fr auto auto auto; gap: 10px; align-items: center; padding: 8px 10px; border: 1px solid var(--border); border-radius: var(--r-sm); }
.osm-row > i { font-size: 18px; color: var(--brand-ink); }
.osm-row-info strong { font-size: 13.5px; display: block; }
.osm-row-info span { font-size: 11px; color: var(--text-muted); }
.osm-count { font-size: 12px; font-weight: 600; color: var(--brand-ink); background: var(--brand-soft); padding: 2px 8px; border-radius: 999px; white-space: nowrap; }
.osm-row .btn { padding: 5px 9px; font-size: 12px; }
.osm-row .btn[disabled] { opacity: 0.4; pointer-events: none; }

/* METRICS */
.metrics { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(10rem, 100%), 1fr)); gap: 12px; }
.metric {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-md); padding: 14px 16px;
  transition: all var(--t-fast) var(--ease);
}
.metric:hover { border-color: var(--border-strong); }
.metric-label {
  font-size: 11.5px; color: var(--text-muted); font-weight: 500;
  margin-bottom: 10px; display: flex; align-items: center; gap: 6px;
}
.metric-label i { font-size: 13px; color: var(--text-faint); }
.metric-row { display: flex; align-items: baseline; gap: 8px; }
.metric-value {
  font-size: 26px; font-weight: 600; letter-spacing: -0.025em;
  line-height: 1; font-feature-settings: 'tnum';
}
.metric-trend {
  font-size: 11.5px; font-weight: 500; font-family: var(--font-mono);
  display: inline-flex; align-items: center; gap: 2px;
}
/* GEFIXT (Runde 114, R114-eng-2, MITTEL, Nachzuegler im eigenen R110-breit-3-Fix):
   siehe Kommentar an .today-due.urgent -- derselbe Fehler an einer weiteren
   Stelle: der NEGATIVE Trend in genau den Uebersichts-Kacheln (#wh-stats),
   die dieser Zyklus gerade mit aria-live versehen hat, stand in derselben
   Gruenfamilie wie der POSITIVE Trend direkt daneben. */
.metric-trend.up { color: var(--success); }
.metric-trend.down { color: var(--berry); }
.metric-trend.flat { color: var(--text-muted); }
.metric-trend i { font-size: 13px; }
.metric-sub { font-size: 11.5px; color: var(--text-faint); margin-top: 6px; }

/* COLS */
.cols { display: grid; grid-template-columns: 1fr 300px; gap: 16px; align-items: start; }

/* FEED */
.feed-card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg); }
.feed-row {
  display: grid; grid-template-columns: 28px 1fr auto;
  gap: 12px; padding: 12px 18px;
  border-bottom: 1px solid var(--border); align-items: flex-start;
}
.feed-row:last-child { border-bottom: none; }
.feed-icon {
  width: 26px; height: 26px; border-radius: 7px;
  display: grid; place-items: center; font-size: 13px;
}
.feed-icon.ok { background: var(--success-soft); color: var(--success); }
.feed-icon.info { background: var(--info-soft); color: var(--info); }
.feed-icon.warn { background: var(--warning-soft); color: var(--warning); }
.feed-icon.dot { background: var(--brand-soft); color: var(--brand-ink); }
.feed-text { font-size: 13px; line-height: 1.45; color: var(--text-muted); }
.feed-text strong { color: var(--text); font-weight: 500; }
.feed-sub { font-size: 11.5px; color: var(--text-faint); margin-top: 2px; }
.feed-time { font-family: var(--font-mono); font-size: 10.5px; color: var(--text-faint); white-space: nowrap; padding-top: 4px; }

/* RAIL */
.rail-card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg); padding: 14px 16px; margin-bottom: 10px; }
.rail-eyebrow {
  font-size: 11px; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--text-faint); font-weight: 600;
  display: flex; align-items: center; gap: 6px; margin-bottom: 8px;
}
.rail-eyebrow i { font-size: 13px; color: var(--info); }
.rail-eyebrow.berry i { color: var(--berry); }
.rail-eyebrow.warn i { color: var(--warning); }
.rail-title { font-size: 15px; font-weight: 600; letter-spacing: -0.015em; line-height: 1.3; margin-bottom: 4px; }
.rail-meta { font-size: 12px; color: var(--text-muted); font-family: var(--font-mono); }
.rail-divider { height: 1px; background: var(--border); margin: 12px 0; }
.rail-list { display: flex; flex-direction: column; gap: 2px; }
.rail-item {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 8px; border-radius: 6px;
  font-size: 12.5px; color: var(--text-muted);
  transition: all var(--t-fast) var(--ease);
  width: 100%; text-align: left;
}
.rail-item i { font-size: 14px; color: var(--text-faint); }
.rail-item:hover { background: var(--surface-2); color: var(--text); }
.rail-item:hover i { color: var(--text); }
.rail-item kbd {
  margin-left: auto; font-family: var(--font-mono); font-size: 10px;
  padding: 1px 5px; background: var(--surface-2);
  border: 1px solid var(--border); border-radius: 4px; color: var(--text-faint);
}

/* MODULES grid */
.mods { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(10rem, 100%), 1fr)); gap: 10px; }
.mod {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-md); padding: 16px;
  display: flex; flex-direction: column; gap: 12px;
  cursor: pointer; transition: all var(--t-fast) var(--ease);
  text-align: left; position: relative; min-height: 110px;
}
.mod:hover { border-color: var(--border-strong); background: var(--surface-2); }
.mod-icon {
  width: 32px; height: 32px; border-radius: 8px;
  display: grid; place-items: center; background: var(--surface-2);
}
.mod-icon i { font-size: 17px; color: var(--text-muted); }
.mod[data-accent="rust"] .mod-icon { background: var(--brand-soft); }
.mod[data-accent="rust"] .mod-icon i { color: var(--brand-ink); }
.mod[data-accent="green"] .mod-icon { background: var(--success-soft); }
.mod[data-accent="green"] .mod-icon i { color: var(--success); }
.mod[data-accent="blue"] .mod-icon { background: var(--info-soft); }
.mod[data-accent="blue"] .mod-icon i { color: var(--info); }
.mod[data-accent="warn"] .mod-icon { background: var(--warning-soft); }
.mod[data-accent="warn"] .mod-icon i { color: var(--warning); }
.mod[data-accent="berry"] .mod-icon { background: var(--berry-soft); }
.mod[data-accent="berry"] .mod-icon i { color: var(--berry); }
.mod-name { font-size: 13.5px; font-weight: 600; letter-spacing: -0.005em; margin-top: auto; }
.mod-meta { font-family: var(--font-mono); font-size: 11px; color: var(--text-faint); display: flex; align-items: center; gap: 6px; }
.mod-meta .sep { opacity: 0.5; }
.mod-pip {
  position: absolute; top: 14px; right: 14px;
  font-family: var(--font-mono); font-size: 9.5px; font-weight: 500; letter-spacing: 0.04em;
  padding: 2px 6px; border-radius: 4px;
  background: var(--surface-3); color: var(--text-muted);
}
.mod-pip.beta { background: var(--info-soft); color: var(--info); }
.mod-pip.live { background: var(--success-soft); color: var(--success); }
.mod-pip.live::before {
  content: ''; display: inline-block;
  width: 5px; height: 5px; background: var(--success);
  border-radius: 50%; margin-right: 5px; vertical-align: 1px;
  animation: pulse 2s ease-in-out infinite;
}
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.4; } }
.mod.add {
  border-style: dashed; background: transparent;
  align-items: center; justify-content: center;
  text-align: center; color: var(--text-faint);
}
.mod.add:hover { color: var(--brand-ink); border-color: var(--brand); background: var(--brand-soft); }
.mod.add i { font-size: 20px; }
.mod.add .mod-name { color: inherit; margin: 0; }

/* ============================================================
   NEUE PATTERNS FÜR MODUL-VIEWS
   ============================================================ */

/* Filter Bar */
.filter-bar { display: flex; gap: 12px; align-items: center; margin-bottom: 24px; flex-wrap: wrap; }
.search-input {
  flex: 1; min-width: 240px;
  display: flex; align-items: center; gap: 8px;
  padding: 7px 14px; background: var(--surface);
  border: 1px solid var(--border); border-radius: var(--r-md);
}
.search-input i { font-size: 16px; color: var(--text-faint); }
.search-input input {
  flex: 1; border: none; outline: none; background: transparent;
  font-family: inherit; font-size: 13px; color: var(--text);
}
.search-input input::placeholder { color: var(--text-faint); }
.chip-group { display: flex; gap: 4px; padding: 3px; background: var(--surface-2); border-radius: var(--r-md); }
.chip {
  padding: 5px 12px; border-radius: 7px;
  font-size: 12.5px; font-weight: 500;
  color: var(--text-muted); transition: all var(--t-fast) var(--ease);
}
.chip:hover { color: var(--text); }
.chip.active { background: var(--surface); color: var(--text); box-shadow: 0 1px 2px rgba(0,0,0,0.06); }

/* Status-Pill (für Beschlüsse etc.) */
.status-pill {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 2px 8px; font-size: 11px; font-weight: 500;
  border-radius: 5px; letter-spacing: 0.01em;
}
.status-pill.passed { background: var(--success-soft); color: var(--success); }
.status-pill.in-kraft { background: var(--info-soft); color: var(--info); }
.status-pill.umsetzung { background: var(--warning-soft); color: var(--warning); }
/* GEFIXT (Runde 114, R114-eng-2, MITTEL, Nachzuegler im eigenen R110-breit-3-Fix):
   "abgelehnt" stand in derselben Gruenfamilie wie .passed/.answered direkt
   daneben -- siehe Kommentar an .today-due.urgent. */
.status-pill.rejected { background: var(--berry-soft); color: var(--berry); }
.status-pill.open { background: var(--surface-2); color: var(--text-muted); }
/* GEFIXT (Runde 113, R110-breit-3, MITTEL): siehe Kommentar an .today-due.urgent
   -- service_faellig/revision_faellig/maengel (service_faellig-Kategorie in
   der bereichsweiten Meldung-Zuordnung) sind "critical", nicht nur "anders". */
.status-pill.critical { background: var(--berry-soft); color: var(--berry); }
.status-pill.processing { background: var(--info-soft); color: var(--info); }
.status-pill.answered { background: var(--success-soft); color: var(--success); }

/* Beschluss-List */
.beschluss-list { display: flex; flex-direction: column; gap: 8px; }
.beschluss-item {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-md); padding: 16px 18px;
  cursor: pointer; transition: all var(--t-fast) var(--ease);
}
.beschluss-item:hover { border-color: var(--border-strong); }
.bes-meta { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; flex-wrap: wrap; }
.bes-id { font-family: var(--font-mono); font-size: 11px; color: var(--text-faint); font-weight: 500; }
.bes-cat {
  font-size: 11px; color: var(--text-muted); padding: 2px 7px;
  background: var(--surface-2); border-radius: 5px;
}
.bes-title { font-size: 15px; font-weight: 600; letter-spacing: -0.01em; margin-bottom: 6px; line-height: 1.3; }
.bes-summary { font-size: 13px; color: var(--text-muted); line-height: 1.5; margin-bottom: 10px; }
.bes-footer { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.bes-date { font-family: var(--font-mono); font-size: 11px; color: var(--text-faint); }
.bes-tags { display: flex; gap: 5px; }
.bes-tag {
  font-size: 10.5px; color: var(--text-faint);
  padding: 1px 6px; border-radius: 4px;
  background: var(--surface-2);
}

/* Person Card */
.person-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 10px; }
.person-card {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-md); padding: 14px 16px;
  transition: all var(--t-fast) var(--ease);
}
.person-card:hover { border-color: var(--border-strong); }
.person-head { display: flex; align-items: center; gap: 11px; margin-bottom: 10px; }
.person-ava {
  width: 36px; height: 36px; border-radius: 50%;
  display: grid; place-items: center;
  font-size: 12px; font-weight: 600; color: #fff; flex-shrink: 0;
}
.person-name { font-size: 13.5px; font-weight: 600; letter-spacing: -0.005em; line-height: 1.2; }
.person-role { font-size: 11.5px; color: var(--text-muted); margin-top: 2px; }
.person-list { display: flex; flex-direction: column; gap: 2px; }
.person-list li {
  list-style: none; font-size: 11.5px; color: var(--text-muted);
  padding: 3px 0; display: flex; align-items: center; gap: 6px;
}
.person-list li::before { content: '·'; color: var(--text-faint); font-weight: 700; }
.person-foot {
  display: flex; align-items: center; justify-content: space-between;
  margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--border);
  font-family: var(--font-mono); font-size: 10.5px; color: var(--text-faint);
}

/* Data Table */
.data-table-wrap {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-md); overflow: hidden;
}
.data-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.data-table thead th {
  text-align: left; padding: 10px 14px;
  font-size: 11px; font-weight: 600; letter-spacing: 0.03em;
  text-transform: uppercase; color: var(--text-faint);
  background: var(--surface-2);
  border-bottom: 1px solid var(--border);
}
.data-table tbody td {
  padding: 11px 14px; border-bottom: 1px solid var(--border);
  color: var(--text);
}
.data-table tbody tr:last-child td { border-bottom: none; }
.data-table tbody tr:hover { background: var(--surface-2); }
.data-table .mono { font-family: var(--font-mono); font-size: 11.5px; color: var(--text-muted); }
.data-table .text-muted { color: var(--text-muted); }

/* DSD Ticket Card */
.ticket-list { display: flex; flex-direction: column; gap: 10px; }
.ticket-card {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-md); padding: 16px 18px;
  display: grid; grid-template-columns: 1fr auto; gap: 16px;
  transition: all var(--t-fast) var(--ease); cursor: pointer;
}
.ticket-card:hover { border-color: var(--border-strong); }
.ticket-meta { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; flex-wrap: wrap; }
.ticket-id { font-family: var(--font-mono); font-size: 11px; color: var(--text-faint); font-weight: 500; }
.ticket-cat {
  font-size: 11px; padding: 2px 7px; border-radius: 5px;
  background: var(--surface-2); color: var(--text-muted);
}
.ticket-title { font-size: 14px; font-weight: 600; line-height: 1.35; margin-bottom: 4px; }
.ticket-preview { font-size: 12.5px; color: var(--text-muted); line-height: 1.5; }
.ticket-side {
  display: flex; flex-direction: column; align-items: flex-end; gap: 6px;
  font-family: var(--font-mono); font-size: 11px; color: var(--text-faint);
}

/* Kanal Card */
.kanal-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(12rem, 100%), 1fr)); gap: 12px; }
.kanal-card {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-md); padding: 16px;
  display: flex; flex-direction: column; gap: 10px;
}
.kanal-head { display: flex; align-items: center; gap: 10px; }
.kanal-icon {
  width: 34px; height: 34px; border-radius: 8px;
  display: grid; place-items: center;
}
.kanal-icon i { font-size: 18px; }
.kanal-name { font-size: 14px; font-weight: 600; }
.kanal-sub { font-size: 11.5px; color: var(--text-muted); }
.kanal-stat { display: flex; align-items: baseline; justify-content: space-between; }
.kanal-reach {
  font-family: var(--font-mono); font-size: 18px; font-weight: 600;
  letter-spacing: -0.02em; color: var(--text);
}
.kanal-label { font-size: 11px; color: var(--text-faint); }
.kanal-toggle {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 11px; font-weight: 500; color: var(--success);
}
.kanal-toggle.off { color: var(--text-faint); }
.kanal-toggle i { font-size: 12px; }

/* Vorlagen-Liste */
.vorlagen-list { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(14rem, 100%), 1fr)); gap: 8px; }
.vorlage {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-md); padding: 12px 14px;
  display: flex; align-items: center; gap: 12px;
  cursor: pointer; transition: all var(--t-fast) var(--ease);
}
.vorlage:hover { border-color: var(--border-strong); background: var(--surface-2); }
.vorlage-icon { font-size: 18px; }
.vorlage-info { flex: 1; min-width: 0; }
.vorlage-name { font-size: 13px; font-weight: 600; }
.vorlage-cat { font-size: 11px; color: var(--text-faint); }

/* Vereine-Liste */
.verein-list { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(14rem, 100%), 1fr)); gap: 10px; }
.verein-card {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-md); padding: 14px 16px;
}
.verein-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }
.verein-name { font-size: 14px; font-weight: 600; }
.verein-kat {
  font-size: 10.5px; padding: 2px 7px; border-radius: 5px;
  background: var(--surface-2); color: var(--text-muted);
}
.verein-meta { font-size: 12px; color: var(--text-muted); display: flex; gap: 14px; }
.verein-meta strong { color: var(--text); font-weight: 600; }

/* Finanz-Tabelle Total */
.data-table tr.total td { background: var(--surface-2); font-weight: 600; }
.data-table .num { font-family: var(--font-mono); text-align: right; font-feature-settings: 'tnum'; }
/* GEFIXT (Runde 114, R114-eng-2, MITTEL, Nachzuegler im eigenen R110-breit-3-Fix):
   negative Betraege standen in derselben Gruenfamilie wie positive direkt
   daneben -- siehe Kommentar an .today-due.urgent. */
.data-table .num.positive { color: var(--success); }
.data-table .num.negative { color: var(--berry); }

/* KI Mode Switcher */
.ki-modes { display: flex; gap: 6px; margin-bottom: 24px; flex-wrap: wrap; padding: 4px; background: var(--surface-2); border-radius: var(--r-md); }
.ki-mode {
  padding: 6px 14px; border-radius: 7px;
  font-size: 12.5px; font-weight: 500;
  color: var(--text-muted); transition: all var(--t-fast) var(--ease);
  display: flex; align-items: center; gap: 6px;
}
.ki-mode i { font-size: 14px; }
.ki-mode:hover { color: var(--text); }
.ki-mode.active { background: var(--surface); color: var(--text); box-shadow: 0 1px 2px rgba(0,0,0,0.06); }

/* CHAT */
.chat-shell {
  max-width: 760px; margin: 0 auto;
  display: flex; flex-direction: column;
  height: calc(100vh - var(--topbar-h) - 80px);
}
.chat-hero { text-align: center; padding: 24px 16px 32px; }
.chat-hero h2 { font-size: 28px; font-weight: 600; letter-spacing: -0.025em; margin-bottom: 8px; }
.chat-hero h2 .accent { color: var(--brand-ink); }
.chat-hero p { color: var(--text-muted); font-size: 14px; max-width: 460px; margin: 0 auto; }
.chat-thread { flex: 1; overflow-y: auto; padding: 8px 4px; display: flex; flex-direction: column; gap: 12px; }
.bubble { max-width: 78%; padding: 12px 16px; border-radius: 14px; font-size: 14px; line-height: 1.5; }
.bubble.user { align-self: flex-end; background: var(--text); color: var(--bg); border-bottom-right-radius: 4px; }
.bubble.bot { align-self: flex-start; background: var(--surface); border: 1px solid var(--border); border-bottom-left-radius: 4px; }
.bubble.bot strong { color: var(--brand-ink); font-weight: 500; }
.chat-input-wrap {
  margin-top: 16px; padding: 10px 14px;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg);
  display: flex; align-items: center; gap: 12px;
}
.chat-input-wrap input { flex: 1; border: none; font-family: inherit; font-size: 14px; outline: none; background: transparent; color: var(--text); }
.chat-input-wrap input::placeholder { color: var(--text-faint); }
.chat-send { width: 34px; height: 34px; border-radius: 50%; background: var(--text); color: var(--bg); display: grid; place-items: center; }
.chat-send:hover { opacity: 0.85; }
.chat-suggest { display: flex; flex-wrap: wrap; gap: 6px; justify-content: center; padding: 16px 0 8px; }
.suggestion {
  padding: 7px 13px; background: var(--surface);
  border: 1px solid var(--border); border-radius: 100px;
  font-size: 12.5px; color: var(--text-muted);
  transition: all var(--t-fast) var(--ease);
}
.suggestion:hover { border-color: var(--brand); color: var(--brand-ink); background: var(--brand-soft); }

/* STORE */
.store-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(290px, 1fr)); gap: 12px; }
.store-card {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-lg); padding: 18px;
  display: flex; flex-direction: column; gap: 12px;
  transition: all var(--t-fast) var(--ease);
}
.store-card:hover { border-color: var(--border-strong); }
.store-head { display: flex; align-items: flex-start; gap: 12px; }
.store-icon { width: 38px; height: 38px; border-radius: 10px; display: grid; place-items: center; flex-shrink: 0; background: var(--surface-2); }
.store-icon i { font-size: 20px; }
.store-icon.rust { background: var(--brand-soft); } .store-icon.rust i { color: var(--brand-ink); }
.store-icon.green { background: var(--success-soft); } .store-icon.green i { color: var(--success); }
.store-icon.blue { background: var(--info-soft); } .store-icon.blue i { color: var(--info); }
.store-icon.warn { background: var(--warning-soft); } .store-icon.warn i { color: var(--warning); }
.store-icon.berry { background: var(--berry-soft); } .store-icon.berry i { color: var(--berry); }
.store-info { flex: 1; min-width: 0; }
.store-name { font-size: 14px; font-weight: 600; letter-spacing: -0.005em; margin-bottom: 3px; }
.store-vendor { font-size: 11.5px; color: var(--text-muted); display: flex; align-items: center; gap: 5px; }
.store-vendor i { font-size: 12px; }
.store-badge { font-size: 10px; font-weight: 500; padding: 1px 6px; border-radius: 4px; letter-spacing: 0.03em; margin-left: 4px; }
.store-badge.verified { background: var(--success-soft); color: var(--success); }
.store-badge.official { background: var(--brand-soft); color: var(--brand-ink); }
.store-desc { font-size: 12.5px; color: var(--text-muted); line-height: 1.5; flex: 1; }
.store-foot { display: flex; gap: 10px; font-size: 10.5px; color: var(--text-faint); font-family: var(--font-mono); padding-top: 10px; border-top: 1px solid var(--border); }
.store-foot-item { display: flex; align-items: center; gap: 4px; }
.store-foot-item i { font-size: 12px; }
.store-actions { display: flex; gap: 6px; }
.store-actions .btn { flex: 1; justify-content: center; padding: 7px 12px; font-size: 12px; }
.btn.installed { background: var(--success-soft); color: var(--success); cursor: default; }
.store-tabs { display: flex; gap: 2px; margin-bottom: 18px; }
.store-tab { padding: 7px 12px; font-size: 12.5px; font-weight: 500; color: var(--text-muted); border-radius: var(--r-sm); transition: all var(--t-fast) var(--ease); }
.store-tab:hover { color: var(--text); background: var(--surface-2); }
.store-tab.active { color: var(--text); background: var(--surface-2); }
.store-tab .count { margin-left: 5px; font-size: 10px; font-family: var(--font-mono); padding: 1px 5px; border-radius: 4px; background: var(--surface-3); color: var(--text-muted); }
.store-tab.active .count { background: var(--text); color: var(--bg); }

/* RESPONSIVE */
@media (max-width: 1024px) {
  /* .metrics/.mods/.kanal-grid/.verein-list/.vorlagen-list bewusst NICHT
     hier -- ihre Basis-Regel ist seit der Fluid-Renovierung
     repeat(auto-fit, minmax(...)) und braucht keine Ueberschreibung mehr.
     Ein fixer Wert hier wuerde (gleiche Spezifitaet, spaetere Quellposition)
     die fluide Regel wieder aushebeln, wie es bis 2026-08-27 tatsaechlich
     passiert ist -- gemessen 0 Ueberlauf, aber die Spaltenzahl war trotzdem
     fix, weil genau diese Zeilen sie zurueckgesetzt haben. */
  .cols { grid-template-columns: 1fr; }
  .canvas { padding: 28px 24px 60px; }
}
@media (max-width: 720px) {
  :root { --sidebar-w: 60px; }
  .sb-brand-text, .sb-collapse, .sb-group-label, .sb-item .label,
  .sb-item .pip, .sb-user-info, .sb-user-menu { display: none; }
  .sb-item { justify-content: center; padding: 8px; }
  .canvas { padding: 22px 16px 60px; }
  .topbar { padding: 0 14px; }
  .cmdk { max-width: none; }
  .topbar-crumb { display: none; }
  /* .mods/.kanal-grid bewusst NICHT hier -- siehe Kommentar im
     1024px-Block oben. */
  .page-head { flex-direction: column; align-items: flex-start; }
  .page-title { font-size: 26px; }
  .today-row { grid-template-columns: 24px 1fr auto; }
  .today-pill, .today-assignee { display: none; }
  .weather-chip { display: none; }
  .person-grid { grid-template-columns: 1fr; }
  .data-table-wrap { overflow-x: auto; }
  .data-table { min-width: 520px; }
}

/* ============================================================
   STANDALONE-OVERRIDES: Werkhof als eigenständiges Modul
   ============================================================ */
.app {
  display: grid;
  grid-template-rows: var(--topbar-h) 1fr;
  grid-template-columns: 1fr;
  height: 100vh;
}
.mod-shell {
  height: 100%;
  grid-template-columns: 260px 1fr;
}
.mod-sidebar {
  background: var(--sidebar-bg);
}
.standalone-back {
  display: flex; align-items: center; gap: 7px;
  padding: 10px 14px;
  font-size: 12px; color: var(--text-muted);
  border-bottom: 1px solid var(--border);
  transition: all var(--t-fast) var(--ease);
  cursor: pointer;
}
.standalone-back:hover { background: var(--surface-2); color: var(--text); }
.standalone-back i { font-size: 14px; }
.mod-content {
  padding: 28px 36px 60px;
}
/* ============================================================
   INTERAKTIVE ZUSATZ-STYLES: Modals, Toasts, Forms, Actions
   ============================================================ */

/* MODAL-System */
.modal-overlay {
  position: fixed; inset: 0;
  background: rgba(15, 23, 42, 0.5);
  backdrop-filter: blur(2px);
  display: none; align-items: center; justify-content: center;
  z-index: 1000;
  opacity: 0;
  transition: opacity 200ms var(--ease);
}
.modal-overlay.show { display: flex; opacity: 1; }
.modal {
  background: var(--surface);
  border-radius: var(--r-lg);
  box-shadow: 0 20px 60px rgba(0,0,0,0.2), 0 8px 16px rgba(0,0,0,0.08);
  width: min(560px, 92vw);
  max-height: 88vh;
  display: flex; flex-direction: column;
  overflow: hidden;
  animation: modalIn 220ms var(--ease);
}
@keyframes modalIn {
  from { opacity: 0; transform: translateY(8px) scale(0.98); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}
.modal-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 18px 22px;
  border-bottom: 1px solid var(--border);
}
.modal-head h3 {
  font-size: 16px; font-weight: 600;
  letter-spacing: -0.01em;
  margin: 0;
}
.modal-close {
  width: 32px; height: 32px;
  display: grid; place-items: center;
  border-radius: 7px;
  background: transparent; color: var(--text-faint);
  transition: all var(--t-fast) var(--ease);
}
.modal-close:hover { background: var(--surface-2); color: var(--text); }
.modal-close i { font-size: 18px; }
.modal-body {
  padding: 22px;
  overflow-y: auto;
  flex: 1;
}
.modal-foot {
  display: flex; justify-content: flex-end; gap: 8px;
  padding: 14px 22px;
  border-top: 1px solid var(--border);
  background: var(--surface-2);
}

/* FORMS */
.form-grid {
  display: flex; flex-direction: column; gap: 16px;
}
.form-row { display: flex; flex-direction: column; gap: 6px; }
.form-row-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.form-row-3 { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 12px; }
.form-row label,
.form-row-2 label,
.form-row-3 label {
  font-size: 12px; font-weight: 500;
  color: var(--text-muted);
  margin-bottom: 2px;
}
/* GEFIXT (Runde 115, R115-breit-4, NIEDRIG): fuer reine Ueberschriften ohne
   jedes zugehoerige Formularfeld (z.B. "Erfasste Mängel", "Rollen &
   Kompetenzen") ist <label> semantisch falsch (kein `for=`-Ziel und keine
   Steuerelement-GRUPPE, die ein <fieldset>/<legend> rechtfertigt) -- dieselbe
   optische Erscheinung ohne das <label>-Element. */
.form-row-label { font-size: 12px; font-weight: 500; color: var(--text-muted); margin-bottom: 2px; }
/* GEFIXT (Runde 115, R115-breit-4, NIEDRIG): fieldset/legend fuer echte
   Steuerelement-GRUPPEN (Checkbox-/Chip-Auswahlen) -- <fieldset> braucht
   einen Reset (Browser-Default hat Rand/Innenabstand), <legend> soll optisch
   wie die uebrigen .form-row-Labels aussehen, nicht wie eine Browser-Legende. */
fieldset.form-row { border: none; padding: 0; margin: 0; min-width: 0; }
.form-row legend,
.form-row-2 legend,
.form-row-3 legend {
  font-size: 12px; font-weight: 500;
  color: var(--text-muted);
  padding: 0; margin-bottom: 6px;
}
.form-row > label,
.form-row-2 > div > label,
.form-row-3 > div > label {
  display: block;
}
input[type="text"],
input[type="number"],
input[type="date"],
input[type="email"],
select,
textarea {
  width: 100%;
  padding: 9px 12px;
  font-size: 14px;
  font-family: inherit;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  transition: border-color var(--t-fast) var(--ease), box-shadow var(--t-fast) var(--ease);
}
input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--brand);
  box-shadow: 0 0 0 3px var(--brand-soft);
}
textarea {
  resize: vertical;
  min-height: 80px;
  font-family: inherit;
}

/* CHECK-PILLS (Mehrfachauswahl Mitarbeiter etc.) */
.check-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 6px;
}
.check-pill {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 12px;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  font-size: 13px;
  cursor: pointer;
  transition: all var(--t-fast) var(--ease);
}
.check-pill:hover { border-color: var(--border-strong); }
.check-pill input { width: auto; margin: 0; }
.check-pill:has(input:checked) {
  background: var(--brand-soft);
  border-color: var(--brand);
  color: var(--brand-ink);
  font-weight: 500;
}

/* TOAST-System */
.toast-container {
  position: fixed;
  /* UNTEN, nicht oben: oben rechts liegen die Seiten-Aktionen ("+ Neue
     Pendenz", "Generieren", "Teilen", "A3-PDF"). Der Toast legte sich mit
     z-index 2000 darueber -- und weil .toast pointer-events wieder aktiviert,
     fing er die Klicks ab, solange er sichtbar war. Unten ist in allen
     Ansichten frei, und am Tablet liegt es naeher am Daumen. */
  bottom: 20px; right: 20px;
  display: flex; flex-direction: column-reverse; gap: 8px;
  z-index: 2000;
  pointer-events: none;
}
.toast {
  display: flex; align-items: center; gap: 9px;
  padding: 11px 16px;
  background: var(--text);
  color: var(--bg);
  border-radius: var(--r-md);
  font-size: 13.5px; font-weight: 500;
  box-shadow: 0 8px 24px rgba(0,0,0,0.18);
  opacity: 0; transform: translateX(20px);
  transition: opacity 220ms var(--ease), transform 220ms var(--ease);
  /* pointer-events bewusst NICHT auf auto: der Toast hat keine Interaktion,
     darf aber nichts abfangen, was unter ihm liegt. */
  pointer-events: none;
  max-width: 360px;
}
.toast.show { opacity: 1; transform: translateX(0); }
.toast i { font-size: 17px; flex-shrink: 0; }
.toast-success { background: #15803D; color: #fff; }
.toast-error   { background: #B91C1C; color: #fff; }
.toast-warning { background: #B45309; color: #fff; }
.toast-info    { background: var(--text); color: var(--bg); }

/* ROW-ACTIONS (Lösch-/Bearbeiten-Buttons in Listen) */
.row-action {
  width: 28px; height: 28px;
  display: grid; place-items: center;
  border-radius: 6px;
  background: transparent; color: var(--text-faint);
  transition: all var(--t-fast) var(--ease);
  opacity: 0.5;
}
.today-row:hover .row-action,
.data-table tr:hover .row-action { opacity: 1; }
.row-action:hover { background: var(--surface-2); color: var(--brand-ink); }
.row-action i { font-size: 14px; }

/* Wochenplan: Task-Delete-Button */
.wh-task { position: relative; }
.wh-task .wh-task-del {
  position: absolute; top: 4px; right: 4px;
  width: 20px; height: 20px;
  display: grid; place-items: center;
  border-radius: 4px;
  background: transparent; color: var(--text-faint);
  opacity: 0;
  transition: all var(--t-fast) var(--ease);
}
.wh-task:hover .wh-task-del { opacity: 1; }
.wh-task .wh-task-del:hover { background: var(--surface-2); color: var(--brand-ink); }
.wh-task .wh-task-del i { font-size: 11px; }

/* ============================================================
   DRAG & DROP — Wochenprogramm
   ============================================================ */
.wh-task {
  cursor: grab;
  user-select: none;
}
.wh-task:active { cursor: grabbing; }
.wh-task.dragging {
  opacity: 0.35;
  cursor: grabbing;
}
.wh-day {
  transition: background var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease);
}
.wh-day.drag-over {
  background: var(--brand-soft);
  border-color: var(--brand);
}
.wh-day.drag-over .wh-day-head {
  background: var(--brand-soft);
}
.wh-task.drop-before {
  box-shadow: inset 0 2px 0 0 var(--brand);
}
.wh-task.drop-after {
  box-shadow: inset 0 -2px 0 0 var(--brand);
}
.wh-day-drop-zone {
  min-height: 24px;
  margin: 0 8px 4px;
  border: 1px dashed transparent;
  border-radius: 4px;
  transition: all var(--t-fast) var(--ease);
}
.wh-day.drag-over .wh-day-drop-zone {
  border-color: var(--brand);
  background: rgba(0, 0, 0, 0.02);
}

/* EMPTY STATE */
.empty-state {
  padding: 32px 20px;
  text-align: center;
  color: var(--text-faint);
  font-size: 13.5px;
}

/* Mängel-Liste in Spielplatz-Detail */
.mangel-list {
  list-style: none; padding: 0; margin: 0;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  overflow: hidden;
}
.mangel-list li {
  display: flex; align-items: center; justify-content: space-between;
  padding: 10px 14px;
  border-bottom: 1px solid var(--border);
  font-size: 13.5px;
}
.mangel-list li:last-child { border-bottom: none; }
.mangel-list li.text-muted { color: var(--text-muted); font-style: italic; }

/* BTN-SMALL */
.btn-small { padding: 6px 12px; font-size: 12.5px; }

/* TODAY-PILL Spezial-Farben für Status */
.today-pill.high { background: #FEE2E2; color: #991B1B; }
.today-pill.med  { background: #FEF3C7; color: #B45309; }

/* RESET-BUTTON in Footer der Sidebar */
.demo-reset {
  margin-top: 8px;
  font-size: 11px;
  color: var(--text-faint);
  background: transparent;
  border: 1px dashed var(--border);
  border-radius: 5px;
  padding: 5px 8px;
  width: 100%;
  transition: all var(--t-fast) var(--ease);
}
.demo-reset:hover { color: var(--brand-ink); border-color: var(--brand-soft); }
.demo-reset i { font-size: 12px; }

/* ============================================================
   BARRIEREFREIHEIT: Bewegung reduzieren
   Respektiert die System-Einstellung "Bewegung reduzieren".
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ============================================================
   MOBILE: Modul-Content-Feinschliff unter 720px.
   Die Reiterleisten-Umwandlung selbst (.mod-shell/.mod-sidebar/.mod-sb-*)
   steht seit der Renovierung 2026-08 im @media (max-width: 1024px)-Block
   weiter unten -- 720px ist eine Teilmenge davon, eine zweite Deklaration
   hier hat frueher genau die Kaskaden-Falle erzeugt, die dieser Kommentar
   jetzt vermeidet (Ursache eines Bugs, gefunden im Code-Review 2026-08-27).
   ============================================================ */
@media (max-width: 720px) {
  .mod-content { padding: 20px 16px 60px; }
}


/* ============================================================
   CIVARA-DESIGN — Umbau nach Marken-Vorlage:
   dunkelgruene Sidebar, CIVARA-Gruen, Fraunces-Displaytitel
   ============================================================ */
:root { --font-display: 'Fraunces', Georgia, serif; }
.page-title { font-family: var(--font-display); font-weight: 600; letter-spacing: -0.2px; }
.login-title { font-family: var(--font-display); font-weight: 600; }
.chat-hero h2 { font-family: var(--font-display); }

.mod-sidebar { background: #0B2B23; border-right: none; }
.mod-sidebar .standalone-back { color: #9DBBAE; }
.mod-sidebar .standalone-back:hover { background: rgba(255,255,255,.06); color: #E8F4EE; }
/* GEFIXT (Runde 113, N4-Nachtrag, MITTEL): #5F8375/#4E7263 lagen auf dieser
   Sidebar-Flaeche (#0B2B23) bei 3.61:1 bzw. 2.83:1 -- unter WCAG-AA 4.5:1.
   #7BA391 (selbe Farbfamilie, heller) erreicht 5.41:1. */
.mod-sb-eyebrow { color: #7BA391; }
.mod-sb-title { color: #F2FAF6; }
.mod-sb-group-label { color: #7BA391; }
.mod-sb-item { color: #9DBBAE; }
/* GEFIXT (Runde 116, R116-eng-1, MITTEL): derselbe Nachzuegler wie
   R115-eng-2 (".active i"), diesmal im Hover-Zustand -- die fruehe
   Deklaration ".mod-sb-item:hover i { color: var(--text) }" blieb lebendig.
   Hell: var(--text) (#0A0A0B) auf der gemischten Hoverflaeche (#1A3830) =
   1.56:1 -- das Icon der Zeile, auf die gerade gezeigt wird, verschwand,
   waehrend die Beschriftung daneben aufhellte. */
.mod-sb-item:hover { background: rgba(255,255,255,.06); color: #DFF0E8; }
.mod-sb-item:hover i { color: #DFF0E8; }
.mod-sb-item.active { background: #2FBF8F; color: #0B2B23; font-weight: 600; }
/* GEFIXT (Runde 115, R115-eng-2, MITTEL): dieser Block ueberschrieb
   .mod-sb-item.active selbst, aber NICHT das darin verschachtelte Icon
   (".mod-sb-item.active i", siehe die jetzt entfernte fruehere Deklaration
   mit var(--brand)) -- die Icon-Regel blieb dadurch lebendig und faerbte
   das Icon der AKTIVEN Zeile weiterhin in --brand. Hell: #27A97E auf
   #2FBF8F = 1.27:1. DUNKEL: --brand ist dort selbst #2FBF8F -- Vorder- und
   Hintergrundfarbe identisch (1.00:1), das Icon war komplett UNSICHTBAR,
   ausgerechnet bei der aktiven (=interessantesten) Zeile der Navigation. */
.mod-sb-item.active i { color: #0B2B23; }
.mod-sb-item .badge { background: rgba(255,255,255,.14); color: #CFE7DD; }
.mod-sb-item.active .badge { background: rgba(11,43,35,.18); color: #0B2B23; }
.mod-sb-foot { border-top: 1px solid rgba(255,255,255,.08); }
/* GEFIXT (Runde 116, R116-eng-2, MITTEL): #4E7263 ist exakt die Farbe, die
   der Fix-Kommentar an .mod-sb-eyebrow/.mod-sb-group-label (siehe oben)
   bereits als 2.83:1 (unter WCAG-AA) benennt -- diese dritte, dauerhaft
   sichtbare Stelle ("Team aktiv" im Sidebar-Fuss) wurde beim damaligen Fix
   nicht mitgezogen. #7BA391 (derselbe Ersatzton wie dort) haelt in beiden
   Themes (5.41:1 hell, 6.11:1 dunkel). */
.mod-team-mini-label { color: #7BA391; }
/* GEFIXT (Runde 117, R117-breit-1/2, MITTEL/NIEDRIG): dieselbe Nachzuegler-
   Klasse wie R115-eng-2/R116-eng-1/R116-eng-2 ("dritte Stelle beim damaligen
   Fix nicht mitgezogen"), hier fuer Rahmenlinien statt Text/Icons -- `--border`
   ist im hellen Theme rgba(11,43,35,.10), rgb(11,43,35) IST #0B2B23 (die
   Sidebar-Flaeche selbst): Kontrast 1.00:1, die Linie ist buchstaeblich
   unsichtbar. In Runde 116 wurde nur .mod-sb-foot umgestellt (Zeile oben),
   der Sidebar-Kopf (.mod-sb-head) und der Zurueck-Knopf (.standalone-back,
   Standalone-Betrieb) blieben stehen. Die vorherige Zeile
   ".mod-sb-group + .mod-sb-group { border-color: ... }" war zudem eine TOTE
   Regel: KEINE der beiden Basisdeklarationen dieses Selektors setzt einen
   border-style/-width -- auf dem Desktop (Zeile 275, .mod-sb-group hat nur
   margin-bottom) entsteht dadurch ueberhaupt keine Linie, unter 1024px
   ueberschreibt die spaetere Kurzform in der Reiterleiste (Zeile 2103) die
   Farbe ohnehin wieder.
   GEFIXT (Runde 118, R118-eng-2, NIEDRIG -- Nachzuegler im eigenen R117-Fix):
   die urspruengliche Runde-117-Fassung nutzte hier `border-left` (2px) +
   `padding-left` (8px) + `margin-left` (2px) -- auf dem Desktop stehen die
   Gruppen aber UNTEREINANDER (anders als in der media-Ergaenzung unten, wo
   sie NEBENEINANDER stehen und derselbe linke Rand tatsaechlich ZWISCHEN
   zwei Gruppen liegt). Der Geschwister-Kombinator trifft die erste Gruppe
   nicht, sie behielt ihre Position, waehrend alle Folgegruppen um 12px nach
   rechts rueckten -- die Sidebar-Navigation stand als Treppe statt in einer
   Flucht, mit zusaetzlichem Breitenverlust fuer die Folgegruppen. `box-shadow:
   inset` legt denselben Akzentstrich ueber das Element, OHNE Platz im
   Boxmodell zu beanspruchen -- keine Verschiebung, keine Breitenaenderung. */
.mod-sb-head { border-bottom-color: rgba(255,255,255,.08); }
.standalone-back { border-bottom-color: rgba(255,255,255,.08); }
.mod-sb-group + .mod-sb-group { box-shadow: inset 2px 0 0 rgba(255,255,255,.10); }

/* GEFIXT (Runde 116, R116-breit-2, MITTEL): die Basisregel (Zeile ~429)
   koppelt background/color BEWUSST (var(--text)/var(--bg), themenabhaengig
   gegenlaeufig) -- dieser Block ersetzt NUR den Hintergrund durch die feste
   Markenfarbe und zerschneidet damit die Kopplung: color blieb var(--bg),
   im dunklen Theme also #0A0A0B auf #0E3A2F = 1.57:1. Betraf JEDEN
   Primaerknopf (Speichern/Anlegen/Uebernehmen/...) im dunklen Theme. */
.btn.primary { background: #0E3A2F; color: #F2FAF6; }
.btn.primary:hover { background: #145243; }
[data-theme="dark"] .mod-sidebar { background: #081F1A; }
[data-theme="dark"] .mod-sb-item.active { color: #06231C; }
/* GEFIXT (Runde 116, R116-eng-4, NIEDRIG): der Scrollgriff nutzte weiterhin
   var(--surface-3) (im dunklen App-Theme #25252B) -- auf der dunkelgruenen
   Sidebar (#081F1A) 1.13:1, praktisch unsichtbar. Bei ~14 Navigationspunkten
   laeuft die Liste auf kurzen Fenstern ueber; ohne sichtbaren Scrollgriff
   fehlt der einzige Hinweis auf weiter unten liegende Bereiche. */
[data-theme="dark"] .mod-sb-scroll::-webkit-scrollbar-thumb { background: #4E9078; }

/* Trockenperiode (Bewässerungs-Auslöser, Soll R12) */
.wh-trocken-row { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin-bottom: 10px; font-size: 12px; color: var(--text-muted); }
.trocken-stat { display: inline-flex; align-items: center; gap: 6px; }
.trocken-stat.aktiv { color: var(--brand-ink); }
.trocken-schwelle { display: inline-flex; align-items: center; gap: 6px; }
.trocken-schwelle input { width: 52px; padding: 2px 6px; font-size: 12px; }
.check-pill-row { display: flex; flex-wrap: wrap; gap: 8px; }

/* Jahresplan aus Daten (Soll R11) */
/* GEFIXT (Runde 116, R116-breit-5, NIEDRIG): .wh-month-task (siehe oben)
   deklariert nur border-bottom -- border-left-style: dashed setzte damit
   Farbe/Breite auf ihre CSS-Defaults (currentColor/medium ~3px) statt eines
   dezenten Markers: ein breiter, fast schwarzer Balken, der die Zeile
   zusaetzlich sichtbar einrueckte. */
.wh-month-task.abgeleitet { opacity: .72; border-left: 2px dashed var(--border); }
.wh-month-task-more, .wh-month-empty { font-size: 11px; color: var(--text-faint); padding: 4px 2px; }
.wh-blocker-hinweis { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: 12px; color: var(--text-muted); margin-bottom: 10px; }
.wh-blocker-hinweis .bl-pill { display: inline-flex; align-items: center; gap: 5px; background: var(--surface-2); border: 1px solid var(--border); border-radius: 999px; padding: 2px 9px; }

/* Routen-Ansicht (Soll R15) */
.wh-route { border: 1px solid var(--border); border-radius: 8px; padding: 8px; margin-bottom: 8px; background: var(--surface); }
.wh-route-head { display: flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 500; margin-bottom: 6px; }
.wh-route-total { margin-left: auto; font-size: 11px; color: var(--text-muted); font-variant-numeric: tabular-nums; }
.wh-route-stop { display: flex; align-items: flex-start; gap: 7px; padding: 3px 0; }
.wh-route-num { flex: 0 0 18px; height: 18px; border-radius: 50%; background: var(--brand); color: #fff; font-size: 10px; display: grid; place-items: center; font-variant-numeric: tabular-nums; }
.wh-route-stop.ohne-geo .wh-route-num { background: var(--text-faint); }
.wh-route-name { font-size: 12px; line-height: 1.3; }
.wh-route-meta { font-size: 10.5px; color: var(--text-faint); }

/* ============================================================
   RESPONSIVE-EBENE (Renovierung 2026-08)
   ============================================================

   Grundsatz wie im GA-Frontend: Inhalte sind fluid (auto-fit, min(),
   flex-wrap) und brauchen keine Breakpoints. Eine Schwelle bleibt --
   dort, wo ein Element zu etwas anderem wird statt nur seine Groesse zu
   aendern: die Modul-Navigation wechselt von der Spalte zur Reiterleiste.

   Diese Schwelle liegt bei 1024 px und nicht mehr bei 720 px. Ein iPad im
   Hochformat ist 768 px breit und fiel damit bisher in die Desktop-Stufe:
   260 px gingen an die Modul-Spalte, und der Werkhof lief um 82 px aus dem
   Bild (gemessen, siehe docs/layout-inventur-2026-08-27.md). Das iPad im
   Feld ist das wichtigste Zielgeraet dieses Moduls.

   Die Reiterleisten-Umwandlung (Kopf/Fuss/Labels ausblenden, Items in eine
   Zeile) galt zunaechst nur unter 720px -- der aeussere Rahmen wechselte
   bei 1024px auf Zeilenlayout, die inneren Elemente blieben aber bis 720px
   im Spalten-Layout haengen. Ergebnis: zwischen 721 und 1024px (exakt das
   iPad-Hochformat) eine ueber die volle Zeile ausgestreckte, aber innen
   weiterhin vertikal gestapelte Navigation -- optisch kaputt, gemessen
   aber unauffaellig, weil nichts *ueberlief*. Die komplette Umwandlung
   steht deshalb hier, in einem einzigen Block; der alte 720px-Block weiter
   unten deklariert diese Selektoren nicht mehr doppelt.
   ============================================================ */

@media (max-width: 1024px) {
  /* Modul-Navigation als Reiterleiste statt Spalte. Steht bewusst hier am
     Ende, damit es den Standalone-Override (.mod-shell 260px) in der
     Kaskade schlaegt. */
  .mod-shell {
    grid-template-columns: 1fr;
    grid-template-rows: auto 1fr;
    height: 100%;
  }
  .mod-sidebar {
    flex-direction: row;
    align-items: stretch;
    overflow-x: auto;
    overflow-y: hidden;
    border-right: none;
    border-bottom: 1px solid var(--border);
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .mod-sidebar::-webkit-scrollbar { display: none; }
  /* Vertikale Elemente auf dem schmalen Screen ausblenden */
  .mod-sidebar .standalone-back,
  .mod-sb-head,
  .mod-sb-foot,
  .mod-sb-group-label { display: none; }
  .mod-sb-scroll {
    display: flex;
    flex-direction: row;
    gap: 4px;
    padding: 8px 12px;
    overflow-x: visible;
  }
  .mod-sb-group {
    display: flex;
    flex-direction: row;
    gap: 4px;
    margin-bottom: 0;
  }
  /* Trennstrich zwischen Gruppen statt Labels */
  /* GEFIXT (Runde 119, R119-eng-1, NIEDRIG -- Regression im eigenen
     R118-eng-2-Fix): die Basisregel (oben im CIVARA-Block) nutzte bis
     Runde 117 dieselbe Eigenschaft (border-left) und wurde von dieser
     spaeteren Regel bei gleicher Spezifitaet vollstaendig ueberschrieben --
     unter 1024px war exakt EINE Linie sichtbar. Seit Runde 118 setzt die
     Basisregel stattdessen `box-shadow` (behebt den Desktop-Treppenversatz),
     eine Eigenschaft, die diese Regel nicht anfasst -- ohne `box-shadow:
     none` liefen unter 1024px BEIDE Deklarationen gleichzeitig: der
     1px-Rahmen dieser Regel UND der 2px-Inset-Schatten der Basisregel, macht
     einen Doppelstrich statt der einen gewollten Trennlinie. */
  .mod-sb-group + .mod-sb-group {
    border-left: 1px solid var(--border);
    padding-left: 4px;
    margin-left: 4px;
    box-shadow: none;
  }
  .mod-sb-item {
    width: auto;
    flex-shrink: 0;
    white-space: nowrap;
    margin-bottom: 0;
    min-height: 44px; /* Touch-Ziel ≥ 44px (PIXUS-Standard) */
  }

  /* Die Topbar darf schrumpfen. Ohne min-width:0 schiebt das Suchfeld die
     Leiste ueber den Rand, statt sich zu kuerzen. */
  .topbar { padding: 0 14px; gap: 10px; }
  .topbar > * { min-width: 0; }
  .cmdk { max-width: none; }
  .cmdk span:not(.cmdk-kbd) { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .cmdk-kbd { display: none; }

  /* Zeilen mit fixer erster Spalte und Aktionen rechts: umbrechen statt
     ueber den Rand schieben. */
  .pool-row {
    grid-template-columns: 1fr auto;
    row-gap: 6px;
  }
  .pool-add { justify-self: start; }

  /* Tabellen scrollen fuer sich, statt die Seite mitzunehmen. */
  .data-table-wrap { overflow-x: auto; max-width: 100%; }
  .data-table { min-width: 520px; }
}

/* GEFIXT (Runde 117, R117-breit-1/2, MITTEL/NIEDRIG): siehe ausfuehrlicher
   Kommentar beim CIVARA-Design-Block oben -- die Reiterleiste (<=1024px, der
   iPad-Fall) zeichnet ihre beiden Trennlinien (Abschluss gegen den
   Inhaltsbereich, Gruppentrennung dazwischen) mit var(--border), das im
   hellen Theme farblich mit der fest dunkelgruenen Sidebar-Flaeche
   verschmilzt (1.00:1). Muss NACH dem obigen @media-Block stehen, um bei
   gleicher Spezifitaet zu gewinnen. */
@media (max-width: 1024px) {
  .mod-sidebar { border-bottom-color: rgba(255,255,255,.08); }
  .mod-sb-group + .mod-sb-group { border-left-color: rgba(255,255,255,.10); }
}

@media (max-width: 720px) {
  /* Der Benutzer-Chip traegt Name und Rolle -- dafuer ist in einer 375 px
     breiten Leiste kein Platz (gemessen: 91 px darueber hinaus). Das Avatar
     allein genuegt; Name und Rolle stehen in den Einstellungen, die derselbe
     Knopf oeffnet. */
  .user-chip { padding: 3px; }
  .user-chip-name,
  .user-chip-role,
  .user-chip-text { display: none; }
  .sync-pill { padding: 0 8px; }

  /* Auf 375 px bleiben sechs Elemente rechts in der Leiste nicht nebeneinander
     stehen. Die Hilfe ist der Eintrag, der im Feld am wenigsten gebraucht wird
     und der ueber die Einstellungen erreichbar bleibt. */
  .top-icon[aria-label="Hilfe"] { display: none; }
  .topbar { gap: 6px; padding: 0 10px; }
}

/* Der Werkhof ist ein Nicht-Scroll-Layout: gescrollt wird im Canvas und in
   Tabellenrahmen, nie im Dokument. Ohne diese Klammer schiebt ein einzelnes
   zu breites Kind die ganze App seitwaerts. */
.app { max-width: 100vw; overflow-x: hidden; }
.topbar { min-width: 0; }
.canvas { min-width: 0; max-width: 100%; }

/* ============================================================
   BEDIENZIELE (Fingergroesse)
   ============================================================

   Haengt bewusst an `pointer: coarse` und nicht an der Bildschirmbreite.
   Der Werkhof wird im Feld bedient, teils mit Handschuhen -- entscheidend
   ist, WOMIT jemand tippt, nicht wie breit sein Schirm ist. Die Regel an
   eine Breite zu haengen liess ein Touch-Notebook oder ein iPad am
   externen Schirm mit 28-px-Zielen zurueck (im Code-Review aufgefallen:
   auf 1440 px zaehlte die Sonde 20 zu kleine Ziele).

   Die Auswahl folgt dem, was die Messung als zu klein gemeldet hat, nicht
   einer Vermutung.
   ============================================================ */

@media (pointer: coarse) {
  .top-icon,
  .sb-item,
  .btn-icon,
  .cmdk,
  .sync-pill,
  .user-chip,
  .mod-sb-item,
  .section-link {
    min-height: 44px;
  }
  .top-icon,
  .sb-item,
  .btn-icon {
    min-width: 44px;
  }
  .mod-sb-item,
  .section-link {
    display: flex;
    align-items: center;
  }
  input,
  select,
  textarea {
    min-height: 44px;
  }
}

/* ============================================================
 * EINGEBETTETER BETRIEB (Rahmen: Civara)
 *
 * Gesetzt von werkhof.js, sobald die App in einem iframe laeuft.
 *
 * Die eigene Bereichs-Navigation entfaellt -- sie wandert in die
 * Navigation des Rahmens, damit nicht zwei Seitenleisten nebeneinander
 * stehen. Die Kopfzeile BLEIBT, wird aber auf das reduziert, was der
 * Rahmen nicht traegt: Synchronisationsstand, Wetter und Konto. Marke,
 * Gemeindename und der Hell-/Dunkel-Schalter sind dort bereits vorhanden;
 * die Befehlspalette, "Hilfe" und die Glocke sind unbelegte Attrappen und
 * haben eingebettet erst recht nichts verloren.
 * ========================================================= */

html[data-eingebettet="1"] .mod-sidebar { display: none; }

/* mod-shell ist ein zweispaltiges Raster (Navigation | Inhalt). Ohne die
   Navigation muss die verbleibende Spalte die volle Breite bekommen --
   sonst bliebe links eine 200px breite Luecke stehen. */
html[data-eingebettet="1"] .mod-shell { grid-template-columns: 1fr; }

/* Dasselbe eine Ebene hoeher: .app stellt eine Spalte fuer eine
   Anwendungs-Seitenleiste bereit, die eingebettet niemand fuellt. */
html[data-eingebettet="1"] .app { grid-template-columns: 1fr; }

html[data-eingebettet="1"] .topbar-crumb,
html[data-eingebettet="1"] .cmdk,
html[data-eingebettet="1"] .top-right .top-icon { display: none; }

/* Die verbleibende Zeile ist eine Werkzeugleiste, keine zweite Kopfzeile:
   flacher, rechtsbuendig, ohne eigene Marke. */
html[data-eingebettet="1"] .topbar {
  height: auto;
  min-height: 44px;
  padding: 6px 20px;
  justify-content: flex-end;
}
