/* Helle Oberfläche: kühle Neutraltöne mit leichtem Blaustich,
   dazu die Signalfarben rot (offen), gelb (Überkapazität), violett (künftig). */
:root {
  color-scheme: light;

  --bg: #f4f6fa;
  --bg-soft: #fbfcfe;
  --card: #ffffff;
  --card2: #eef2f8;
  /* Die Organisationseinheit im Grün der Wortmarke - mit wenig Gewicht
     (06.10.2026): NUR der Kopf ist grün, die Fläche hinter den Rollen
     bleibt weiss, der Rand nimmt den Ton leise auf. */
  --oe-kopf: #e2f1e9;
  --oe-linie: #c7e2d4;
  --line: #d3dbe7;
  --line-soft: #e4e9f1;
  --text: #1b2437;
  --muted: #5e6a80;
  --brand: #2f5bd7;
  --brand-dark: #22459f;
  --brand-soft: #e6ecfb;
  --ok: #17845a;
  --warn: #a96b00;
  --warn-fill: #f3c24b;
  --warn-soft: #fdf3dc;
  --danger: #c4342f;
  --danger-fill: #e0564e;
  --danger-soft: #fdeceb;
  /* ⚠️ Kräftiger als --danger-soft: Die Pillen liegen auf den eingefärbten
     Flächen der Rollen, und dort verschwände ein zartes Rosa. */
  --overload-fill: #f7c4bf;
  --future: #6f47c9;
  --future-fill: #9b7cf0;
  --future-soft: #f0eafc;
  --marke-gruen: #00875a;    /* Wortmarke - satt und auf Weiss noch 4,55:1 */
  --radius: 12px;
  --shadow: 0 1px 2px rgba(27, 36, 55, .06), 0 1px 3px rgba(27, 36, 55, .04);
}

* { box-sizing: border-box; }
[hidden] { display: none !important; }

html { height: 100%; }
body {
  margin: 0;
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  background: var(--bg);
  color: var(--text);
  font-size: 15px;
  /* Organisationseinheiten und Mitarbeiter scrollen jede für sich, in ihrem
     eigenen Bereich: Beim Ziehen einer Person auf eine weit unten stehende
     Rolle muss beides gleichzeitig erreichbar bleiben.

     ⚠️ Trotzdem kein height: 100% und kein overflow: hidden hier. Beides
     hatte der Körper schon einmal - zusammen mit den festen Höhen von
     Kopfzeile, Zeitstrahl und Kennzahlen blieb auf einem Fenster von 620 px
     für die Planung ein Sehschlitz von 116 px übrig, den man nicht
     wegscrollen konnte. Stattdessen bekommen die Spalten von
     spaltenhoeheMessen() eine gemessene Höhe mit Untergrenze: Passt sie
     nicht mehr ins Fenster, wächst die Seite und scrollt eben doch. */
  min-height: 100%;
  display: flex;
  flex-direction: column;
}
.topbar, .timeline, .kpis { flex: 0 0 auto; }

h2 { font-size: 16px; margin: 0; }
h3 { margin: 0 0 12px; font-size: 17px; }

/* ---------- Topbar ---------- */
.topbar {
  display: flex; align-items: center;
  gap: 16px; flex-wrap: wrap;
  padding: 14px 20px;
  border-bottom: 1px solid var(--line);
  background: rgba(255, 255, 255, .88);
  position: sticky; top: env(safe-area-inset-top, 0px); z-index: 30;
  backdrop-filter: blur(8px);
}
/* ⚠️ Die Reihenfolge der Kopfzeile ist eine Aussage (03.10.2026): links das
   Menü (hinaus aus dieser Seite), daneben Rückgängig/Vor (zurück in der
   eigenen Arbeit), dann Marke und Organisationsname - die Antwort auf „wo
   bin ich". Ganz rechts allein das Abmelden. */
.kopf-links { display: flex; align-items: center; gap: 14px; flex: 0 0 auto; }
/* ⚠️ Die Grösse der Marke steht hier, seit sie ein eigenes Kind der
   Kopfzeile ist (03.10.2026) - vorher kam sie aus `.brand strong`, und mit
   diesem Kasten fiel sie weg: Die Marke stand plötzlich in Grundschrift da. */
.topbar .wortmarke { font-size: 25px; letter-spacing: -0.02em; }
/* ⚠️ Der Name der Organisation darf umbrechen und notfalls in einem Wort
   trennen: Er kommt vom Nutzer und kann beliebig lang sein - abgeschnitten
   wäre er die Antwort auf „wo bin ich", die man nicht lesen kann. */
#org-name { min-width: 0; overflow-wrap: anywhere; }
/* ⚠️ Das Abmelden bleibt rechts, auch wenn die Zeile umbricht: nicht über
   `justify-content`, sondern über diesen Rand - sonst hinge es an der
   Breite der Marke. */
.topbar-actions { margin-left: auto; }
/* ⚠️ Auf schmalen Geräten rutscht NUR der Organisationsname in die zweite
   Zeile (03.10.2026): Die Marke bleibt oben zwischen Menü und Abmelden -
   sie ist das Zeichen, an dem man die Seite erkennt, und gehört in die
   Zeile, die immer zu sehen ist. */
@media (max-width: 680px) {
  .topbar { gap: 10px; padding: 12px 14px; }
  .kopf-links { gap: 10px; }
  #org-name { font-size: 18px; }
  /* ⚠️ Die Marke schrumpft mit dem Fenster, statt umzubrechen: Sie ist ein
     Stück, das nicht trennbar ist, und soll in der ersten Zeile bleiben. */
  .topbar .wortmarke { font-size: clamp(14px, 3.9vw, 19px); padding: .18em .5em; }
}
@media (max-width: 560px) {
  .topbar .wortmarke { font-size: clamp(12px, 3.2vw, 19px); }
  .verlauf .btn.icon { width: 30px; height: 30px; }
  .verlauf .btn.icon svg { width: 18px; height: 18px; }
}
/* ⚠️ WAS umbricht, entscheidet eine Messung, keine Fensterbreite
   (`kopfzeileOrdnen()`, 03.10.2026): Die Breite der Zeile hängt am Namen
   der Organisation, und den schreibt der Nutzer. Erste Stufe: Der Name geht
   nach unten. Zweite Stufe, wenn das nicht reicht: auch der Verlauf - dann
   steht er neben dem Namen. Das Abmelden bleibt in beiden Fällen oben. */
.topbar.name-unten #org-name { order: 5; flex-basis: 100%; }
.topbar.verlauf-unten .kopf-links { display: contents; }
.topbar.verlauf-unten .verlauf { order: 4; }
.topbar.verlauf-unten.name-unten #org-name { flex: 1 1 auto; flex-basis: auto; }
.topbar-actions { display: flex; gap: 8px; flex-wrap: wrap; }

/* Rückgängig/Vor: zwei Zeichen neben dem Organisationsnamen. Sie sollen in
   der hellen Kopfzeile sofort ins Auge fallen - dunkler Strich, kräftiger
   Rand. Gesperrt sind sie blass und nicht anklickbar; ein Knopf, der nichts
   tun kann, soll auch so aussehen - aber noch lesbar bleiben. */
.verlauf { display: inline-flex; align-items: center; gap: 4px; }
.verlauf .btn.icon {
  width: 34px; height: 32px;
  border-color: var(--line);
  color: var(--text);
}
.verlauf .btn.icon svg { width: 21px; height: 21px; stroke: currentColor; stroke-width: 12; }
.verlauf .btn.icon:hover:not(:disabled) {
  color: var(--brand-dark); border-color: var(--brand); background: var(--brand-soft);
}
.verlauf .btn.icon:disabled { color: var(--muted); opacity: .5; cursor: default; }
.verlauf .btn.icon:disabled:hover { background: #fff; border-color: var(--line); }

/* ---------- Buttons & Eingaben ---------- */
.btn {
  border: 1px solid var(--line);
  background: #fff;
  color: var(--text);
  border-radius: 9px;
  padding: 7px 12px;
  font-size: 14px;
  cursor: pointer;
  line-height: 1.2;
}
.btn:hover { border-color: var(--brand); color: var(--brand); }
.btn.primary { background: var(--brand); border-color: var(--brand); color: #fff; font-weight: 600; }
.btn.primary:hover { background: var(--brand-dark); border-color: var(--brand-dark); color: #fff; }
.btn.primary.danger-solid { background: var(--danger); border-color: var(--danger); }
.btn.primary.danger-solid:hover { background: #a82b27; border-color: #a82b27; }
.btn.ghost { background: transparent; color: var(--muted); }
.btn.ghost:hover { color: var(--brand); }
.btn.danger:hover { border-color: var(--danger); color: var(--danger); }
.btn.small { padding: 5px 9px; font-size: 13px; }
.btn.toggle { background: transparent; color: var(--muted); }
.btn.toggle:hover { color: var(--future); }
/* „Einzelansicht OE", solange sie aktiv ist: violett wie alles, was
   filtert - sie ist ein Filter auf diese eine Einheit. */
.btn.toggle.on {
  background: var(--future-soft); border-color: #c9b6f2;
  color: #4a2f91; font-weight: 600;
}
.btn.icon { padding: 7px 13px; font-size: 15px; line-height: 1; }
.btn.link {
  background: none; border: none; color: var(--muted);
  padding: 2px 4px; font-size: 12px; text-decoration: underline; cursor: pointer;
}
.btn.link:hover { color: var(--brand); }

input[type="text"], input[type="number"], input[type="date"], input[type="search"], select, textarea {
  background: #fff;
  border: 1px solid var(--line);
  color: var(--text);
  border-radius: 8px;
  padding: 7px 9px;
  font-size: 14px;
  font-family: inherit;
}
input:focus, select:focus, textarea:focus, .btn:focus-visible {
  outline: 2px solid var(--brand); outline-offset: 1px;
}
label { font-size: 13px; color: var(--muted); }

.inline-form { display: flex; gap: 6px; }
.inline-form input[type="text"] { min-width: 272px; flex: 1 1 272px; }

/* ---------- Zeitstrahl ---------- */
.timeline {
  display: flex; align-items: center; gap: 20px; flex-wrap: wrap;
  padding: 12px 20px;
  border-bottom: 1px solid var(--line);
  background: var(--card2);
  position: sticky; top: calc(var(--topbar-h, 64px) + env(safe-area-inset-top, 0px)); z-index: 25;
}
.timeline-head { display: flex; align-items: center; gap: 8px; }
.month-jump { display: flex; flex-direction: column; gap: 3px; }
.month-jump .btn { padding: 3px 9px; }
.month-display { min-width: 165px; text-align: center; }
.month-label { display: block; font-weight: 700; font-size: 17px; }
/* „Heute" im Markengrün - derselbe Ton wie der Knopf zur graphischen
   Darstellung. Er springt an den Anfang und ist damit der einzige
   Sprungknopf am Zeitstrahl; blass war er dort zu leicht zu übersehen. */
.heute-knopf {
  background: var(--marke-gruen); border-color: var(--marke-gruen);
  color: #fff; font-weight: 600;
  box-shadow: 0 1px 2px rgba(0, 135, 90, .25);
}
.heute-knopf:hover { background: #016c48; border-color: #016c48; color: #fff; }
/* Ein künftiger Monat als orange Plakette - dieselben Töne wie die Marke
   „über 0,20" an einer Rolle, nur grösser. So sieht man auf einen Blick,
   dass man nicht im laufenden Monat arbeitet. */
.month-label.zukunft {
  display: inline-block;
  padding: 1px 10px; border-radius: 999px;
  color: #86560a; background: var(--warn-soft); border: 1px solid #e8cf96;
}
.slider-wrap { flex: 1 1 320px; min-width: 260px; position: relative; }
#month-slider { width: 100%; accent-color: var(--brand); margin: 0; }
.ticks { position: relative; height: 10px; margin-top: 2px; }
/* ⚠️ Der Strich ist 2px breit, die Trefferfläche darf das nicht sein: Der
   Kasten liesse sich sonst kaum treffen. Deshalb ein 12px breites Feld mit
   dem Strich darin - sichtbar bleibt der Strich. */
.ticks span {
  position: absolute; top: 0; width: 12px; height: 10px;
  transform: translateX(-6px); cursor: pointer;
}
.ticks span::after {
  content: ''; position: absolute; left: 5px; top: 0; width: 2px; height: 7px;
  background: var(--warn); border-radius: 1px;
}
.ticks span:hover::after { height: 10px; background: var(--warn-dark, #8a5600); }
.slider-ends { display: flex; justify-content: space-between; font-size: 11px; color: var(--muted); }

/* ---------- Kennzahlen ---------- */
.kpis {
  display: grid; gap: 10px; padding: 14px 20px 0;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
}
.kpi {
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 10px 13px; box-shadow: var(--shadow);
  display: flex; flex-direction: column; gap: 1px;
  font: inherit; text-align: left;
}
button.kpi { cursor: pointer; }
button.kpi:hover { border-color: var(--future); }
.kpi .k-label { font-size: 12px; color: var(--muted); }
.kpi .k-value { font-size: 20px; font-weight: 700; font-variant-numeric: tabular-nums; }
/* Der Verweis bekommt Luft nach oben - sonst klebt er an der Zahl und
   liest sich wie ihre Einheit. */
.kpi .k-link { font-size: 12px; color: var(--future); font-weight: 600; margin-top: 6px; }
.kpi.future.on { background: var(--future-soft); border-color: #c9b6f2; }
/* Eine Kachel, nach der gerade gefiltert wird, trägt dieselbe violette
   Fläche wie die künftigen - sie ist dann kein Kennwert mehr, sondern der
   Grund, warum die Listen daneben kurz sind. */
.kpi.aktiv { background: var(--future-soft); border-color: #c9b6f2; }
.kpi.gap .k-value { color: var(--danger); }
.kpi.over .k-value { color: var(--warn); }
.kpi.future .k-value { color: var(--future); }

/* ---------- Grundraster ---------- */
.columns {
  display: grid; gap: 16px; padding: 16px 20px;
  /* ⚠️ Immer DREI Spuren, die dritte im Normalfall 0 breit: Ändert sich die
     Anzahl der Spuren, kann der Browser nicht dazwischen rechnen - die
     Spalten springen. Mit gleichbleibender Anzahl gleiten die Breiten, und
     die bestehende Liste wandert sichtbar nach links, während die neue von
     rechts hereinzieht. */
  /* ⚠️ 70 % Einheiten, 30 % Mitarbeiter - als Verhältnis, nicht als feste
     Breite: Auf einem grossen Bildschirm wuchsen sonst nur die
     Rollenbalken, während die Kartenspalte bei 400px stehen blieb.
     ⚠️ Die leere dritte Spur steht als `0fr`, nicht als `0px`: Zwischen
     einer festen und einer Anteilsbreite kann der Browser nicht rechnen -
     die Spalte spränge herein, statt zu wachsen. */
  grid-template-columns: minmax(0, 7fr) minmax(0, 3fr) minmax(0, 0fr);
  grid-template-areas: "oe ma1 ma2";
  transition: grid-template-columns .5s ease;
  /* Beide Spalten füllen die Zeile gleich hoch aus - jede scrollt darin für
     sich. Die Höhe selbst setzt spaltenhoeheMessen() in planung.js
     (Fenster minus Kopf, mindestens 320 px). */
  align-items: stretch;
  flex: 1 1 auto;
  min-height: 0;
}
.col { display: flex; flex-direction: column; min-height: 0; }
.col-units { grid-area: oe; }
.col-staff { grid-area: ma1; }
.col-staff-zwei { grid-area: ma2; }
/* ⚠️ Beim Hereinkommen wird die Spalte nicht eingeblendet, sondern sie
   WÄCHST: Die Einheiten werden schmäler, ihre Spur breiter - dabei schieben
   sie die andere Liste vor sich her nach links. `overflow: hidden` hält den
   Inhalt in der wachsenden Spur, sonst stünde er schon da, bevor Platz für
   ihn ist.
   Hinaus geht sie wie eine gelöschte Zeile: blass und zur Seite. Dieselbe
   Dauer wie `ZWEITE_DAUER` in planung.js - erst danach wird sie versteckt. */
/* Die Dauer gehört zu `ZWEITE_WEG` in planung.js - das Verschwinden darf
   dauern, danach erst wandern die Breiten. */
.col-staff-zwei { overflow: hidden; transition: opacity .7s ease, transform .7s ease; }
.col-staff-zwei.geht { opacity: 0; transform: translateX(48px); }
/* Wer Bewegung abbestellt hat, bekommt keine. */
@media (prefers-reduced-motion: reduce) {
  .col-staff-zwei, .columns, .col-staff { transition: none; }
}
/* ⚠️ Dasselbe Mass wie in der ersten Spalte: Dort sitzt das Suchfeld in
   `.search` mit 10px Abstand nach unten, darüber die Kopfzeile mit 10px.
   Ohne den gleichen Wert stehen die beiden Felder nebeneinander auf
   verschiedener Höhe. */
#staff2-search { width: 100%; margin: 0 0 10px; }
/* Die Pille der zweiten Liste steht wie die der ersten über dem Suchfeld. */
#staff2-filter {
  margin: 0 0 10px;
  display: flex; flex-direction: column; align-items: flex-start; gap: 6px;
}
#staff2-filter:empty { display: none; }
#staff2-filter .seg { max-width: 100%; }
#staff2-filter .seg button { max-width: 100%; white-space: normal; }

/* ---------- Zwei Mitarbeiterspalten ----------

   Sind „Workload-Overloads" und „Überkapazitäten" zugleich gefiltert,
   schiebt sich rechts eine zweite Liste herein. ⚠️ Die Einheiten werden
   dafür schmäler, nicht die Listen: Die Rollenbalken vertragen weniger
   Breite als zwei Kartenspalten nebeneinander. */
/* Herein gemächlich, zurück zügig - wie die Spalte selbst. */
/* Mit zwei Listen teilen sich diese nicht das eine Drittel - dann stünden
   zwei Kartenspalten zu je einem Sechstel da. Die Einheiten geben ab, wie
   bisher: die Hälfte ihnen, je ein Viertel den Listen. */
.columns.zwei-ma {
  grid-template-columns: minmax(0, 2fr) minmax(0, 1fr) minmax(0, 1fr);
  transition-duration: .9s;
}
/* ⚠️ Die Lücke zur dritten Spur bleibt auch bei Breite 0 stehen - ohne
   diesen Ausgleich endete die Liste 16px vor dem Rand, solange sie allein
   steht. Mitanimiert, damit auch das gleitet.
   ⚠️ `:not(.col-staff-zwei)` ist kein Schmuck: Die zweite Spalte trägt
   dieselbe Klasse, und diese Regel überschrieb sonst ihre eigene
   Übergangsangabe - sie verschwand schlagartig statt zu verblassen. */
.col-staff:not(.col-staff-zwei) {
  margin-right: -16px; transition: margin-right .9s ease;
}
.columns.zwei-ma .col-staff:not(.col-staff-zwei) { margin-right: 0; }

/* ⚠️ Reicht die Breite nicht mehr für alle drei, wandern die beiden
   Listen nach oben und die Einheiten darunter über die ganze Breite -
   lieber eine Spalte unter die andere als drei zu schmale nebeneinander.
   ⚠️ Die Grenze liegt bei 1280px: Darüber gehen sich Einheiten (mindestens
   rund 560) und zwei Listen à 330 samt Lücken aus. Sie war einmal bei
   1400 - damit stapelte ein 1300px breites Fenster, obwohl drei Spalten
   noch gepasst hätten, und das Wandern blieb aus. */
@media (min-width: 1051px) and (max-width: 1279px) {
  .columns.zwei-ma {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    grid-template-areas:
      "ma1 ma2"
      "oe  oe";
  }
}
/* Untereinander und gestapelt gibt es keine leere dritte Spur - dort
   braucht die Liste den Ausgleich nicht. */
@media (max-width: 1279px) {
  .col-staff { margin-right: 0; }
}
/* Untereinander scrollt die Seite, nicht jede Spalte für sich - sonst
   endete die untere am Fensterrand. `spaltenhoeheMessen()` setzt die
   Klasse. */
body.ma-gestapelt { height: auto; overflow: visible; display: block; }
body.ma-gestapelt .col,
body.ma-gestapelt .col-scroll {
  display: block; overflow: visible; min-height: 0; padding-right: 0;
}
body.ma-gestapelt .timeline { position: static; }
.col-top { flex: 0 0 auto; }
/* ⚠️ overscroll-behavior: contain ist hier kein Feinschliff, sondern der
   Kern: Ohne es gibt eine Liste am Ende ihres Wegs den Schwung an die Seite
   weiter - am Trackpad reicht ein kräftiger Wisch, und plötzlich wandert
   die ganze Seite, statt dass die Spalte zu Ende scrollt. */
.col-scroll {
  flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain;
  padding-right: 6px; scrollbar-gutter: stable;
}
.col-scroll::-webkit-scrollbar { width: 10px; }
.col-scroll::-webkit-scrollbar-thumb { background: #cdd6e4; border-radius: 6px; border: 2px solid var(--bg); }
.col-scroll::-webkit-scrollbar-thumb:hover { background: #b6c2d6; }
.col-scroll.drop-scroll { box-shadow: inset 0 0 0 2px var(--brand-soft); border-radius: var(--radius); }

/* Schmale Fenster: alles untereinander, nichts klebt, nur die Seite
   scrollt. Zwei eigene Scrollbereiche lohnen sich nur nebeneinander -
   untereinander wären sie bloß im Weg. Die gemessene Höhe nimmt
   spaltenhoeheMessen() hier wieder weg. */
@media (max-width: 1050px) {
  body { height: auto; overflow: visible; display: block; }
  .columns, .columns.zwei-ma {
    grid-template-columns: 1fr; overflow: visible; padding-bottom: 60px;
    grid-template-areas: "oe" "ma1" "ma2";
  }
  .col, .col-scroll { display: block; overflow: visible; min-height: 0; padding-right: 0; }
  .timeline { position: static; }
}

.col-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 8px; flex-wrap: wrap; margin-bottom: 10px;
}
.head-right { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
/* Die Umschaltung der Mitarbeiterliste in eigener Zeile - leer nimmt sie
   keinen Platz weg. */
/* Die Umschaltung der Mitarbeiterliste: eine oder zwei Pillengruppen,
   untereinander. ⚠️ Abgeschnitten wird nichts - „Nur Überkapazitäten laut
   Filter OE" endete sonst nach zwei Silben mit drei Punkten. */
#staff-filter {
  margin: 0 0 10px;
  display: flex; flex-direction: column; align-items: flex-start; gap: 6px;
}
#staff-filter:empty { display: none; }
#staff-filter .seg { max-width: 100%; }
#staff-filter .seg button { max-width: 100%; white-space: normal; }
.hint { font-size: 12px; color: var(--muted); margin: 0 0 10px; }
/* Der Name der filternden Kachel über der Mitarbeiterliste - dasselbe
   Violett, das die Kachel selbst trägt. */
.hint.kachel-filter { color: var(--future); font-weight: 700; font-size: 13px; }
.empty {
  border: 1px dashed var(--line); border-radius: var(--radius);
  padding: 18px; text-align: center; color: var(--muted); font-size: 14px;
  background: var(--bg-soft);
}

/* ---------- Organisationseinheit ---------- */
.unit {
  background: var(--card); border: 1px solid var(--oe-linie);
  border-radius: var(--radius); margin-bottom: 14px; overflow: hidden;
  box-shadow: var(--shadow);
}
.unit-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px; flex-wrap: wrap;
  padding: 11px 14px; background: var(--oe-kopf); border-bottom: 1px solid var(--oe-linie);
}
/* ⚠️ Die Klappfläche reicht bis zu den Knöpfen (30.09.2026): Ohne `flex: 1`
   endete sie am letzten Buchstaben der Zahlenzeile, und daneben lagen
   gemessen 342 px, auf denen ein Klick ins Leere ging - mitten in der
   Kachel, die man treffen wollte. */
.unit-headline { display: flex; align-items: flex-start; gap: 8px; min-width: 0; flex: 1 1 auto; }
.unit-title { font-weight: 700; font-size: 15px; display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.unit-title .btn.link { font-weight: 400; }
.unit-drag {
  cursor: grab; color: var(--muted); font-size: 15px; line-height: 1.2;
  padding: 1px 2px; border-radius: 5px; user-select: none;
}
.unit-drag:hover { color: var(--brand); background: var(--brand-soft); }
.unit-drag:active { cursor: grabbing; }
.unit.dragging { opacity: .5; }
.unit.drop-before { box-shadow: 0 -3px 0 0 var(--brand); }
.unit.drop-after { box-shadow: 0 3px 0 0 var(--brand); }
.unit-meta { font-size: 12px; color: var(--muted); }

/* Griff der Rolle - dasselbe Zeichen wie bei der Einheit und bei den
   Zuordnungen, nur kleiner: Er steht in einer Zeile mit dem Rollennamen. */
.role-drag {
  cursor: grab; color: var(--muted); font-size: 13px; line-height: 1;
  padding: 1px 2px; margin-right: 2px; border-radius: 5px; user-select: none;
}
.role-drag:hover { color: var(--brand); background: var(--brand-soft); }
.role-drag:active { cursor: grabbing; }
.role.dragging { opacity: .5; }
.role.drop-before { box-shadow: 0 -3px 0 0 var(--brand); }
.role.drop-after { box-shadow: 0 3px 0 0 var(--brand); }
.unit-actions { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
.unit-body { padding: 10px 14px 14px; }

/* ---------- Rolle ---------- */
.role {
  border: 1px solid var(--role-line, var(--line-soft)); border-radius: 10px;
  padding: 10px 12px; margin-bottom: 10px; background: var(--role-bg, var(--bg-soft));
  transition: border-color .12s, background .12s, box-shadow .12s;
}
.role.dragover {
  border-color: var(--brand); background: var(--brand-soft);
  box-shadow: 0 0 0 2px rgba(47, 91, 215, .2);
}
.role.has-gap { border-left: 3px solid var(--danger-fill); }
.role.future { border-left: 3px solid var(--future-fill); }
.role.inactive { opacity: .6; }
.role-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
.role-name { font-weight: 600; }
.note-icon {
  display: inline-block; margin-left: 6px; cursor: help;
  font-size: 12px; color: var(--warn); background: var(--warn-soft);
  border: 1px solid #e8cf96;
  border-radius: 50%; width: 16px; height: 16px; line-height: 14px; text-align: center;
}
.role-numbers {
  font-size: 13px; color: var(--muted);
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
}
.role-numbers strong { color: var(--text); }
.fte-input { width: 68px; text-align: right; font-variant-numeric: tabular-nums; }

/* Keine Pfeilchen an den VZÄ-Feldern - eingegeben wird mit der Tastatur.
   ⚠️ Sie sassen genau dort, wo man hinfasst, und ein Klick daneben hat
   einen Wert verstellt, ohne dass es auffiel. Alle diese Felder tragen
   data-fte, also greift eine Regel für alle: im Balken, am Namenschip, auf
   der Mitarbeiterkarte und im Zuweisen-Dialog.
   ⚠️ type="number" bleibt: Am Telefon erscheint dann die Zifferntastatur,
   und der Browser prüft die Eingabe weiter. */
input[data-fte]::-webkit-outer-spin-button,
input[data-fte]::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
input[data-fte] { -moz-appearance: textfield; appearance: textfield; }
.changed-dot { color: var(--warn); font-size: 11px; }
.changed-dot.muted { color: var(--muted); font-size: 11px; }

.bar {
  display: flex; height: 16px; border-radius: 6px; overflow: hidden;
  background: #e9edf4; margin: 9px 0 8px; border: 1px solid var(--line-soft);
  min-width: 26px; max-width: 100%;
}
.bar span { display: block; height: 100%; }
.seg-filled { background: linear-gradient(180deg, #4b78e3, #2f5bd7); }
.seg-filled.alt { background: linear-gradient(180deg, #3ba0c4, #2c80a3); }
/* Offen, also unbesetzt: rot-WEISS schraffiert (30.09.2026). ⚠️ Zwei
   Rottöne waren eine Fläche - „hier ist etwas" -, und genau das ist an
   dieser Stelle nicht der Fall. Das Weiss dazwischen zeigt die Lücke, und
   der Abschnitt sieht keinem anderen mehr ähnlich. */
.seg-gap { background: repeating-linear-gradient(45deg, #e0564e, #e0564e 6px, #fff 6px, #fff 12px); }
.seg-over { background: repeating-linear-gradient(45deg, #f3c24b, #f3c24b 6px, #dca82c 6px, #dca82c 12px); }
/* Grenze zwischen zwei Stücken derselben Art: Zwei Menschen, die zur
   Überbesetzung beitragen, oder zwei Rollen, die über dem Ausmaß liegen,
   grenzen unmittelbar aneinander und sähen sonst aus wie eines.
   ⚠️ Als Innenschatten, nicht als Rand: Ein Rand käme zu den Prozentbreiten
   hinzu und verschöbe den ganzen Balken. */
.seg-over.geteilt,
.seg-overload.geteilt,
.seg-ma-overload.geteilt { box-shadow: inset 1px 0 0 #1b2437; }
.seg-planned { background: repeating-linear-gradient(45deg, #9b7cf0, #9b7cf0 6px, #7f5ce0 6px, #7f5ce0 12px); }
/* Im Balken der ROLLE: besetzt, aber über dem Ausmass dieses Menschen.
   ⚠️ Blau mit weissen Streifen wie `.seg-ma-over` im Dashboard
   Organisationseinheiten (04.10.2026) - und wie die Pille darunter und der
   Strahl der Mitarbeiterkarte: Überlast hat überall dieselbe Farbe. Rot
   bleibt dem „offen" (`.seg-gap`) - nebeneinander sahen „hier fehlt
   jemand" und „hier trägt jemand zu viel" sonst verwandt aus. */
.seg-ma-overload,
.seg-overload {
  background-color: #2f5bd7;
  background-image: repeating-linear-gradient(45deg,
    rgba(255, 255, 255, .55) 0 4px, rgba(255, 255, 255, 0) 4px 9px);
}
/* ⚠️ Die beiden Enden des Strahls - was frei ist und was darüber hinausgeht -
   sind SCHRAFFIERT, und zwar wie im Dashboard Mitarbeiter (30.09.2026):
   Sie sind kein Anteil wie die Rollen, sondern eine Auskunft über den Rest.
   Wer vom Dashboard in die Liste kommt, soll dieselbe Sache nicht zweimal
   lernen müssen - deshalb hier dieselben Streifen wie dort (`.ma-frei`,
   `.ma-over`).
   ⚠️ Der Overload ist seit 04.10.2026 BLAU schraffiert (siehe
   `.seg-ma-overload` oben) - wie im Dashboard Organisationseinheiten, in
   den Pillen, im Rollenbalken und im Dashboard Mitarbeiter (`.ma-over`). */
.seg-free { background: repeating-linear-gradient(45deg, #f3c24b, #f3c24b 6px, #dca82c 6px, #dca82c 12px); }
.role.future .bar { opacity: .9; }

.assignees { display: flex; flex-wrap: wrap; gap: 6px; }
.chip {
  display: inline-flex; align-items: center; gap: 6px;
  background: #fff; border: 1px solid var(--line);
  border-radius: 999px; padding: 3px 5px 3px 10px; font-size: 13px;
}
.chip.future { border-color: #c9b6f2; background: var(--future-soft); color: #4a2f91; }
/* ⚠️ Dieselben Streifen wie im Zuordnungsstrahl: blau mit weissen
   Streifen (04.10.2026, vorher rot). Die Pille sagt damit dasselbe wie der
   Strahl drüben, und man muss die Farbe nur einmal lesen lernen. Gezeigt
   wird sie nur beim Filter „Workload-Overloads".
   ⚠️ Das Muster liegt HINTEN: Gefüllt wird in der Reihenfolge der Person,
   und was über ihr Ausmaß hinausragt, ist der Rest. Wie breit es ist, sagt
   das `background-size` an der Pille selbst. Der Rand färbt mit, sonst
   schwebt die Schraffur in einer weissen Pille. */
.chip.chip-over {
  border-color: #9fb4ec;
  /* ⚠️ Zwei Schichten statt background-color: Die Farbe muss mit dem
     Muster an derselben Stelle abbrechen, und background-size schneidet
     nur Bilder zu. Ein einfarbiger Verlauf IST ein Bild. */
  background-image:
    repeating-linear-gradient(45deg, rgba(255, 255, 255, .55) 0 4px, rgba(255, 255, 255, 0) 4px 9px),
    linear-gradient(#2f5bd7, #2f5bd7);
  background-position: right center;
  background-repeat: no-repeat;
}
/* Ausgeschieden: Der Name ist rot durchgestrichen - die Zahl daneben und die
   Marke „ausgeschieden 06/2026" bleiben lesbar, sonst stünde der Strich auch
   durch die Auskunft, die man gerade braucht. */
.chip.gone { border-color: #eaa9a5; background: var(--danger-soft); color: #93241f; }
/* Liegt der Name ganz auf dem Muster, steht er weiss und fett da:
   Schwarz auf der Schraffur war zu lesen, aber nur mit Mühe.
   Gesetzt wird die Klasse erst nach dem Zeichnen
   (`namenAufMusterPruefen()`) - vorher weiss niemand, wie breit die Pille
   wird. */
.chip.chip-auf-muster .chip-name { color: #fff; font-weight: 700; }
.chip.chip-auf-muster .chip-name:hover { color: #fff; text-decoration: underline; }
.chip.gone .chip-name { color: var(--danger); text-decoration: line-through; }
.chip .chip-fte {
  width: 58px; text-align: right; padding: 2px 4px; font-size: 12px;
  font-variant-numeric: tabular-nums;
}
.chip select { padding: 2px 4px; font-size: 12px; max-width: 130px; }
.chip .x { background: none; border: none; color: var(--muted); cursor: pointer; font-size: 14px; padding: 0 4px; }
.chip .x:hover { color: var(--danger); }

.tag {
  font-size: 11px; padding: 1px 7px; border-radius: 999px;
  border: 1px solid var(--line); color: var(--muted); background: #fff;
  white-space: nowrap;
}
.tag.gap { border-color: #eaa9a5; background: var(--danger-soft); color: #93241f; }
.tag.over { border-color: #e8cf96; background: var(--warn-soft); color: #86560a; }
.tag.future { border-color: #c9b6f2; background: var(--future-soft); color: #4a2f91; }
/* ⚠️ Overloads tragen dieselbe Schraffur wie die überlastete Pille, nur
   ganz blass - seit 04.10.2026 also blau: „offen" (einfarbig rot) sagt
   etwas über die ROLLE, die Schraffur etwas über die MENSCHEN -
   nebeneinander in derselben Zeile darf das nicht verwechselbar sein. */
.tag.overload {
  border-color: #9fb4ec; color: #1f3f9e;
  background:
    repeating-linear-gradient(45deg,
      rgba(47, 91, 215, .22) 0 4px, rgba(47, 91, 215, .08) 4px 8px);
}

/* ---------- Mitarbeiter ---------- */
.staff-group-title {
  font-size: 12px; text-transform: uppercase; letter-spacing: .07em; font-weight: 600;
  color: var(--muted); margin: 14px 0 8px;
}
.staff-group-title.future { color: var(--future); }
.emp {
  background: var(--card); border: 1px solid var(--line);
  border-radius: 10px; padding: 10px 12px; margin-bottom: 9px; cursor: grab;
  box-shadow: var(--shadow);
}
.emp:hover { border-color: #b9c6db; }
.emp:active { cursor: grabbing; }
.emp.dragging { opacity: .5; }
.emp.future { border-color: #c9b6f2; }
.emp.former { background: var(--bg-soft); color: var(--muted); }
.emp.former .emp-name { color: var(--danger); text-decoration: line-through; }
.emp-head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; flex-wrap: wrap; }
.emp-name { font-weight: 600; }
.emp-dates { font-size: 11px; color: var(--muted); }
.emp-numbers {
  font-size: 12px; color: var(--muted);
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin-top: 4px;
}
.emp-roles { display: flex; flex-direction: column; gap: 5px; margin-top: 8px; }
/* Überschriften über den Zuordnungen - die Spaltenbreiten folgen der Zeile
   darunter: Rollenauswahl dehnbar, VZÄ-Feld 58px, dahinter das „×". */
.emp-assign-kopf {
  display: flex; gap: 6px; font-size: 11px; color: var(--muted);
  text-transform: uppercase; letter-spacing: .04em; padding: 0 2px;
}
.emp-assign-kopf .k-griff { flex: 0 0 auto; width: 14px; }
.emp-assign-kopf span:nth-child(2) { flex: 1 1 auto; }
.emp-assign-kopf span:last-child { flex: 0 0 auto; width: 58px; text-align: right; margin-right: 22px; }
.emp-assign-row { display: flex; align-items: center; gap: 6px; font-size: 12px; flex-wrap: nowrap; }
.emp-assign-row .role-ref {
  flex: 1 1 auto; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.emp-assign-row .chip-fte {
  flex: 0 0 auto; width: 58px; text-align: right; padding: 3px 5px; font-size: 12px;
  font-variant-numeric: tabular-nums;
}
/* Der Griff in der Namenspille - dieselbe Optik wie die übrigen. */
.chip-drag {
  flex: 0 0 auto; width: 12px; margin-left: -4px; text-align: center;
  cursor: grab; color: var(--muted); font-size: 11px; line-height: 1;
  user-select: none;
}
.chip-drag:hover { color: var(--brand); }
.chip-drag:active { cursor: grabbing; }
/* Die gezogene Pille bleibt sichtbar, aber zurückgenommen - sie ist gerade
   unterwegs, und die anderen weichen ihr aus. */
.chip.wandert { opacity: .45; }

/* Griff zum Umsortieren - dieselbe Sprache wie bei den Organisationseinheiten. */
.asg-drag {
  flex: 0 0 auto; width: 14px; text-align: center; cursor: grab;
  color: var(--muted); font-size: 12px; line-height: 1; user-select: none;
}
.asg-drag:hover { color: var(--brand); }
.asg-drag:active { cursor: grabbing; }
.emp-assign-row.dragging { opacity: .5; }
.emp-assign-row.drop-before { box-shadow: 0 -2px 0 0 var(--brand); }
.emp-assign-row.drop-after { box-shadow: 0 2px 0 0 var(--brand); }
.emp-assign-row .x { background: none; border: none; color: var(--muted); cursor: pointer; font-size: 14px; padding: 0 4px; }
.emp-assign-row .x:hover { color: var(--danger); }
.emp-footer { display: flex; gap: 6px; align-items: center; margin-top: 8px; flex-wrap: wrap; }
/* ⚠️ Das Auswahlfeld nimmt die ganze Zeile: „bearbeiten" und „löschen"
   gehören eine Zeile darunter. Daneben standen sie dicht an „Rolle
   zuordnen …" - zwei ganz verschiedene Dinge in einer Zeile. */
.emp-footer select { flex: 1 1 100%; font-size: 12px; }
/* Und dort rechtsbündig, wie die Knöpfe an den Rollen in der linken Spalte. */
.emp-footer .btn.link:first-of-type { margin-left: auto; }

/* ---------- Tooltip / Hinweis / Dialog ---------- */
.tooltip {
  /* ⚠️ fixed, nicht absolute: Der Kasten wird bei offenem Fenster in den
     Dialog gehängt (sonst läge er unter dessen Ebene und wäre unsichtbar).
     Dort zählen Bildschirmkoordinaten - dieselben, die das Mausereignis
     liefert. */
  position: fixed; z-index: 60; max-width: 300px;
  background: #1b2437; border: 1px solid #1b2437;
  color: #f4f6fa; border-radius: 8px; padding: 8px 10px;
  font-size: 13px; line-height: 1.4; white-space: pre-wrap;
  box-shadow: 0 10px 24px rgba(27, 36, 55, .22); pointer-events: none;
}
/* ⚠️ Breite ausdrücklich (08.10.2026): Mit `left: 50%` allein darf die
   Meldung nur die halbe Bildschirmbreite nutzen - am Handy wurde die
   Demo-Meldung dadurch ein schmaler, hoher Turm. So nimmt sie, was ihr Text
   braucht, höchstens aber 85 % der Breite. */
.toast {
  position: fixed; bottom: calc(22px + env(safe-area-inset-bottom, 0px)); left: 50%;
  transform: translateX(-50%);
  width: max-content; max-width: 85vw; box-sizing: border-box; text-align: center;
  background: #1b2437; border: 1px solid #1b2437; color: #f4f6fa;
  padding: 9px 16px; border-radius: 999px; font-size: 14px; z-index: 70;
  box-shadow: 0 10px 24px rgba(27, 36, 55, .22);
}
dialog {
  max-height: 86vh; overflow: auto;
  border: 1px solid var(--line); background: var(--card); color: var(--text);
  border-radius: var(--radius); padding: 18px; min-width: min(420px, 92vw);
  box-shadow: 0 18px 48px rgba(27, 36, 55, .22);
}
dialog::backdrop { background: rgba(27, 36, 55, .35); }
.field { display: flex; flex-direction: column; gap: 4px; margin-bottom: 11px; }
.field-row { display: flex; gap: 10px; }
.field-row .field { flex: 1; }
/* Datumsfeld mit × daneben - der eingebaute Kalender kennt kein „nichts". */
.datum-zeile { display: flex; align-items: center; gap: 6px; }
.datum-zeile input { flex: 1 1 auto; min-width: 0; }
.datum-leeren {
  flex: 0 0 auto; width: 26px; height: 26px; border-radius: 50%;
  border: 1px solid var(--line); background: #fff; color: var(--muted);
  font-size: 15px; line-height: 1; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
}
.datum-leeren:hover { color: var(--danger); border-color: var(--danger); }
/* Vorbelegt, nicht eingegeben: Steht der Zeitstrahl in der Zukunft, schlägt
   der Dialog diesen Monat als Beginn vor. Gelb sagt „von der Seite" - beim
   ersten Anfassen wird es schwarz (`vorbelegungAufheben()`). */
.field input.vorbelegt { color: var(--warn); font-weight: 600; }
.modal-actions { display: flex; align-items: center; justify-content: flex-end; gap: 8px; margin: 16px 0 0; padding: 0; }
/* ⚠️ Die Auskunft steht LINKS neben den Knöpfen und schiebt sie nach rechts
   (`margin-right: auto`): Sie gehört zu dem, was man gerade getan hat - ein
   Toast über der Seite wäre weiter weg als der Knopf, den man eben gedrückt
   hat. Leer nimmt sie keinen Platz. */
.modal-meldung {
  margin-right: auto; font-size: 13px; line-height: 1.35;
  text-align: left; max-width: 60%;
}
.modal-meldung:empty { display: none; }
.modal-meldung.gut { color: var(--ok); font-weight: 600; }
.modal-meldung.schlecht { color: var(--danger); font-weight: 600; }
/* Der dritte Knopf gehört nach links - er nimmt etwas weg, statt zu bestätigen. */
#modal-extra { margin-right: auto; }
/* „Alle" im Trichter sitzt, wo früher „Auswahl löschen" stand - links. */
#modal-alle { margin-right: auto; font-weight: 600; cursor: pointer; }
/* Was es im gewählten Monat nicht gibt: sichtbar, aber blass und gesperrt. */
.check.gesperrt { color: var(--muted); opacity: .5; cursor: default; }
/* Rollen einer nicht gewählten Einheit: blass, aber sehr wohl anklickbar -
   wer sie bewusst dazunimmt, soll das können. */
/* Zwei blasse Zustände mit derselben Optik: „nicht in der Auswahl" und
   „von der Suche nicht getroffen". Beide bleiben anklickbar. */
.check.nicht-dabei, .check.such-blass { color: var(--muted); opacity: .55; }
.check.nicht-dabei:hover, .check.such-blass:hover { opacity: 1; }
.kein-treffer { display: block; padding: 2px 0; }
#modal textarea { width: 100%; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; }

/* Speicherort-Anzeige in der Kopfzeile */
button.storage {
  background: none; border: none; padding: 0; cursor: pointer; font: inherit;
}
.storage {
  font-size: 12px; color: var(--muted);
  border: 1px solid var(--line); background: #fff;
  border-radius: 999px; padding: 5px 11px; white-space: nowrap;
}
.storage.ok { color: var(--ok); border-color: #a9d8c2; background: #edf8f3; }
.storage.warn { color: var(--warn); border-color: #e8cf96; background: var(--warn-soft); }

/* ---------- Farbauswahl für Rollenkacheln ---------- */
.swatches { display: flex; gap: 6px; flex-wrap: wrap; }
.swatch {
  width: 30px; height: 30px; border-radius: 8px; cursor: pointer;
  border: 1px solid var(--line); color: var(--muted); font-size: 13px; line-height: 1;
}
.swatch.selected { outline: 2px solid var(--brand); outline-offset: 1px; }

/* ---------- Graphische Darstellung ---------- */

/* Der Knopf sitzt bündig unter dem Zeitstrahl, linksbündig mit allem
   anderen auf der Seite. Er trägt das Grün der Wortmarke: Blau gehört den
   „+"-Knöpfen, Rot und Gelb sind Signalfarben - so ist er die einzige
   grüne Fläche der Seite und damit sofort zu finden. */
.chart-leiste { padding: 12px 20px 0; display: flex; flex-wrap: wrap; gap: 10px; }
.chart-knopf {
  display: inline-flex; align-items: center; gap: 8px;
  background: var(--marke-gruen); border-color: var(--marke-gruen);
  color: #fff; font-weight: 600;
  box-shadow: 0 1px 2px rgba(0, 135, 90, .25);
}
.chart-knopf:hover { background: #016c48; border-color: #016c48; color: #fff; }

/* ---------- Szenarien ----------

   Gelb wie die Überkapazität: Ein Szenario ist eine Annahme, keine Tatsache. */
.szenario-knopf {
  display: inline-flex; align-items: center; gap: 8px;
  background: var(--warn-soft); border-color: var(--warn-fill); color: var(--warn);
  font-weight: 600;
}
.szenario-knopf:hover { background: var(--warn-fill); border-color: var(--warn-fill); color: #3d2a00; }
/* ⚠️ Im Szenario ist der Knopf GEFÜLLT gelb, nicht nur umrandet: Er ist dann
   kein Angebot mehr, sondern der Hinweis, wo man steht - und der Weg zurück. */
body.im-szenario .szenario-knopf {
  background: var(--warn-fill); border-color: var(--warn-fill); color: #3d2a00;
}
body.im-szenario .szenario-knopf:hover { background: #e7b63c; border-color: #e7b63c; }

/* ⚠️ Im Szenario färbt sich der Bereich mit Monat und Zeitstrahl: Man soll
   auf einen Blick sehen, dass man nicht im Ist-Stand plant - sonst wundert
   man sich später, warum die Änderung dort fehlt. */
body.im-szenario .timeline {
  background: var(--warn-soft);
  border-bottom-color: var(--warn-fill);
}
body.im-szenario .timeline .month-label { color: var(--warn); }

#szenario-modal {
  width: min(560px, 92vw); box-sizing: border-box;
  max-height: 90vh; overflow: auto;
  border: none; border-radius: var(--radius); padding: 0 0 18px;
  background: var(--card); color: var(--text);
  box-shadow: 0 18px 50px rgba(20, 32, 56, .28);
}
#szenario-modal::backdrop { background: rgba(20, 32, 56, .45); }
.szenario-erklaerung {
  margin: 14px 20px 0; font-size: 13px; color: var(--muted); line-height: 1.5;
}
.szenario-neu { display: flex; gap: 8px; margin: 14px 20px 0; flex-wrap: wrap; }
.szenario-neu input { flex: 1 1 220px; min-width: 0; }
.szenario-voll {
  margin: 14px 20px 0; padding: 11px 13px; font-size: 13px;
  background: var(--warn-soft); border: 1px solid var(--warn-fill);
  border-radius: 9px; color: var(--warn);
}
.szenario-liste { list-style: none; margin: 16px 20px 0; padding: 0; }
.szenario-liste li {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 0; border-top: 1px solid var(--line-soft);
}
.szenario-liste li:first-child { border-top: 0; }
.szenario-liste li.leer { color: var(--muted); font-size: 14px; }
.szenario-liste .sz-was { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.szenario-liste .sz-name { font-weight: 600; color: var(--warn); }
.szenario-liste .sz-basis { font-size: 12px; color: var(--muted); }
/* Auch „Laden" gelb: Was in ein Szenario führt, trägt dessen Farbe. */
.szenario-liste [data-sz-laden] {
  background: var(--warn-soft); border-color: var(--warn-fill); color: var(--warn); font-weight: 600;
}
.szenario-liste [data-sz-laden]:hover { background: var(--warn-fill); border-color: var(--warn-fill); color: #3d2a00; }
.szenario-liste .sz-hier { font-size: 12px; color: var(--warn); }
.szenario-liste li.hier { background: var(--warn-soft); border-radius: 8px; padding-inline: 8px; }
/* Grau wie in GastroSubs - rot erst, wenn der Finger darauf liegt. Derselbe
   Knopf steht an jeder Stelle, an der etwas gelöscht wird. */
.papierkorb { color: var(--muted); width: 32px; height: 30px; }
.papierkorb:hover { color: var(--danger); border-color: var(--danger); background: var(--danger-soft); }
.papierkorb svg { width: 17px; height: 17px; }
#meldung-szenario { margin: 14px 20px 0; }
.chart-knopf svg { width: 17px; height: 17px; fill: currentColor; flex: 0 0 auto; }

/* Das Fenster nimmt 90 % der Breite - genug Platz für nebeneinander
   stehende Balken, und ringsum bleibt die Seite sichtbar. Die Höhe wächst
   mit dem Inhalt, gedeckelt vom Fenster; darüber hinaus scrollt es in sich. */
.chart-modal {
  width: 90vw; max-width: 90vw; box-sizing: border-box;
  max-height: 96vh; overflow: auto;
  margin: 2vh auto; border: none; border-radius: var(--radius);
  padding: 0 0 16px; background: var(--card); color: var(--text);
  box-shadow: 0 18px 50px rgba(20, 32, 56, .28);
}
.chart-modal::backdrop { background: rgba(20, 32, 56, .45); }
.chart-kopf {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: 14px 20px; border-bottom: 1px solid var(--line-soft);
  position: sticky; top: 0; background: var(--card); z-index: 2;
}
.chart-kopf h3 { margin: 0; font-size: 16px; flex: 1 1 auto; }
/* Drucken links neben dem × - dort sucht man Werkzeuge zum Fenster, und
   das × bleibt die letzte Schaltfläche wie überall. */
.chart-drucken { flex: 0 0 auto; }
.chart-close {
  flex: 0 0 auto; width: 32px; height: 32px; border-radius: 50%;
  border: 1px solid var(--line); background: var(--bg-soft); color: var(--muted);
  font-size: 18px; line-height: 1; cursor: pointer;
}
.chart-close:hover { border-color: var(--danger); color: var(--danger); }

/* Der Zeitstrahl wandert hier herein; er bringt seinen eigenen Rahmen mit. */
.chart-zeitstrahl .timeline { position: static; border-bottom: 1px solid var(--line-soft); }

/* Alle Einheiten in einer Reihe, jede mit einem Kästchen davor. */
.chart-auswahl {
  display: flex; flex-wrap: wrap; gap: 8px 18px;
  padding: 12px 20px; border-bottom: 1px solid var(--line-soft);
}
.chart-wahl {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 13px; cursor: pointer;
}
.chart-wahl input { cursor: pointer; }

/* Künftiges: Rollen und Mitarbeiter nebeneinander, die Einheiten darunter
   über die ganze Breite - sie führen ihre Rollen als Chips mit. */
.zukunft-inhalt { padding: 16px 20px 4px; }
.zukunft-spalten { display: grid; grid-template-columns: 1fr 1fr; gap: 10px 22px; }
.zukunft-unten { margin-top: 18px; }
.zukunft-inhalt h4 {
  margin: 0 0 8px; font-size: 14px; color: var(--muted);
  text-transform: uppercase; letter-spacing: .04em;
}
@media (max-width: 860px) {
  .zukunft-spalten { grid-template-columns: 1fr; }
}

/* Die Kennzahlen über der Grafik - dieselben Zahlen wie in den Kacheln. */
.chart-kpis {
  display: flex; flex-wrap: wrap; gap: 8px 22px;
  padding: 12px 20px 0; font-size: 13px;
}
.chart-kpis .ck { display: flex; align-items: baseline; gap: 7px; }
.chart-kpis .ck-label { color: var(--muted); }
.chart-kpis .ck-value { font-size: 16px; font-weight: 700; font-variant-numeric: tabular-nums; }
.chart-kpis .gap .ck-value { color: var(--danger); }
.chart-kpis .over .ck-value { color: var(--warn); }

.chart-legend {
  display: flex; gap: 14px; flex-wrap: wrap;
  font-size: 12px; color: var(--muted); padding: 12px 20px 0;
}
.chart-legend i {
  display: inline-block; width: 11px; height: 11px; border-radius: 3px;
  margin-right: 5px; vertical-align: -1px;
}
/* ⚠️ Zweigeteilt wie im Bild: Die Säule wechselt je Person zwischen Blau
   und Türkis (.seg-filled und .seg-filled.alt) - eine einfarbige Marke
   liesse die zweite Farbe unerklärt. */
.lg-filled {
  background: linear-gradient(135deg, #2f5bd7 0 50%, #2c80a3 50% 100%);
}
.lg-gap { background: repeating-linear-gradient(45deg, #e0564e, #e0564e 4px, #fff 4px, #fff 8px); }
.lg-planned { background: repeating-linear-gradient(45deg, #9b7cf0, #9b7cf0 4px, #7f5ce0 4px, #7f5ce0 8px); }

/* ⚠️ Umbrechen statt nach rechts scrollen: Bei sieben Einheiten lag die
   Hälfte ausserhalb des Bildes, und ein waagrechter Balken unter einer
   Grafik wird leicht übersehen. Was nicht mehr nebeneinander passt, geht
   in die nächste Zeile - gescrollt wird nur noch senkrecht, wie überall. */
.chart {
  display: flex; flex-wrap: wrap; gap: 18px;
  padding: 14px 20px; align-items: flex-start;
}
.chart-unit {
  border: 1px solid var(--line-soft); border-radius: 10px;
  padding: 8px 10px 6px; background: var(--bg-soft);
  /* Schrumpfen darf sie, wachsen nicht: Zwei Einheiten mit je zwei Rollen
     sollen nicht die halbe Breite auseinandergezogen werden. */
  flex: 0 1 auto; max-width: 100%;
}
/* Auch innerhalb einer Einheit: Eine Einheit mit vielen Rollen ist sonst
   breiter als das Fenster und ragt hinaus. */
.chart-plotrow { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 10px 7px; }
.chart-col { display: flex; flex-direction: column; align-items: center; gap: 3px; }
.chart-value { font-size: 10px; color: var(--muted); font-variant-numeric: tabular-nums; }
.chart-plot {
  height: 150px; width: 32px; display: flex; align-items: flex-end;
  border-bottom: 1px solid var(--line);
}
.chart-stack {
  width: 100%; display: flex; flex-direction: column-reverse;
  border-radius: 4px 4px 0 0; overflow: hidden; min-height: 2px;
}
.chart-stack span { display: block; width: 100%; }
.chart-stack span + span { border-top: 1px solid rgba(255, 255, 255, .6); }
.seg-role { background: var(--brand); }
.chart-label {
  font-size: 11px; font-weight: 600; letter-spacing: .02em; color: var(--text);
  white-space: nowrap; border: 1px solid transparent; border-radius: 5px; padding: 1px 6px;
}
.chart-label.future { color: var(--future); }
.chart-unit-name {
  font-size: 12px; font-weight: 600; color: var(--muted);
  margin-top: 7px; padding-top: 6px; border-top: 1px solid var(--line-soft); text-align: center;
}

/* ---------- OE-Zugehörigkeit der Mitarbeiter ---------- */
.emp-units { display: flex; gap: 4px; flex-wrap: wrap; margin-top: 5px; }
.emp-units .tag { font-size: 10px; padding: 1px 6px; }
.emp-units .tag.here { border-color: var(--brand); color: var(--brand); background: var(--brand-soft); }

.checks { display: flex; flex-direction: column; gap: 5px; max-height: 170px; overflow-y: auto; }
/* Im Mitarbeiter-Trichter gibt es nur EINE Liste - sie darf die Höhe nehmen,
   die sich die beiden Listen über den Einheiten teilen. */
#modal.ma-filter .checks { max-height: min(400px, 55vh); }
.check { display: flex; align-items: center; gap: 7px; font-size: 14px; color: var(--text); }
.check input { accent-color: var(--brand); }

.seg { display: inline-flex; border: 1px solid var(--line); border-radius: 999px; overflow: hidden; }
.seg button {
  border: none; background: #fff; color: var(--muted);
  font: inherit; font-size: 12px; padding: 4px 10px; cursor: pointer;
  max-width: 130px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.seg button + button { border-left: 1px solid var(--line); }
.seg button:hover { color: var(--future); }
/* Auch diese Schalter filtern die Liste - also dieselbe Farbe wie Trichter,
   „Filter zurücksetzen" und die filternde Kachel. */
.seg button.on { background: var(--future); color: #fff; font-weight: 600; }

/* ---------- Suchfeld über den Mitarbeitern ---------- */
.search { position: relative; margin-bottom: 10px; }
.search input {
  width: 100%; padding-right: 34px;
  -webkit-appearance: none; appearance: none;
}
.search input::-webkit-search-cancel-button { display: none; }
.search-clear {
  position: absolute; top: 50%; right: 6px; transform: translateY(-50%);
  width: 24px; height: 24px; border-radius: 50%;
  border: 1px solid var(--line); background: #fff; color: var(--muted);
  font-size: 15px; line-height: 1; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 1px 3px rgba(27, 36, 55, .12);
}
.search-clear:hover { color: var(--danger); border-color: var(--danger); }

/* ---------- Übersicht der künftig erforderlichen Rollen ---------- */
.future-list { display: flex; flex-direction: column; gap: 10px; max-height: 52vh; overflow-y: auto; }
.future-row {
  border: 1px solid var(--line-soft); border-left: 3px solid var(--future-fill);
  border-radius: 9px; padding: 9px 11px; background: var(--bg-soft);
}
.fr-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 3px; }
.fr-people { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 7px; }
.fr-people .chip { padding: 3px 10px; }

/* Im Zuweisen-Dialog steht die Mitarbeiterkarte nur zum Ansehen: kein
   Ziehen, keine Knöpfe, gedämpft - damit niemand dort zu tippen beginnt. */
.nur-anzeige { margin-bottom: 14px; }
.nur-anzeige .emp { cursor: default; box-shadow: none; background: var(--bg-soft); }
.nur-anzeige .emp:hover { border-color: var(--line); }
.nur-anzeige input, .nur-anzeige select { background: var(--card2); color: var(--muted); }
.nur-anzeige .x, .nur-anzeige .btn, .nur-anzeige .asg-drag,
.nur-anzeige .emp-footer { display: none; }
.zuweisen-frage { margin: 0 0 4px; font-weight: 600; }
/* Ein Hinweis, kein Formular: Die Überschrift steht mittig, und der Rat
   darunter bekommt einen eigenen Absatz - er sagt etwas anderes als der
   Satz davor. */
#modal.hinweis #modal-title { text-align: center; }
/* ⚠️ Schmaler als die Bearbeiten-Fenster: Die laufen über die ganze Breite,
   weil dort Spalten nebeneinander stehen. Ein paar Zeilen Text lesen sich in
   einer schmalen Spalte besser - über 900 px wandert das Auge am Zeilenende
   ins Leere. */
#modal.schmal { width: 520px; max-width: 92vw; min-width: 0; }
/* Der Datenimport: erst der Satz mit dem Verweis auf die Vorlage, dann die
   Dateiauswahl. */
.import-text { margin: 0 0 18px; line-height: 1.5; }
/* Die Wahl beim NAP-Import: zwei Zeilen untereinander. */
.nap-wahl { display: flex; flex-direction: column; gap: 8px; margin: 0 0 18px; }
.nap-frage-bst { margin-bottom: 8px; }
.nap-frage-bst label { font: inherit; color: inherit; margin: 0; display: inline; }
.nap-bst { width: 90px; }
/* ⚠️ Im Grün der Marke, nicht im Blau der Bedienelemente: Der Verweis führt
   aus der Seite heraus und holt eine Datei - er tut etwas anderes als die
   blauen Knöpfe, mit denen man hier arbeitet. */
.import-text a,
.willkommen-excel a {
  color: var(--marke-gruen); font-weight: 600;
  text-decoration: underline; text-underline-offset: 2px;
}
.import-text a:hover,
.willkommen-excel a:hover { color: #046647; }
/* Ein Dialog ohne Überschrift (die Begrüssung einer neuen Organisation)
   soll oben keine leere Zeile tragen. */
#modal-title:empty { display: none; }
.import-feld { display: block; margin: 0 0 6px; font-size: 13px; color: var(--muted); }
/* ⚠️ Das Dateifeld trägt denselben Rahmen wie jedes Eingabefeld, und der
   Knopf darin sieht aus wie die übrigen Knöpfe: Der eingebaute sieht in
   jedem Browser anders aus und fiel aus der Seite heraus. */
#import-datei {
  display: block; width: 100%; box-sizing: border-box;
  background: #fff; border: 1px solid var(--line); border-radius: 8px;
  padding: 7px 9px; font-size: 14px; font-family: inherit; color: var(--muted);
  cursor: pointer;
}
#import-datei::file-selector-button {
  font: inherit; font-size: 13px;
  margin: -2px 10px -2px 0;
  padding: 5px 11px;
  border: 1px solid var(--line); border-radius: 8px;
  background: var(--card2); color: var(--text);
  cursor: pointer;
}
#import-datei:hover::file-selector-button {
  border-color: var(--brand); color: var(--brand-dark); background: var(--brand-soft);
}
.schmal-rat { margin: 12px 0 0; }
.willkommen-anmerkung { margin: 10px 0 0; font-size: 12.5px; font-style: italic; color: var(--muted); }
/* Der Excel-Satz ist ein eigener Gedanke - mit Luft davor, damit er nicht an
   der Anmerkung hängt. */
.schmal-rat.willkommen-excel { margin-top: 22px; }
/* Luft zwischen dem Hinweis und dem Kästchen darunter - sonst liest sich
   „Diesen Hinweis nicht mehr anzeigen" wie ein Teil des Satzes. */
.zuweisen-frage + .check { display: block; margin-top: 14px; }
/* Der Monat sticht heraus: Die Zuordnung gilt ab ihm, nicht ab heute -
   und im Fliesstext übersieht man ihn sonst. */
.zuweisen-per { color: var(--warn); }

/* Eine einzelne Zahl braucht keine eigene Zeile für die Beschriftung. */
/* ⚠️ flex-direction ausdrücklich: .field stapelt sonst weiter senkrecht,
   und die Beschriftung stünde unter der Zahl statt daneben. */
.field.kompakt { display: flex; flex-direction: row; align-items: center; gap: 10px; }
.field.kompakt input { width: 68px; text-align: right; font-variant-numeric: tabular-nums; }
.field.kompakt label { margin: 0; }

/* ---------- Zugeklappte OE ---------- */
.unit.collapsed .unit-head { border-bottom: none; }

/* ----------------------------------------------- Serverfassung: Kopfzeile */

.topbar-actions .konto {
  color: var(--muted);
  font-size: 12px;
  max-width: 200px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* „Organisationen“ ist ein Verweis, soll aber aussehen wie die Schaltflächen daneben. */
.topbar-actions a.btn { text-decoration: none; display: inline-flex; align-items: center; }

/* Wer nur lesen darf, bekommt die Werkzeuge zum Ändern gar nicht erst zu sehen.
   Den Rest erledigt lesemodusAnwenden() nach jedem Zeichnen: Felder gesperrt,
   ändernde Schaltflächen ausgeblendet, kein Ziehen. */
body.nur-lesen .nur-bearbeiten,
body.nur-lesen #form-unit,
body.nur-lesen #btn-add-emp { display: none; }

/* ------------------------------------------------------------- Wortmarke */

/* Die Marke sitzt in einem weissen Feld: „Arbeits“ und „.net“ im Anthrazit
   der Oberfläche, „zeitMaschine“ in sattem Grün (#00875a, 4,55:1 auf Weiss).
   Der feine Rand ist nötig, damit das weisse Feld auch auf weissem Grund -
   etwa in der Kopfzeile der Planung - als Marke erkennbar bleibt. */
.wortmarke {
  display: inline-block;
  white-space: nowrap;
  letter-spacing: -.012em;
  background: #fff;
  border: 1px solid var(--line);
  /* Voll gerundet: die beiden Schmalseiten sind je ein halber Kreis, die
     Rundung läuft ohne Knick durch. Seitlich mehr Luft, damit „A“ und „t“
     nicht in die Bögen laufen. */
  border-radius: 999px;
  padding: .18em .62em;
  box-shadow: var(--shadow);
}
.wortmarke .w-dunkel,
.wortmarke .w-akzent { font-size: inherit; }
.wortmarke .w-dunkel { color: var(--text); }
.wortmarke .w-akzent { color: var(--marke-gruen); }

/* Neben der Wortmarke steht, in welcher Organisation man gerade ist - in
   derselben Größe: Das ist die Antwort auf „wo bin ich“ und keine
   Beiläufigkeit. */
#org-name {
  color: var(--text);
  font-weight: 600;
  font-size: 25px;
  letter-spacing: -0.02em;
}

/* ------------------------------------------------- Zeichen und Menü

   Zwei Schaltflächen ohne Beschriftung: Abmelden und das Menü. Beide tragen
   title und aria-label, damit sie auch ohne Text benennbar bleiben. Die
   Zeichen stammen aus den Material Symbols (Apache 2.0) und liegen als SVG
   in der Seite - nichts wird aus dem Netz nachgeladen. */

.btn.icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 34px;
  padding: 0;
}
.btn.icon svg { width: 20px; height: 20px; fill: currentColor; }

.menu { position: relative; }

/* ⚠️ Kein Knopf, nur drei Striche: Das Menü ist kein Werkzeug dieser Seite,
   sondern der Weg hinaus - Rahmen und Fläche hätten es zu einem der Knöpfe
   gemacht, mit denen man hier arbeitet. Die Fläche zum Treffen bleibt
   trotzdem gross genug. */
.menu-striche {
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 32px;
  border: 0; background: none; padding: 0;
  color: var(--text); cursor: pointer; border-radius: 8px;
}
.menu-striche svg { width: 26px; height: 26px; fill: currentColor; }
.menu-striche:hover { background: var(--brand-soft); color: var(--brand-dark); }

.menu-liste {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  z-index: 40;
  min-width: 210px;
  display: flex;
  flex-direction: column;
  padding: 6px;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 10px;
  box-shadow: 0 8px 24px rgba(27, 36, 55, .14);
}
.menu-liste > * {
  font: inherit;
  text-align: left;
  text-decoration: none;
  color: var(--text);
  background: none;
  border: 0;
  border-radius: 7px;
  padding: 8px 10px;
  cursor: pointer;
}
.menu-liste > *:hover { background: var(--card2); }
.menu-liste > *:focus-visible { outline: 2px solid var(--brand); outline-offset: -2px; }

/* Die beiden Klapp-Verweise stehen unmittelbar unter der Überschrift - dort,
   wo man sie sucht, wenn man die Liste ordnen will. */
.klapp-links { display: flex; gap: 12px; margin: -4px 0 8px; }

/* Der Trichter neben der Überschrift: klein, still - und auffällig, sobald
   eine Auswahl gesetzt ist, damit niemand vor einer verkürzten Liste steht
   und den Grund sucht. */
.kopf-gruppe { display: flex; align-items: center; gap: 8px; min-width: 0; }
/* ⚠️ „+ Mitarbeiter" bleibt an seinem Platz (22.10.2026): Wird es eng -
   Trichter, „Filter zurücksetzen" und „alle aufklappen" neben der
   Überschrift -, bricht die GRUPPE in sich um, nicht die Kopfzeile. Sonst
   wanderte der Knopf je nach Filter in eine zweite Zeile. */
#col-staff .col-head { flex-wrap: nowrap; align-items: flex-start; }
#col-staff .kopf-gruppe { flex-wrap: wrap; flex: 1 1 auto; row-gap: 2px; }
#col-staff .head-right { flex: none; }
.btn.icon.klein { padding: 4px 7px; }
.btn.icon.klein svg { width: 16px; height: 16px; fill: currentColor; display: block; }

/* ---------- Alles, was filtert, ist violett ----------
   Blau gehört dem Anlegen („+"-Knöpfe), Rot und Gelb sind Signalfarben -
   und Violett trägt schon die aktive Kachel und der Name des Filters über
   der Mitarbeiterliste. Wer die Farbe sieht, weiss: Hier wird der
   Ausschnitt gesetzt, hier fehlen deshalb Zeilen. */
/* ⚠️ Der Trichter selbst bleibt ruhig, solange nichts gewählt ist - die
   Farbe meldet einen Zustand („hier fehlen Zeilen"), nicht eine
   Möglichkeit. Erst mit einer Auswahl wird er violett. */
#btn-filter:hover { background: var(--future-soft); border-color: #c9b6f2; color: var(--future); }
.btn.icon.klein.on {
  background: var(--future-soft); border-color: var(--future); color: var(--future);
}
#filter-reset { color: var(--future); }
#filter-reset:hover { color: #4a2f91; }


/* Der Name im Namenschip ist anklickbar: Er schränkt die Mitarbeiterliste
   auf diese Person ein. Der Rest des Chips bleibt zum Ziehen. */
.chip-name { cursor: pointer; border-radius: 4px; padding: 0 1px; }
.chip-name:hover { color: var(--brand); text-decoration: underline; }

/* Namenschips liegen nebeneinander - die Marke beim Umsortieren gehört
   deshalb an die Seite, nicht nach oben oder unten. */
.chip.drop-before { box-shadow: -3px 0 0 0 var(--brand); }
.chip.drop-after { box-shadow: 3px 0 0 0 var(--brand); }

/* ---------- Löschbares Suchfeld ----------
   Dasselbe × wie in der Mitarbeitersuche, nur von `loeschbar.js` erzeugt:
   Kontoseite (Organisation, Branche, Ort) und Trichter der Planung. */
.suchfeld-huelle { position: relative; display: block; }
.suchfeld-huelle > input { width: 100%; padding-right: 32px; box-sizing: border-box; }
.feld-loeschen {
  position: absolute; top: 50%; right: 6px; transform: translateY(-50%);
  width: 22px; height: 22px; border-radius: 50%; padding: 0;
  border: 1px solid var(--line); background: #fff; color: var(--muted);
  font-size: 14px; line-height: 1; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
}
.feld-loeschen:hover { color: var(--danger); border-color: var(--danger); }

/* ---------------------------------------------------- Übersichten als PDF

   Derselbe Zuschnitt wie die graphische Darstellung (.chart-modal), darin
   eine Zeile je Übersicht: links der Haken, rechts die Einschränkung. */
.pdf-teil {
  display: grid; grid-template-columns: 210px minmax(0, 1fr); gap: 14px;
  align-items: start; padding: 14px 20px; border-top: 1px solid var(--line-soft);
}
.pdf-haken { font-weight: 600; padding-top: 5px; }
.pdf-wahl { position: relative; min-width: 0; }
/* Der Knopf trägt die Auswahl als Text - sonst müsste man das Feld öffnen,
   um zu sehen, worauf man eingeschränkt hat. */
.pdf-pulldown { width: 100%; justify-content: space-between; text-align: left; }
.pdf-pulldown::after { content: '▾'; margin-left: 8px; color: var(--muted); }
.pdf-pulldown[aria-expanded="true"]::after { content: '▴'; }
/* ⚠️ Das Fenster behält seine Grösse: Der Platz für das offene Feld ist von
   Anfang an da (.pdf-teile), und das Feld schwebt darin. Wuchs das Fenster
   beim Aufklappen, sprang alles darunter - und der Knopf, den man gerade
   treffen wollte, war woanders. Deshalb auch der reservierte Platz statt
   eines Feldes im Fluss; abgeschnitten wird nichts, weil es hineinpasst. */
.pdf-feld { position: relative; }
/* ⚠️ Gebaut wie der Trichter über der OE-Liste (29.09.2026): oben ein
   eigener Rollbereich für die Einheiten, darunter einer für die Rollen,
   und der Knopf „Übernehmen" steht FEST darunter. Vorher rollte das ganze
   Panel als eines - dann wandert der Knopf beim Suchen aus dem Bild, und
   man scrollt bis ans Ende, nur um zu bestätigen. */
.pdf-panel {
  position: absolute; z-index: 5; left: 0; right: 0; top: calc(100% + 6px);
  padding: 10px 12px; display: flex; flex-direction: column;
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: 0 12px 28px rgba(27, 36, 55, .18);
}
/* ⚠️ Jede Gruppe mit EIGENEM, festem Rollbereich - wie im Trichter
   (`.checks`, 140px): Teilten sie sich den Platz nach Inhalt, schrumpfte
   die kürzere Liste auf eine Zeile zusammen, während die längere alles
   bekam (gemessen: 27 px gegen 158 px). */
.pdf-panel-gruppe { display: flex; flex-direction: column; }
/* ⚠️ Ebenfalls an der Fensterhöhe: Auf einem niedrigen Bildschirm werden
   die beiden Rollbereiche kürzer, statt das Fenster über den Rand zu
   schieben. */
.pdf-panel-gruppe .checks { max-height: min(140px, 13vh); }
.pdf-panel h4 {
  margin: 8px 0 6px; font-size: 12px; text-transform: uppercase;
  letter-spacing: .04em; color: var(--muted);
}
.pdf-panel h4:first-child { margin-top: 0; }
/* ⚠️ Enge Zeilen im Pulldown: Hier stehen Namen untereinander, die man
   überfliegt - je mehr auf einmal zu sehen sind, desto weniger muss man
   rollen. */
.pdf-panel .check { padding: 0; line-height: 1.35; }
.pdf-panel .checks { gap: 1px; }
.pdf-namen { margin-top: 10px; }
.pdf-namen .search-wrap { max-width: 320px; }
.pdf-alle { font-weight: 600; margin: 8px 0 4px; }
.pdf-namen-liste {
  max-height: 180px; overflow-y: auto; padding: 6px 10px;
  border: 1px solid var(--line-soft); border-radius: var(--radius);
  display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 2px 14px;
}
.pdf-namen-leer { color: var(--muted); font-size: 13px; padding: 4px 0; }
#pdf-modal .modal-actions { padding: 0 20px; }
@media (max-width: 700px) {
  .pdf-teil { grid-template-columns: 1fr; }
}
/* Zwei Übersichten nebeneinander: Untereinander stand das Fenster hoch und
   schmal, obwohl 90 % Breite zur Verfügung stehen. */
.pdf-teile {
  display: grid; grid-template-columns: 1fr 1fr; gap: 20px;
  padding: 14px 20px; border-top: 1px solid var(--line-soft);
  /* Platz für das zweite, tiefer stehende Feld - siehe .pdf-panel.
     ⚠️ Nach oben begrenzt durch die FENSTERHÖHE (29.09.2026): Sonst wird
     das Fenster höher als der Bildschirm und muss selbst gerollt werden -
     dann wandert der Knopf „PDF-Übersicht drucken" aus dem Bild, und man
     rollt ein Fenster, das eigentlich alles auf einmal zeigen soll. */
  min-height: min(560px, 62vh); align-items: start;
}
.pdf-teile .pdf-teil { display: block; padding: 0; border: 0; }
.pdf-teile .pdf-haken { margin-bottom: 7px; padding-top: 0; }
.pdf-wahl .pdf-feld + .pdf-feld { margin-top: 6px; }
.pdf-panel-suche { margin-bottom: 8px; }
.pdf-panel-suche input, .pdf-namen .search-wrap input { width: 100%; }
/* Fest unten, nicht mitrollend - deshalb `flex: 0 0 auto`. */
.pdf-panel-fuss {
  display: flex; justify-content: flex-end; margin-top: 10px; flex: 0 0 auto;
}
.pdf-panel-suche, .pdf-panel .pdf-alle { flex: 0 0 auto; }
/* Ein Knopf mit Zeichen davor - wie der Drucken-Knopf im Dashboard. */
.btn.mit-symbol { display: inline-flex; align-items: center; gap: 6px; }
.btn.mit-symbol svg { width: 16px; height: 16px; fill: currentColor; }
@media (max-width: 900px) {
  .pdf-teile { grid-template-columns: 1fr; }
}

/* Die Rolle als Bild im Zuweisen-Dialog: Balken und Pillen, sonst nichts.
   ⚠️ Knöpfe und Griffe raus - gesperrt stünden sie nur im Weg und liessen
   einen klicken, wo nichts passiert. */
/* ⚠️ In der Vorschau ist kein Name anklickbar: Ohne diese Regel sähe er beim
   Darüberfahren aus wie ein Verweis (blau, unterstrichen) und führte doch
   nirgendwohin. */
.nur-anzeige .chip-name { cursor: default; }
.nur-anzeige .chip-name:hover { color: inherit; text-decoration: none; }
.nur-anzeige .chip-drag,
.nur-anzeige .chip .x,
.nur-anzeige .role-head .btn,
.nur-anzeige .papierkorb { display: none; }
.chip-wert { font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; }
.rolle-vorschau { margin-top: 10px; }
.rolle-vorschau .role { margin: 0; }

/* Dashboard Mitarbeiter: dieselben Säulen wie bei den Rollen, dazu zwei
   eigene Abschnitte. ⚠️ Was jemand in ANDEREN Einheiten trägt, steht ganz
   blass da - es gehört zum Bild (sonst sähe die Säule zu kurz aus), aber
   nicht in den Vordergrund dieser Kachel. */
.seg-fremd {
  background: linear-gradient(180deg, #4b78e3, #2f5bd7);
  opacity: .16;
}
.lg-fremd { background: linear-gradient(180deg, #4b78e3, #2f5bd7); opacity: .16; }
/* Überkapazität und Overload im Dashboard schraffiert: Sie sind kein Anteil
   wie die Rollen, sondern eine Auskunft über den Rest - das soll man auch
   dann sehen, wenn die Farben nebeneinander klein werden. */
.ma-frei { background: repeating-linear-gradient(45deg, #f3c24b, #f3c24b 6px, #dca82c 6px, #dca82c 12px); }
.ma-over {
  /* ⚠️ Blau gestreift wie im Dashboard Organisationseinheiten
     (`.seg-ma-over`, 04.10.2026) - vorher rot. Überlast sieht damit in
     beiden Dashboards, im Strahl und in den Pillen gleich aus. */
  background-color: #2f5bd7;
  background-image: repeating-linear-gradient(45deg,
    rgba(255, 255, 255, .55) 0 4px, rgba(255, 255, 255, 0) 4px 9px);
}
.lg-free { background: repeating-linear-gradient(45deg, #f3c24b, #f3c24b 4px, #dca82c 4px, #dca82c 8px); }
.lg-over {
  background-color: #2f5bd7;
  background-image:
    repeating-linear-gradient(45deg, rgba(255, 255, 255, .55) 0 3px, rgba(255, 255, 255, 0) 3px 7px);
}
/* Zeichen und Wort im Druckknopf - wie beim grünen Knopf darunter. */
.chart-drucken { display: inline-flex; align-items: center; gap: 6px; }
.chart-drucken svg { width: 17px; height: 17px; fill: currentColor; }
/* Gelb schraffiert wie der Abschnitt im Balken: über dem Bedarf besetzt. */
.lg-ueber { background: repeating-linear-gradient(45deg, #f3c24b, #f3c24b 4px, #dca82c 4px, #dca82c 8px); }
/* Unter der VZÄ-Zahl: was offen ist (rot) und was darüber liegt (gelb).
   ⚠️ Nur, wenn es etwas zu sagen gibt - eine Null unter jeder Säule wäre
   Rauschen, und die Zeile soll ins Auge fallen, wenn sie dasteht. */
.chart-extra {
  display: flex; justify-content: center; gap: 6px;
  font-size: 10px; font-weight: 600; line-height: 1.2; min-height: 12px;
}
.chart-extra .rot { color: var(--danger); }
.chart-extra .blau { color: var(--brand); }
.chart-extra .gelb { color: var(--warn); }
/* Die Kennzahlen der Einheit unter ihrem Namen - dieselben Farben wie
   überall: rot für offen, gelb für freie Kapazität, und Null bleibt grau. */
.chart-unit-kpi {
  display: flex; flex-wrap: wrap; justify-content: center; gap: 4px 12px;
  margin-top: 2px; font-size: 11px; color: var(--muted);
}
.chart-unit-kpi b { color: var(--text); font-size: 12px; }
.chart-unit-kpi .rot b { color: var(--danger); }
.chart-unit-kpi .gelb b { color: var(--warn); }
/* Wer hier über seinem Ausmass liegt (rot, mit Rolle) und wer Kapazität frei
   hat (gelb) - unter den Kennzahlen der Einheit, je ein Block mit
   Überschrift und einer Zeile je Eintrag. */
/* ⚠️ Untereinander, nicht nebeneinander: Zwei Listen mit je eigener
   Überschrift nebeneinander liest man als eine - man springt beim Lesen
   zwischen den Spalten hin und her. */
.chart-unit-leute {
  display: flex; flex-direction: column; align-items: flex-start; gap: 4px;
  margin-top: 5px; font-size: 10.5px; line-height: 1.45;
}
.chart-leute-block { text-align: left; }
.chart-leute-block span { display: block; }
.chart-leute-titel { display: block; font-weight: 700; }
.chart-unit-leute .rot { color: var(--danger); }
.chart-unit-leute .blau { color: var(--brand); }
.chart-unit-leute .gelb { color: var(--warn); }
.chart-unit-leute b { font-weight: 700; }
/* Besetzt, aber über dem Ausmass der Person: blau mit weissem Muster.
   ⚠️ Bewusst NICHT in der Farbe der Rolle - der Abschnitt soll aus ihr
   herausfallen, denn er sagt etwas über den MENSCHEN, nicht über die Rolle.
   In der Legende steht dasselbe Blau. */
.seg-ma-over {
  background-color: #2f5bd7;
  background-image: repeating-linear-gradient(45deg,
    rgba(255, 255, 255, .55) 0 4px, rgba(255, 255, 255, 0) 4px 9px);
}
/* Ausgeschieden, aber nicht nachbesetzt: grau. ⚠️ Keine Rollenfarbe und
   kein Blau - die Säule steht für jemanden, der nicht mehr da ist; was
   bleibt, ist die Lücke. Die Spuren trennt eine helle Linie, sonst sähen
   zwei Rollen aus wie eine. */
.seg-weg {
  background: linear-gradient(180deg, #b9bfcc, #9aa2b4);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .6);
}
.lg-weg { background: linear-gradient(180deg, #b9bfcc, #9aa2b4); }
/* Kürzel und Zahl blass UND durchgestrichen - dieselbe Sprache wie der
   Name in der Rolle: Die Person ist weg, nur ihre Lücke steht noch da. */
.chart-col.weg .chart-label,
.chart-col.weg .chart-value { color: var(--muted); text-decoration: line-through; }

/* In der Legende dieselbe Machart: ⚠️ das weisse Muster ZUERST, sonst läge
   es hinter der Farbe und wäre nicht zu sehen. */
.lg-ma-over {
  background-color: #2f5bd7;
  background-image:
    repeating-linear-gradient(45deg, rgba(255, 255, 255, .55) 0 3px, rgba(255, 255, 255, 0) 3px 7px);
}

/* Der Name als Klappschalter (OE und Rolle): sieht aus wie Text, ist aber
   ein Knopf. ⚠️ Kein Unterstrich und keine Farbe - der Name ist die
   Überschrift, nicht ein Verweis - auch beim Darüberfahren bleibt er
   still; dass er klickbar ist, sagt der Zeiger.
   `text-align: left` und `padding: 0`, weil ein <button> beides von sich
   aus anders macht und der Name sonst mittig und eingerückt stünde. */
.titel-knopf {
  font: inherit; color: inherit; background: none; border: 0;
  padding: 0; margin: 0; text-align: left; cursor: pointer;
}
.titel-knopf:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; border-radius: 3px; }
/* Der Kopfteil der Mitarbeiterkarte ist als Ganzes der Klappschalter -
   dieselbe Machart wie bei Einheit und Rolle (siehe `.klappflaeche`). */
.emp-oben { cursor: pointer; }
.emp-oben input, .emp-oben select, .emp-oben .note-icon { cursor: auto; }

/* Bricht eine Kopfzeile um, brechen alle um (Klasse setzt
   oeKopfAusrichten()): Die Knöpfe stehen dann bei JEDER Einheit unter dem
   Namen, links ausgerichtet wie er. */
#units.aktionen-unten .unit-headline { flex: 1 1 100%; }
#units.aktionen-unten .unit-actions { flex: 1 1 100%; justify-content: flex-start; }

/* Ein Dreieck sagt die Richtung: ▲ klappt zu, ▼ klappt auf. ⚠️ Schwarz,
   nicht in der Farbe des Verweises - es ist ein Zeichen, kein Wort, und
   soll neben dem Text stehen, nicht in ihm verschwinden.
   ⚠️ Über `::after`, nicht im Text: Die beiden Verweise der
   Mitarbeiterlisten bekommen ihre Beschriftung beim Zeichnen gesetzt
   (`klappVerweis()`), und ein Zeichen im Übersetzungstext müsste in jeder
   Sprache mitgepflegt werden. */
[data-act="alle-zu"]::after,
[data-act="emp-klapp-alle"][data-id="zu"]::after { content: ' \25B2'; color: #000; }
[data-act="alle-auf"]::after,
[data-act="emp-klapp-alle"][data-id="auf"]::after { content: ' \25BC'; color: #000; }

/* Die Flächen, die zu- und aufklappen (Einheit, Rolle, Mitarbeiterkarte).
   Was darin selbst etwas tut, behält seinen Zeiger. */
.klappflaeche { cursor: pointer; }
.klappflaeche input, .klappflaeche select, .klappflaeche .note-icon,
.klappflaeche .role-numbers, .klappflaeche .unit-drag, .klappflaeche .role-drag { cursor: auto; }

/* Dasselbe Zeichen wie bei „alle auf-/zuklappen": ▲ klappt zu, ▼ klappt
   auf. ⚠️ Es steht hinter dem Namen, weil man dort klickt - und sagt
   damit zugleich, DASS die Kachel klappt; ohne Zeichen sah man es der
   Überschrift nicht an. Etwas kleiner als der Name: ein Hinweis, keine
   zweite Überschrift. */
/* ⚠️ Am ganzen Titelblock, nicht am Namensknopf: Hinter dem Namen können
   noch das „i" der Notiz und Merker wie „offen 0,30" oder „über 0,30"
   stehen - das Dreieck gehört ans ENDE der Zeile, sonst steht es mitten
   drin. */
.unit-title::after, .role-name::after, .emp-name::after {
  content: '\25B2'; color: #000; font-size: .78em; font-weight: 400;
}
/* ⚠️ Der Abstand als `margin`, nicht als Leerzeichen im `content`: Vor dem
   Dreieck steht oft ein Merker („über 0,30") oder das „i" der Notiz, und
   ein einzelnes Leerzeichen klebte daran. Bei der Einheit sorgt schon der
   `gap` der Kopfzeile dafür. */
.role-name::after, .emp-name::after { margin-left: 7px; }
.unit.collapsed .unit-title::after,
.role.zu .role-name::after,
.emp.zu .emp-name::after { content: '\25BC'; }

/* Die Abschnitte des Zuordnungsstrahls führen zur Rolle. */
.emp .bar [data-act="asg-zeigen"] { cursor: pointer; }

/* Kurz aufleuchten, wenn man über den Zuordnungsstrahl hierher gesprungen
   ist. ⚠️ FÜNF Pulse im halben Takt (03.10.2026), nicht drei im ganzen:
   Die Gesamtdauer bleibt dieselbe, aber das schnellere Flackern fällt im
   Augenwinkel auf - drei langsame Pulse las man als ruhiges Atmen und
   übersah sie neben allem anderen, was sich beim Monatswechsel ändert. */
@keyframes pille-blitz {
  0% { box-shadow: 0 0 0 0 rgba(var(--blitz-ton), .55); }
  70% { box-shadow: 0 0 0 9px rgba(var(--blitz-ton), 0); }
  100% { box-shadow: 0 0 0 0 rgba(var(--blitz-ton), 0); }
}
/* Der Ton kommt vom angeklickten Abschnitt (siehe pilleBlitzen()); ohne ihn
   das Blau von „besetzt". */
.chip.blitz { --blitz-ton: 47, 91, 215; animation: pille-blitz .55s ease-out 5; }
/* Wer Bewegung abbestellt hat, bekommt einen ruhigen Rahmen statt Pulsen. */
@media (prefers-reduced-motion: reduce) {
  .chip.blitz { animation: none; box-shadow: 0 0 0 2px rgb(var(--blitz-ton)); }
}

/* Der Löschknopf im Bearbeiten-Fenster trägt den Papierkorb - dasselbe
   Zeichen, das vorher in der Kachel stand. */
#modal-extra.mit-symbol { display: inline-flex; align-items: center; gap: 6px; }
#modal-extra.mit-symbol svg { width: 16px; height: 16px; fill: currentColor; }

/* Die Abschnitte des Rollenbalkens führen zu ihrem Menschen - wie die Pille
   darunter. ⚠️ In der Vorschau des Zuweisen-Fensters nicht: Dort wird nur
   gezeigt, wie es aussähe; ein Filter mitten im Dialog wäre ein Sprung, den
   niemand verlangt hat. */
.role .bar [data-act="emp-filter"] { cursor: pointer; }
.nur-anzeige .bar [data-act] { pointer-events: none; }

/* Was bei dieser Person noch kommt - violett wie alles Künftige, eine Zeile
   je Monat. ⚠️ Knöpfe, keine Absätze: Jede Zeile springt in ihren Monat,
   und das gehört auch für die Tastatur erreichbar. */
.emp-kuenftig { display: flex; flex-direction: column; gap: 1px; margin-top: 6px; }
.emp-kuenftig-zeile {
  font: inherit; font-size: 12px; line-height: 1.4; text-align: left;
  color: var(--future); background: none; border: 0; padding: 1px 0; cursor: pointer;
}
.emp-kuenftig-zeile:hover { text-decoration: underline; text-underline-offset: 2px; }
.emp-kuenftig-zeile .k-monat { font-weight: 700; }

/* Der Sprung in einen anderen Monat: Die Anzeige links oben blitzt fünfmal
   im halben Takt, sonst übersieht man ihn. */
@keyframes monat-blitz {
  0% { box-shadow: 0 0 0 0 rgba(111, 71, 201, .55); }
  70% { box-shadow: 0 0 0 10px rgba(111, 71, 201, 0); }
  100% { box-shadow: 0 0 0 0 rgba(111, 71, 201, 0); }
}
.month-label.blitz { animation: monat-blitz .55s ease-out 5; border-radius: 6px; }
@media (prefers-reduced-motion: reduce) {
  .month-label.blitz { animation: none; box-shadow: 0 0 0 2px var(--future); }
}

/* Der laufende Monat in der Liste der Veränderungen: schwarz, kein Verweis -
   er ist die Lage, keine Aussicht. */
.emp-kuenftig-jetzt { font-size: 12px; line-height: 1.4; color: var(--text); padding: 1px 0; }
.emp-kuenftig-jetzt .k-monat { font-weight: 700; }
/* Violett wie alles, was aus der Zeit kommt - der Text bleibt schwarz. */
.emp-kuenftig-jetzt.blitz {
  --blitz-ton: 111, 71, 201; animation: pille-blitz .55s ease-out 5; border-radius: 4px;
}
@media (prefers-reduced-motion: reduce) {
  .emp-kuenftig-jetzt.blitz { animation: none; box-shadow: 0 0 0 2px rgb(var(--blitz-ton)); }
}

/* ------------------------------------------------- Fusszeile (04.10.2026)
   AGB · Datenschutz · Impressum, unter den Spalten (die Spaltenhöhe zieht sie ab, siehe spaltenhoeheMessen) - klein und
   grau, denn man sucht sie, statt über sie zu stolpern. */
.fusszeile {
  display: flex; justify-content: center; flex-wrap: wrap; gap: 8px;
  padding: 18px 16px 22px; font-size: 13px; color: var(--muted);
}
.fusszeile a { color: var(--muted); text-decoration: none; }
.fusszeile a:hover { color: var(--text); text-decoration: underline; }
