/* Disposition-Board — Sidebar-Layout + adaptives Raster, scoped auf .dispo */
.dispo{
  --cyan:#0099CC;--cyan-d:#0077A3;
  --d-ink:#0E1419;--d-ink2:#3A4750;--d-line:#D7DEE3;--d-line2:#EAEEF1;
  --d-paper:#F4F6F8;--d-white:#FFFFFF;--d-rust:#C5503B;
  --dw:44px;--label:200px;--barh:28px;
  /* ---- Hoehen-Raster ----------------------------------------------------
     Drei Rollen statt sechs gewachsener Sonderwerte. Ein Schrittmass, das mit
     --barh mitwaechst, damit die Abstufung bei jeder Dichte gleich stark wirkt
     (ein fester 2px-Schritt ist bei --barh 24 nur 8%, bei 12 aber 17%).
       eigenstaendig  volle Hoehe   Person, Geraet, Fahrzeug standalone/override
       gekoppelt      - 1 Schritt   Fahrzeug derived (folgt MA), ghost
       kontext        - 2 Schritte  Objektband, Vorgangsband und ihre Labels
     Boden 12px: das ist die kleinste Hoehe, die Rahmen plus Beschriftung noch
     traegt (gemessen — bei 10px schneiden derived und ghost an, weil der Rahmen
     1-2px vom Inhalt frisst). barhForLane() klemmt --barh selbst bei 12px, bei
     kompakt fallen die drei Rollen darum auf eine Hoehe zusammen. Das ist
     gewollt: in 12px ist keine lesbare Treppe unterzubringen, und unterschieden
     werden die Balken dort ohnehin ueber Farbe, Schraffur und Rahmen. */
  --h-step:max(2px,calc(var(--barh) * .125));
  --h-eigen:var(--barh);
  --h-koppel:max(12px,calc(var(--barh) - var(--h-step)));
  --h-kontext:max(12px,calc(var(--barh) - 2 * var(--h-step)));
  --d-shadow:0 1px 0 rgba(14,20,25,.04),0 2px 8px rgba(14,20,25,.06);
  color:var(--d-ink);--fs:1;font-size:calc(12px * var(--fs));
}
.dispo *{box-sizing:border-box}
.dispo-empty{padding:28px 16px;color:var(--d-ink2);font-size:13px;text-align:center}

/* ---- Layout: linke Sidebar + Board ---- */
.dispo-main{display:grid;grid-template-columns:200px minmax(0,1fr);gap:14px;align-items:start}
.dispo-boardwrap{min-width:0;position:relative}
.dispo-side{display:flex;flex-direction:column;gap:7px;position:sticky;top:8px;overflow:auto;overscroll-behavior:contain;scrollbar-width:thin;scrollbar-color:#C3CED6 transparent}
/* Der Scrollbalken der Steuerung bleibt sichtbar. Sie scrollt seit jeher (fitHeight
   setzt max-height), aber macOS zeigt Overlay-Scrollbalken nur waehrend des Scrollens —
   ein Block unterhalb der Kante sah dadurch aus, als gaebe es ihn nicht (gemeldet
   Lukas 11.09.2026 zu «Darstellung»). */
.dispo-side::-webkit-scrollbar{width:9px}
.dispo-side::-webkit-scrollbar-track{background:transparent}
.dispo-side::-webkit-scrollbar-thumb{background:#C3CED6;border-radius:6px;border:2px solid var(--d-paper)}
.dispo-side::-webkit-scrollbar-thumb:hover{background:#A9B8C4}
@media(max-width:820px){
  .dispo-main{grid-template-columns:1fr}
  .dispo-side{position:static;overflow:visible;max-height:none}
}

/* ---- Sidebar ein-/ausklappen (mehr Platz fürs Gantt-Board) ---- */
/* Collapse-Button im Steuerungs-Kopf; Reopen-Handle nur eingeklappt am Board-Rand */
.dispo .side-head{display:flex;align-items:center;justify-content:space-between;gap:6px;margin-bottom:1px}
.dispo .side-head-t{font-weight:700;text-transform:uppercase;letter-spacing:.06em;font-size:calc(10.5px * var(--fs));color:var(--d-ink2)}
.dispo .side-toggle{flex:none;width:24px;height:24px;padding:0;display:inline-flex;align-items:center;justify-content:center;border:1px solid var(--d-line);background:var(--d-white);color:var(--d-ink2);border-radius:7px;cursor:pointer;box-shadow:var(--d-shadow);font-size:14px;font-weight:700;line-height:1}
.dispo .side-toggle:hover{color:var(--cyan-d);border-color:var(--cyan)}
.dispo .side-reopen{display:none}
/* z-index 12, nicht 9: .board-head hat ebenfalls 9 und steht SPAETER im DOM, lag also
   oben — der Knopf war gerendert, aber jeder Klick landete auf der Kalenderleiste.
   Am 10.09.2026 im Live-Cockpit gemessen (elementFromPoint traf .c1 der Kopfleiste):
   eine einmal eingeklappte Steuerung liess sich damit gar nicht mehr aufklappen, und
   ohne sie war kein Filter mehr erreichbar — «Nur disponierte» blieb an und das Board
   sah leer gefiltert aus. */
/* Fuellung halbtransparent DUNKEL, nicht deckend weiss (Ansage Lukas 10.09.2026:
   «viel zu dominant, leichtere fuellung»). Der Knopf sitzt bei top:6px mitten in der
   68px hohen Kalenderleiste, die var(--d-ink) = rgb(14,20,25) dunkel ist — deckend
   weiss war dort ein greller Kasten. Dunkel-transparent traegt BEIDE Gruende: bei
   leerem Board (.dispo-empty) liegt er auf hellem Untergrund, und dort waere ein
   heller Knopf mit weissem Pfeil unlesbar. Kein Schatten mehr, er soll nicht
   aufliegen, sondern zur Leiste gehoeren. */
.dispo.side-collapsed .side-reopen{position:absolute;top:6px;left:6px;z-index:12;display:inline-flex;align-items:center;justify-content:center;width:26px;height:26px;padding:0;border:1px solid rgba(255,255,255,.22);background:rgba(14,20,25,.55);color:#fff;border-radius:7px;cursor:pointer;box-shadow:none;font-size:14px;font-weight:700;line-height:1}
.dispo.side-collapsed .side-reopen:hover{background:var(--cyan);border-color:var(--cyan);color:#fff}
.dispo.side-collapsed .dispo-side{display:none}

/* Klapp-Abschnitte der Steuerung (0.6.601). Die Spalte war nach dem Umzug der
   Kopfecken-Funktionen 770px hoch; «Werkzeuge» (101px) und «Darstellung» (104px)
   werden selten angefasst und stehen darum zugeklappt. Der Kopf ist ein Knopf und
   sieht aus wie die uebrigen Gruppen-Labels, damit die Spalte ruhig bleibt. */
.dispo .side-sec{display:flex;flex-direction:column;gap:7px}
.dispo .side-sec .sec-head{display:flex;align-items:center;gap:6px;width:100%;background:none;border:0;
  padding:1px 2px;cursor:pointer;font:inherit;font-weight:700;font-size:calc(10.5px * var(--fs));
  text-transform:uppercase;letter-spacing:.06em;color:var(--d-ink2);text-align:left}
.dispo .side-sec .sec-head:hover{color:var(--cyan-d)}
.dispo .side-sec .sec-head:focus-visible{outline:2px solid var(--cyan);outline-offset:2px;border-radius:6px}
.dispo .side-sec .sec-car{flex:none;width:9px;font-size:9px;line-height:1}
.dispo .side-sec .sec-body{display:none;flex-direction:column;gap:7px}
.dispo .side-sec.offen .sec-body{display:flex}
.dispo.side-collapsed .dispo-main{grid-template-columns:1fr}
/* Sektions-Trenner + sekundäre Darstellungs-Gruppe in der Sidebar */
.dispo .side-sep{height:1px;background:var(--d-line);margin:5px 2px;opacity:.7}
.dispo .side-grp.side-display{gap:5px}
.dispo .side-grp.side-display .lbl{opacity:.75}
.dispo .rowh{display:flex;align-items:center;gap:7px;padding:1px 2px}
.dispo .rowh-l{font-weight:700;text-transform:uppercase;letter-spacing:.05em;font-size:calc(9.5px * var(--fs));color:var(--d-ink2)}
.dispo .rowh input[type=range]{flex:1;min-width:0;accent-color:var(--cyan);height:16px;cursor:pointer}
.dispo .rowh-v{font-weight:700;font-size:calc(10px * var(--fs));color:var(--d-ink2);min-width:30px;text-align:right}
.dispo .resfilter{width:100%;border:1px solid var(--d-line);border-radius:8px;height:28px;padding:0 9px;font:inherit;font-size:calc(12px * var(--fs));color:var(--d-ink);background:var(--d-white);box-shadow:var(--d-shadow)}
.dispo .resfilter:focus{outline:none;border-color:var(--cyan)}
.dispo .resfilter::placeholder{color:var(--d-ink2);opacity:.7}
.dispo .util-head .resfilter{display:none;width:190px;height:26px;flex:none;margin-left:auto}
.dispo.util-open .util-head .resfilter{display:inline-block}

/* ---- Controls (in Sidebar gestapelt) ---- */
.dispo .ctl{background:var(--d-white);border:1px solid var(--d-line);border-radius:9px;box-shadow:var(--d-shadow);display:flex;align-items:center;padding:3px;width:100%}
.dispo .ctl button{border:1px solid var(--d-line);background:var(--d-line2);cursor:pointer;font-weight:700;font-size:calc(11px * var(--fs));text-transform:uppercase;letter-spacing:.04em;color:var(--d-ink2);padding:0 8px;height:25px;border-radius:6px;display:flex;align-items:center;justify-content:center;gap:5px}
.dispo .ctl button[aria-selected="true"],.dispo .ctl button.act{background:var(--d-ink);border-color:var(--d-ink);color:#fff}
/* Alle Passiv-Buttons leicht grau (aktiv unverändert); Hover nur im Passiv-Zustand */
.dispo .ctl button:not(.act):not([aria-selected="true"]):hover{border-color:var(--cyan);color:var(--cyan-d)}
.dispo .ctl.solo{justify-content:center;height:30px}
.dispo .ctl.solo .lbl{color:var(--d-ink)}
.dispo #d-weeks button,.dispo #d-view button,.dispo #d-res button{flex:1;padding:0 4px}
.dispo .wk button{width:30px;flex:none;padding:0;font-size:16px;color:var(--d-ink)}
.dispo .wk .label{flex:1;padding:0 8px;text-align:center}
.dispo .wk .kw{font-weight:700;color:var(--cyan-d);font-size:calc(13px * var(--fs))}
.dispo .wk .range{font-size:calc(10.5px * var(--fs));color:var(--d-ink2)}
.dispo .side-grp{display:flex;flex-direction:column;gap:4px}
.dispo .lbl{font-weight:700;font-size:calc(10.5px * var(--fs));text-transform:uppercase;letter-spacing:.06em;color:var(--d-ink2)}
.dispo .mode{display:flex;align-items:center;justify-content:center;gap:7px;font-weight:700;font-size:11.5px;text-transform:uppercase;letter-spacing:.05em;border:1px dashed var(--d-line);background:var(--d-white);height:36px;padding:0 12px;border-radius:9px;cursor:pointer;color:var(--d-ink2)}
.dispo .mode.on{border-style:solid;border-color:var(--d-rust);color:var(--d-rust);background:#FCEEEB}
.dispo .mode .dot{width:9px;height:9px;border-radius:2px;background:var(--d-rust);opacity:.4}.dispo .mode.on .dot{opacity:1}

/* ---- Palette (vertikal in Sidebar) ---- */
.dispo .palette{background:var(--d-white);border:1px solid var(--d-line);border-radius:11px;padding:10px;box-shadow:var(--d-shadow);display:flex;flex-direction:column;align-items:stretch;gap:6px;max-height:40vh;overflow:auto}
.dispo .palette .ttl{font-weight:700;text-transform:uppercase;letter-spacing:.07em;font-size:calc(10.5px * var(--fs));color:var(--d-ink2);margin-bottom:2px}
.dispo .palette .pal-empty{font-size:calc(12px * var(--fs));color:var(--d-ink2);font-style:italic}
.dispo .palette .pal-grp{display:flex;align-items:center;gap:6px;width:100%;border:none;background:none;cursor:pointer;padding:3px 0;margin-top:4px;font:inherit;font-weight:700;text-transform:uppercase;letter-spacing:.07em;font-size:calc(10.5px * var(--fs));color:var(--d-ink2);text-align:left}
.dispo .palette .pal-grp:first-child{margin-top:0}
.dispo .palette .pal-grp .cv{display:inline-block;transition:transform .12s;flex:none;font-size:10px}
.dispo .palette .pal-grp:not(.collapsed) .cv{transform:rotate(90deg)}
.dispo .palette .pal-grp .t{flex:1}
.dispo .palette .pal-grp .n{flex:none;font-weight:700;color:var(--d-ink2);background:var(--d-paper);border:1px solid var(--d-line);border-radius:9px;padding:0 6px;font-size:calc(9.5px * var(--fs))}
.dispo .chip{display:flex;align-items:center;gap:7px;padding:5px 9px;border-radius:7px;cursor:grab;font-weight:600;font-size:calc(12px * var(--fs));background:var(--d-paper);border:1px solid var(--d-line);user-select:none;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.dispo .chip:hover{box-shadow:var(--d-shadow)}
.dispo .chip .swatch{width:12px;height:12px;border-radius:3px;flex:none}
/* ★ Favorit im Personal-Chip. margin-left:auto schiebt ihn an den rechten Rand,
   damit die Sterne einer Spalte untereinander stehen. */
.dispo .chip .pin{margin-left:auto;flex:none;cursor:pointer;font-size:calc(13px * var(--fs));line-height:1;color:#94a3b8;opacity:.7}
.dispo .chip .pin:hover{opacity:1;color:#64748b}
.dispo .chip .pin.on{color:#E0A21B;opacity:1}
.dispo.readonly .chip .pin{display:none}

/* ---- Board ---- */
.dispo .board{background:var(--d-white);border:1px solid var(--d-line);border-radius:13px;box-shadow:var(--d-shadow);overflow:auto;max-height:78vh;position:relative}
/* Kalenderleiste KOMPLETT ausserhalb des Scrollbereichs.
   Vorher war der Kopf ein position:sticky-Element IM Board. Sticky klebt aber am
   oberen Rand seines Scroll-Containers — sobald die SEITE (.content) scrollte,
   wanderte das ganze Board samt Leiste aus dem Bild («Kalender scrollt weg,
   wenn der Scrollbereich zu hoch ist»). Jetzt: eigener, nicht scrollender
   Kopf-Container ueber dem Board, horizontal per JS mitgezogen, und zusaetzlich
   sticky am Viewport, solange die .boardbox sichtbar ist.
   WICHTIG: .boardbox darf KEIN overflow bekommen — overflow != visible auf einem
   Vorfahren macht position:sticky wirkungslos. */
.dispo .boardbox{position:relative;background:var(--d-white);border:1px solid var(--d-line);border-radius:13px;box-shadow:var(--d-shadow)}
.dispo .boardbox>.board{background:transparent;border:0;box-shadow:none;border-radius:0 0 12px 12px}
.dispo .board-head{position:sticky;top:0;z-index:9;overflow:hidden;background:var(--d-ink);border-radius:12px 12px 0 0}
.dispo .board-head .row.head{position:static;border-bottom:0}
/* Der Kopf hat keine vertikale Scrollbar, das Board schon → gleiche Scrollbreite
   herstellen, sonst laeuft die Leiste am rechten Anschlag um die Scrollbarbreite aus. */
.dispo .board-head .row.head::after{content:"";flex:none;width:var(--sbw,0px)}
.dispo .row{display:flex;border-bottom:1px solid var(--d-line2);width:max-content;min-width:100%}
/* Ressourcen-Zeilen ohne Trennlinie: der 1px-Border würde sonst den Abstand ZWISCHEN den Balken
   um 1px grösser machen als den Rand zum Gruppen-Rahmen (ungleicher unterer Rand). */
.dispo .row.k-person,.dispo .row.k-geraet,.dispo .row.k-vehicle,.dispo .row.k-ghost{border-bottom:none}
.dispo .row.head{z-index:6}
.dispo .corner,.dispo .rl{width:var(--label);min-width:var(--label);position:sticky;left:0;background:var(--d-white);z-index:4;border-right:1px solid var(--d-line)}
.dispo .row:nth-child(even) .rl{background:#FBFCFD}
.dispo .corner{z-index:7;background:var(--d-ink)}
.dispo .kwband,.dispo .dayband{display:flex;background:var(--d-ink)}
.dispo .kwcell{height:19px;display:flex;align-items:center;justify-content:center;color:#fff;font-weight:700;font-size:calc(10.5px * var(--fs));letter-spacing:.04em;border-right:1px solid #29343d;overflow:hidden}
.dispo .dcell{width:var(--dw);min-width:var(--dw);height:32px;display:flex;flex-direction:column;align-items:center;justify-content:center;color:#fff;border-right:1px solid #29343d;overflow:hidden}
.dispo .dcell .wd{font-weight:700;font-size:calc(9.5px * var(--fs));text-transform:uppercase;letter-spacing:.06em;opacity:.8}
.dispo .dcell .dd{font-weight:700;font-size:calc(11.5px * var(--fs));margin-top:1px}
.dispo .dcell.today{background:var(--cyan-d)}.dispo .dcell.today .wd{opacity:1}
/* Wochenende in der Kalenderleiste: deutlich hellerer Block, Sonntag zusaetzlich warm eingefaerbt */
.dispo .dcell.we{background:#2A3945}
.dispo .dcell.we .wd{opacity:1;color:#A9BECD}
.dispo .dcell.we .dd{color:#DCE6ED}
.dispo .dcell.so{background:#33434F}
.dispo .dcell.so .wd,.dispo .dcell.so .dd{color:#F0A794}
.dispo .dcell.sa{border-left:1px solid #4A5E6E}
.dispo .corner .c1{height:19px}
.dispo .corner .c2{height:32px;display:flex;align-items:center;padding-left:12px;font-weight:700;text-transform:uppercase;letter-spacing:.08em;font-size:calc(11px * var(--fs));color:#fff}
.dispo .rl{padding:0 10px;display:flex;flex-direction:column;justify-content:center}
.dispo .rl .nm{font-weight:600;font-size:calc(12px * var(--fs));line-height:1.1}
.dispo .rl .fn{font-size:calc(10.5px * var(--fs));color:var(--d-ink2);margin-top:1px}
/* Ortschaft hinter dem Objekt-/Vorgangstitel — bewusst leiser als der Titel */
.dispo .rl .rl-ort{font-weight:500;color:var(--d-ink2);margin-left:6px;font-size:calc(11px * var(--fs))}
.dispo .rl .rl-ort::before{content:"\1F4CD";margin-right:2px;font-weight:400}
.dispo .rl .sw{width:9px;height:9px;border-radius:2px;display:inline-block;margin-right:6px;vertical-align:middle}
/* Swatch-Grösse nach Hierarchie: Objekt > Vorgang > Ressource */
.dispo .row.k-obj .rl .sw{width:14px;height:14px;border-radius:3px}
.dispo .row.k-vg .rl .sw{width:11px;height:11px}

.dispo .track{position:relative;flex:none;z-index:2}
.dispo .track .gline{position:absolute;top:0;bottom:0;width:1px;background:var(--d-line2)}
.dispo .track .gtoday{position:absolute;top:0;bottom:0;background:rgba(0,153,204,.05)}
.dispo .track .gwe{position:absolute;top:0;bottom:0;background:rgba(91,107,120,.14)}
.dispo .track .gwe.so{background:rgba(91,107,120,.20)}
.dispo .track .gwe.sa{box-shadow:inset 1px 0 0 rgba(91,107,120,.45)}

.dispo .bar{position:absolute;height:var(--h-eigen);border-radius:7px;color:#fff;font-size:calc(12px * var(--fs));line-height:1;font-weight:500;box-shadow:0 1px 3px rgba(0,0,0,.18);display:flex;align-items:center;padding:0 7px;cursor:grab;overflow:hidden;touch-action:none;user-select:none}
.dispo .bar:active{cursor:grabbing}
.dispo .bar .nm{flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;pointer-events:none}
.dispo .bar.nacht::before{content:"";position:absolute;inset:0;background:linear-gradient(180deg,rgba(13,20,30,.5),rgba(13,20,30,.8))}
.dispo .bar.nacht>*{position:relative;z-index:1}
.dispo .bar .shift{flex:none;display:flex;align-items:center;gap:3px;font-size:9.5px;font-weight:700;background:rgba(0,0,0,.2);padding:2px 5px;border-radius:4px;margin-left:5px;cursor:pointer;text-transform:uppercase}
.dispo .bar .shift.ro{cursor:default}
.dispo .bar .shift svg{width:10px;height:10px}
/* Das entfernen-Kreuz bleibt IMMER stehen (Entscheid Lukas 10.09.2026): darum absolut
   an den rechten Rand statt in den Flex-Fluss — im Fluss war es das erste, was
   overflow:hidden bei schmalen Balken abschnitt. right:9px laesst den Resize-Griff
   (8px, z-index 3) frei, der sonst die halbe Klickflaeche des × verdeckte.
   Den Platz reserviert .has-x per padding-right; die Klasse setzt makeBar(). */
.dispo .bar.has-x{padding-right:28px}
.dispo .bar.ro.has-x{padding-right:7px}
.dispo .bar .x{position:absolute;right:9px;top:50%;transform:translateY(-50%);flex:none;width:15px;height:15px;border-radius:4px;background:rgba(255,255,255,.22);display:flex;align-items:center;justify-content:center;cursor:pointer;font-size:12px;font-weight:700}
.dispo .bar .x:hover{background:rgba(255,255,255,.42)}
/* Gesperrtes Kreuz: bleibt stehen, wird zum Schloss und behaelt seinen Platz —
   ein verschwundenes Kreuz laesst den Nutzer suchen und erklaert nichts. Der Klick
   loest den Toast mit dem Grund aus (removeBar -> pastGuard). */
.dispo .bar .x.gesperrt{background:rgba(255,255,255,.14);font-size:9px;cursor:help}
.dispo .bar .x.gesperrt:hover{background:rgba(255,255,255,.3)}
.dispo .bar .h{position:absolute;top:0;bottom:0;width:8px;cursor:ew-resize;z-index:3}
.dispo .bar .h.l{left:0}.dispo .bar .h.r{right:0}
.dispo .bar .h::after{content:"";position:absolute;top:50%;transform:translateY(-50%);width:3px;height:12px;border-radius:2px;background:rgba(255,255,255,.6)}
.dispo .bar .h.l::after{left:2px}.dispo .bar .h.r::after{right:2px}
/* Absenzbalken: Schraffur in der TYPFARBE — --abs-c1/--abs-c2/--abs-bd/--abs-fg
   setzt makeBar() via absPal(lanr) (ABS_PAL = gleiche Palette wie der
   Ferien-Ueberblick). Vorher stand hier ein fixes Rost-Muster mit
   !important -> die Typfarben kamen nie an. Fallback = altes Rost. */
.dispo .bar.absenz{background:repeating-linear-gradient(45deg,var(--abs-c1,#FBEDEA) 0 6px,var(--abs-c2,#F6DED9) 6px 12px)!important;color:var(--abs-fg,#C5503B);border:1px solid var(--abs-bd,#EEC9C1);box-shadow:none;font-weight:700;text-transform:uppercase;font-size:10.5px;letter-spacing:.06em}
.dispo .bar.absenz .x{background:rgba(197,80,59,.18);color:var(--d-rust)}
/* «Arbeit trotz Absenz» (v0.6.565): am selben Tag ist ein Arbeitsrapport erfasst.
   Gleiche Sprache wie im Ferien-Ueberblick — Rand in der Signalfarbe plus feine
   Diagonalstreifen darueber. Signalfarbe kommt je Lohnart als --kf/--kfs mit
   (Krankheit/Unfall anthrazit, sonst rot), weil der Balken dort selbst rot ist.
   Nicht zu verwechseln mit .bar.conflict — das ist die Dispo-Ueberschneidung. */
.dispo .bar.absenz.abs-konflikt{border-color:var(--kf,#B91C1C)!important;position:relative}
.dispo .bar.absenz.abs-konflikt::after{content:"";position:absolute;inset:0;pointer-events:none;
  border-radius:inherit;
  background:repeating-linear-gradient(45deg,var(--kfs,rgba(185,28,28,.55)) 0 1.5px,transparent 1.5px 5px)}

.dispo .trash{display:flex;align-items:center;justify-content:center;gap:9px;min-height:44px;padding:8px 10px;border:2px dashed var(--d-line);border-radius:11px;color:var(--d-ink2);font-weight:700;text-transform:uppercase;letter-spacing:.08em;font-size:calc(11px * var(--fs));text-align:center}
.dispo .trash.over{border-color:var(--d-rust);color:var(--d-rust);background:#FCEEEB}
.dispo .stats{display:flex;gap:10px;flex-wrap:wrap;margin-top:13px}
.dispo .stat{background:var(--d-white);border:1px solid var(--d-line);border-radius:10px;padding:10px 15px;box-shadow:var(--d-shadow);min-width:118px}
.dispo .stat .n{font-weight:700;font-size:21px;color:var(--cyan-d);line-height:1}
.dispo .stat .l{font-weight:700;text-transform:uppercase;letter-spacing:.08em;font-size:11px;color:var(--d-ink2);margin-top:5px}
.dispo .hint{font-size:calc(11.5px * var(--fs));color:var(--d-ink2);margin-top:13px;line-height:1.8}
.dispo .hint b{color:var(--cyan-d)}

/* Vorgang-anlegen-Overlay */
.dispo-ov{position:fixed;inset:0;z-index:3000;background:rgba(15,23,42,.4);display:flex;align-items:center;justify-content:center;padding:16px}
.dispo-ov-card{background:#fff;border-radius:14px;padding:20px 22px;width:min(460px,96vw);box-shadow:0 20px 60px rgba(15,23,42,.28);font:14px/1.5 system-ui,Segoe UI,Roboto,sans-serif}
.dispo-ov-card h3{margin:0 0 14px;font-size:16px}
.dispo-ov-l{display:flex;flex-direction:column;gap:4px;font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.04em;color:#64748b;margin-bottom:12px}
.dispo-ov-in{border:1px solid #dbe2ea;border-radius:8px;height:38px;padding:0 10px;font:inherit;font-weight:400;text-transform:none;letter-spacing:0;color:#0f172a}
.dispo-ov-row{display:flex;gap:12px}.dispo-ov-row .dispo-ov-l{flex:1}
.dispo-ov-note{font-size:12px;color:#475569;background:#f1f5f9;border-radius:8px;padding:8px 10px;margin:-4px 0 12px}
.dispo-ov-btns{display:flex;justify-content:flex-end;gap:10px;margin-top:6px}
.dispo-ov-cancel{border:1px solid #dbe2ea;background:#fff;border-radius:8px;padding:8px 16px;cursor:pointer;font:inherit}
.dispo-ov-ok{border:0;background:#0099CC;color:#fff;border-radius:8px;padding:8px 18px;cursor:pointer;font:inherit;font-weight:600}
/* Loeschen ist unwiderruflich: eigener, roter Knopf, damit er sich nicht mit
   «Speichern» verwechselt.
   ACHTUNG harte Farbwerte, keine var(--...): .dispo-ov wird an document.body
   gehaengt und liegt damit AUSSERHALB von .dispo, wo die Variablen definiert sind.
   Mit var() waere der Knopf transparent mit weisser Schrift — also unsichtbar.
   Genau darum arbeiten auch .dispo-ov-ok/-cancel mit festen Werten. */
.dispo-ov-del{border:0;background:#C5503B;color:#fff;border-radius:8px;padding:8px 18px;cursor:pointer;font:inherit;font-weight:700}
.dispo-ov-del:hover{background:#a93f2c}
.dispo-ov-del:disabled{opacity:.5;cursor:default}
.dispo-ov-card.vg-del-card{max-width:420px}
.vg-del-card .vgdel-zr{font-size:12.5px;font-weight:700;color:#3A4750;margin:-6px 0 12px}
.vg-del-card .vgdel-mit{font-size:12.5px;color:#0E1419;background:#F4F6F8;border:1px solid #D7DEE3;border-radius:8px;padding:10px 12px;margin-bottom:14px}
.vg-del-card .vgdel-h{font-weight:700;margin-bottom:6px}
.vg-del-card .vgdel-mit ul{margin:0;padding-left:18px}
.vg-del-card .vgdel-mit li{margin:2px 0}
.vg-del-card .vgdel-leer{color:#3A4750}
.vg-del-card .vgdel-warn{margin-top:8px;color:#8A5A00;font-size:11.5px}

/* ---- Ebenen-Einrückung (vorgangszentriert) ---- */
.dispo .row.lvl1 .rl{padding-left:24px}
.dispo .row.lvl2 .rl{padding-left:40px}
.dispo .row.k-vg .rl,.dispo .row.k-obj .rl{background:#F0F4F7;font-weight:700}
/* Projekt-(Objekt-)Zeile: ganze Zeile leicht hinterlegt (Track transparent → Zeilen-Hintergrund scheint durch). */
.dispo .row.k-obj{background:#EAF0F4}
.dispo .row.k-obj .rl{background:#E1E8EE}
.dispo .row.k-vg .rl .nm,.dispo .row.k-obj .rl .nm{font-size:calc(13px * var(--fs));font-weight:600}
.dispo .row.k-vehicle .rl .nm{font-weight:600;color:var(--d-ink2)}
/* Geisterzeile («rapportiert, aber nicht eingeteilt»): sieht bewusst NICHT aus wie eine
   Personalzeile — sie ist kein Dispo-Eintrag, sondern eine Meldung aus dem Rapport.
   Darum blasser, kursiver Name und ein Ring in der gruenen Ist-Farbe von Band und Balken.
   Der Ring steht VOR dem Namen: die Spalte schneidet hinten ab, ein Vermerk dahinter
   waere als erstes verschwunden. */
.dispo .row.k-ghost .rl .nm{font-weight:500;color:var(--d-ink2);font-style:italic}
.dispo .rl .rl-ist{display:inline-block;margin-right:5px;font-style:normal;color:#2E9E5B;
  font-size:calc(11px * var(--fs));line-height:1}
/* Gruppen-Kopfzeilen (Objekt-Ansicht, Gruppieren Sparte → Bauführer) */
.dispo .row.k-grp{background:#D7E3EA}
.dispo .row.k-grp .rl{background:#CBDAE3;font-weight:800}
.dispo .row.k-grp .rl .nm{font-size:calc(13px * var(--fs));font-weight:800;text-transform:uppercase;letter-spacing:.03em;color:var(--d-ink)}
.dispo .row.k-grpbf{background:#E7EEF2}
.dispo .row.k-grpbf .rl{background:#DCE6EC;font-weight:700}
.dispo .row.k-grpbf .rl .nm{font-size:calc(12.5px * var(--fs));font-weight:700;color:var(--d-ink2);padding-left:6px}

/* ---- Balken-Typen ---- */
/* Einheit in der calc(): calc(16px - 2) ist ungueltig. Weil der Wert aus einer var()
   kommt, wird die Deklaration nicht schon beim Parsen verworfen, sondern ist "invalid
   at computed-value time" — sie faellt damit NICHT auf die Basisregel .dispo .bar
   zurueck, sondern auf height:auto. Die drei standen dadurch dichteunabhaengig auf
   Inhaltshoehe (19/15/17px) und ragten bei kompakt/normal ueber ihre Lane hinaus.
   Gleicher Fehler wie beim .objbar, dort am 10.09.2026 behoben. Seit dem Hoehen-Raster
   (siehe .dispo) stehen hier keine eigenen calc() mehr, sondern nur noch die Rolle. */
/* Geist-Balken = «rapportiert, aber nicht eingeteilt» (v0.6.595, Optik korrigiert
   in 0.6.596). «Soll ist Soll und Ist ist Ist» (Ansage Lukas 11.09.2026) — der
   Balken zeigt, was war, und darf nie wie ein Dispo-Eintrag aussehen, den man nur
   noch bestaetigen muss.
   NICHT ueber den Farbton unterscheiden: 0.6.595 setzte ihn in die Ist-Farbe
   #2E9E5B, und FERIEN traegt in ABS_PAL #22C55E — im Board waren die beiden nicht
   auseinanderzuhalten (Rueckmeldung Lukas 11.09.2026 am laufenden Board). Jeder
   Farbton der Palette ist belegt: rot Krankheit, orange Unfall, gruen Ferien,
   indigo/violett/teal/amber die uebrigen Absenzen, cyan Personal, orange Geraete,
   graublau Fahrzeug. Darum trennt jetzt die FORM:
     - keine Flaeche, nur ein gepunkteter Anthrazit-Rahmen → kein Kategorie-Balken
     - der gruene 3px-Streifen unten ist derselbe wie .istband → «rapportiert»
       bleibt in der etablierten Sprache, ohne den ganzen Balken einzufaerben
   pointer-events bleibt an, sonst erschiene der title nicht; Zieh-Handler haengen
   ohnehin keine dran, und der Track darunter bekommt seine Drops weiterhin
   (der Geist ist sein Kind, .closest('.track') findet ihn). */
.dispo .bar.t-ghost{background:transparent!important;border:1.5px dotted rgba(14,20,25,.62);
  border-radius:8px;box-shadow:none;color:var(--d-ink2);opacity:1;cursor:help;height:var(--h-koppel)}
.dispo .bar.t-ghost .nm{font-style:italic;opacity:.9}
.dispo .bar.t-ghost::after{content:"";position:absolute;left:3px;right:3px;bottom:1px;height:3px;
  border-radius:2px;background:#2E9E5B;pointer-events:none}
/* Hinterlegung flach statt schraffiert. Die Schraffur der Zeitsperre (.bar.zeitsperre::after)
   laeuft ebenfalls unter 45 Grad, nur mit Periode 7px statt 12px — auf einem vergangenen oder
   fixierten Fahrzeugbalken lagen damit zwei gleichwinklige Raster uebereinander und ergaben
   Moire statt zwei lesbarer Aussagen. Die 45-Grad-Schraffur gehoert jetzt allein der Zeitsperre.
   Das Fahrzeug ist ohnehin an drei anderen Merkmalen kenntlich: hellgrauer Grund, Haarlinie und
   die reduzierte Hoehe aus dem Hoehen-Raster (--h-koppel). */
.dispo .bar.t-vehicle.derived{background:#EEF1F4!important;color:var(--d-ink2);border:1px solid #D2DAE0;box-shadow:none;cursor:default;height:var(--h-koppel);font-size:calc(11px * var(--fs))}
.dispo .bar.t-geraete{border:1px solid rgba(0,0,0,.12)}

/* ---- Badges ---- */
.dispo .bar .badge{flex:none;display:inline-flex;align-items:center;justify-content:center;font-size:11px;margin-left:5px;line-height:1;cursor:default}
.dispo .bar .badge.hotel{filter:saturate(1.1)}
.dispo .bar .badge.warn{background:#FFE8C2;color:#8A5A00;border-radius:4px;padding:1px 4px;font-weight:700}
.dispo .bar.conflict{outline:2px solid #C0392B;outline-offset:-2px}
.dispo .bar.t-vehicle.derived.conflict{outline:2px solid #C0392B}

/* ---- Doppelbelegungs-Stat ---- */
.dispo .stat.warn{border-color:#E0892B;background:#FFF6EA}
.dispo .stat.warn .n{color:#B5651D}

/* ---- Hotel-Nächte-Band (unter dem Personal-Balken) ---- */
.dispo .track .hband{position:absolute;height:3px;border-radius:2px;box-shadow:0 0 0 1px rgba(255,255,255,.55);cursor:help;z-index:2}

/* ---- Fahrzeug umteilen/entkoppeln ---- */
/* Kein !important auf dem Grund: makeBar() setzt bei einem Statusbalken (Reparatur /
   Revision / Defekt) die Statusfarbe inline, und !important hier schlug sie — alle drei
   Arten rendertem darum im selben Standardgrau, erkennbar nur noch am Rahmen. Ein
   normaler standalone-Balken bekommt gar kein Inline-background (makeBar nimmt isVeh
   ausdruecklich aus) und holt sein Grau weiterhin von hier. */
.dispo .bar.t-vehicle.standalone{background:#7A8892;color:#fff;cursor:grab}
.dispo .bar.t-vehicle.standalone:active{cursor:grabbing}
.dispo .bar .veh-edit,.dispo .bar .ge-edit{flex:none;margin-left:5px;cursor:pointer;font-weight:700;font-size:13px;opacity:.85}
.dispo .bar .veh-edit:hover,.dispo .bar .ge-edit:hover{opacity:1}
.dispo .bar.t-vehicle.override{background:#5B6B78!important;color:#fff;border:1px solid #47535d}

/* ---- Temporär-Bedarf (v0.6.799) ----------------------------------------
   Eine eingeplante Stelle, für die noch keine Person zugeteilt ist.

   !important ist hier nicht Bequemlichkeit, sondern nötig: makeBar setzt die
   Balkenfarbe INLINE und hellt sie für Tagbalken auf 62% auf (Zeile ~3120 in
   fretus-dispo.js). Ein aufgehelltes Violett auf hellem Grund ist genau das,
   was ein Bedarf nicht sein darf — er soll auffallen, nicht sich einfügen.
   Aus demselben Grund die eigene Textfarbe: textOn() rechnet gegen den
   aufgehellten Grund und gäbe dunkle Schrift auf dunklem Balken.

   Violett = Einsatz liegt in der Zukunft, der Name ist noch nicht fällig.
   Rot (.faellig) = erster Einsatztag erreicht; ab hier mahnt temp-bedarf-mail
   täglich die Bauführung und das Personalbüro. Die diagonale Schraffur macht
   den Unterschied auch dort erkennbar, wo Farbe allein nicht trägt
   (Farbsehschwäche, Beamer, Ausdruck). */
.dispo .bar.bedarf{
  background:#8E5BC6!important;color:#fff!important;border-color:#6f43a0!important;
  background-image:repeating-linear-gradient(135deg,rgba(255,255,255,.22) 0 5px,transparent 5px 10px)!important;
}
.dispo .bar.bedarf.faellig{
  background:#B3261E!important;border-color:#8c1d18!important;
  box-shadow:0 0 0 1px rgba(179,38,30,.45);
}
/* 👤 benennen — wie .bar-log erst beim Hover, damit der Balken ruhig bleibt.
   Beim fälligen Bedarf dauerhaft sichtbar: dort ist das Benennen die Aufgabe,
   nicht eine Nebenfunktion, die man sich per Hover suchen soll. */
.dispo .bar .temp-name{flex:none;margin-left:5px;cursor:pointer;font-size:12px;line-height:1;opacity:0;transition:opacity .12s}
.dispo .bar:hover .temp-name{opacity:.95}
.dispo .bar.faellig .temp-name{opacity:1}
.dispo .bar .temp-name:hover{opacity:1;transform:scale(1.15)}
.dispo .bar.ro .temp-name{display:none}
/* Zeilenbeschriftung links: die offene Stelle auch dann erkennbar, wenn der
   Balken gerade ausserhalb des sichtbaren Zeitfensters liegt. Die Klasse haengt
   an der Zeile (.rl), nicht an einem .sub — ein sub-Element gibt es in der
   Beschriftung nicht, br.sub wird nur in der Hover-Karte verwendet. */
.dispo .rl.bedarf .nm{color:#8E5BC6;font-weight:600}
.dispo .rl.bedarf.faellig .nm{color:#B3261E}

.dispo .rl .sw.clickable{cursor:pointer;width:12px;height:12px;box-shadow:0 0 0 1px rgba(0,0,0,.15)}
.dispo .rl .sw.clickable:hover{box-shadow:0 0 0 2px rgba(0,0,0,.35)}

/* eigener Vorgangs-Zeitraum (getönte Fläche innerhalb der umspannenden Klammer) */
/* Die Einheit fehlte in der calc() — calc(28px - 4) ist ungueltig, die Hoehe fiel
   still auf auto zurueck und kam nur ueber den Inhalt zustande. Seit die Beschriftung
   in .objbar-lbl ausgelagert ist, hat der Balken keinen Inhalt mehr: ohne Einheit waere
   er 0px hoch und unsichtbar. */
.dispo .track .objbar{position:absolute;top:auto;bottom:2px;height:var(--h-kontext);line-height:1;border-radius:6px;display:flex;align-items:center;gap:6px;padding:0 6px;font-size:calc(10.5px * var(--fs));font-weight:700;overflow:hidden;white-space:nowrap;z-index:2;box-shadow:var(--d-shadow)}
/* Beschriftung des Objektbalkens: eigenes Overlay, damit sie bei kurzen Balken
   vollstaendig NEBEN den Balken ausweichen kann (.out) statt abgeschnitten zu werden.
   Innen liegen die Chips auf der Objektfarbe und bleiben halbtransparent; draussen auf
   dem hellen Track brauchen sie einen deckenden Grund samt Haarlinie. Positioniert wird
   in appendObjBar()/fitObjLabels(). pointer-events:none, damit Drag und Infokarte auf
   den Track durchfallen — nur die klickbare Summe holt sich die Zeiger zurueck. */
.dispo .track .objbar-lbl{position:absolute;bottom:2px;height:var(--h-kontext);line-height:1;display:flex;align-items:center;gap:6px;font-size:calc(10.5px * var(--fs));font-weight:700;white-space:nowrap;pointer-events:none;z-index:4}
/* Die Beschriftung beginnt immer am Balkenanfang und laeuft hinten einfach hinaus
   (Ansage Lukas 11.09.2026). Bis 0.6.590 wich sie stattdessen als ganzes Paket nach
   rechts NEBEN den Balken aus, sobald sie innen nicht passte (.out) — dadurch stand
   sie bei kurzen Balken weit weg von dem, was sie beschriftet.
   Weil das Paket nun zugleich ueber dem farbigen Balken UND ueber dem hellen Track
   liegen kann, tragen die Chips durchgehend eine Haarlinie — sonst verlaeuft ihr Rand
   draussen im hellen Track. Der Grund bleibt mit 78% bewusst durchlaessig: deckend
   verschwindet ein kurzer Balken vollstaendig unter der Beschriftung, und man saehe
   nicht mehr, wo das Objekt aufhoert. Bei 78% schimmert die Objektfarbe durch und die
   Balkenkante bleibt ablesbar, die Schrift bleibt trotzdem lesbar (gemessen an einem
   150px-Balken mit 270px Beschriftung). Damit entfaellt die Sonderform .out. */
.dispo .track .objbar-lbl .bf,
.dispo .track .objbar-lbl .sum{flex:none;border-radius:5px;padding:1px 7px;background:rgba(255,255,255,.78);box-shadow:0 0 0 1px rgba(15,23,42,.14);color:#0f172a}
.dispo .track .objbar-lbl .sum{font-weight:800}
.dispo .track .objbar-lbl .sum.clickable{pointer-events:auto;cursor:pointer}
.dispo .track .objbar-lbl .sum.clickable:hover{background:var(--d-white);box-shadow:0 0 0 2px var(--cyan)}
/* Ortschaft der Baustelle (v_objekt.ort) — Stammdatum, deshalb transparenter als Bauführer/Summe */
.dispo .track .vgself{position:absolute;height:var(--h-kontext);border-radius:6px;opacity:.22;pointer-events:none;z-index:1}
.dispo .track .vgself.movable{pointer-events:auto;cursor:move;touch-action:none;height:var(--h-kontext);opacity:.32;border:1px solid rgba(0,0,0,.28);box-shadow:0 1px 2px rgba(0,0,0,.12)}
.dispo .track .vgself.movable:hover{opacity:.5;box-shadow:0 1px 3px rgba(0,0,0,.2)}
.dispo .track .vgself.movable.dragging{opacity:.6;z-index:6;box-shadow:0 2px 6px rgba(0,0,0,.28)}
.dispo .track .vgself .h{position:absolute;top:0;bottom:0;width:9px;cursor:ew-resize;z-index:4;pointer-events:auto;border-radius:6px}
.dispo .track .vgself .h.l{left:0}.dispo .track .vgself .h.r{right:0}
.dispo .track .vgself .h:hover{background:rgba(0,0,0,.14)}
.dispo .track .vgself-lbl{position:absolute;top:5px;height:var(--h-kontext);line-height:1;display:flex;align-items:center;gap:8px;font-size:calc(10.5px*var(--fs));font-weight:600;color:#0f172a;pointer-events:none;overflow:hidden;white-space:nowrap;z-index:2}
.dispo .track .vgself-lbl .ws{display:inline-flex;align-items:center;background:#E6F4FA;color:var(--cyan-d);border-radius:5px;padding:1px 6px;font-weight:700}
.dispo .track .vgself-lbl .ws::before{content:"\1F4CD";margin-right:3px;font-weight:400}
.dispo .track .vgself-lbl .ws.wh::before{content:"\1F3ED"}
/* Fallback-Chip: Ortschaft aus dem Objekt, wenn am Vorgang kein Installationsplatz/Werkhof hinterlegt ist */
.dispo .track .vgself-lbl .ws.ort{background:#EEF2F5;color:var(--d-ink2);font-weight:600;min-width:0;overflow:hidden;text-overflow:ellipsis}

/* ---- Hierarchie-Klammern (Overlay hinter den Balken) ---- */
.dispo .grp-layer{position:absolute;top:0;left:0;pointer-events:none;z-index:1}
.dispo .grpbox{position:absolute;border:2px solid;border-radius:12px;box-sizing:border-box;background:transparent}
.dispo .grpbox.ge{border-radius:10px;border-style:solid;opacity:.9}

/* Gefiltert (Gruppierung nach Gerät): Box und Vorgangsbalken zeigen nur den
   Ausschnitt dieser Gruppe und sind nicht ziehbar — gestrichelt, damit das
   sichtbar ist und niemand vergeblich am Rand zieht. */
.dispo .grpbox.cut{border-style:dashed;opacity:.75}
.dispo .track .vgself.cut{border:1px dashed rgba(0,0,0,.35);opacity:.26}
/* Loesch-Kreuz AUF dem Vorgangsbalken (Auftrag Lukas 10.09.2026). Absolut am
   rechten Rand statt im Label: es soll bei Platzmangel als Letztes stehen bleiben,
   und .vgself-lbl wird von fitVgLabels() eingedampft. Erscheint erst beim Hover
   ueber der Zeile — dauerhaft sichtbar waere es auf jedem Balken ein Loeschknopf
   direkt unter dem Mauszeiger. z-index ueber Label (2) und Griffen (4). */
.dispo .track .vg-del-bar{position:absolute;top:7px;width:16px;height:16px;padding:0;border:0;border-radius:5px;
  background:rgba(255,255,255,.9);color:var(--d-rust);font-size:13px;font-weight:800;line-height:1;
  display:none;align-items:center;justify-content:center;cursor:pointer;z-index:6;
  box-shadow:0 0 0 1px rgba(15,23,42,.18)}
.dispo .row.k-vg:hover .vg-del-bar{display:flex}
.dispo .track .vg-del-bar:hover{background:var(--d-rust);color:#fff;box-shadow:0 0 0 2px rgba(197,80,59,.35)}
.dispo .track .vg-del-bar.gesperrt{color:var(--d-ink2);font-size:9px;cursor:help;background:rgba(255,255,255,.82)}
.dispo .track .vg-del-bar.gesperrt:hover{background:#fff;color:var(--d-ink);box-shadow:0 0 0 2px rgba(15,23,42,.2)}
/* Laufender Vorgang: dasselbe Kreuz, aber es verkuerzt auf heute statt zu loeschen.
   Darum cyan und nicht rostrot — die Wirkung ist nicht dieselbe. */
.dispo .track .vg-del-bar.kuerzen{color:var(--cyan-d)}
.dispo .track .vg-del-bar.kuerzen:hover{background:var(--cyan);color:#fff;box-shadow:0 0 0 2px rgba(0,153,204,.35)}
.vg-del-card .vgdel-pfeil{color:#3A4750;font-weight:400}

/* Zeitsperre: der Bereich VOR heute gehoert dem Administrator (Grenze korrigiert
   11.09.2026 — der heutige Tag bleibt disponierbar, an ihm wird ja gearbeitet).
   Passiv erkennbar (Schraffur, kein Zeiger), die Begruendung kommt als Toast erst
   beim Versuch — bei 1450 von 1473 Vorgaengen waere ein Popup unbenutzbar.
   .ganz = abgeschlossen, .zeitsperre ohne .ganz = laufend (rechter Griff bleibt).

   Die Schraffur endet an der HEUTE-Linie und nicht am Balkenende (Ansage Lukas
   10.09.2026): so ist bei einem laufenden Vorgang zu sehen, WELCHER Teil fest ist.
   Sie endet neu VOR der Heute-Spalte, nicht dahinter — die Heute-Spalte ist frei.
   Die Breite setzt festBreitePx() beim Zeichnen als --fest-w; bei abgeschlossenen
   Balken ist das die volle Breite, darum braucht .ganz keine eigene Regel mehr.
   Der Fallback 0 lässt die Schraffur weg, statt sie über den ganzen Balken zu legen —
   falsch herum wäre schlimmer als gar nicht. Die Kante rechts markiert die Grenze. */
.dispo .track .vgself.zeitsperre.ganz{cursor:not-allowed}
.dispo .track .vgself.zeitsperre::after{content:"";position:absolute;left:0;top:0;bottom:0;
  width:var(--fest-w,0);border-radius:6px 0 0 6px;pointer-events:none;
  box-shadow:inset -1px 0 0 rgba(15,23,42,.28);
  background:repeating-linear-gradient(45deg,rgba(15,23,42,.10) 0 3px,transparent 3px 7px)}
.dispo .track .vgself.zeitsperre.ganz::after{border-radius:6px;box-shadow:none}
.dispo .bar.zeitsperre.ganz{cursor:default}
.dispo .bar.zeitsperre::after{content:"";position:absolute;left:0;top:0;bottom:0;
  width:var(--fest-w,0);border-radius:7px 0 0 7px;pointer-events:none;
  box-shadow:inset -1px 0 0 rgba(15,23,42,.3);
  background:repeating-linear-gradient(45deg,rgba(15,23,42,.13) 0 3px,transparent 3px 7px)}
.dispo .bar.zeitsperre.ganz::after{border-radius:7px;box-shadow:none}
.dispo .grpbox .bh{position:absolute;top:0;bottom:0;width:12px;pointer-events:auto;cursor:ew-resize}
.dispo .grpbox .bh.l{left:-6px}.dispo .grpbox .bh.r{right:-6px}
.dispo .grpbox .bh:hover{background:rgba(0,0,0,.06)}

/* ---- Monatsband in der Datumsleiste ---- */
.dispo .monthband{display:flex;background:var(--d-ink)}
.dispo .mcell{height:17px;display:flex;align-items:center;justify-content:center;color:#fff;font-weight:700;font-size:calc(10px * var(--fs));letter-spacing:.05em;border-right:1px solid #29343d;overflow:hidden;white-space:nowrap}
.dispo .corner .c0{height:17px}
.dispo .row.head{z-index:6}

/* ---- Titel 1-zeilig ---- */
.dispo.oneline .rl .nm{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}

/* ---- Titel-Umschalter im Kopf ---- */
.dispo .corner .c2{justify-content:space-between;padding-right:10px;gap:8px}
.dispo .corner .c2 .cl{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* ---- Farbwähler-Palette (benannte Farben) ---- */
.dispo-ov .fc-palette{display:flex;flex-wrap:wrap;gap:6px;margin:4px 0 6px}
.dispo-ov .fc-sw{width:28px;height:28px;border-radius:7px;border:1px solid rgba(0,0,0,.15);cursor:pointer;padding:0}
.dispo-ov .fc-sw:hover{outline:2px solid rgba(0,0,0,.35);outline-offset:1px}
.dispo-ov .fc-sw.sel{outline:2px solid #0E1419;outline-offset:1px}
.dispo-ov .pal-empty{font-size:12px;color:#64748b;font-style:italic}

/* ---- Ist-Band (Soll-Ist-Abgleich: rapportierte Tage auf dem Objekt) ---- */
.dispo .track .istband{position:absolute;height:3px;border-radius:2px;background:#2E9E5B;box-shadow:0 0 0 1px rgba(255,255,255,.55);z-index:3;pointer-events:none}

/* ---- Personen-Reihenfolge im Vorgang (▲▼) ---- */
/* WICHTIG: sticky (nicht relative), sonst scrollt die Titel-Spalte beim horizontalen
   Scroll weg. sticky ist ebenso Containing-Block für die absolut positionierten
   Kinder (.reorder / .vg-betrag / .vg-edit / .vg-del). */
.dispo .rl{position:sticky;left:0}
.dispo .reorder{position:absolute;right:6px;top:50%;transform:translateY(-50%);display:none;flex-direction:column;gap:1px}
.dispo .row.k-person:hover .reorder{display:flex}
.dispo .reorder button{border:1px solid var(--d-line);background:var(--d-white);cursor:pointer;font-size:9px;line-height:1;width:18px;height:13px;border-radius:3px;color:var(--d-ink2);padding:0;display:flex;align-items:center;justify-content:center}
.dispo .reorder button:hover{background:var(--d-paper);color:var(--d-ink)}

/* ---- Feiertage ---- */
.dispo .dcell.fh{background:#7a4f12}
.dispo .dcell.fh .wd{opacity:1}
.dispo .track .gfh{position:absolute;top:0;bottom:0;background:rgba(224,137,43,.12)}

/* ---- Vorgang löschen ---- */

/* ---- Spaltenbreiten-Griff (1. Spalte) ---- */
.dispo .colresize{position:absolute;top:0;right:-3px;width:8px;height:100%;cursor:ew-resize;z-index:8}
.dispo .colresize:hover{background:rgba(0,153,204,.35)}

/* ---- Vorgang Betrag/Bearbeiten ---- */
.dispo .vg-betrag{position:absolute;right:34px;top:8px;font-size:10.5px;font-weight:700;color:var(--cyan-d);background:#E6F4FA;border-radius:5px;padding:2px 6px;pointer-events:none;white-space:nowrap}
/* Hoehe an die Zeile gebunden. top:8px + height:22px verlangte 30px ab Zeilenoberkante;
   eine einzeilige Zeile ist bei normal aber 21px hoch (LANE 17 + ROWPAD 4) und bei kompakt
   17px — die Knoepfe ragten 9 bzw. 13px heraus und wurden von der naechsten .rl verdeckt,
   die als sticky spaeter gezeichnet wird. Bei kompakt lag ihre Mitte darunter, sie waren
   also nicht mehr anklickbar. Die Masse stammen aus der Zeit vor v0.6.480, als die Dichten
   noch 15/20/28 waren. Neu vertikal zentriert und auf die Zeilenhoehe gedeckelt:
   min(22px, 100% - 2px) laesst sie nie hoeher werden als die Zeile, die sie traegt. */
.dispo .vg-edit{position:absolute;right:6px;top:50%;transform:translateY(-50%);display:none;border:1px solid var(--d-line);background:var(--d-white);cursor:pointer;font-size:11px;line-height:1;width:22px;height:min(22px,calc(100% - 2px));border-radius:5px;padding:0;align-items:center;justify-content:center}
.dispo .row.k-vg:hover .vg-edit{display:flex}
.dispo .vg-edit:hover{background:var(--d-paper)}
.dispo .row.k-vg:hover .vg-betrag{display:none}

/* ---- Collapse-Chevron (jede Hierarchie-Ebene) ---- */
.dispo .caret{display:inline-flex;width:14px;justify-content:center;align-items:center;vertical-align:middle;cursor:pointer;color:var(--d-ink2);font-size:10px;transition:transform .12s;transform:rotate(0deg);flex:none;user-select:none;margin-right:2px}
.dispo .caret.open{transform:rotate(90deg)}
.dispo .caret:hover{color:var(--cyan-d)}
.dispo .caret-sp{display:inline-block;width:16px;vertical-align:middle}

/* ---- Ressourcenarten ein-/ausblenden (Multi-Toggle) ---- */
.dispo .ctl.multi{flex-wrap:wrap}
.dispo .ctl.multi button{background:var(--d-line2);color:var(--d-ink2)}
.dispo .ctl.multi button.act{background:var(--cyan);border-color:var(--cyan);color:#fff}

/* ---- Hotel-Badge am Personal-Balken (prominenter) ---- */
.dispo .bar .badge.hotel{filter:saturate(1.1);background:rgba(255,255,255,.92);border-radius:5px;padding:0 4px;display:inline-flex;align-items:center;gap:2px;font-size:11px;line-height:1.5}
.dispo .bar .badge.hotel .bn{font-size:9px;font-weight:800;color:#2E86C1}
/* Hotel-Nächte-Band kräftiger */
.dispo .track .hband{height:5px;border-radius:3px}

/* ---- Auslastungs-Pane (2. Ebene, unterhalb des Boards) ---- */
.dispo .util{margin-top:13px;background:var(--d-white);border:1px solid var(--d-line);border-radius:12px;box-shadow:var(--d-shadow);overflow:hidden}
.dispo .util-head{display:flex;align-items:center;gap:8px;padding:7px 12px;cursor:pointer;font-weight:700;text-transform:uppercase;letter-spacing:.06em;font-size:calc(11px * var(--fs));color:var(--d-ink);user-select:none}
.dispo .util-head:hover{background:var(--d-paper)}
.dispo .util-head .ut-caret{display:inline-flex;width:14px;justify-content:center;color:var(--d-ink2);transition:transform .12s}
.dispo .util-head .ut-caret.open{transform:rotate(90deg)}
.dispo .util-head .ut-sub{margin-left:auto;font-weight:600;text-transform:none;letter-spacing:0;font-size:11px;color:var(--d-ink2)}
.dispo .util-body{padding:0 15px}
.dispo.util-open .util-body{border-top:1px solid var(--d-line2);padding:12px 15px 14px}
.dispo .ut-empty{color:var(--d-ink2);font-size:12px;padding:6px 0}
.dispo .ut-sec{margin-bottom:14px}
.dispo .ut-sec:last-child{margin-bottom:0}
.dispo .ut-sech{font-weight:700;text-transform:uppercase;letter-spacing:.06em;font-size:11px;color:var(--d-ink2);margin:2px 0 6px;display:flex;align-items:center;gap:6px}
.dispo .ut-sech .ut-cnt{background:var(--d-paper);border:1px solid var(--d-line);border-radius:8px;padding:0 6px;font-size:10px;color:var(--d-ink)}
.dispo .ut-row{display:flex;align-items:center;gap:10px;padding:4px 4px;font-size:12px;border-bottom:1px solid var(--d-line2);border-radius:4px}
.dispo .ut-row.conf{background:#FFF6EA}
.dispo .ut-nm{flex:0 0 190px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.dispo .ut-days{flex:0 0 46px;text-align:right;font-weight:700;color:var(--cyan-d)}
.dispo .ut-bar{flex:1;height:8px;background:var(--d-line2);border-radius:5px;overflow:hidden;min-width:60px}
.dispo .ut-bar>span{display:block;height:100%;background:var(--cyan);border-radius:5px}
.dispo .ut-tn{flex:0 0 auto;display:flex;gap:9px;color:var(--d-ink2);font-size:11px;font-weight:600}
.dispo .ut-tn i{font-style:normal}
.dispo .ut-gap{flex:none;font-size:10.5px;color:#B5651D;background:#FFF6EA;border:1px solid #F0D9B5;border-radius:6px;padding:1px 6px;font-weight:700}
.dispo .ut-warn{flex:none;color:#C0392B;font-weight:800}
.dispo .ut-free{font-size:11px;color:var(--d-ink2);font-style:italic;padding:6px 0 0}

/* ===== v0.6.59: 2. Pane = read-only Ressourcen-Board + Splitter + kompakte Stats ===== */
/* Oberes Board in der Höhe per Splitter steuerbar */
/* --board-h ist die Hoehe des GESAMTEN Boardbereichs (Kalenderleiste + Zeilen) —
   so bleiben die gespeicherten Werte aus der Zeit vor dem ausgelagerten Kopf gueltig. */
.dispo #d-board{max-height:calc(var(--board-h,70vh) - var(--headh,68px))}
.dispo.util-open #d-board{max-height:calc(var(--board-h,46vh) - var(--headh,68px))}
/* Splitter-Griff zwischen den Panes */
/* Der Griff ist 8px hoch und sitzt unmittelbar ueber .util-head — und ein Klick auf
   den Auslastungs-Kopf klappt das Pane ZU. Wer den Griff um zwei Pixel verfehlte,
   schloss also die Auslastung, statt die Trennlinie zu ziehen. Das ::before vergroessert
   die Trefferflaeche nach oben und unten auf 20px, ohne das Layout zu veraendern, und
   liegt mit z-index ueber dem Kopf. */
.dispo .dispo-split{display:none;height:8px;margin:1px 0;cursor:row-resize;align-items:center;justify-content:center;position:relative;z-index:10}
.dispo .dispo-split::before{content:"";position:absolute;left:0;right:0;top:-5px;bottom:-7px}
.dispo.util-open .dispo-split{display:flex}
.dispo .dispo-split span{display:block;width:34px;height:3px;border-radius:2px;background:var(--d-line);transition:background .12s}
.dispo .dispo-split:hover span{background:var(--cyan)}
/* untere Pane: enthält jetzt ein eigenes Board */
.dispo.util-open .util-body{border-top:1px solid var(--d-line2);padding:0}
.dispo .util-body .board{box-shadow:none;border:0;border-left:0;border-right:0;border-bottom:0;border-radius:0 0 12px 12px;max-height:var(--util-h,46vh)}
/* Auslastungs-Restype-Umschalter im Kopf */
.dispo .util-head .ut-restype{margin-left:14px;box-shadow:none;display:none;width:auto;flex:none}
.dispo.util-open .util-head .ut-restype{display:flex}
.dispo .util-head .ut-restype button{height:24px;padding:0 10px;font-size:calc(11px * var(--fs))}
.dispo .util-head .ut-onlydisp{margin-left:8px;box-shadow:none;display:none;width:auto;flex:none}
.dispo.util-open .util-head .ut-onlydisp{display:flex}
.dispo .util-head .ut-onlydisp button{height:24px;padding:0 10px;font-size:calc(11px * var(--fs))}

/* «＋ Temporär» in der Kopfzeile des Auslastungs-Panes (v0.6.803).
   ACHTUNG: bewusst OHNE .util-open-Gate — anders als .resfilter, .ut-restype und
   .ut-onlydisp, die nur im aufgeklappten Pane erscheinen. Der Knopf gehoert nicht
   zur Auslastung, er steht nur dort; waere er mitversteckt, muesste man das Pane
   aufklappen, um einen Bedarf anzulegen — genau der Umweg, den er abschafft. */
.dispo .util-head .ut-temp{flex:none;margin-left:10px;height:24px;padding:0 10px;border:1px solid #8E5BC6;border-radius:6px;background:var(--d-white);color:#8E5BC6;font:inherit;font-size:calc(11px * var(--fs));font-weight:700;text-transform:none;letter-spacing:0;cursor:pointer;white-space:nowrap}
.dispo .util-head .ut-temp:hover{background:#8E5BC6;color:#fff}

/* Zeilenbeschriftung eines offenen Bedarfs ist anklickbar (= benennen). Zweiter
   Weg neben dem 👤 am Balken, fuer den Fall, dass der Einsatz nur ein, zwei Tage
   dauert und der Balken zu schmal fuer ein Symbol ist. */
.dispo .rl.bedarf.klickbar{cursor:pointer}
.dispo .rl.bedarf.klickbar:hover .nm{text-decoration:underline}
/* 👤 an der Beschriftung — dauerhaft sichtbar, anders als die Hover-Knoepfe der
   Vorgangszeile. Es ist der einzige Weg zum Benennen, der bei einem eintaegigen
   Einsatz (19px Balken) noch funktioniert; was die taegliche Mahnung erst
   erfuellbar macht, darf man nicht suchen muessen. */
.dispo .rl.bedarf{position:relative;padding-right:32px}
.dispo .rl.bedarf .rl-temp{position:absolute;right:6px;top:50%;transform:translateY(-50%);display:flex;border:1px solid #8E5BC6;background:var(--d-white);cursor:pointer;font-size:11px;line-height:1;width:22px;height:min(22px,calc(100% - 2px));border-radius:5px;padding:0;align-items:center;justify-content:center}
.dispo .rl.bedarf .rl-temp:hover{background:#8E5BC6}
.dispo .rl.bedarf.faellig .rl-temp{border-color:#B3261E}
/* read-only Balken (2. Pane): keine Bedien-Elemente, kein Grab-Cursor */
.dispo .bar.ro{cursor:default;box-shadow:0 1px 2px rgba(0,0,0,.14)}
.dispo .bar.ro .x,.dispo .bar.ro .shift,.dispo .bar.ro .veh-edit,.dispo .bar.ro .ge-edit,.dispo .bar.ro .h{display:none}
/* Auslastungs-Pane (read-only) mit Resize: Griffe wieder einblenden. */
.dispo .bar.ro.rz .h{display:block}
/* Auslastungs-Pane: es rendert mit _interactive=false und traegt deshalb .ro, ist aber
   ausdruecklich «loeschbar (✕) + Dauer ueber die Griffe anpassbar» (makeBar). Die Griffe
   holte .ro.rz .h schon zurueck, das Kreuz fehlte in dieser Ausnahme — der Handler hing
   dran, der Knopf war unsichtbar. Das padding-right muss mit: .ro.has-x hatte es auf 7px
   gesenkt, weil dort kein × sass; seit 0.6.570 sitzt es absolut am rechten Rand. */
.dispo .bar.ro.rz .x{display:flex}
.dispo .bar.ro.rz.has-x{padding-right:28px}
/* Am Wandscreen (Host gibt readOnly) bleibt es aus — dort wird nicht geloescht. */
.dispo.readonly .bar.ro.rz .x{display:none}
.dispo.readonly .bar.ro.rz.has-x{padding-right:7px}
/* kompakte Stats-Zeile statt vier grosser Kacheln */
.dispo .stats{display:flex;gap:14px;flex-wrap:wrap;margin-top:10px;align-items:center;padding:6px 12px;background:var(--d-white);border:1px solid var(--d-line);border-radius:9px;box-shadow:var(--d-shadow)}
.dispo .stats .stat{background:none;border:0;border-radius:0;padding:0;min-width:0;box-shadow:none;font-size:calc(12px * var(--fs));color:var(--d-ink2);display:inline-flex;align-items:center}
.dispo .stats .stat b{color:var(--cyan-d);font-size:calc(14px * var(--fs));font-weight:800;margin-right:4px}
.dispo .stats .stat.warn{color:#B5651D}
.dispo .stats .stat.warn b{color:#B5651D}

/* ===== Ressourcen-Zeile als Drag-Quelle (2. Pane → oberes Board) ===== */
.dispo .rl.drag-src{cursor:grab}
.dispo .rl.drag-src:active{cursor:grabbing}
.dispo .rl.drag-src:hover{background:#EFF7FB}

/* ===== Schrift-Umschalter: Normalschrift statt fett (Test) ===== */
.dispo.thin .rl .nm,
.dispo.thin .row.k-vg .rl .nm,
.dispo.thin .row.k-obj .rl .nm{font-weight:500}
.dispo.thin .bar,
.dispo.thin .bar .nm{font-weight:500}
.dispo.thin .chip,
.dispo.thin .ut-nm,
.dispo.thin .stats .stat{font-weight:500}
.dispo.thin .lbl,
.dispo.thin .ctl button,
.dispo.thin .kwcell,
.dispo.thin .mcell,
.dispo.thin .dcell .wd,
.dispo.thin .dcell .dd,
.dispo.thin .corner .c2,
.dispo.thin .util-head,
.dispo.thin .ut-sech{font-weight:600}
.dispo.thin .stats .stat b,
.dispo.thin .ut-days{font-weight:700}


/* ---- Sparte-Wähler im Board-Kopf (Ecke) + Popover ---- */


/* ---- Globale Collapse-Stufen (2x2) ---- */
.dispo #d-level{flex-wrap:wrap;gap:2px}
.dispo #d-level button{flex:1 1 44%;padding:0 4px;font-size:calc(10px * var(--fs))}


/* ---- Ebenen-Wähler im Board-Kopf ---- */

/* Statusbalken Maschine/Fahrzeug ohne Baustelle: Reparatur / Revision / Defekt.
   Kraeftige Flaeche statt Pastell — Einsatzbalken werden mit lighten(.62) aufgehellt,
   Statusbalken behalten ihre volle Farbe (#C0562F / #6E7B8B / #9B2226) und tragen ihr
   Label im Balken.
   Die frueher hier deklarierte Schraffur ist ersatzlos weg. Sie hat nie gezeichnet:
   makeBar() setzt el.style.background = b.color als Inline-Shorthand, und der setzt
   background-image auf none — inline schlaegt die Regel hier, die kein !important trug.
   (Bei .bar.absenz klappt dieselbe Konstruktion nur deshalb, weil dort background mit
   !important steht.) Wiederbeleben waere auch falsch: die Schraffur lief unter 45 Grad
   wie die der Zeitsperre und haette sie auf dem Balken unlesbar gemacht — genau der
   Fehler, der am 11.09.2026 beim Fahrzeugbalken behoben wurde. Die 45-Grad-Schraffur
   gehoert der Zeitsperre allein. */
.dispo .bar.status{border-style:solid;font-weight:600}
.dispo .bar.status .nm{color:#fff}

/* ---- Änderungsprotokoll (🕘) ------------------------------------------------
   Aufruf: Vorgangszeile (.vg-log), Ressourcen-Balken (.bar-log), Sidebar (#d-log),
   «Vorgang bearbeiten»-Dialog. Zeigt je Ereignis eine Zeile pro geändertem Feld. */
.dispo .vg-log{position:absolute;right:32px;top:50%;transform:translateY(-50%);display:none;border:1px solid var(--d-line);background:var(--d-white);cursor:pointer;font-size:11px;line-height:1;width:22px;height:min(22px,calc(100% - 2px));border-radius:5px;padding:0;align-items:center;justify-content:center}
.dispo .row.k-vg:hover .vg-log{display:flex}
.dispo .vg-log:hover{background:var(--d-paper)}
.dispo .bar .bar-log{flex:none;margin-left:4px;cursor:pointer;font-size:10px;line-height:1;opacity:0;transition:opacity .12s}
.dispo .bar:hover .bar-log{opacity:.92}
.dispo .bar .bar-log:hover{opacity:1;transform:scale(1.15)}
.dispo .bar.ro .bar-log{display:none}

.dispo-ov-card.lg-card{width:min(780px,96vw)}
.lg-card .lg-sub{font-size:12.5px;color:#475569;margin:-8px 0 12px;font-weight:600}
.lg-card .ctl.lg-scope{display:flex;gap:6px;margin-bottom:10px}
.lg-card .ctl.lg-scope button{border:1px solid #dbe2ea;background:#fff;border-radius:7px;padding:5px 10px;cursor:pointer;font:inherit;font-size:12px;color:#475569}
.lg-card .ctl.lg-scope button.act{background:#0099CC;border-color:#0099CC;color:#fff;font-weight:600}
.lg-card .lg-search{height:32px;margin-bottom:10px;width:100%;font-size:13px}
.lg-card .lg-list{max-height:min(58vh,520px);overflow:auto;border:1px solid #eef2f6;border-radius:10px;background:#FAFCFD;padding:8px}
.lg-card .lg-info{padding:14px 8px;color:#64748b;font-size:13px}
.lg-card .lg-info.err{color:#C0392B}
.lg-card .lg-e{background:#fff;border:1px solid #e8eef3;border-left:3px solid #94a3b8;border-radius:8px;padding:8px 10px;margin-bottom:7px}
.lg-card .lg-e.a-insert{border-left-color:#2E9E5B}
.lg-card .lg-e.a-update{border-left-color:#0099CC}
.lg-card .lg-e.a-delete{border-left-color:#C0392B}
.lg-card .lg-top{display:flex;align-items:baseline;gap:8px;flex-wrap:wrap}
.lg-card .lg-akt{font-size:10px;font-weight:800;text-transform:uppercase;letter-spacing:.05em;padding:2px 6px;border-radius:4px;background:#EEF2F6;color:#475569;flex:none}
.lg-card .a-insert .lg-akt{background:#E6F6EC;color:#1E7A45}
.lg-card .a-update .lg-akt{background:#E6F4FA;color:#0A6C8F}
.lg-card .a-delete .lg-akt{background:#FCEEEB;color:#A5342A}
.lg-card .lg-subj{font-size:13px;font-weight:600;color:#0f172a;flex:1;min-width:140px}
.lg-card .lg-meta{font-size:11.5px;color:#64748b;white-space:nowrap}
.lg-card .lg-diff{list-style:none;margin:6px 0 0;padding:0;display:flex;flex-direction:column;gap:3px}
.lg-card .lg-diff li{display:flex;align-items:center;gap:6px;flex-wrap:wrap;font-size:12.5px;line-height:1.45}
.lg-card .lg-f{flex:none;min-width:130px;font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.03em;color:#64748b}
.lg-card .lg-a{color:#94a3b8;text-decoration:line-through}
.lg-card .lg-ar{color:#94a3b8;font-weight:700}
.lg-card .lg-n{color:#0f172a;font-weight:600}
.lg-card .lg-empty{color:#b6c2ce;font-style:normal}
.lg-card .lg-uuid{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11px;color:#94a3b8}
.lg-card .lg-sw{display:inline-block;width:11px;height:11px;border-radius:3px;border:1px solid rgba(15,23,42,.15);margin-right:4px;vertical-align:-1px}
.lg-card .lg-none{color:#94a3b8;font-size:12px}

/* ---- Datumssprung / Heute (sichtbares Feld statt 1px-Geisterinput) ---- */
.dispo .navrow input.d-jumpin{height:22px;border:1px solid var(--d-line);border-radius:5px;background:var(--d-white);color:var(--d-ink);font:inherit;font-size:calc(10.5px*var(--fs));padding:0 4px;min-width:0;width:118px}
.dispo .navrow input.d-jumpin:hover{border-color:var(--cyan)}

/* ---- Betrag direkt am Balken ändern ---- */
.dispo .track .vgself-lbl .betr{background:#E6F4FA;color:var(--cyan-d);border-radius:5px;padding:1px 6px;font-weight:800;flex:none}
.dispo .track .vgself-lbl .betr.clickable{pointer-events:auto;cursor:pointer}
.dispo .track .vgself-lbl .betr.clickable:hover{background:var(--cyan);color:#fff}

/* ---- Aufträge ohne Vorgang ---- */
.dispo-ov-fix{border:1px solid #dbe2ea;border-radius:8px;min-height:38px;display:flex;align-items:center;padding:0 10px;font-weight:600;text-transform:none;letter-spacing:0;color:#0f172a;background:#F6F9FB}
.lg-card .oa-row{display:flex;align-items:center;gap:10px;background:#fff;border:1px solid #e8eef3;border-left:3px solid #E0892B;border-radius:8px;padding:7px 10px;margin-bottom:6px}
.lg-card .oa-main{flex:1;min-width:0;font-size:13px;color:#0f172a;display:flex;flex-direction:column;gap:1px}
.lg-card .oa-sub{font-size:11.5px;color:#64748b;font-weight:400}
.lg-card .oa-add{flex:none;padding:5px 12px;font-size:12.5px}

/* ---- Arbeit mit Fixtermin (vorgang.fixtermin) ------------------------------
   Gesperrter Vorgang: doppelter Rahmen + 📌-Marker, keine Griffe, nicht ziehbar. */
.dispo .track .vgself.fix{border-style:double;border-width:4px;cursor:not-allowed;opacity:.75}
.dispo .track .vgself-lbl .fixb{background:#7a4f12;color:#fff;border-radius:5px;padding:1px 6px;font-weight:800;flex:none;letter-spacing:.02em}
.dispo .vgpin{margin-left:5px;font-size:calc(11px*var(--fs));cursor:help}
.dispo-ov-chk{display:flex;align-items:center;gap:8px;margin:2px 0 12px;font-size:13px;font-weight:600;color:#0f172a;cursor:pointer}
.dispo-ov-chk input{width:16px;height:16px;accent-color:#0099CC;cursor:pointer}

/* Betrag-Platzhalter: bei Planumsatz 0 nur dezent beim Hovern der Vorgangszeile */
.dispo .track .vgself-lbl .betr.zero{background:transparent;color:#0f172a;border:1px dashed rgba(15,23,42,.35);opacity:0;transition:opacity .12s;font-weight:700}
.dispo .row.k-vg:hover .vgself-lbl .betr.zero{opacity:.85}
.dispo .track .vgself-lbl .betr.zero:hover{opacity:1;background:var(--cyan);border-color:var(--cyan);color:#fff}

/* ---- Dialog-Buttonzeile: bricht um statt aus dem Fenster zu fallen ---- */
.dispo-ov-btns{flex-wrap:wrap;align-items:center;row-gap:8px}
.dispo-ov-btns .ov-left{display:flex;gap:8px;flex-wrap:wrap;margin-right:auto}
.dispo-ov-btns .ov-right{display:flex;gap:10px;margin-left:auto}
.dispo-ov-cancel,.dispo-ov-ok{white-space:nowrap}
.dispo-ov-btns .ov-danger{border-color:#C0392B;color:#C0392B}
.dispo-ov-btns .ov-danger:hover{background:#FCEEEB}

/* ---- Read-only (Wandscreen / fretus-board) ---- */
/* Die Schreib-UI wird gar nicht erst gebaut (RO in shell()), die Drag-Handler
   nicht gebunden (paintBoard interactive=false). Hier bleibt nur, was sonst
   optisch Interaktion verspricht, die es nicht gibt. */
.dispo.readonly .bar,
.dispo.readonly .bar:active,
.dispo.readonly .bar.t-vehicle.standalone,
.dispo.readonly .bar.t-vehicle.standalone:active,
.dispo.readonly .chip{cursor:default}
.dispo.readonly .bar .h,
.dispo.readonly .track .vgself .h,
.dispo.readonly .grpbox .bh{display:none}
.dispo.readonly .track .vgself.movable{cursor:default}

/* Ladefehler statt stiller Leermeldung — ein RLS-Riegel sah vorher aus wie
   «keine Vorgaenge in diesem Zeitraum». */
.dispo .dispo-loaderr{color:#8a2020;text-align:left;max-width:64ch;margin:0 auto;line-height:1.5}
.dispo .dispo-loaderr b{display:block;margin-bottom:6px;font-size:calc(13px * var(--fs))}
.dispo .dispo-loaderr .hinweis{display:inline-block;margin-top:8px;color:var(--d-ink2);font-size:calc(11px * var(--fs))}

/* ---- Hover-Infokarte am Board («Rich-Tooltip») -------------------------
   Die Zeilen sind bewusst flach, auf den Balken steht deshalb kaum noch Text.
   Alles Weitere (Objekt, Vorgang, Personal, Geraete, Fahrzeuge, Hotel,
   Doppelbelegungen) steht in dieser Karte. Sie haengt bewusst an document.body
   (position:fixed) — im Board wuerde sie am overflow des Scrollcontainers
   abgeschnitten. Klassenname trotzdem .dispo-* → Scoping bleibt gewahrt. */
.dispo-tip{position:fixed;left:0;top:0;z-index:4000;max-width:390px;min-width:210px;background:#0E1419;color:#EAF1F6;border:1px solid #2B3A45;border-radius:10px;box-shadow:0 12px 34px rgba(9,14,20,.38);padding:9px 11px;font:500 11.5px/1.45 system-ui,-apple-system,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;pointer-events:none}
.dispo-tip .tp-h{display:flex;align-items:center;gap:7px;font-weight:800;font-size:12.5px;color:#fff;min-width:0}
.dispo-tip .tp-dot{width:9px;height:9px;border-radius:3px;flex:none;box-shadow:0 0 0 1px rgba(255,255,255,.35)}
.dispo-tip .tp-t{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.dispo-tip .tp-s{color:#9FB3C2;text-transform:uppercase;letter-spacing:.06em;font-size:9.5px;font-weight:700;margin:1px 0 6px 16px}
.dispo-tip .tp-r{display:flex;gap:8px;padding:1px 0}
.dispo-tip .tp-r .k{flex:0 0 104px;color:#8FA6B6}
.dispo-tip .tp-r .v{flex:1;min-width:0;color:#EAF1F6}
.dispo-tip i{font-style:normal;color:#9FB3C2}
.dispo-tip .tp-sec{margin-top:7px;border-top:1px solid #22303A;padding-top:5px}
.dispo-tip .tp-st{display:flex;align-items:center;gap:6px;color:#9FB3C2;text-transform:uppercase;letter-spacing:.06em;font-size:9.5px;font-weight:800}
.dispo-tip .tp-st .n{background:#22303A;border-radius:8px;padding:0 5px;font-size:9.5px;font-weight:700}
.dispo-tip ul{list-style:none;margin:3px 0 0;padding:0}
.dispo-tip li{display:flex;gap:8px;align-items:baseline;padding:1px 0;min-width:0}
.dispo-tip li b{font-weight:700;color:#fff;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.dispo-tip li .d{margin-left:auto;color:#8FA6B6;white-space:nowrap;font-variant-numeric:tabular-nums}
.dispo-tip li.tp-more{color:#8FA6B6;font-style:italic}
.dispo-tip .tp-f{margin-top:7px;border-top:1px solid #22303A;padding-top:5px;color:#8FA6B6;font-size:10px}

/* ---- Zeilenhöhe skaliert die Steuerungs-Sidebar mit --------------------
   Der Regler «Zeilenhöhe» hat bis v0.6.483 nur das Board verändert: die
   Sidebar hängt an --fs, und --fs klebt unterhalb von LANE 24 am Minimum 0.8 —
   im ganzen nutzbaren Bereich passierte dort also nichts.
   Trick: in der Sidebar wird --fs lokal auf --ui gesetzt. Damit greifen alle
   bestehenden calc(x * var(--fs))-Regeln ohne Umbau, und nur die wenigen fixen
   Pixelmasse müssen einzeln nachziehen. --ui kommt aus uiForLane(LANE).

   ACHTUNG Reihenfolge: dieser Block MUSS am Dateiende stehen. Die Regeln
   .dispo-side .ctl button und .dispo .ctl button sind gleich spezifisch —
   weiter oben würde die spätere gewinnen und nichts skalieren. Aus demselben
   Grund wird die Schmalspur-Regel für .dispo-main hier wiederholt. */
.dispo-side{--fs:var(--ui,1);min-width:0}   /* min-width:0 — sonst haelt die
   automatische Mindestbreite des Grid-Items die Spalte breiter als das clamp() */
.dispo-main{grid-template-columns:clamp(150px,calc(235px * var(--ui,1)),340px) minmax(0,1fr)}
@media(max-width:820px){ .dispo-main{grid-template-columns:1fr} }
.dispo-side .ctl button{height:calc(25px * var(--ui,1))}
.dispo-side .ctl.solo{height:calc(30px * var(--ui,1))}
.dispo-side .side-toggle{width:calc(24px * var(--ui,1));height:calc(24px * var(--ui,1));font-size:calc(14px * var(--ui,1))}
.dispo-side .resfilter{height:calc(28px * var(--ui,1))}
.dispo-side .navrow input.d-jumpin{height:calc(22px * var(--ui,1));width:calc(118px * var(--ui,1))}
.dispo-side .rowh input[type=range]{height:calc(16px * var(--ui,1))}
.dispo-side .palette{padding:calc(10px * var(--ui,1))}
.dispo-side .chip{padding:calc(5px * var(--ui,1)) calc(9px * var(--ui,1))}
.dispo-side .chip .swatch{width:calc(12px * var(--ui,1));height:calc(12px * var(--ui,1))}
.dispo-side .trash{min-height:calc(44px * var(--ui,1))}
