/* Elektro-PPS - Oberflaeche
   Mobil zuerst, ab 900px die Seitenleiste. Farben ausschliesslich ueber Tokens,
   damit heller und dunkler Modus gleich sauber aussehen. */

/* `color-scheme` faerbt mit, was nicht uns gehoert: Rollbalken, das
   Datumsfeld, die Auswahlliste. Ohne die Zeile stehen in der dunklen Ansicht
   weisse Kalender vor dunklen Karten. Sie folgt derselben Dreiteilung wie die
   Tokens - Vorgabe hell, dunkel per Geraet, und `data-theme` schlaegt beides. */
:root{
  color-scheme:light;
  --ground:#E9EDF1; --surface:#FFFFFF; --surface-2:#F5F8FA; --surface-3:#EDF1F5;
  --line:#D3DCE4; --line-soft:#E4EAF0;
  --ink:#0F1820; --ink-2:#46586B; --ink-3:#78899B;
  --accent:#1F4E9C; --accent-2:#2F6FD0; --accent-soft:#E2EAF7; --auf-accent:#FFFFFF;
  --ok:#177A45;  --ok-bg:#DFF1E6;  --ok-line:#9FD6B5;
  --run:#B26B00; --run-bg:#FBEDD6; --run-line:#EEC583;
  --blk:#BF3226; --blk-bg:#FAE2DF; --blk-line:#EEA79F;
  --idle:#7E8FA1;--idle-bg:#E8EDF2; --idle-line:#CBD5DF;
  --eng:#6A4BB8; --eng-bg:#E6E0F7; --eng-line:#BEACEC;
  --ibn:#1B5FA8; --ibn-bg:#DCE9F8;
  --liefer:#0E7C74; --liefer-bg:#D6EFEC; --liefer-line:#8FCFC8;
  --sk:#A03A7A; --sk-bg:#F7E1EF; --sk-line:#E5B3D3;
  --absenz:#6B6257; --absenz-bg:#EDE9E3; --absenz-line:#D2CABF;
  --schatten:0 1px 2px rgba(15,24,32,.06), 0 8px 24px rgba(15,24,32,.07);
}
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]){
    color-scheme:dark;
    --ground:#0B1017; --surface:#141C25; --surface-2:#1A242F; --surface-3:#202C38;
    --line:#2B3846; --line-soft:#222E3A;
    --ink:#E7EDF3; --ink-2:#A4B3C3; --ink-3:#76889B;
    --accent:#77A8F2; --accent-2:#9CC1F7; --accent-soft:#18273D; --auf-accent:#0B1017;
    --ok:#5FCE8D;  --ok-bg:#10301E;  --ok-line:#255F3C;
    --run:#F0B457; --run-bg:#32250D; --run-line:#6B4E17;
    --blk:#F58077; --blk-bg:#3A1A17; --blk-line:#6E312A;
    --idle:#8497A9;--idle-bg:#1E2833; --idle-line:#334252;
    --eng:#B49BF5; --eng-bg:#231B3C; --eng-line:#453370;
    --ibn:#8FBCF0; --ibn-bg:#17293F;
    --liefer:#5CCFC4; --liefer-bg:#0F2E2B; --liefer-line:#256560;
    --sk:#EE9BCB; --sk-bg:#3A1B30; --sk-line:#6E3057;
    --absenz:#C6B9A7; --absenz-bg:#2A2620; --absenz-line:#4B4339;
    --schatten:0 1px 2px rgba(0,0,0,.5), 0 8px 24px rgba(0,0,0,.4);
  }
}
:root[data-theme="dark"]{
  color-scheme:dark;
  --ground:#0B1017; --surface:#141C25; --surface-2:#1A242F; --surface-3:#202C38;
  --line:#2B3846; --line-soft:#222E3A;
  --ink:#E7EDF3; --ink-2:#A4B3C3; --ink-3:#76889B;
  --accent:#77A8F2; --accent-2:#9CC1F7; --accent-soft:#18273D; --auf-accent:#0B1017;
  --ok:#5FCE8D;  --ok-bg:#10301E;  --ok-line:#255F3C;
  --run:#F0B457; --run-bg:#32250D; --run-line:#6B4E17;
  --blk:#F58077; --blk-bg:#3A1A17; --blk-line:#6E312A;
  --idle:#8497A9;--idle-bg:#1E2833; --idle-line:#334252;
  --eng:#B49BF5; --eng-bg:#231B3C; --eng-line:#453370;
  --ibn:#8FBCF0; --ibn-bg:#17293F;
  --liefer:#5CCFC4; --liefer-bg:#0F2E2B; --liefer-line:#256560;
    --sk:#EE9BCB; --sk-bg:#3A1B30; --sk-line:#6E3057;
    --absenz:#C6B9A7; --absenz-bg:#2A2620; --absenz-line:#4B4339;
  --schatten:0 1px 2px rgba(0,0,0,.5), 0 8px 24px rgba(0,0,0,.4);
}

*{box-sizing:border-box}
/* `hidden` muss immer ausblenden.
   Der Browser gibt einem [hidden] nur `display:none` als Vorgabe mit, und jede
   eigene Regel mit `display` schlaegt sie: `.feld{display:block}`,
   `.knopf{display:inline-flex}`, `.hilfe{display:block}`. Das ist dreimal
   dieselbe Falle gewesen - ein ausgeblendetes Element, das trotzdem dastand.
   Eine Zeile hier statt einer Ausnahme je Klasse. */
[hidden]{display:none !important}
html{-webkit-text-size-adjust:100%}
body{
  margin:0; background:var(--ground); color:var(--ink);
  font-family:"IBM Plex Sans",system-ui,-apple-system,Segoe UI,Roboto,sans-serif;
  font-size:15px; line-height:1.55; -webkit-font-smoothing:antialiased;
}
h1,h2,h3,h4{margin:0; text-wrap:balance; letter-spacing:-.012em}
p{margin:0}
a{color:var(--accent); text-decoration:none}
a:hover{text-decoration:underline}
button{font:inherit; color:inherit; background:none; border:0; cursor:pointer}
img{max-width:100%; display:block}
/* Die Symbole bringen nur ein viewBox mit. Ohne diese Grundgroesse wachsen sie
   ueberall dort ins Riesenhafte, wo keine eigene Regel greift - etwa in einem
   <summary>. Jede spezifischere Regel sticht sie weiterhin aus. */
svg{width:16px; height:16px; vertical-align:-.16em}
:focus-visible{outline:2px solid var(--accent-2); outline-offset:2px; border-radius:4px}
.mono{font-family:"IBM Plex Mono",ui-monospace,SFMono-Regular,Menlo,monospace; font-variant-numeric:tabular-nums}
.cond{font-family:"IBM Plex Sans Condensed","IBM Plex Sans",sans-serif}
.nur-lesbar{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
@media (prefers-reduced-motion:reduce){*{transition:none !important; animation:none !important}}

/* ---------------- Grundgeruest ---------------- */
.app{display:flex; min-height:100dvh}
.rail{display:none}
.body{flex:1; display:flex; flex-direction:column; min-width:0}

.topbar{
  position:sticky; top:0; z-index:20; display:flex; align-items:center; gap:11px;
  padding:11px 14px; background:var(--surface); border-bottom:1px solid var(--line);
}
.topbar h1{font-size:16px; font-weight:600; letter-spacing:-.022em; min-width:0;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.zurueck{display:flex; align-items:center; gap:4px; font-size:13px; color:var(--accent); font-weight:500; flex:none}
.zurueck svg{width:15px;height:15px}
.kwchip{margin-left:auto; display:flex; align-items:center; gap:6px; font-size:11.5px; color:var(--ink-2);
  background:var(--surface-3); border:1px solid var(--line); border-radius:7px; padding:3px 9px; white-space:nowrap; flex:none}
.kwchip b{color:var(--ink); font-weight:600}
.kwchip svg{width:13px;height:13px}
.inhalt{flex:1; padding:13px 13px 84px; max-width:1180px; width:100%; margin:0 auto}

/* ---------------- Navigation ---------------- */
.tabbar{
  position:fixed; bottom:0; left:0; right:0; display:flex; z-index:30;
  background:var(--surface); border-top:1px solid var(--line);
  padding:6px 4px calc(8px + env(safe-area-inset-bottom,0px));
}
.tabbar a{flex:1; min-width:0; display:flex; flex-direction:column; align-items:center; gap:3px;
  font-size:10px; color:var(--ink-3); font-weight:500; padding:3px 0; position:relative; text-decoration:none}
/* Ein langes Wort ("Einstellungen") darf die Leiste nicht breiter machen als das
   Telefon: min-width:0 laesst das Feld schrumpfen, der Rest wird gekuerzt.
   `.engschrift` ist die Ausnahme fuer genau dieses Wort - bei sieben Kacheln auf
   375px stehen ihm 52px zu, und in 10px braucht es 62px. Lieber zwei Punkt
   kleiner als ein "Einstellu..." in der Leiste. */
.tabbar a span{max-width:100%; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.tabbar a.engschrift span{font-size:8.5px; letter-spacing:-.2px}
.tabbar a svg{width:20px;height:20px}
.tabbar a[aria-current="page"]{color:var(--accent); font-weight:600}
.tabbar .punkt{position:absolute; top:1px; left:50%; margin-left:6px; width:7px;height:7px;
  border-radius:50%; background:var(--blk); border:1.5px solid var(--surface)}

@media (min-width:900px){
  .tabbar{display:none}
  .rail{
    display:flex; flex-direction:column; width:206px; flex:none; padding:16px 12px;
    background:var(--surface); border-right:1px solid var(--line);
    position:sticky; top:0; height:100dvh; overflow-y:auto;
  }
  .inhalt{padding:18px 20px 40px}

  /* ---- Eingeklappte Seitenleiste ----
     Nur Symbole, keine Beschriftung. Jeder Punkt traegt ein title-Merkmal,
     damit beim Zeigen trotzdem steht, wohin er fuehrt. Unter 900px gibt es
     die Leiste gar nicht - dort fuehrt die Tableiste unten, und deshalb
     steht das hier bewusst innerhalb der Abfrage. */
  .app.railzu .rail{width:64px; padding:16px 8px; align-items:center}
  .app.railzu .railkopf{flex-direction:column; gap:10px}
  .app.railzu .marke{padding:0}
  .app.railzu .marke b{display:none}
  .app.railzu .navlink{justify-content:center; padding:10px 0; width:100%; position:relative}
  .app.railzu .navlink > span:not(.zahl){display:none}
  /* Die Zahl haette in 64px keinen Platz mehr neben dem Symbol - sie sitzt
     deshalb als kleine Marke in der Ecke, wie auf der Tableiste. */
  .app.railzu .navlink .zahl{position:absolute; top:3px; right:9px; margin-left:0;
    min-width:0; font-size:9px; padding:0 4px; line-height:14px}
  .app.railzu .railfuss{padding:13px 0 4px; width:100%}
  .app.railzu .nutzerzeile{justify-content:center}
  .app.railzu .nutzerzeile > div{display:none}
  .app.railzu .abmelden > span{display:none}
  .app.railzu .abmelden{padding-left:0; padding-right:0}
}
.railkopf{display:flex; align-items:center; gap:6px; padding:4px 4px 18px}
.railschalter{margin-left:auto; flex:none; display:grid; place-items:center;
  width:28px; height:28px; border-radius:7px; color:var(--ink-3)}
.railschalter:hover{background:var(--surface-3); color:var(--ink)}
.railschalter svg{width:17px;height:17px}
.marke{display:flex; align-items:center; gap:9px; padding:0 4px}
.marke b{font-size:14.5px; font-weight:600; letter-spacing:-.02em; white-space:nowrap}
.blitz{width:27px;height:27px;border-radius:6px;background:var(--accent);display:grid;place-items:center;flex:none}
.blitz svg{width:15px;height:15px;display:block}
.navlink{display:flex; align-items:center; gap:10px; padding:9px 11px; border-radius:8px;
  font-size:13.5px; font-weight:500; color:var(--ink-2); text-decoration:none; transition:background .15s,color .15s}
.navlink svg{width:17px;height:17px;flex:none;opacity:.85}
.navlink:hover{background:var(--surface-3); color:var(--ink); text-decoration:none}
.navlink[aria-current="page"]{background:var(--accent-soft); color:var(--accent); font-weight:600}
.navlink .zahl{margin-left:auto; font-size:10.5px; font-weight:600; background:var(--ink-3);
  color:var(--surface); border-radius:20px; padding:1px 6px; min-width:18px; text-align:center}
.navlink .zahl.rot{background:var(--blk)}
.railfuss{margin-top:auto; padding:13px 10px 4px; border-top:1px solid var(--line-soft)}
.railfuss .nutzerzeile{display:flex; align-items:center; gap:9px; margin-bottom:9px}
.railfuss .nm{font-size:12.5px; font-weight:600; line-height:1.2}
.railfuss .rl{font-size:11px; color:var(--ink-3); line-height:1.2}
.avatar{width:28px;height:28px;border-radius:50%; background:var(--accent); color:var(--auf-accent);
  display:grid; place-items:center; font-size:10.5px; font-weight:600; flex:none}

/* ---------------- Bausteine ---------------- */
.sechead{display:flex; align-items:baseline; gap:9px; margin:20px 2px 9px}
.sechead:first-child{margin-top:2px}
.sechead h2{font-family:"IBM Plex Sans Condensed","IBM Plex Sans",sans-serif; font-size:12px;
  font-weight:700; text-transform:uppercase; letter-spacing:.13em; color:var(--ink-3)}
.sechead .hinweis{font-size:11.5px; color:var(--ink-3); margin-left:auto}
.karte{background:var(--surface); border:1px solid var(--line); border-radius:11px}
.pad{padding:13px 14px}
.stapel{display:flex; flex-direction:column; gap:7px}
.leer{font-size:13px; color:var(--ink-3); padding:18px 14px; text-align:center}

.meldung{background:var(--accent-soft); color:var(--accent); border:1px solid var(--accent-2);
  border-radius:9px; padding:9px 13px; font-size:13.5px; font-weight:500; margin-bottom:12px}

/* KPI */
.kpis{display:grid; gap:9px; grid-template-columns:repeat(2,1fr)}
@media (min-width:760px){.kpis{grid-template-columns:repeat(4,1fr); gap:11px}}
.kpi{background:var(--surface); border:1px solid var(--line); border-radius:11px; padding:12px 13px;
  position:relative; overflow:hidden; display:block; text-decoration:none; color:inherit; transition:border-color .15s}
.kpi:hover{border-color:var(--ink-3); text-decoration:none}
.kpi .streifen{position:absolute; left:0; top:0; bottom:0; width:4px; background:var(--accent)}
.kpi .n{font-size:29px; font-weight:600; letter-spacing:-.035em; line-height:1.05;
  font-family:"IBM Plex Mono",monospace; font-variant-numeric:tabular-nums}
.kpi .lbl{font-size:11.5px; color:var(--ink-2); font-weight:500; margin-top:3px; line-height:1.3}
.kpi .sub{font-size:10.5px; color:var(--ink-3); margin-top:5px}
.kpi.ok .streifen{background:var(--ok)} .kpi.ok .n{color:var(--ok)}
.kpi.run .streifen{background:var(--run)} .kpi.run .n{color:var(--run)}
.kpi.blk .streifen{background:var(--blk)} .kpi.blk .n{color:var(--blk)}
.kpi.idle .streifen{background:var(--idle)} .kpi.idle .n{color:var(--ink-2)}

/* Meilensteinleiste */
.leiste{display:flex; gap:3px; align-items:stretch}
.ms{flex:1; min-width:0; border-radius:4px; padding:4px 2px 3px; text-align:center; border:1px solid transparent}
.ms .k{font-family:"IBM Plex Sans Condensed","IBM Plex Sans",sans-serif; font-size:9.5px;
  font-weight:700; letter-spacing:.05em; display:block; line-height:1.15}
.ms .v{font-size:8.5px; line-height:1.15; opacity:.85; display:block; font-family:"IBM Plex Mono",monospace}
.ms.idle{background:var(--idle-bg); border-color:var(--idle-line); color:var(--idle)}
.ms.run{background:var(--run-bg); border-color:var(--run-line); color:var(--run)}
.ms.ok{background:var(--ok-bg); border-color:var(--ok-line); color:var(--ok)}
.ms.blk{background:var(--blk-bg); border-color:var(--blk-line); color:var(--blk)}
.leiste.gross{gap:5px; flex-wrap:wrap}
.leiste.gross .ms{padding:0; min-width:96px; border:0; background:none}
.leiste.gross .ms-knopf{width:100%; border-radius:8px; padding:9px 4px 8px; border:1px solid transparent; display:block; text-align:center}
.leiste.gross .ms .k{font-size:11px}
.leiste.gross .ms .v{font-size:10px; margin-top:2px}
.leiste.gross .ms .zeichen{display:block; font-size:13px; font-weight:700; line-height:1; margin-bottom:3px}
.ms-knopf.idle{background:var(--idle-bg); border-color:var(--idle-line); color:var(--idle)}
.ms-knopf.run{background:var(--run-bg); border-color:var(--run-line); color:var(--run)}
.ms-knopf.ok{background:var(--ok-bg); border-color:var(--ok-line); color:var(--ok)}
.ms-knopf.blk{background:var(--blk-bg); border-color:var(--blk-line); color:var(--blk)}
.ms-knopf:hover{filter:brightness(.97)}

/* Anlagenzeile */
.zeile{background:var(--surface); border:1px solid var(--line); border-radius:10px; padding:10px 12px;
  display:block; text-decoration:none; color:inherit; transition:border-color .15s}
.zeile:hover{border-color:var(--accent-2); text-decoration:none}
.zeile.pendent{border-left:4px solid var(--blk)}
.zkopf{display:flex; align-items:baseline; gap:8px; flex-wrap:wrap}
.aid{font-family:"IBM Plex Mono",monospace; font-size:13.5px; font-weight:600; color:var(--ink)}
.atyp{font-size:11px; font-weight:600; color:var(--ink-2); background:var(--surface-3);
  border:1px solid var(--line-soft); border-radius:4px; padding:1px 6px; font-family:"IBM Plex Mono",monospace}
.objekt{font-size:14px; font-weight:600; letter-spacing:-.015em}
.kunde{font-size:12.5px; color:var(--ink-3)}
.zbeschrieb{font-size:12px; color:var(--ink-2); margin-top:4px; overflow:hidden; text-overflow:ellipsis;
  display:-webkit-box; -webkit-line-clamp:1; line-clamp:1; -webkit-box-orient:vertical}
.zmeta{display:flex; align-items:center; gap:9px; flex-wrap:wrap; margin-top:5px}
.zleiste{margin-top:8px}
.zgrund{display:flex; gap:6px; align-items:flex-start; margin-top:6px;
  font-size:12px; color:var(--blk); line-height:1.4}
.zgrund svg{flex:none; width:14px; height:14px; margin-top:1px}

.tag{font-size:10.5px; font-weight:600; border-radius:20px; padding:2px 8px; white-space:nowrap;
  display:inline-flex; align-items:center; gap:4px}
.tag.avor{background:var(--accent-soft); color:var(--accent)}
.tag.eng{background:var(--eng-bg); color:var(--eng)}
.tag.bereit{background:var(--idle-bg); color:var(--ink-2)}
.tag.verk{background:var(--run-bg); color:var(--run)}
.tag.liefer{background:var(--liefer-bg); color:var(--liefer)}
.tag.sk{background:var(--sk-bg); color:var(--sk)}
.tag.ibn{background:var(--ibn-bg); color:var(--ibn)}
.tag.fertig{background:var(--ok-bg); color:var(--ok)}
.tag.krit{background:var(--blk-bg); color:var(--blk)}
.tag.pend{background:var(--surface-3); color:var(--ink-2); border:1px solid var(--line)}
.tag svg{width:11px;height:11px}
.termin{font-size:11.5px; color:var(--ink-2); font-family:"IBM Plex Mono",monospace;
  display:inline-flex; align-items:center; gap:4px}
.termin.bald{color:var(--blk); font-weight:600}
.termin svg{width:12px;height:12px}
.wer{font-size:11.5px; color:var(--ink-3); display:inline-flex; align-items:center; gap:4px}
.wer svg{width:12px;height:12px}

/* Brennpunkt */
.brennpunkt{background:var(--surface); border:1px solid var(--line); border-left:4px solid var(--blk);
  border-radius:10px; padding:11px 13px; display:block; text-decoration:none; color:inherit}
.brennpunkt:hover{border-color:var(--blk); border-left-color:var(--blk); text-decoration:none}
.grund{font-size:12px; color:var(--blk); font-weight:500; margin-top:4px; display:flex; align-items:flex-start; gap:5px}
.grund svg{width:13px;height:13px;flex:none;margin-top:2px}

/* Pendenzen */
.pzeile{display:flex; gap:10px; align-items:flex-start; padding:10px 12px; border-bottom:1px solid var(--line-soft)}
.pzeile:last-child{border-bottom:0}
/* **`padding:0` ist kein Schoenheitsfehler.** Das Kaestchen ist eine <button>
   und erbt sonst die allgemeine Polsterung; der Inhaltskasten wird damit
   schmaler als das Zeichen darin, und ein Rasterelement, das breiter ist als
   seine Spur, setzt sich an deren Anfang statt in die Mitte - der Haken sass
   drei Pixel zu weit rechts. Dasselbe gilt fuer die Zeilenhoehe. */
.haken{width:22px;height:22px;border:1.8px solid var(--line); border-radius:6px; flex:none; margin-top:1px;
  padding:0; line-height:0; display:grid; place-items:center;
  background:var(--surface); transition:background .15s,border-color .15s}
.haken svg{width:13px;height:13px; opacity:0; color:var(--auf-accent); display:block}
.haken:hover{border-color:var(--ok)}
.pzeile.erledigt .haken{background:var(--ok); border-color:var(--ok)}
.pzeile.erledigt .haken svg{opacity:1; color:#fff}
.pzeile.erledigt .ptext{text-decoration:line-through; color:var(--ink-3)}
/* Eine Pendenz, die die Anlage aufhaelt, traegt denselben roten Streifen wie die Zeile in der Liste. */
.pzeile.pendent{border-left:4px solid var(--blk); padding-left:8px}
.ptext{font-size:13.5px; font-weight:500; line-height:1.4}
.pmeta{font-size:11px; color:var(--ink-3); margin-top:3px; display:flex; gap:8px; flex-wrap:wrap; align-items:center}
.ohne{color:var(--blk); font-weight:600}

/* Verlauf */
.jzeile{display:flex; gap:11px; padding:10px 2px}
.jlinie{flex:none; width:20px; display:flex; flex-direction:column; align-items:center}
.jpunkt{width:9px;height:9px;border-radius:50%; background:var(--idle); border:2px solid var(--surface); flex:none; margin-top:5px}
.jpunkt.ok{background:var(--ok)} .jpunkt.run{background:var(--run)}
.jpunkt.blk{background:var(--blk)} .jpunkt.acc{background:var(--accent)}
.jbalken{flex:1; width:1.5px; background:var(--line); margin:3px 0 -10px}
.jzeile:last-child .jbalken{display:none}
.jtext{font-size:13px; line-height:1.5; white-space:pre-wrap}
.jmeta{font-size:11px; color:var(--ink-3); margin-top:2px; font-family:"IBM Plex Mono",monospace}

/* Phasen-Stepper */
.stepper{display:flex; gap:3px; background:var(--surface-3); border:1px solid var(--line); border-radius:9px; padding:3px}
.stepper button{flex:1; text-align:center; font-size:10.5px; font-weight:600; padding:8px 2px;
  border-radius:6px; color:var(--ink-3); line-height:1.2; transition:background .15s,color .15s}
.stepper button:hover{background:var(--surface)}
/* Acht Phasen: ausgeschrieben erst, wenn sie nebeneinander Platz haben. */
.stepper .phlang{display:none}
@media (min-width:640px){ .stepper .phlang{display:inline} .stepper .phkurz{display:none} }
/* Der Weg nach Mountair SK - eine leise Zeile unter der Leiste, weil ihn nur
   ein Bruchteil der Anlagen geht. In der Leiste selbst stuende er den sieben
   ueblichen Phasen im Weg. */
.skweg{display:inline-flex; align-items:center; gap:6px; margin-top:7px; padding:2px 2px;
  font-size:11.5px; color:var(--ink-3)}
.skweg:hover{color:var(--sk)}
.skweg svg{width:13px; height:13px; transform:rotate(180deg)}
/* Erledigte Schritte gruen hinterlegt - dieselbe Sprache wie bei den AVOR-Punkten. */
.stepper button.vorbei{color:var(--ok); background:var(--ok-bg)}
.stepper button.vorbei:hover{background:var(--ok-line)}
.stepper button.jetzt{background:var(--accent); color:var(--auf-accent)}
.stepper button.jetzt:hover{background:var(--accent)}

/* Filterchips */
.chips{display:flex; gap:6px; overflow-x:auto; padding-bottom:4px; margin-bottom:11px; scrollbar-width:none}
.chips::-webkit-scrollbar{display:none}
.chip{font-size:12px; font-weight:500; border:1px solid var(--line); background:var(--surface);
  border-radius:20px; padding:5px 12px; white-space:nowrap; color:var(--ink-2); text-decoration:none; flex:none}
.chip:hover{border-color:var(--ink-3); text-decoration:none}
.chip[aria-current="true"]{background:var(--ink); color:var(--ground); border-color:var(--ink)}
.chip .c{opacity:.6; margin-left:4px; font-family:"IBM Plex Mono",monospace}

/* Balken */
/* «Verteilung nach Phase» auf der Startseite - eine Zeile je Phase.

   Hiess einmal `.balken` und war damit unlesbar: derselbe Name stand weiter
   unten ein zweites Mal im Stylesheet, fuer einen 6px hohen Fortschrittsbalken.
   Die spaetere Regel gewinnt, also wurden Beschriftung, Bahn und Zahl zu drei
   6px hohen blauen Kloetzchen. Genau die Falle, vor der der Kommentar bei
   `.verkstand` warnt - deshalb heisst das hier jetzt eindeutig. */
.phasenzeile{display:flex; align-items:center; gap:9px; padding:5px 0}
.phasenzeile .phasenname{font-size:12px; color:var(--ink-2); width:96px; flex:none}
.phasenbahn{flex:1; height:9px; background:var(--surface-3); border-radius:5px; overflow:hidden}
.phasenfuell{display:block; height:100%; border-radius:5px; background:var(--idle)}
.phasenzahl{font-size:12px; font-family:"IBM Plex Mono",monospace; color:var(--ink-2);
  width:24px; text-align:right; flex:none}

/* Die Farbe kommt aus `cls` der Phase (domain.js) und nicht aus einer eigenen
   Liste in der Vorlage - dort fehlte «Mountair SK», und der Balken blieb
   farblos. Eine neue Phase braucht hier eine Zeile, sonst ist sie grau. */
.phasenfuell.eng{background:var(--eng)}
.phasenfuell.avor{background:var(--accent)}
.phasenfuell.bereit{background:var(--idle)}
.phasenfuell.sk{background:var(--sk)}
.phasenfuell.verk{background:var(--run)}
.phasenfuell.liefer{background:var(--liefer)}
.phasenfuell.ibn{background:var(--ibn)}
.phasenfuell.fertig{background:var(--ok)}

/* Formulare */
.feld{display:block; margin-bottom:12px}
.feld > span{display:block; font-size:12px; font-weight:600; color:var(--ink-2); margin-bottom:4px}
/* Grundform des Hinweises: gilt auch, wo er unter einer ganzen Feldgruppe
   steht und nicht unter einem einzelnen Feld (Lieferadresse). */
.hilfe{display:block; font-size:11.5px; color:var(--ink-3); font-weight:400; line-height:1.45}
.feld .hilfe{font-size:11.5px; color:var(--ink-3); font-weight:400; margin-top:3px; display:block}
input[type=text],input[type=email],input[type=password],input[type=date],input[type=number],
input[type=search],select,textarea{
  width:100%; font:inherit; font-size:15px; color:var(--ink); background:var(--surface);
  border:1px solid var(--line); border-radius:8px; padding:9px 11px; transition:border-color .15s;
}
input:focus,select:focus,textarea:focus{border-color:var(--accent-2); outline:none; box-shadow:0 0 0 3px var(--accent-soft)}
textarea{resize:vertical; min-height:88px; line-height:1.5}
/* Ein Textfeld, das wirklich nur zwei Zeilen braucht (Empfaenger der Lieferadresse). */
textarea.knapp{min-height:0}
select{appearance:none; background-image:linear-gradient(45deg,transparent 50%,var(--ink-3) 50%),linear-gradient(135deg,var(--ink-3) 50%,transparent 50%);
  background-position:calc(100% - 17px) 50%,calc(100% - 12px) 50%; background-size:5px 5px,5px 5px; background-repeat:no-repeat; padding-right:34px}
.reihe{display:flex; gap:9px; flex-wrap:wrap}
.reihe > *{flex:1; min-width:130px}

.knopf{display:inline-flex; align-items:center; justify-content:center; gap:6px; font-size:13.5px;
  font-weight:600; border-radius:8px; padding:9px 15px; border:1px solid var(--line);
  background:var(--surface); color:var(--ink-2); text-decoration:none; transition:background .15s,border-color .15s}
.knopf:hover{background:var(--surface-3); text-decoration:none}
.knopf svg{width:15px;height:15px}
.knopf.haupt{background:var(--accent); border-color:var(--accent); color:var(--auf-accent)}
.knopf.haupt:hover{background:var(--accent-2)}
.knopf.rot{color:var(--blk)}
.knopf.klein{font-size:12px; padding:6px 11px}
.knopfreihe{display:flex; gap:8px; flex-wrap:wrap; margin-top:12px}

/* Von Hand ausloesen, unter dem Trennstrich derselben Karte wie die Einstellung:
   links die Test-Mail mit ihrer Adresse, rechts der echte Versand. Auf dem Handy
   bricht die Zeile um. `flex-end` haelt die Knoepfe auf der Linie der Eingabe -
   ohne das haengen sie an der Beschriftung. */
.versandzeile{display:flex; gap:10px; flex-wrap:wrap; align-items:flex-end;
  margin-top:16px; padding-top:14px; border-top:1px solid var(--line)}
.versandzeile > form{min-width:0}
.versandzeile .reihe{gap:8px}

/* Eine Zeile aus Eingabefeld und Knopf, beide auf derselben Linie. `.feld`
   bringt 12px Abstand nach unten mit, und bei `flex-end` zaehlt die Aussenkante
   und nicht die Eingabe - der Knopf sass dadurch 12px zu tief. */
.feldzeile{align-items:flex-end}
.feldzeile .feld{margin-bottom:0}
/* Auf dem Handy stehen die beiden Formulare untereinander, jedes ueber die volle
   Breite - sonst bleibt fuer die Adresse ein Feld uebrig, in dem man sie nicht
   mehr lesen kann. */
@media (max-width:640px){
  .versandzeile{flex-direction:column; align-items:stretch}
  .versandzeile > form{width:100%}
}
/* Ein Knopf, der eine kleine Liste aufklappt (Sitzungsliste: PDF, Excel,
   Drucken). Ein <details> - damit braucht das Menue kein JavaScript. */
.knopfmenu{position:relative}
.knopfmenu > summary{list-style:none; cursor:pointer}
.knopfmenu > summary::-webkit-details-marker{display:none}
.knopfmenu[open] > summary{background:var(--surface-3); border-color:var(--ink-3)}
.knopfmenuliste{position:absolute; z-index:30; top:calc(100% + 5px); left:0; min-width:190px;
  background:var(--surface); border:1px solid var(--line); border-radius:10px;
  box-shadow:var(--schatten); padding:5px; display:grid; gap:1px}
.knopfmenuliste a{display:flex; align-items:center; gap:8px; padding:8px 10px; border-radius:7px;
  font-size:13px; color:var(--ink); text-decoration:none}
.knopfmenuliste a:hover{background:var(--accent-soft); text-decoration:none}
.knopfmenuliste svg{width:15px; height:15px; color:var(--ink-3)}

/* Fotos */
.fotogitter{display:grid; grid-template-columns:repeat(auto-fill,minmax(140px,1fr)); gap:9px}
.foto{border:1px solid var(--line); border-radius:9px; overflow:hidden; background:var(--surface-3); position:relative}
.foto img{width:100%; height:120px; object-fit:cover}
.foto .bu{padding:6px 8px; font-size:11px; color:var(--ink-2); line-height:1.35}
.foto .bu .wann{color:var(--ink-3); font-family:"IBM Plex Mono",monospace; font-size:10px; display:block; margin-top:2px}

/* Anmeldeseiten */
.schlicht{min-height:100dvh; display:grid; place-items:center; padding:24px 16px; background:var(--ground)}
.schlicht .box{width:100%; max-width:392px; background:var(--surface); border:1px solid var(--line);
  border-radius:14px; padding:26px 24px; box-shadow:var(--schatten)}
.schlicht .marke{justify-content:center; padding:4px 8px 6px}
.schlicht h1{font-size:21px; font-weight:600; text-align:center; margin-bottom:5px}
.schlicht .unter{font-size:13px; color:var(--ink-3); text-align:center; margin-bottom:20px; line-height:1.5}
.schlicht .fuss{text-align:center; font-size:13px; color:var(--ink-3); margin-top:16px}
.fehlerbox{background:var(--blk-bg); border:1px solid var(--blk-line); color:var(--blk); border-radius:8px;
  padding:9px 12px; font-size:13px; font-weight:500; margin-bottom:14px}

/* Verwaltung */
.uzeile{display:flex; align-items:center; gap:11px; padding:11px 13px; border-bottom:1px solid var(--line-soft); flex-wrap:wrap}
.uzeile:last-child{border-bottom:0}
.uinfo{flex:1; min-width:150px}
.uname{font-size:13.5px; font-weight:600}
.umail{font-size:11.5px; color:var(--ink-3); font-family:"IBM Plex Mono",monospace; overflow:hidden; text-overflow:ellipsis}
.rolle{font-size:10.5px; font-weight:600; border-radius:5px; padding:2px 7px; background:var(--surface-3);
  color:var(--ink-2); border:1px solid var(--line-soft); white-space:nowrap}
.rolle.admin{background:var(--accent-soft); color:var(--accent); border-color:transparent}
.rolle.gesperrt{background:var(--blk-bg); color:var(--blk); border-color:transparent}

/* ---------------- Statusbericht / Druck ---------------- */
.bericht{max-width:900px; margin:0 auto; background:var(--surface); border:1px solid var(--line);
  border-radius:12px; padding:26px 26px 32px}
.bericht h1{font-size:23px; font-weight:600; letter-spacing:-.02em}
.bericht .stand{font-size:13px; color:var(--ink-3); margin-top:4px}
.bericht h2{font-size:13px; font-weight:700; text-transform:uppercase; letter-spacing:.11em;
  color:var(--ink-3); margin:24px 0 9px; font-family:"IBM Plex Sans Condensed","IBM Plex Sans",sans-serif}
/* Die Phasentitel muessen staerker auffallen als die uebrigen h2: die
   Tabellen darunter haben ueberall dieselben Spalten, nur der Titel
   unterscheidet, welche Phase gerade folgt. */
.bericht h2.phase{font-size:16px; color:var(--ink); letter-spacing:.02em; margin-top:28px}
.btab{width:100%; border-collapse:collapse; font-size:12.5px}
.btab th{text-align:left; font-size:10.5px; text-transform:uppercase; letter-spacing:.08em;
  color:var(--ink-3); font-weight:700; padding:5px 7px; border-bottom:1px solid var(--line)}
.btab td{padding:6px 7px; border-bottom:1px solid var(--line-soft); vertical-align:top}
.btab .nr{font-family:"IBM Plex Mono",monospace; font-weight:600; white-space:nowrap}
.btab tr.blk td{background:var(--blk-bg)}
.btab .leise{color:var(--ink-3); font-weight:400}
.btab .nr.bald{color:var(--blk)}
/* Der Anlagentyp gehoert zur Nummer, ist aber nicht die Nummer. */
.btab .typ{display:block; font-family:"IBM Plex Sans",sans-serif; font-weight:400;
  font-size:10.5px; color:var(--ink-3); letter-spacing:0}
.btab tr.fort td{padding-top:0; border-bottom:1px solid var(--line-soft)}

/* Kopf des Berichts: Titel und Stand links, der Schnellstatus darunter. */
.bkopf{border-bottom:1px solid var(--line); padding-bottom:14px; margin-bottom:4px}
.bericht .subline{font-size:13px; color:var(--ink-2); margin-top:9px}
.bericht .subline b{font-family:"IBM Plex Mono",monospace; font-weight:600; color:var(--ink)}
.bericht .subline b.warn{color:var(--blk)}
.bericht .anzahl{color:var(--ink-3); font-weight:400; letter-spacing:0; text-transform:none}

/* Die Kacheln: eine Zahl gross, darunter wofuer sie steht. Auf dem Handy zwei
   nebeneinander, ab 700px so viele, wie hineinpassen. Die Pipeline nimmt zwei
   Plaetze - sie wird als Weg gelesen, nicht als einzelne Zahl. */
.kpis{display:grid; grid-template-columns:repeat(2,1fr); gap:10px; margin-bottom:6px}
@media (min-width:700px){ .kpis{grid-template-columns:repeat(4,1fr)} }
.kpi{background:var(--surface-2); border:1px solid var(--line-soft); border-radius:10px;
  padding:12px 13px; display:flex; flex-direction:column; gap:2px;
  -webkit-print-color-adjust:exact; print-color-adjust:exact}
.kpi .zahl{font-family:"IBM Plex Mono",monospace; font-size:27px; font-weight:600;
  line-height:1.1; letter-spacing:-.02em}
.kpi .was{font-size:11px; font-weight:600; text-transform:uppercase; letter-spacing:.07em;
  color:var(--ink-3)}
.kpi.haupt{background:var(--accent-soft); border-color:transparent}
.kpi.haupt .zahl{color:var(--accent)}
.kpi.warn{background:var(--blk-bg); border-color:var(--blk-line)}
.kpi.warn .zahl{color:var(--blk)}
.kpi.pipe{grid-column:1 / -1}
.kpi.pipe .stufen{display:flex; gap:4px; margin-top:6px; flex-wrap:wrap}
.kpi.pipe .stufe{flex:1; min-width:52px; background:var(--surface); border:1px solid var(--line-soft);
  border-radius:7px; padding:5px 6px; display:flex; flex-direction:column; align-items:center;
  -webkit-print-color-adjust:exact; print-color-adjust:exact}
.kpi.pipe .stufe b{font-family:"IBM Plex Mono",monospace; font-size:15px; line-height:1.2}
.kpi.pipe .stufe span{font-size:9.5px; color:var(--ink-3); white-space:nowrap}
.kpi.pipe .stufe.leer{opacity:.45}

/* Der Blocker-Radar: der einzige Kasten mit Rand im ganzen Bericht - was hier
   steht, braucht einen Entscheid, alles andere ist Bericht. */
.radar{border:1px solid var(--blk-line); border-radius:10px; padding:2px 10px 4px;
  -webkit-print-color-adjust:exact; print-color-adjust:exact}
.radar .btab tr:last-child td{border-bottom:0}
.grund{display:block; color:var(--blk); font-weight:500}
.grund + .grund{margin-top:2px}
.ruhig{font-size:13px; color:var(--ok); background:var(--ok-bg); border-radius:8px;
  padding:9px 12px; -webkit-print-color-adjust:exact; print-color-adjust:exact}

/* Wer zustaendig ist, als Pille mit Kuerzel - im Fliesstext einer Tabelle
   findet das Auge einen Namen sonst nicht wieder. */
.wer{display:inline-flex; align-items:center; gap:5px; white-space:nowrap;
  font-size:12px; color:var(--ink-2)}
.wer .kuerzel{display:inline-grid; place-items:center; width:19px; height:19px; border-radius:50%;
  background:var(--accent-soft); color:var(--accent); font-size:9.5px; font-weight:700;
  text-transform:uppercase; letter-spacing:.02em;
  -webkit-print-color-adjust:exact; print-color-adjust:exact}
/* Die Fachmarke im Bericht ("Ueberfaellig", "Heute") - eine Pille in einer
   Tabellenzelle. Heisst bewusst nicht .fach: so heisst weiter unten der
   Behaelter eines Aufgabenfachs, und ein "display:inline-block" mit
   Grossbuchstaben hat den dort zur schmalen Kachel zusammengezogen. */
.fachpille{display:inline-block; font-size:9.5px; font-weight:700; text-transform:uppercase;
  letter-spacing:.06em; border-radius:4px; padding:2px 6px; font-family:"IBM Plex Sans",sans-serif;
  -webkit-print-color-adjust:exact; print-color-adjust:exact}
.fachpille.blk{background:var(--blk-bg); color:var(--blk)}
.fachpille.run{background:var(--run-bg); color:var(--run)}
.fachpille.acc{background:var(--accent-soft); color:var(--accent)}
.fachpille.idle{background:var(--idle-bg); color:var(--idle)}

.erledigtzeile{font-size:12px; color:var(--ink-3); margin-top:9px; line-height:1.6}
.erledigtzeile b{color:var(--ok); font-family:"IBM Plex Mono",monospace}
.legende{margin-top:22px; font-size:11px; color:var(--ink-3); line-height:1.6}

/* Die sechs AVOR-Punkte im Bericht: Farbe statt Zeichenkette. Die Hintergruende
   muessen auch im Druck stehen bleiben, sonst bleibt nur graue Schrift uebrig. */
.avorstreifen{display:inline-flex; gap:3px; flex-wrap:wrap}
.avorstreifen .p{
  font-family:"IBM Plex Sans Condensed","IBM Plex Sans",sans-serif;
  font-size:9.5px; font-weight:700; letter-spacing:.04em; line-height:1.15;
  border:1px solid transparent; border-radius:3px; padding:2px 4px; white-space:nowrap;
  -webkit-print-color-adjust:exact; print-color-adjust:exact;
}
.avorstreifen .p.idle{background:var(--idle-bg); border-color:var(--idle-line); color:var(--idle)}
.avorstreifen .p.run{background:var(--run-bg);  border-color:var(--run-line);  color:var(--run)}
.avorstreifen .p.ok{background:var(--ok-bg);    border-color:var(--ok-line);   color:var(--ok)}
.scrollx{overflow-x:auto}

@media print{
  @page{size:A4; margin:14mm}
  :root{--ground:#fff; --surface:#fff; --surface-2:#fff; --surface-3:#f2f2f2;
        --ink:#000; --ink-2:#333; --ink-3:#666; --line:#bbb; --line-soft:#ddd}
  .rail,.tabbar,.topbar,.nichtdrucken{display:none !important}
  body{background:#fff; font-size:10.5pt}
  .inhalt{padding:0; max-width:none}
  .bericht{border:0; border-radius:0; padding:0; max-width:none}
  .bericht h2{margin-top:16px; break-after:avoid}
  .btab{break-inside:auto}
  .btab tr{break-inside:avoid}
  .karte{break-inside:avoid; box-shadow:none}
  a{color:#000; text-decoration:none}
}

/* ---------------- Wochenuebersicht und Gantt ---------------- */
.nur-breit{display:none}
.nur-schmal{display:block}
@media (min-width:700px){
  .nur-breit{display:block}
  .nur-schmal{display:none}
}
.nur-mit-js{display:none}
html.js .nur-mit-js{display:inline-flex}

/* Ab Tablet soll die ganze Woche auf eine Seite passen und dabei so viel Platz
   bekommen wie da ist: die Seite erhaelt Bildschirmhoehe, das Raster den Rest. */
.wochenseite{display:flex; flex-direction:column; min-height:0}
@media (min-width:700px){
  .app:has(.wochenseite){height:100dvh; min-height:100dvh}
  .app:has(.wochenseite) .body{min-height:0}
  .app:has(.wochenseite) .inhalt{
    display:flex; flex-direction:column; min-height:0; max-width:none;
  }
  .wochenseite{flex:1; min-height:0}
  .warnstreifen{flex:none}
}
/* Erst ab 900px ist die untere Leiste weg - vorher braucht sie ihren Platz. */
@media (min-width:900px){
  .app:has(.wochenseite) .inhalt{padding-bottom:16px}
}

.wochenkopf{display:flex; flex-wrap:wrap; gap:11px; align-items:center;
  justify-content:space-between; margin-bottom:13px}
.wochennav{display:flex; align-items:center; gap:8px; flex-wrap:wrap}
.wochennav .knopf{padding:6px 10px}
.kwtitel{font-size:17px; font-weight:600; letter-spacing:-.02em; display:flex; align-items:baseline; gap:5px}
.kwtitel .jahr{font-size:12px; color:var(--ink-3); font-family:"IBM Plex Mono",monospace; font-weight:500}
.wochennav .spanne{font-size:12px; color:var(--ink-3); font-family:"IBM Plex Mono",monospace}
.umschalter{display:flex; gap:6px}

/* Wochenraster: ein Gitter statt einer Tabelle, damit die Zeilen die
   verfuegbare Hoehe unter sich aufteilen und nichts seitwaerts wegrutscht. */
.wochenraster{
  display:none;                      /* auf dem Handy zaehlt die Tagesliste */
  flex:1; min-height:0; overflow:auto;
  grid-template-columns:clamp(84px,13vw,150px) repeat(var(--spalten,5),minmax(0,1fr));
  grid-template-rows:auto;
  grid-auto-rows:minmax(54px,1fr);
  gap:1px; background:var(--line-soft);
  border:1px solid var(--line); border-radius:11px;
}
@media (min-width:700px){ .wochenraster{display:grid} }
/* Erste Zeile Kopf, zweite - falls vorhanden - die Termine: beide nur so hoch
   wie noetig, damit die Einteilung darunter den ganzen Rest bekommt. */
.wochenraster{grid-template-rows:auto}
.wochenraster.mit-terminen{grid-template-rows:auto auto}
.wr-kopf{
  position:sticky; top:0; z-index:3; background:var(--surface-2);
  display:flex; flex-direction:column; justify-content:center; gap:1px;
  padding:7px 8px; text-align:left; min-width:0;
  font-family:"IBM Plex Sans Condensed","IBM Plex Sans",sans-serif; color:var(--ink-3);
}
.wr-kopf b{font-size:clamp(11px,1.3vw,14.5px); font-weight:700; letter-spacing:.06em;
  text-transform:uppercase; color:var(--ink-2); line-height:1.15}
.wr-kopf .datum{font-size:clamp(9.5px,1vw,12px); font-family:"IBM Plex Mono",monospace; line-height:1.15}
.wr-kopf.heute{background:var(--accent-soft)}
.wr-kopf.heute b, .wr-kopf.heute .datum{color:var(--accent)}
.wr-ecke{left:0; z-index:5; font-size:10px; font-weight:700; letter-spacing:.1em;
  text-transform:uppercase; justify-content:flex-end; padding-bottom:8px}
.wr-tagkopf{cursor:pointer; width:100%; transition:background .12s}
.wr-tagkopf:hover{background:var(--accent-soft)}
.wr-tagkopf:hover b{color:var(--accent)}

.wr-name{
  position:sticky; left:0; z-index:2; background:var(--surface);
  display:flex; align-items:center; gap:7px; padding:5px 8px; min-width:0;
}
.wr-name .avatar{width:24px; height:24px; font-size:9.5px}
.wr-name .pname{font-size:clamp(11.5px,1.15vw,14px); font-weight:600; letter-spacing:-.01em;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap}

.wr-tag{background:var(--surface); display:flex; flex-direction:column; gap:2px;
  padding:3px; min-width:0}

/* Terminzeile: haengt am Tag, nicht an einer Person. */
.wr-terminkopf{gap:5px; color:var(--ink-3)}
.wr-terminkopf svg{width:14px; height:14px}
.wr-terminkopf .pname{font-size:11px; font-weight:700; text-transform:uppercase; letter-spacing:.08em;
  font-family:"IBM Plex Sans Condensed","IBM Plex Sans",sans-serif; color:var(--ink-3)}
.wr-termine{background:var(--surface); display:flex; flex-direction:column; gap:3px;
  padding:4px 3px; min-width:0; min-height:26px}
.wr-termine.heute{background:color-mix(in srgb, var(--accent-soft) 40%, var(--surface))}
/* Der Terminchip traegt dieselbe Marke wie die Terminansicht (mk-schrank,
   mk-ibn, mk-liefer): Symbol und Farbe kommen aus --mk, nicht mehr fest aus
   den Liefer-Tokens. Vorher war jeder Termin teal, ob IBN oder Schaltschrank. */
.terminchip, .terminzeile{--mk:var(--ink-3); --mk-bg:var(--surface-2); --mk-line:var(--line)}
.terminchip{display:flex; flex-direction:column; gap:1px; min-width:0; text-decoration:none;
  border:1px solid var(--mk-line); background:var(--mk-bg); color:var(--mk);
  border-radius:6px; padding:3px 6px; font-size:11px; line-height:1.3}
.terminchip:hover{text-decoration:none; filter:brightness(.97)}
.terminchip b{font-family:"IBM Plex Mono",monospace; font-size:10.5px; font-weight:600; flex:none}
.terminchip span{overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.tchip-kopf{display:flex; align-items:center; gap:4px; min-width:0}
.tchip-kopf .terminmarke svg{width:13px; height:13px}
.tchip-anlage{display:flex; gap:5px; align-items:baseline; font-size:10px; color:var(--ink-3)}
.tchip-anlage .mono{font-family:"IBM Plex Mono",monospace; font-weight:600; flex:none}

.terminkarte{margin-bottom:7px; overflow:hidden}
.terminzeile{display:flex; gap:9px; align-items:center; padding:9px 12px; text-decoration:none;
  color:inherit; border-bottom:1px solid var(--line-soft); border-left:3px solid var(--mk)}
.terminzeile:last-child{border-bottom:0}
.terminzeile:hover{text-decoration:none; background:var(--surface-2)}
.terminzeile .terminmarke{flex:none}
.terminzeile .tzeit{flex:none; width:46px; font-family:"IBM Plex Mono",monospace; font-size:11.5px;
  font-weight:600; color:var(--mk)}
.terminzeile .ttext{font-size:13px; line-height:1.4}
.terminzeile .ttext .mono{font-size:11px; color:var(--ink-3); margin-left:4px}
.wr-tag.heute{background:color-mix(in srgb, var(--accent-soft) 40%, var(--surface))}

.slot{
  flex:1 1 0; min-height:0; min-width:0; width:100%;
  display:flex; align-items:center; gap:5px; text-align:left;
  border:1px dashed transparent; border-radius:6px; padding:2px 4px;
}
.slot .ht{font-family:"IBM Plex Sans Condensed","IBM Plex Sans",sans-serif; font-size:9.5px;
  font-weight:700; color:var(--ink-3); width:17px; flex:none; letter-spacing:.05em;
  align-self:flex-start; margin-top:3px}
.slot.frei{background:var(--surface-2); border-color:var(--line-soft); color:var(--ink-3)}
button.slot.frei{cursor:pointer; transition:background .12s,border-color .12s,color .12s}
button.slot.frei:hover{background:var(--accent-soft); border-color:var(--accent-2); color:var(--accent)}
.slot .plus{margin-left:auto; font-size:15px; line-height:1; font-weight:600; opacity:0}
button.slot.frei:hover .plus, button.slot.frei:focus-visible .plus{opacity:.8}
.slot.zielt{outline:2px solid var(--accent-2); outline-offset:-1px; background:var(--accent-soft)}

.halbtag{display:flex; align-items:center; gap:6px; padding:2px 0}
.halbtag .ht{font-family:"IBM Plex Sans Condensed","IBM Plex Sans",sans-serif; font-size:9.5px;
  font-weight:700; color:var(--ink-3); width:19px; flex:none; letter-spacing:.05em}
.halbtag .frei{font-size:11px; color:var(--ink-3); opacity:.55; font-style:italic}
.halbtag.schmal{padding:3px 0}
/* Der Anker nach dem Abhaken zieht die Zeile an den oberen Rand - mit etwas
   Luft darueber, damit die Ueberschrift ihres Fachs mit im Bild bleibt und man
   sieht, wo man ist. */
.pzeile.aufgabe{scroll-margin-top:96px}
.freiknopf{width:100%; text-align:left; cursor:pointer; margin:3px 0;
  border:1px dashed var(--line); border-radius:7px; background:var(--surface-2); padding:6px 9px}
.freiknopf .frei{font-style:normal; opacity:.8}
.freiknopf .plus{margin-left:auto; font-size:15px; line-height:1; font-weight:600; color:var(--accent)}

.einsatz{display:flex; align-items:center; gap:4px; border-radius:6px; padding:3px 5px;
  border:1px solid transparent; flex:1; min-width:0}
.einsatz a{display:flex; align-items:baseline; gap:5px; min-width:0; flex:1; text-decoration:none; color:inherit}
.einsatz a:hover{text-decoration:underline}
.einsatz .mono{font-size:11px; font-weight:600; flex:none}
.einsatz .ort{font-size:11px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; opacity:.85}
.einsatz.avor{background:var(--accent-soft); border-color:var(--accent-soft); color:var(--accent)}
.einsatz.eng{background:var(--eng-bg); border-color:var(--eng-line); color:var(--eng)}
.einsatz.bereit{background:var(--idle-bg); border-color:var(--idle-line); color:var(--ink-2)}
.einsatz.verk{background:var(--run-bg); border-color:var(--run-line); color:var(--run)}
.einsatz.sk{background:var(--sk-bg); border-color:var(--sk-line); color:var(--sk)}
.einsatz.liefer{background:var(--liefer-bg); border-color:var(--liefer-line); color:var(--liefer)}
.einsatz.ibn{background:var(--ibn-bg); border-color:var(--ibn-bg); color:var(--ibn)}
.einsatz.fertig{background:var(--ok-bg); border-color:var(--ok-line); color:var(--ok)}
/* Papierkorb - die zweite Ansicht des Archivs. Diese Regeln standen als
   <style> in der eigenen Vorlage; die gibt es nicht mehr, und ein zweites
   Stylesheet erst recht nicht. */
.pkzeile{display:flex; gap:12px; align-items:flex-start; flex-wrap:wrap;
  padding:12px; border-bottom:1px solid var(--line-soft)}
.pkzeile:last-child{border-bottom:0}
.pkinhalt{flex:1; min-width:220px}
.pkmeta{font-size:11.5px; color:var(--ink-3); margin-top:4px; line-height:1.4}
.pkmeta b{color:var(--ink-2)}
.pkknoepfe{display:flex; gap:7px; flex-wrap:wrap; align-items:flex-start}
.pkknoepfe form{margin:0}

/* Absenz - Ferien, Frei, ein Kurs. Eigene Farbe **und** Schraffur: die Farbe
   allein waere in einer Reihe von acht Phasenfarben nur die neunte, die
   Schraffur sagt ohne Legende «hier arbeitet niemand». Bewusst nicht `.frei`
   genannt, das ist im Raster schon der leere Halbtag. */
.einsatz.absenz{
  color:var(--absenz); border-color:var(--absenz-line); background:var(--absenz-bg);
  background-image:repeating-linear-gradient(-45deg,
    transparent 0 5px, var(--absenz-line) 5px 6px);
}
.einsatz .absenztext{display:flex; align-items:baseline; gap:5px; min-width:0; flex:1;
  font-size:11px; font-weight:600; font-style:italic}
.wochenraster .einsatz .absenztext{flex-wrap:wrap; row-gap:0; font-size:clamp(10px,.95vw,12.5px)}

.einsatz .weg{font-size:14px; line-height:1; opacity:.5; padding:0 2px; flex:none; color:inherit}
.einsatz .weg:hover{opacity:1; color:var(--blk)}
.einsatz form{display:flex; flex:none}

/* Im Raster darf ein Einsatz die Hoehe der Zelle nutzen und umbrechen. */
.wochenraster .einsatz{align-self:stretch; align-items:flex-start}
.wochenraster .einsatz a{flex-wrap:wrap; row-gap:0}
.wochenraster .einsatz .mono{font-size:clamp(10px,.95vw,12.5px)}
.wochenraster .einsatz .ort{font-size:clamp(10px,.95vw,12.5px); white-space:normal;
  line-height:1.3; text-overflow:clip}

/* Ziehen und Ablegen */
.wochenraster [data-einsatz]{cursor:grab; touch-action:none;
  -webkit-user-select:none; user-select:none}
.wochenraster [data-einsatz] a{-webkit-user-drag:none; cursor:inherit}
.wochenraster [data-einsatz]:active{cursor:grabbing}
.zieht-original{opacity:.3}
.zieht-geist{position:fixed; top:0; left:0; z-index:100; pointer-events:none;
  transform:translate(-50%,-50%) rotate(-1.5deg); max-width:230px;
  box-shadow:var(--schatten); opacity:.96}
body.zieht-laeuft{cursor:grabbing; -webkit-user-select:none; user-select:none}

.tagzeile{display:flex; gap:10px; align-items:flex-start; padding:10px 12px; border-bottom:1px solid var(--line-soft)}
.tagzeile:last-child{border-bottom:0}
.tagzeile .pname{font-size:13px; font-weight:600; margin-bottom:3px}

/* Dialog zum Einteilen */
.dlg{border:0; border-radius:14px; padding:20px 20px 18px; color:var(--ink);
  width:min(580px, calc(100vw - 28px)); background:var(--surface); box-shadow:var(--schatten)}
.dlg::backdrop{background:rgba(8,14,20,.55)}
.dlgtitel{font-size:17px; font-weight:600; letter-spacing:-.02em}
.dlgwann{font-size:12.5px; color:var(--ink-3); margin:2px 0 15px; min-height:1em}
/* Fliesstext im Dialog - fuer Nachfragen, die mehr als eine Zeile brauchen. */
.dlgtext{font-size:13px; color:var(--ink-2); line-height:1.5; margin:7px 0 16px}
.dlgfuss{display:flex; gap:8px; align-items:center; flex-wrap:wrap; justify-content:flex-end}
.dlgfuss .hinweis{font-size:11.5px; color:var(--ink-3); flex:1 1 180px; line-height:1.4}
@media (max-width:560px){ .dlgfuss .hinweis{flex:1 1 100%; margin-bottom:2px} }
.dlg .feld{margin-bottom:10px}

/* Personenwahl als Kaestchen-Chips - auf dem Tablet mit dem Finger bedienbar. */
.leutewahl{border:0; padding:0; margin:0 0 12px; min-width:0}
.leutewahl > legend{padding:0; font-size:12px; font-weight:600; color:var(--ink-2); margin-bottom:5px}
.wahl{display:flex; gap:6px; flex-wrap:wrap}
.wahlchip{display:inline-flex; align-items:center; gap:6px; cursor:pointer;
  border:1px solid var(--line); background:var(--surface); border-radius:20px;
  padding:6px 13px 6px 10px; font-size:13px; font-weight:500; color:var(--ink-2);
  transition:background .12s,border-color .12s,color .12s}
.wahlchip input{accent-color:var(--accent); width:15px; height:15px; margin:0; flex:none}
.wahlchip:hover{border-color:var(--ink-3)}
.wahlchip:has(input:checked){background:var(--accent-soft); border-color:var(--accent-2); color:var(--accent); font-weight:600}
.wahlchip:has(input:focus-visible){outline:2px solid var(--accent-2); outline-offset:2px}

/* Gantt - die Terminansicht.
   Sie beantwortet zwei Fragen zugleich: **wo stehe ich** (die Heute-Spalte als
   durchgehende Linie) und **was ist wann** (Balken fuer Einsaetze, Marken fuer
   Termine). Beides muss auf einen Blick gehen, deshalb sind die Zeilen knapp
   und die Farben streng verteilt: Phasenfarbe im Balken, Markenfarbe im
   Symbol, Rot nur fuer pendent. */
.gantt{width:100%; border-collapse:separate; border-spacing:0; font-size:12px}
.gantt thead th{background:var(--surface-2); border-bottom:1px solid var(--line); padding:5px 4px;
  font-size:10px; font-weight:700; color:var(--ink-3); text-align:center; white-space:nowrap;
  font-family:"IBM Plex Sans Condensed","IBM Plex Sans",sans-serif; min-width:52px}
.gantt thead th .n{display:block; font-size:12px; font-family:"IBM Plex Mono",monospace; color:var(--ink-2)}
.gantt thead th.jetzt{background:var(--accent-soft); color:var(--accent)}
.gantt thead th.jetzt .n{color:var(--accent)}
.gantt th.fix{position:sticky; left:0; z-index:2; background:var(--surface); text-align:left;
  border-right:1px solid var(--line); min-width:200px; padding:3px 9px}
.gantt thead th.fix{background:var(--surface-2); z-index:3; min-width:200px; padding:6px 9px}
.gantt tbody th.fix{border-bottom:1px solid var(--line-soft)}
.gantt tbody tr{height:31px}
.gantt tbody th.fix.pendent{box-shadow:inset 3px 0 0 var(--blk)}
/* Der Traeger, nicht die Zelle: eine <th> mit display:flex faellt aus dem
   Tabellenlayout und nimmt die feste Spalte ihre Breite und das Kleben mit. */
.gantt tbody th.fix .zk{display:flex; align-items:center; gap:7px; min-width:0}
.gantt tbody th.fix a{display:flex; align-items:baseline; gap:7px; min-width:0; flex:1;
  text-decoration:none; color:inherit}
.gantt tbody th.fix a:hover{text-decoration:underline}
.gantt tbody th.fix .nr{font-size:12px; font-weight:600; flex:none}
.gantt tbody th.fix .ort{font-size:12px; font-weight:500; color:var(--ink-2);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
/* Das Phasen-Etikett steht rechts am Rand der festen Spalte - eine eigene
   Zeile darunter kostete die halbe Tabellenhoehe. */
.gantt tbody th.fix .tag{flex:none; margin-left:auto}
.gantt td{border-bottom:1px solid var(--line-soft); padding:3px 2px; position:relative;
  background:var(--surface); text-align:center; vertical-align:middle}
/* **Nicht `.balken` nennen.** Den Namen gibt es in diesem flachen Stylesheet
   schon zweimal - unter anderem als 6px hoher Fortschrittsbalken mit fester
   Hoehe. Der Gantt-Balken war dadurch 6px hoch und hat die Kuerzel darin
   abgeschnitten: man sah einen Strich und nie, wer eingeteilt ist. */
.einsatzbalken{display:block; border-radius:3px; padding:2px 3px; font-size:9.5px;
  font-weight:600; font-family:"IBM Plex Sans Condensed","IBM Plex Sans",sans-serif;
  line-height:1.3; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.einsatzbalken.avor{background:var(--accent); color:var(--auf-accent)}
.einsatzbalken.eng{background:var(--eng); color:var(--auf-accent)}
.einsatzbalken.bereit{background:var(--idle); color:var(--surface)}
.einsatzbalken.verk{background:var(--run); color:var(--auf-accent)}
.einsatzbalken.sk{background:var(--sk); color:var(--auf-accent)}
.einsatzbalken.liefer{background:var(--liefer); color:var(--auf-accent)}
.einsatzbalken.ibn{background:var(--ibn); color:var(--auf-accent)}
.einsatzbalken.fertig{background:var(--ok); color:var(--auf-accent)}

/* ---- Marken: was in dieser Spalte ansteht ----
   Die Raute davor war ein 9px-Quadrat am rechten Zellenrand und sagte weder,
   welcher Termin gemeint ist, noch auf welchen Tag er faellt. Jetzt traegt
   jede Marke ihr eigenes Symbol, die Zelle ihre Farbe und links einen
   senkrechten Streifen ueber die volle Hoehe - der zieht das Auge auf die
   Spalte, auch wenn die Zeile weit unten steht. */
/* **Nicht `.marke` nennen** - so hiess das hier zuerst, und `.marke` ist in
   diesem flachen Stylesheet die Wortmarke in der Seitenleiste, mit
   `display:flex`. Die Tabellenzelle fiel damit aus dem Tabellenlayout und
   legte sich ueber die Nachbarspalte: der Liefertermin stand im falschen
   Monat. Gleiches gilt fuer `.balken` weiter oben. */
.gantt td.hat-termin{background:var(--mk-bg)}
.gantt td.hat-termin::before{content:""; position:absolute; left:0; top:0; bottom:0; width:3px;
  background:var(--mk)}
.gantt td .terminmarken{position:relative; display:flex; align-items:center; justify-content:center;
  gap:2px; line-height:0}
.gantt td.belegt .terminmarken{margin-top:2px}
.terminmarke{display:inline-flex; align-items:center; gap:2px; color:var(--mk); min-width:0}
.terminmarke svg{width:15px; height:15px; vertical-align:0; flex:none}
.mkdatum{font-family:"IBM Plex Sans Condensed","IBM Plex Sans",sans-serif; font-style:normal;
  font-size:9.5px; font-weight:700; line-height:1; letter-spacing:-.02em;
  overflow:hidden; text-overflow:clip; white-space:nowrap}
/* Die drei Marken aus TERMIN_MARKEN in domain.js. Rot fehlt mit Absicht:
   es heisst in dieser Anwendung ueberall "pendent". */
.mk-schrank{--mk:var(--run);    --mk-bg:var(--run-bg);    --mk-line:var(--run-line)}
.mk-ibn{--mk:var(--ibn);        --mk-bg:var(--ibn-bg);    --mk-line:color-mix(in srgb, var(--ibn) 40%, transparent)}
.mk-liefer{--mk:var(--liefer);  --mk-bg:var(--liefer-bg); --mk-line:var(--liefer-line)}
.mk-andere{--mk:var(--ink-3);   --mk-bg:var(--surface-3); --mk-line:var(--line)}

/* Samstag und Sonntag: grau hinterlegt, damit die Arbeitswoche als Block
   dasteht. Steht vor `.hat-termin`, damit ein Termin am Wochenende trotzdem seine
   Farbe behaelt - gleiche Spezifitaet, es gewinnt die spaetere Regel. */
.gantt td.we{background:var(--idle-bg); border-left:1px solid var(--line-soft)}
.gantt thead th.we{background:var(--idle-bg); color:var(--idle); border-left:1px solid var(--line-soft)}
.gantt thead th.we .n{color:var(--idle)}
.gantt td.hat-termin.we{background:var(--mk-bg)}

/* ---- Wo man ist ----
   `jetzt` ist die gewaehlte Woche, `heute` der heutige Tag - meist dieselbe
   Spalte, nach dem Blaettern aber nicht mehr. Die Tuenchung markiert die
   Auswahl, die Linie die Gegenwart; als inset-Schatten, damit sie die
   Spaltenbreite nicht verschiebt. */
.gantt td.jetzt{background:color-mix(in srgb, var(--accent-soft) 45%, var(--surface))}
.gantt td.jetzt.we{background:color-mix(in srgb, var(--accent-soft) 45%, var(--idle-bg))}
.gantt td.jetzt.hat-termin{background:var(--mk-bg)}
.gantt td.heute, .gantt thead th.heute{box-shadow:inset 2px 0 0 var(--accent-2)}
.gantt thead th.heute{background:var(--accent-soft); color:var(--accent)}
.gantt thead th.heute .n{color:var(--accent)}

/* Die obere Kopfzeile: KW, Monat oder Quartal ueber den Spalten darunter. */
.gantt thead tr.gruppen th{font-size:10.5px; color:var(--ink-2); padding:3px 4px;
  border-bottom:1px solid var(--line-soft); border-left:1px solid var(--line-soft)}
.gantt thead tr.gruppen th.fix{border-left:0}
/* Tagesspalten sind schmal - sonst waeren vier Wochen einen Meter breit. */
.gantt.tage thead th{min-width:30px; padding:5px 1px}
.gantt.tage thead th.fix{min-width:200px; padding:6px 9px}
.gantt.tage td{padding:3px 1px}
.gantt.tage .einsatzbalken{padding:2px 1px; font-size:9px; letter-spacing:-.02em}
.gantt.tage .terminmarke svg{width:13px; height:13px}

.rasterwahl{display:flex; align-items:center; gap:6px 14px; flex-wrap:wrap; margin:-4px 0 11px; flex:none}
.rastergruppe{display:inline-flex; align-items:center; gap:6px; flex-wrap:wrap}
.rasterlabel{font-family:"IBM Plex Sans Condensed","IBM Plex Sans",sans-serif; font-size:11px;
  font-weight:700; text-transform:uppercase; letter-spacing:.11em; color:var(--ink-3);
  margin-right:2px}
.ganttrahmen{flex:1; min-height:0; overflow:auto}

/* Legende: eine Zeile aus kleinen Paaren Symbol-Wort. Sie steht unter der
   Tabelle und darf keine Hoehe fressen. */
.ganttlegende{display:flex; flex-wrap:wrap; gap:4px 14px; align-items:center;
  font-size:11.5px; color:var(--ink-3); margin-top:7px; flex:none}
.lgd{display:inline-flex; align-items:center; gap:5px; white-space:nowrap}
.lgd .terminmarke svg{width:13px; height:13px}
.lgdbalken{width:16px; height:7px; border-radius:2px; background:var(--accent)}
.lgdpendent{width:3px; height:13px; border-radius:2px; background:var(--blk)}

/* Beide Kopfzeilen bleiben beim Rollen stehen - die untere unter der oberen,
   deshalb der Versatz. 23px ist die Hoehe der Gruppenzeile. */
.gantt thead tr.gruppen th{position:sticky; top:0; z-index:3}
.gantt thead tr:not(.gruppen) th{position:sticky; top:23px; z-index:3}
.gantt thead th.fix{z-index:5}
.gantt tbody th.fix{z-index:2}
@media (max-width:1180px){
  .gantt th.fix, .gantt thead th.fix, .gantt.tage thead th.fix{min-width:150px; padding:3px 7px}
  .gantt thead th{min-width:40px; padding:5px 2px}
  .gantt tbody th.fix .nr, .gantt tbody th.fix .ort{font-size:11px}
}
/* Auf dem Handy nimmt die Anlagenspalte sonst die halbe Breite: die Tabelle
   waechst nach ihrem laengsten Inhalt. `width` deckelt sie, den Rest schneidet
   der Ort mit Auslassungspunkten ab - Nummer und Phase bleiben ganz. */
@media (max-width:700px){
  .gantt th.fix, .gantt thead th.fix, .gantt.tage thead th.fix{min-width:0; width:138px; padding:3px 6px}
  .gantt tbody th.fix .zk{gap:5px}
  .gantt tbody th.fix .ort{font-size:10.5px}
  .gantt tbody th.fix .tag{font-size:9px; padding:1px 4px}
}

/* Nachfrage vor einer Aktion, die man nicht rueckgaengig machen kann.
   Steht in der Seite statt im Browserdialog - siehe app.js. */
.nachfrage{border:1px solid var(--blk-line); background:var(--blk-bg); border-radius:10px;
  padding:11px 13px; margin-top:8px}
.nachfrage p{font-size:12.5px; line-height:1.45; color:var(--blk); margin-bottom:10px}
.nachfrage .knoepfe{display:flex; gap:8px; flex-wrap:wrap}

/* Reiter auf der Anlagenseite. Ohne JavaScript sind alle Abschnitte sichtbar
   und die Reiterleiste bleibt verborgen - dann ist die Seite wie vorher. */
.reiter{display:none}
.js .reiter{display:flex; gap:4px; margin:2px 0 4px; overflow-x:auto; scrollbar-width:none;
  border-bottom:1px solid var(--line)}
.js .reiter::-webkit-scrollbar{display:none}
.reiter button{flex:none; font-size:13px; font-weight:600; color:var(--ink-3);
  padding:9px 13px; border-bottom:2px solid transparent; margin-bottom:-1px; white-space:nowrap}
.reiter button:hover{color:var(--ink-2)}
.reiter button[aria-selected="true"]{color:var(--accent); border-bottom-color:var(--accent)}
.reiter button .c{font-size:11px; font-weight:600; color:var(--ink-3);
  background:var(--surface-3); border-radius:20px; padding:1px 6px; margin-left:2px}
.reiter button[aria-selected="true"] .c{background:var(--accent-soft); color:var(--accent)}

/* Die Anlagenzeile zeigt statt der sechs Kaestchen nur, wie viele AVOR-Punkte
   erledigt sind. Die Kaestchen stehen auf der Anlagen- und der Auftragsseite. */
.tag.avorkurz{background:var(--surface-3); color:var(--ink-2); border:1px solid var(--line)}
.tag.avorkurz.fertig{background:var(--ok-bg); color:var(--ok); border-color:var(--ok-line)}
.phasenwahl{display:flex; gap:6px; flex:none}
.phasenwahl select{font-size:12px; padding:4px 26px 4px 10px; border-radius:20px; height:auto}
.js .nur-ohne-js{display:none}

/* Anlage im Papierkorb: der Hinweis steht ueber allem anderen. */
.papierkorbbalken{display:flex; gap:12px; align-items:center; flex-wrap:wrap;
  border:1px solid var(--blk-line); background:var(--blk-bg); border-radius:11px;
  padding:11px 13px; margin-bottom:12px}
.papierkorbbalken p{flex:1; min-width:220px; font-size:12.5px; color:var(--blk); line-height:1.45}
.papierkorbbalken svg{vertical-align:-.2em}
.auftragweit .zeile1{display:flex; gap:8px; align-items:flex-start; font-size:13px;
  font-weight:500; color:var(--ink); line-height:1.35}
.auftragweit input{margin-top:2px; flex:none}

/* ---------------- Anlagenliste als Tabelle ----------------
   Aufbau wie die Produktionsliste: eine Zeile je Anlage. Fuenf Spalten passen
   auch auf ein Handy - es gibt darum nur diese eine Darstellung.

   **Zwei Spalten teilen sich die freie Breite**: Objekt und Pendenzen. Beide
   brauchen dafuer `max-width:0` - das ist der Kniff, mit dem eine Tabellen-
   spalte ueberhaupt kuerzen kann, statt sich am laengsten Inhalt aufzublasen.
   Die Prozentwerte sind nur ein Verhaeltnis: die Pendenz ist ein Satz, das
   Objekt zwei Woerter. */
.ltab{width:100%; border-collapse:collapse; font-size:13px}
.ltab th{text-align:left; font-size:10px; font-weight:700; text-transform:uppercase;
  letter-spacing:.08em; color:var(--ink-3); padding:8px 7px; white-space:nowrap;
  border-bottom:1px solid var(--line)}
.ltab td{padding:9px 7px; border-bottom:1px solid var(--line-soft); vertical-align:middle}
.ltab tbody tr:last-child td{border-bottom:0}
.ltab tbody tr:hover td{background:var(--surface-2)}
/* Aufgehalten wird markiert, nicht flaechig gefaerbt: steht die halbe Tabelle
   in Rot, unterscheidet die Farbe die Zeilen nicht mehr, sondern verwischt sie.
   Der schmale Balken links und der rote Grund hinter dem Objekt genuegen. */
.ltab .anr{font-family:"IBM Plex Mono",monospace; font-weight:600; font-size:13px; white-space:nowrap}

/* Die ganze Zeile ist der Link, nicht nur die Nummer: auf dem Tablet trifft man
   eine Nummer schlecht. Der Link deckt dazu die Zeile ab, statt dass jede Zelle
   einen eigenen bekommt - so bleibt es ein Link, den man auch in einem neuen
   Reiter oeffnen kann. */
.ltab tbody tr{position:relative}
.ltab tbody tr:hover{cursor:pointer}
.ltab .anr::after{content:""; position:absolute; inset:0}
.ltab .anrsp{border-left:3px solid transparent; width:1%}
.ltab tr.pendent .anrsp{border-left-color:var(--blk)}
.ltab .objsp b{font-size:13.5px; font-weight:600}
.ltab .klein{font-size:11.5px; color:var(--ink-3)}
.ltab .mono{font-family:"IBM Plex Mono",monospace; font-size:12px; white-space:nowrap; width:1%}
.ltab .mono.bald{color:var(--blk); font-weight:600}
.ltab .num{text-align:center; width:1%}
/* Objekt und Kunde stehen nebeneinander, der Kunde kleiner und grau. */
.ltab .objsp{max-width:0; width:40%; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.ltab .objsp .kunde{font-size:11.5px; color:var(--ink-3); margin-left:7px; font-weight:400}
/* Die Pendenzen bekommen den Rest - sie sind der Grund, warum die Zeile in den
   Brennpunkten steht, und in dieser Spalte beginnt jedes Ausrufezeichen in
   jeder Zeile an derselben Stelle. */
.ltab .pendsp{max-width:0; width:60%; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}

/* Sortierbare Spaltenkoepfe: der ganze Kopf ist der Verweis, der Pfeil zeigt
   die Richtung. Der Platz fuer den Pfeil ist immer da, damit die Kopfzeile
   beim Sortieren nicht springt. */
.ltab th a.sortlink{color:inherit; text-decoration:none; display:inline-flex; align-items:center; gap:3px}
.ltab th a.sortlink:hover{color:var(--ink-1)}
.ltab th .pfeil{display:inline-block; min-width:8px; font-size:10px; line-height:1}
.ltab th.sortiert{color:var(--ink-1)}

@media (max-width:640px){
  .ltab th, .ltab td{padding-left:5px; padding-right:5px}
  /* Eine Sammelanlage heisst schon mal 42560-1a/1b/1c. In einer Zeile treibt
     das die erste Spalte auf, bis der Termin rechts aus dem Bild faellt -
     auf dem Handy darf die Bezeichnung deshalb umbrechen. */
  .ltab .anr{font-size:12px; white-space:normal; overflow-wrap:anywhere}
  .ltab .objsp .kunde{display:none}
}

/* Die AVOR-Punkte als Zeichen - in der Liste wie auf der Auftragsseite. */
.ms-punkt{display:inline-grid; place-items:center; width:22px; height:22px; border-radius:6px;
  font-size:12px; font-weight:700; line-height:1}
.ms-punkt.ok{color:var(--ok); background:var(--ok-bg)}
.ms-punkt.run{color:var(--run); background:var(--run-bg)}
.ms-punkt.idle{color:var(--idle); background:var(--idle-bg)}
/* Ein Punkt, den die Anlageart nicht kennt - die Spalte bleibt, damit die
   Zeile nicht unter den falschen Kopf rutscht. */
.ms-punkt.leer{background:none}

/* Die offenen Pendenzen in ihrer eigenen Spalte: was die Anlage aufhaelt in
   Rot mit Zeichen, der Rest grau. Die Spalte schneidet am rechten Rand ab -
   eine Zeile je Anlage ist mehr wert als der ganze Satz, und der steht im
   title und auf der Anlagenseite.

   **Das Zeichen bekommt eine feste Breite und faellt nicht mit um.** Sonst
   ruecken die Titel je nach Zeichenbreite verschieden weit ein, und die Spalte
   waere zwar ausgerichtet, der Text darin aber wieder nicht.

   Auf dem Handy fehlt die Breite dafuer: dort bricht die Spalte um und die
   Pendenzen stehen untereinander, statt unsichtbar abgeschnitten zu werden. */
.ltab .pendtext{color:var(--ink-3); font-size:12px}
.ltab .pendtext + .pendtext{margin-left:8px}
.ltab .pendtext + .pendtext::before{content:"· "; color:var(--line)}
.ltab .pendtext.auf{color:var(--blk); font-weight:500}
.ltab .pendtext.auf svg{width:13px; height:13px; margin-right:4px; vertical-align:-.15em; flex:none}
@media (max-width:640px){
  /* max-width:0 ist der Kniff, mit dem die Spalte in einer Tabelle ueberhaupt
     kuerzen kann. Sobald umgebrochen statt gekuerzt wird, presst genau dieser
     Kniff die Spalte auf ein Wort je Zeile zusammen - hier muss er weg. */
  .ltab .objsp{white-space:normal; max-width:none; width:auto}
  .ltab .pendsp{white-space:normal; max-width:none; width:auto}
  /* Umbruch notfalls mitten im Wort: sonst bestimmt das laengste Wort der
     Pendenz, wie breit die Spalte mindestens sein muss. */
  .ltab .pendtext{display:block; margin-top:2px; line-height:1.4; overflow-wrap:anywhere}
  .ltab .pendtext + .pendtext{margin-left:0}
  .ltab .pendtext + .pendtext::before{content:none}
  /* Drei Zeilen, dann Schluss. Ohne Deckel wird aus einer Zeile je Anlage auf
     dem Handy ein Absatz je Anlage, und die Liste ist nicht mehr zu
     ueberfliegen. Der ganze Satz steht im title und auf der Anlagenseite. */
  .ltab .pendliste{display:-webkit-box; -webkit-box-orient:vertical;
    -webkit-line-clamp:3; line-clamp:3; overflow:hidden}
}

/* ---------------- Einklappbare Abschnitte ----------------
   Die Ueberschrift ist der Griff. Ohne JavaScript funktioniert das ebenso,
   nur merkt sich der Browser dann nicht, was zu war. */
.abschnitt > summary{list-style:none; cursor:pointer}
.abschnitt > summary::-webkit-details-marker{display:none}
.abschnitt > summary::after{content:"▾"; font-size:11px; color:var(--ink-3);
  margin-left:8px; transition:transform .15s; display:inline-block}
.abschnitt:not([open]) > summary::after{transform:rotate(-90deg)}
.abschnitt > summary:hover h2{color:var(--ink-2)}
.abschnitt > summary .hinweis{margin-left:auto}

/* ---------------- Termine ----------------
   Die Terminzeile steht auf der Anlagenseite und auf der Startseite - darum
   hier und nicht mehr in der Vorlage. */
.tzeile{display:flex; gap:11px; align-items:flex-start; padding:10px 12px; border-bottom:1px solid var(--line-soft)}
.tzeile:last-child{border-bottom:0}
.tdatum{flex:none; width:104px; line-height:1.3}
.tdatum b{display:block; font-size:12.5px; font-weight:600; font-family:"IBM Plex Mono",monospace}
.tdatum span{display:block; font-size:10.5px; color:var(--ink-3)}
.tinhalt{flex:1; min-width:0}
.ttitel{font-size:13.5px; font-weight:500; line-height:1.4}
.tnotiz{font-size:12px; color:var(--ink-2); margin-top:2px; line-height:1.4}
.tzeile.vorbei .tdatum b, .tzeile.vorbei .ttitel{color:var(--ink-3); font-weight:400}
.tweg{color:var(--ink-3); padding:2px; flex:none; line-height:0}
.tweg:hover{color:var(--blk)}
.tvergangen > summary{font-size:12px; color:var(--ink-3); cursor:pointer; padding:9px 12px;
  border-top:1px solid var(--line-soft)}
.tvergangen[open] > summary{border-bottom:1px solid var(--line-soft)}
.pbearbeiten > summary{font-size:11.5px; color:var(--accent); cursor:pointer; margin-top:5px; width:fit-content}
.pbearbeiten[open] > summary{margin-bottom:2px}

/* ---------------- Aufgaben ----------------
   Arbeiten ohne Anlage. Die Zeile ist dieselbe wie bei den Pendenzen
   (.pzeile/.haken/.ptext), dazu kommt nur, was Aufgaben eigenes haben. */
.anotiz{font-size:12px; color:var(--ink-2); margin-top:2px; line-height:1.4}
.pmeta .faellig{color:var(--blk); font-weight:600}
.pmeta .frei{color:var(--ink-3)}
/* Was ueberfaellig ist, traegt denselben roten Streifen wie eine blockierende
   Pendenz - auf der Startseite ist er das einzige Zeichen dafuer, dort gibt es
   kein Fach darum. */
.pzeile.spaet{border-left:3px solid var(--blk); padding-left:9px}

/* ---------------- Fortschritt der Verkabelung ----------------
   Die laengste Phase einer Anlage; ohne diese Zahl steht in jeder Liste
   wochenlang «Verkab.» und sonst nichts. Der Wert wird von Hand gesetzt
   (VERKABELUNG_STUFEN in domain.js) und nur in dieser Phase gezeigt.

   **Nicht `.balken` und nicht `.bahn` nennen** - beide Namen sind in diesem
   flachen Stylesheet schon vergeben, `.bahn` sogar fuer genau so einen
   Fortschrittsbalken an anderer Stelle. */
.verkstand{border:1px solid var(--line); background:var(--surface); border-radius:11px;
  padding:11px 13px; margin-top:11px}
.verkkopf{display:flex; align-items:baseline; justify-content:space-between; gap:10px;
  margin-bottom:7px}
.verklabel{font-family:"IBM Plex Sans Condensed","IBM Plex Sans",sans-serif; font-size:11px;
  font-weight:700; text-transform:uppercase; letter-spacing:.1em; color:var(--ink-3)}
.verkwert{font-size:15px; font-weight:600; letter-spacing:-.02em; display:flex;
  align-items:baseline; gap:7px}
.verkwort{font-size:12px; font-weight:400; color:var(--ink-3)}
.verkbahn{display:block; height:8px; border-radius:5px; background:var(--surface-3);
  overflow:hidden}
.verkfuell{display:block; height:100%; border-radius:5px; background:var(--run);
  transition:width .2s}
/* Voll ist gruen, nicht orange - «fertig» heisst in dieser Anwendung ueberall
   gruen, und ein oranger Vollbalken laese sich als «noch dran» lesen. */
.verkfuell[style*="width:100%"]{background:var(--ok)}
.verkwahl{display:flex; gap:5px; flex-wrap:wrap; margin-top:9px}
.verkwahl .chip{padding:4px 11px; font-size:12px}

/* Dieselbe Bahn, klein: in der Anlagentabelle unter dem Phasen-Etikett und im
   Statusbericht. Feste Breite, damit die Spalte nicht mitwaechst. */
.verkbahn.mini{width:44px; height:4px; border-radius:3px; margin-top:3px}
.ltab .phasesp{white-space:nowrap; width:1%}
.ltab .phasesp .tag b{font-variant-numeric:tabular-nums}
.btab .verkzelle{white-space:nowrap}
.btab .verkzelle b{font-size:12px; font-variant-numeric:tabular-nums}

/* Fach: Ueberfaellig, Heute, Diese Woche, Spaeter, Ohne Datum. Der Streifen
   links sagt auf einen Blick, wie dringend das Fach ist.

   **Eine Zeile mit eigenem Streifen legt sich darueber**, statt daneben zu
   stehen (`margin-left:-3px` weiter unten). Vorher sah man bei einer
   abgehakten Aufgabe im Fach «Ueberfaellig» zwei Streifen nebeneinander -
   erst das Rot des Fachs, dann das Gruen der Zeile - und die Zeile war
   erledigt und trotzdem rot angestrichen. */
.fach{border-left:3px solid var(--line); overflow:hidden}
.fach.blk{border-left-color:var(--blk)}
.fach.run{border-left-color:var(--run)}
.fach.acc{border-left-color:var(--accent)}
.fach.idle{border-left-color:var(--idle-line)}

/* ---------------- Mounti ----------------
   Der Chat als eigene Seite: eine Spalte in der Mitte, Beitraege untereinander,
   Eingabe unten fest. Dasselbe Muster wie bei ChatGPT und Gemini, weil es dort
   nicht zufaellig so aussieht - man liest von oben nach unten und tippt unten.
   Die Seite fuellt die Hoehe selbst und rollt innen, damit die Eingabe stehen
   bleibt statt mitzuwandern. */
.mounti{display:flex; flex-direction:column; height:calc(100dvh - 132px);
  max-width:760px; margin:0 auto; width:100%}
@media (min-width:900px){ .mounti{height:calc(100dvh - 108px)} }

.mtverlauf{flex:1; overflow-y:auto; display:flex; flex-direction:column; gap:18px;
  padding:4px 2px 18px}

/* Begruessung, solange nichts gefragt wurde - mit dem Maskottchen.
   Er steht auf keinem Grund und wirft keinen Schatten: das Bild ist
   durchsichtig freigestellt und sitzt damit im hellen wie im dunklen Modus
   richtig. Die Hoehe richtet sich nach der Fensterhoehe, weil unter ihm noch
   drei Vorschlaege und die Eingabe Platz brauchen. */
.mtstart{margin:auto 0; text-align:center; padding:12px 8px}
.mtmaskottchen{height:clamp(84px, 16vh, 150px); width:auto; margin:0 auto 8px;
  -webkit-user-select:none; user-select:none; -webkit-user-drag:none}
.mtstart h1{font-size:23px; font-weight:600; letter-spacing:-.02em; margin-bottom:7px}
.mtstart p{font-size:13.5px; color:var(--ink-3); line-height:1.6; max-width:46ch; margin:0 auto}
.mtfehlt{margin-top:14px !important; color:var(--blk) !important}
.mtvorschlaege{display:flex; flex-direction:column; gap:7px; max-width:380px; margin:16px auto 0}
.mtvorschlaege button{border:1px solid var(--line); background:var(--surface); border-radius:10px;
  padding:10px 13px; font-size:13px; color:var(--ink-2); text-align:left}
.mtvorschlaege button:hover{border-color:var(--accent-2); color:var(--accent)}

/* Die Frage rechts als Blase, die Antwort ueber die volle Breite - so trennt
   ChatGPT die beiden Seiten, und es liest sich ruhiger als zwei Blasen. */
.mtfrage{align-self:flex-end; max-width:80%; background:var(--accent-soft); color:var(--accent);
  border-radius:16px 16px 4px 16px; padding:10px 14px; font-size:14px; line-height:1.55;
  font-weight:500; white-space:pre-wrap}
.mtantwort{font-size:14.5px; line-height:1.68; color:var(--ink); white-space:pre-wrap}
.mtantwort.fehler{color:var(--blk); background:var(--blk-bg); border:1px solid var(--blk-line);
  border-radius:11px; padding:10px 13px}
.mtantwort a{text-decoration:underline}
.mtmodell{font-size:11px; color:var(--ink-3); margin-top:8px}

/* Mounti steht neben jeder Antwort - **als Pseudo-Element, nicht als Kind**.
   `verweise()` in app.js baut den Inhalt der Blase aus ihrem eigenen Text neu
   auf (textContent = "" und dann Stueck fuer Stueck); ein echtes Kind waere
   dabei jedes Mal weg. So kostet der Kopf ausserdem keine Zeile JavaScript. */
.mtantwort, .mtdenkt{position:relative; padding-left:40px; min-height:28px}
.mtantwort::before, .mtdenkt::before{
  content:""; position:absolute; left:0; top:0; width:28px; height:28px;
  border-radius:50%; background:var(--accent-soft) url("/img/mounti-kopf.png") 50% 58%/23px no-repeat;
}
.mtantwort.fehler{padding-left:40px}
.mtantwort.fehler::before{left:8px; top:8px}

/* Drei Punkte, solange gewartet wird. */
.mtdenkt{display:flex; gap:5px; align-items:center; padding:4px 0 4px 40px}
.mtdenkt span{width:7px;height:7px;border-radius:50%;background:var(--ink-3);
  animation:mtpuls 1.2s infinite ease-in-out}
.mtdenkt span:nth-child(2){animation-delay:.15s}
.mtdenkt span:nth-child(3){animation-delay:.3s}
@keyframes mtpuls{0%,60%,100%{opacity:.25} 30%{opacity:1}}

.mteingabe{flex:none; padding-top:6px}
.mtfeld{display:flex; align-items:flex-end; gap:8px; background:var(--surface);
  border:1px solid var(--line); border-radius:16px; padding:8px 8px 8px 14px;
  box-shadow:var(--schatten)}
.mtfeld:focus-within{border-color:var(--accent-2)}
.mtfeld textarea{flex:1; border:0; background:none; padding:6px 0; resize:none; font-size:14.5px;
  line-height:1.5; max-height:180px; box-shadow:none}
.mtfeld textarea:focus{outline:none; box-shadow:none}
.mtsenden{flex:none; display:grid; place-items:center; width:34px; height:34px; border-radius:50%;
  background:var(--accent); color:var(--auf-accent)}
.mtsenden:disabled{background:var(--surface-3); color:var(--ink-3)}
.mtsenden svg{width:17px;height:17px}
.mtfuss{display:flex; align-items:center; gap:10px; flex-wrap:wrap;
  font-size:11.5px; color:var(--ink-3); margin-top:8px; padding:0 4px}
.mtneu{font-size:11.5px; color:var(--accent); font-weight:500}
.mtneu:hover{text-decoration:underline}

/* Die gepflegten Auswahllisten unter «Team»: je Eintrag eine Zeile mit den
   Feldern nebeneinander, darunter die Knoepfe, die nicht zum Formular gehoeren
   (eigene Formulare - ein Formular im Formular gibt es in HTML nicht). */
.listenzeile{padding:11px 12px 4px; border-top:1px solid var(--line-soft)}
.karte > .listenzeile:first-child{border-top:0}
.listenfelder{display:flex; gap:9px; flex-wrap:wrap}
.listenfelder > .feld{flex:1; min-width:150px; margin-bottom:8px}
.listenfelder > .feld.schmal{flex:0 1 130px}
.listenknoepfe{display:flex; align-items:center; gap:9px; flex-wrap:wrap; padding-bottom:4px}
.listenknoepfe .hinweis{margin-left:auto}
.listenzusatz{display:flex; gap:7px; flex-wrap:wrap; padding:0 12px 11px}

/* Erfassen: zwei schmale Zeilen. Oben der Titel mit dem Knopf, unten das
   Freiwillige in kleiner Schrift. Auf dem Handy klappt app.js das Ganze zu -
   dort zaehlt die Liste, nicht das Formular. */
.aufgabeneu{margin-bottom:11px; padding:11px 12px}
.aufgabeneu > summary.neukopf{list-style:none; cursor:pointer; display:flex; align-items:center;
  gap:7px; font-size:13.5px; font-weight:600; color:var(--accent)}
.aufgabeneu > summary.neukopf::-webkit-details-marker{display:none}
.aufgabeneu[open] > summary.neukopf{margin-bottom:10px}
.neuzeile{display:flex; gap:8px; align-items:center; flex-wrap:wrap}
.neuzeile + .neuzeile{margin-top:8px}
.neuzeile .titelfeld{flex:1; min-width:180px}
.neuzeile .knopf{flex:none}
.neuzeile.fein{gap:6px 14px; font-size:12px; color:var(--ink-3)}
.minifeld{display:flex; align-items:center; gap:6px; min-width:0}
.minifeld > span{font-size:11.5px; font-weight:600; color:var(--ink-2); white-space:nowrap}
.minifeld input, .minifeld select{padding:5px 8px; font-size:12.5px; width:auto; min-width:0}
.minifeld select{max-width:150px}

/* Formularfelder in der Import-Vorschau und im Aufgabenformular */
.aufgabenfelder{display:grid; gap:9px; grid-template-columns:1fr; align-items:end}
.aufgabenfelder .feld{margin-bottom:0}

/* Schnelleingabe auf der Startseite: eine Zeile, ein Knopf. */
.schnellaufgabe{display:flex; gap:8px; padding:10px 12px; border-top:1px solid var(--line-soft)}
.schnellaufgabe input{flex:1; min-width:0}
.schnellaufgabe .knopf{flex:none}
.mehr{display:block; font-size:12.5px; font-weight:600; color:var(--accent);
  padding:9px 12px; border-top:1px solid var(--line-soft)}
.hilfetext{font-size:12px; color:var(--ink-3); line-height:1.5; margin:14px 2px 0}

/* Kacheln in den Phasenfarben - dieselben wie in der Verteilung darunter. */
.kpi.avor .streifen{background:var(--accent)} .kpi.avor .n{color:var(--accent)}
.kpi.verk .streifen{background:var(--run)} .kpi.verk .n{color:var(--run)}
.kpi.bereit .streifen{background:var(--idle)} .kpi.bereit .n{color:var(--ink-2)}

/* ---------------- Import aus der Auftragsliste ----------------
   Eine Karte je Anlage: oben die Auswahl mit Herkunft aus der Excel-Zeile,
   darunter die Felder zum Nachbessern. Auf dem Handy stapelt sich alles. */
.impkopfzeile{display:flex; gap:12px; flex-wrap:wrap; align-items:flex-end; margin-bottom:4px}
.impknoepfe{display:flex; gap:8px; flex-wrap:wrap; margin-left:auto; align-items:center}
.impzeile{padding:11px 12px; margin-bottom:9px}
.impwahl{display:flex; gap:9px; align-items:baseline; flex-wrap:wrap; cursor:pointer; margin-bottom:9px}
.impwahl input{flex:none; width:18px; height:18px; align-self:center}
.impid{font-size:13.5px; font-weight:600}
.impmeta{font-size:11px; color:var(--ink-3); flex:1; min-width:0}
.impinfo{font-size:11.5px; color:var(--ink-3); margin-top:7px; line-height:1.45}
.impfelder{display:grid; gap:9px; grid-template-columns:1fr; margin-bottom:9px}
.impfelder .feld{margin-bottom:0}
@media (min-width:700px){
  .impfelder{grid-template-columns:repeat(auto-fit,minmax(150px,1fr))}
  .impfelder .feld.schmal{max-width:170px}
}
/* ---------------- Abgleich mit der MSR-Liste ----------------
   Eine Zeile je Unterschied: was in der PPS steht, was die Liste sagt, und
   woher sie es hat. */
.difflist{list-style:none; display:grid; gap:2px; margin:2px 0 4px}
.diffzeile{border-radius:7px; padding:5px 7px}
.diffzeile:hover{background:var(--surface-3)}
.diffzeile > label{display:flex; gap:8px; align-items:baseline; flex-wrap:wrap;
  cursor:pointer; font-size:12.5px}
.diffzeile input[type="checkbox"]{flex:none; width:17px; height:17px; align-self:center}
.diffname{font-weight:600; min-width:110px}
.diffvon{color:var(--ink-3); text-decoration:line-through}
.diffpfeil{color:var(--ink-3)}
.diffnach{font-weight:600; color:var(--ok)}
.diffwoher{font-size:11px; color:var(--ink-3); margin-left:auto}
.diffsperre{font-size:11px; color:var(--ink-3); margin:3px 0 0 25px; line-height:1.45}
.diffzeile.gesperrt{opacity:.55}
.diffzeile.gesperrt > label{cursor:default}
/* Ein Hinweis, den man gelesen haben muss, bevor man das Feld darunter
   ausfuellt - kein Fehler, aber auch keine Nebensache. */
.warnkasten{display:flex; gap:8px; align-items:flex-start; font-size:12px; line-height:1.6;
  color:var(--run); background:var(--run-bg); border:1px solid var(--run-line);
  border-radius:8px; padding:8px 10px; margin-bottom:12px}
.warnkasten svg{width:15px; height:15px; flex:none; margin-top:2px}

/* Wann zuletzt abgeglichen wurde - die erste Frage beim Wochenlauf. */
.importstand{display:flex; gap:7px; align-items:center; font-size:12px; color:var(--ink-2);
  background:var(--surface-3); border-radius:7px; padding:7px 9px; margin-bottom:11px}
.importstand svg{width:14px; height:14px; flex:none; opacity:.7}
/* Ein Feld, das man selten braucht: zugeklappt, aber auffindbar. */
.klappfeld{margin-bottom:11px}
.klappfeld > summary{cursor:pointer; font-size:12px; color:var(--accent); font-weight:500;
  list-style:none; padding:3px 0}
.klappfeld > summary::-webkit-details-marker{display:none}
.klappfeld > summary::before{content:"▸ "; font-size:10px}
.klappfeld[open] > summary::before{content:"▾ "}

/* ---------------- Loses Material: der Konfigurator ----------------
   Eine Zeile je Geraet mit Stueckzahl-Stepper, die Gruppen als <details>.
   Unten eine feste Leiste mit der Zahl der Positionen und dem Knopf - auf dem
   Handy soll man nicht zurueckrollen muessen, um abzuschliessen. */
.lsform{padding-bottom:70px}
/* .nur-mit-js zeichnet Knoepfe als inline-flex - die Suchkarte braucht die volle Breite. */
html.js .lssuchkarte{display:block; padding:8px 10px}
.lssuche{width:100%; font-size:14px; padding:9px 11px; border:1px solid var(--line); border-radius:8px;
  background:var(--surface); color:var(--ink)}
.lsgruppe{margin-bottom:9px}
.lsgruppe > summary{list-style:none; cursor:pointer; display:flex; align-items:center; gap:8px;
  font-size:11.5px; font-weight:700; letter-spacing:.06em; text-transform:uppercase;
  color:var(--ink-3); padding:8px 2px 5px}
.lsgruppe > summary::-webkit-details-marker{display:none}
.lsgruppe > summary::before{content:"▸"; font-size:10px}
.lsgruppe[open] > summary::before{content:"▾"}
.lszahl{margin-left:auto; font-size:11px; font-weight:600; color:var(--accent); text-transform:none; letter-spacing:0}
/* Die Zeilen sind bewusst knapp: der Katalog hat gegen fuenfzig Geraete, und
   wer eine Kiste packt, will moeglichst viele davon auf einmal sehen. Die
   Stepper bleiben trotzdem 30px hoch - darunter trifft man sie mit dem Finger
   nicht mehr zuverlaessig. */
.lszeile{display:flex; align-items:center; gap:8px; padding:4px 10px; border-top:1px solid var(--line-soft)}
.lszeile:first-child{border-top:0}
.lszeile.gewaehlt{background:var(--accent-soft)}
.lstext{flex:1; min-width:0}
.lstyp{display:block; font-size:12px; font-weight:600; line-height:1.3}
.lsbeschreibung{display:block; font-size:11px; color:var(--ink-2); line-height:1.3}
.lshersteller{color:var(--ink-3)}
.lshersteller::before{content:" · "}
/* Ab Tablet steht die Beschreibung neben dem Typ statt darunter: eine Zeile
   je Geraet, und aufs Mal sieht man doppelt so viele. Auf dem Handy waere
   dafuer kein Platz - dort bleibt es bei zwei Zeilen. */
@media (min-width:700px){
  .lstext{display:flex; flex-wrap:wrap; align-items:baseline; column-gap:8px}
  .lstyp{line-height:1.35}
  .lsbeschreibung{line-height:1.35}
}
.lsstepper{display:flex; align-items:center; gap:4px; flex:none}
.lsstepper input{width:42px; text-align:center; padding:5px 3px; font-size:13px; font-weight:600;
  border:1px solid var(--line); border-radius:7px; background:var(--surface); color:var(--ink);
  -moz-appearance:textfield}
.lsstepper input::-webkit-inner-spin-button, .lsstepper input::-webkit-outer-spin-button{-webkit-appearance:none; margin:0}
/* Die beiden Knoepfe: das Zeichen wird ueber flex mittig gesetzt, nicht ueber
   line-height - ein «−» und ein «+» haben verschiedene Hoehen, und mit einer
   festen Zeilenhoehe sitzt immer eines von beiden daneben. */
.lsknopf{width:30px; height:30px; flex:none; padding:0; cursor:pointer;
  display:inline-flex; align-items:center; justify-content:center;
  border:1px solid var(--line); border-radius:8px; background:var(--surface-3);
  color:var(--ink-2); font-size:16px; font-weight:600; line-height:1;
  transition:background .12s, border-color .12s, color .12s}
.lsknopf:hover{background:var(--accent-soft); border-color:var(--accent-2); color:var(--accent)}
.lsknopf:active{background:var(--accent-soft); border-color:var(--accent); color:var(--accent)}
.lsleer{font-size:12.5px; color:var(--ink-3); padding:8px 4px}
.lsaufnehmen{display:flex; gap:7px; align-items:center; font-size:12px; color:var(--ink-2); margin-bottom:6px}
.lsaufnehmen input{width:16px; height:16px}
/* Lieferadresse: PLZ schmal, Ortschaft nimmt den Rest. */
.lsplzort{display:grid; grid-template-columns:110px 1fr; gap:10px}

/* Anderes Geraet: oben die Liste des schon Erfassten, darunter der eine Block.
   Die Liste sieht aus wie eine Quittung - kurze Zeilen, je eine zum Wegwerfen. */
.freiliste{list-style:none; margin:0 0 12px; padding:0; display:grid; gap:1px}
.freiliste:empty{display:none}
.freizeile{display:flex; align-items:flex-start; gap:9px; padding:6px 9px; font-size:12.5px;
  background:var(--surface-2); border:1px solid var(--line-soft); border-radius:8px}
.freianzahl{flex:none; font-weight:600; font-variant-numeric:tabular-nums; color:var(--accent)}
.freitext{flex:1; min-width:0; line-height:1.35}
.freiunten{display:block; font-size:11.5px; color:var(--ink-3); line-height:1.3}
.freiunten:empty{display:none}
.freizeile .tweg{line-height:1; font-size:13px; padding:2px 4px; align-self:center}
.freihilfe{font-size:12px; color:var(--ink-3); margin-bottom:9px; line-height:1.45}
.lsleiste{position:fixed; left:0; right:0; bottom:calc(58px + env(safe-area-inset-bottom,0px)); z-index:25;
  display:flex; align-items:center; justify-content:space-between; gap:12px;
  padding:9px 14px; background:var(--surface); border-top:1px solid var(--line)}
@media (min-width:900px){ .lsleiste{left:206px; bottom:0} .app.railzu .lsleiste{left:64px} }
.lssumme{font-size:13px; color:var(--ink-2)}
.lssumme b{font-size:16px; color:var(--ink)}

/* Bilderkennung: Knopf und Vorschlagsliste unter dem Fotofeld.
   .nur-mit-js zeichnet als inline-flex - der Kasten braucht die volle Breite. */
html.js .lserk{display:block; margin-top:11px; padding-top:10px; border-top:1px solid var(--line-soft)}
.lserkkopf{display:flex; align-items:center; gap:10px; flex-wrap:wrap}
.lserk .knopf:disabled{opacity:.5; cursor:default}
.lserkstand{font-size:12px; color:var(--ink-3)}
.lserkstand.gut{color:var(--ok)}
.lserkstand.warnung{color:var(--blk)}
.lserkliste{margin-top:9px; border:1px solid var(--line); border-radius:8px; overflow:hidden}
.lserkliste.uebernommen{opacity:.6}
.lserkzeile{display:flex; align-items:flex-start; gap:9px; padding:8px 10px; font-size:12.5px;
  border-top:1px solid var(--line-soft); cursor:pointer}
.lserkzeile:first-child{border-top:0}
.lserkzeile.unsicher{background:var(--run-bg)}
.lserkzeile input{width:16px; height:16px; flex:none; margin:2px 0 0}
.lserkanzahl{flex:none; font-weight:600; font-variant-numeric:tabular-nums; color:var(--accent)}
.lserktext{min-width:0}
.lserkunten{display:block; font-size:11.5px; color:var(--ink-3); line-height:1.35}
.lserkanmerkung{font-size:11.5px; color:var(--ink-2); padding:8px 10px; background:var(--surface-2);
  border-top:1px solid var(--line-soft)}
.lserkfuss{display:flex; gap:8px; padding:9px 10px; border-top:1px solid var(--line-soft)}

/* Verwaltung: stillgelegte Geraete bleiben sichtbar, aber gedaempft. */
.katalogzeile.stillgelegt{opacity:.55}

.diffwarnung{display:flex; gap:7px; align-items:flex-start; font-size:11.5px;
  color:var(--blk); background:var(--blk-bg); border-radius:7px; padding:6px 8px; margin-bottom:7px}
.diffwarnung svg{width:14px; height:14px; flex:none; margin-top:1px}

.meldung.fehler{background:var(--blk-bg); color:var(--blk); border-color:var(--blk-line)}

/* Abgehakte Aufgabe: bleibt stehen, wird gruen und traegt einen Wegwerf-Knopf.
   Nur die Aufgabe - eine erledigte Pendenz an der Anlage sieht weiter aus wie bisher.
   Der negative Rand links zieht den gruenen Streifen ueber den roten des
   Fachs; ohne ihn stuenden beide nebeneinander. */
.pzeile.aufgabe.erledigt{background:var(--ok-bg); border-left:3px solid var(--ok); padding-left:9px}
.pzeile.aufgabe.erledigt .ptext{color:var(--ink-2)}
/* **Nur im Fach.** Auf der Startseite stehen dieselben Zeilen in einer
   gewoehnlichen Karte ohne Streifen - dort raegte der negative Rand die Zeile
   drei Pixel aus der Karte heraus. */
.fach > .pzeile.aufgabe.erledigt, .fach > .pzeile.aufgabe.spaet{margin-left:-3px}
.pzeile.aufgabe .vonwem{color:var(--ok)}

/* Der Wegwerf-Knopf steht rechts in der Zeile und meldet sich erst, wenn man
   hinzeigt - er ist die Ausnahme, nicht der naechste Schritt. Auf einem
   Bildschirm ohne Zeiger ist er dauerhaft sichtbar, sonst waere er gar nicht
   zu finden. */
.wegform{flex:none; margin-left:auto; align-self:flex-start}
.wegknopf{display:grid; place-items:center; width:28px; height:28px; border-radius:8px;
  color:var(--ink-3); opacity:.45; transition:opacity .12s, color .12s, background .12s}
.wegknopf svg{width:15px; height:15px; display:block}
.pzeile:hover .wegknopf, .wegknopf:focus-visible{opacity:1}
.wegknopf:hover{color:var(--blk); background:var(--blk-bg); opacity:1}
@media (hover:none){ .wegknopf{opacity:.7} }
.freiwillig{font-weight:400; color:var(--ink-3)}
.schnelldatum{display:flex; gap:5px; flex-wrap:wrap}
.schnelldatum .chip{padding:3px 9px; font-size:11.5px}


/* ---------------------------------- Quiz ----------------------------------
   Alle Klassen hier tragen den Vorsatz `quiz`, und die Kindklassen stehen
   ausschliesslich geschachtelt (`.quizantwort .text`). Das Stylesheet ist
   flach und ohne Namensraeume: ein bares `.text` waere eine Regel, die auf
   jeder Seite gilt - genau die Falle, die `.balken` und `.marke` schon
   zweimal gestellt haben.

   Zielgeraet ist das Handy: eine Frage pro Seite, jede Antwort ein grosser
   Knopf, den man mit dem Daumen trifft. */

/* Die Schrittleiste auf der Uebersicht: eine Zeile je Frage, aber nur mit
   Kategorie - der Fragetext darf hier nicht stehen, sonst laesst sich die
   Zeitmessung umgehen (siehe routes/quiz.js). */
.quizschritte{list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:5px}
.quizschritt a{display:flex; align-items:center; gap:10px; padding:9px 11px;
  border:1px solid var(--line); border-left:3px solid var(--idle);
  border-radius:9px; background:var(--surface-2); color:inherit; text-decoration:none}
.quizschritt a:hover{border-color:var(--ink-3); text-decoration:none}
.quizschritt .nr{font-family:"IBM Plex Mono",monospace; font-weight:600; color:var(--ink-3);
  width:16px; flex:none}
.quizschritt .kat{flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis;
  white-space:nowrap; font-weight:500}
.quizschritt .stand{font-size:12px; font-weight:600; color:var(--ink-3); flex:none}
.quizschritt.ok a{border-left-color:var(--ok); background:var(--ok-bg)}
.quizschritt.ok .stand{color:var(--ok)}
.quizschritt.blk a{border-left-color:var(--blk); background:var(--blk-bg)}
.quizschritt.blk .stand{color:var(--blk)}
.quizschritt.gesperrt a{border-left-color:var(--idle); opacity:.6}

.quizweiter{margin-top:11px; width:100%; justify-content:center}
.quizfertig{margin-top:11px; font-size:13px; color:var(--ok); display:flex; align-items:center; gap:6px}
.quizfertig svg{width:16px; height:16px; flex:none}

/* «Frage stimmt nicht» - unten in der Karte, leise: es ist der Notausgang
   und nicht die Hauptsache. Die Karte mit «x von y richtig in der Abteilung»
   stand einmal hier; sie ist auf Wunsch der Abteilung weg, die Rangliste
   steht unter /quiz/rangliste. */
.quizmelden{margin-top:16px; padding-top:12px; border-top:1px solid var(--line-soft)}
.quizmelden .knopf{color:var(--ink-3)}
.quizmelden .knopf:hover{color:var(--blk); border-color:var(--blk-line)}
.quizgemeldet{margin-top:16px; padding-top:12px; border-top:1px solid var(--line-soft);
  display:flex; align-items:center; gap:7px; font-size:12.5px; color:var(--run)}
.quizgemeldet svg{width:15px; height:15px; flex:none}

/* ---- Die Frageseite ---- */
.quizfrage .quizkopf{display:flex; align-items:center; justify-content:space-between;
  gap:10px; margin-bottom:10px}
.quizfrage .chip.ok{background:var(--ok-bg); border-color:var(--ok-line); color:var(--ok)}
.quizfrage .chip.blk{background:var(--blk-bg); border-color:var(--blk-line); color:var(--blk)}
.quiztext{font-size:19px; line-height:1.35; margin:0 0 14px}

/* Der Bonusbalken. Reine Anzeige - gerechnet wird auf dem Server. Ohne
   JavaScript bleibt er auf hundert Prozent stehen und die Regel steht als
   Satz darunter. */
.quizbonus{display:flex; align-items:center; gap:9px; margin-bottom:6px}
.quizbahn{flex:1; height:8px; border-radius:5px; background:var(--surface-3);
  overflow:hidden; border:1px solid var(--line-soft)}
.quizfuell{display:block; height:100%; width:100%; background:var(--accent);
  transition:width .95s linear}
.quizfuell.warm{background:var(--run)}
.quizfuell.leer{background:var(--idle)}
.quizbonuszahl{font-family:"IBM Plex Mono",monospace; font-weight:600; font-size:13px;
  color:var(--ink-2); flex:none; min-width:62px; text-align:right}
.quizregel{margin-bottom:14px}

/* Jede Antwort ist ein Absendeknopf: ein Tipp statt Ankreuzen und Abschicken.
   Bei laufender Uhr ist das der Unterschied zwischen ueberlegen und hetzen. */
.quizantworten{display:flex; flex-direction:column; gap:8px; list-style:none; margin:0; padding:0}
.quizantwort{display:flex; align-items:center; gap:11px; width:100%; text-align:left;
  padding:13px 13px; border:1px solid var(--line); border-radius:11px;
  background:var(--surface-2); color:var(--ink); font:inherit; font-size:15px; cursor:pointer}
.quizantwort:hover{border-color:var(--accent); background:var(--accent-soft)}
.quizantworten.aufgeloest .quizantwort{cursor:default}
.quizantworten.aufgeloest .quizantwort:hover{border-color:var(--line); background:var(--surface-2)}
.quizantwort .buchstabe{font-family:"IBM Plex Mono",monospace; font-weight:600;
  width:24px; height:24px; flex:none; display:grid; place-items:center; border-radius:50%;
  background:var(--surface-3); color:var(--ink-2); font-size:12.5px}
.quizantwort .text{flex:1; min-width:0}
.quizantwort .zeichen{flex:none; font-size:11.5px; font-weight:600; color:var(--ink-3);
  display:flex; align-items:center}
.quizantwort .zeichen svg{width:17px; height:17px}
.quizantwort.ok{border-color:var(--ok-line); background:var(--ok-bg)}
.quizantwort.ok .buchstabe,.quizantwort.ok .zeichen{background:transparent; color:var(--ok)}
.quizantwort.blk{border-color:var(--blk-line); background:var(--blk-bg)}
.quizantwort.blk .buchstabe,.quizantwort.blk .zeichen{background:transparent; color:var(--blk)}

.quizloesung{margin-top:14px; font-size:14.5px; font-weight:500}
.quizloesung.ok{color:var(--ok)}
.quizloesung.blk{color:var(--blk)}
.quizerklaerung{margin-top:7px; font-size:13.5px; color:var(--ink-2);
  border-left:3px solid var(--line); padding-left:11px}

/* ---- Die Rangliste ----
   Sie benutzt die Tabelle des Statusberichts (`.btab`) und ergaenzt nur die
   Rechtsausrichtung und die eigene Zeile. */
.quizrang .r{text-align:right}
.quizrang tr.ich td{background:var(--accent-soft)}
.quizrang tr.ich td:first-child{box-shadow:inset 3px 0 0 var(--accent)}

@media (min-width:700px){
  .quiztext{font-size:22px}
  .quizweiter{width:auto}
}

/* Die Quizkarte auf der Startseite: Stand links, Knopf rechts. */
.quizkarte{display:flex; align-items:center; justify-content:space-between; gap:12px;
  flex-wrap:wrap; margin-bottom:11px}
.quizkarte .hinweis{margin-top:2px}

/* Der Knopf fuer die weitere Runde, mit dem Grund daneben. Auf dem Handy
   rutscht der Grund unter den Knopf - nebeneinander lief er sonst bis an den
   Rand und wurde umgebrochen, wo es gerade passte. */
.quizrundeform{align-items:center; flex-wrap:wrap; margin-bottom:11px}
.quizrundeform .hinweis{flex-basis:100%}
@media (min-width:560px){
  .quizrundeform .hinweis{flex-basis:auto}
}

/* ---- Quizpflege in der Verwaltung ----
   Eine Frage ist eine Zeile, die sich zum Bearbeiten aufklappt: bei hundert
   Fragen will niemand hundert offene Formulare, und die Zeile allein sagt
   schon, worum es geht und wie oft sie richtig beantwortet wurde. */
.quizpflege{border-bottom:1px solid var(--line-soft); padding:9px 12px}
.quizpflege:last-child{border-bottom:0}
.quizpflege > summary{display:flex; align-items:baseline; gap:10px; cursor:pointer;
  list-style:none; font-size:13.5px}
.quizpflege > summary::-webkit-details-marker{display:none}
.quizpflege > summary::before{content:"›"; color:var(--ink-3); font-weight:700; flex:none}
.quizpflege[open] > summary::before{content:"⌄"}
.quizpflege[open] > summary{font-weight:600}
.quizpflege .frage{flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.quizpflege[open] .frage{white-space:normal}
.quizpflege .stand{flex:none; font-family:"IBM Plex Mono",monospace; font-size:11.5px;
  color:var(--ink-3)}
.quizpflege .stand.blk{color:var(--blk); font-weight:600}

/* Antwort plus Radioknopf fuer «das ist die richtige» - vier davon
   untereinander, damit der Zusammenhang ohne Erklaerung klar ist. */
.quizantwortfeld{display:flex; align-items:center; gap:9px; margin-bottom:5px}
.quizantwortfeld input[type="radio"]{accent-color:var(--ok); width:17px; height:17px;
  margin:0; flex:none}
.quizantwortfeld input[type="text"]{flex:1; min-width:0}
.quizantwortfeld:has(input[type="radio"]:checked) input[type="text"]{
  border-color:var(--ok-line); background:var(--ok-bg)}
.quizmenge{opacity:.6; font-family:"IBM Plex Mono",monospace; font-weight:400}
