:root{--bg:#f2f4f4;--card:#fff;--text:#141a1c;--muted:#67747a;--line:#dde3e4;--primary:#127561;--teal:#7ec8b4;--ok:#1e7d5a;--warn:#b5701a;--bad:#c0392b;--nav:#0e1416;--navtext:#c8d2d4;--r:10px}
@media(prefers-color-scheme:dark){:root{--bg:#0e1416;--card:#161e21;--text:#e8eeef;--muted:#93a1a5;--line:#263134;--nav:#080d0f;--primary:#7ec8b4;--ok:#7ed3ae;--warn:#e0a24f;--bad:#e57373}}
*{box-sizing:border-box;-webkit-tap-highlight-color:transparent}html{overscroll-behavior-y:none;-webkit-text-size-adjust:100%}html,body{margin:0;background:var(--bg);color:var(--text);font:15px/1.45 Arial,Helvetica,-apple-system,Segoe UI,sans-serif}
a{color:var(--primary);text-decoration:none}.hidden{display:none!important}.muted{color:var(--muted)}.small{font-size:12px}.err{color:var(--bad);min-height:1em}
h1{font-size:23px;margin:0 0 4px;font-weight:800;letter-spacing:-.02em}h2{font-size:18px;margin:18px 0 8px;font-weight:800;letter-spacing:-.01em}h3{font-size:15px;margin:12px 0 6px;font-weight:700}
label{text-transform:none}.kpi .l{letter-spacing:.02em}
.app{display:grid;grid-template-columns:220px 1fr;min-height:100vh}
.side{background:var(--nav);color:var(--navtext);padding:16px 10px;display:flex;flex-direction:column;gap:2px;position:sticky;top:0;height:100vh;height:100dvh}
.side .brand{font-weight:800;font-size:21px;letter-spacing:-.01em;color:#fff;padding:6px 10px 16px;letter-spacing:.02em}.side .brand small{display:block;font-size:9.5px;font-weight:600;color:var(--teal);letter-spacing:.22em;text-transform:uppercase;margin-top:3px}
.side a{color:var(--navtext);padding:10px 12px;border-radius:8px;display:flex;align-items:center;gap:8px}
.side a.active,.side a:hover{background:#17252a;color:#fff}.side a.active{box-shadow:inset 3px 0 0 var(--teal)}.side .spacer{flex:1}
.bottom{display:none}
main{padding:18px 20px 90px;max-width:1200px;width:100%}
/* Der Inhaltsbereich: Gruppenreiter oben, darunter die Seite. min-width:0 haelt
   breite Tabellen im Raster, statt die Seitenleiste zu verschieben. */
.inhalt{min-width:0;display:flex;flex-direction:column}
.gruppen{display:flex;gap:4px;flex-wrap:wrap;padding:10px 20px 0;max-width:1200px;width:100%}
.gruppen a{padding:7px 13px;border-radius:8px 8px 0 0;color:var(--muted);font-size:14px;
  border:1px solid transparent;border-bottom:none;white-space:nowrap}
.gruppen a:hover{color:var(--text);background:var(--card)}
.gruppen a.active{background:var(--card);border-color:var(--line);color:var(--text);font-weight:600}
.gruppen:not(.hidden) + main{padding-top:8px}
.card{background:var(--card);border:1px solid var(--line);border-radius:var(--r);padding:14px 16px;margin-bottom:12px}
.grid{display:grid;gap:12px;grid-template-columns:repeat(auto-fill,minmax(180px,1fr))}
.grid2{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(320px,1fr))}
.kpi .v{font-size:24px;font-weight:700}.kpi .l{color:var(--muted);font-size:12px}
.kpi.warn .v{color:var(--warn)}.kpi.bad .v{color:var(--bad)}.kpi.ok .v{color:var(--ok)}
.row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.row.between{justify-content:space-between}.right{text-align:right}
.btn{border:1px solid var(--line);background:var(--card);color:var(--text);padding:8px 12px;border-radius:8px;cursor:pointer;font-size:14px}
.btn.primary{background:var(--primary);border-color:var(--primary);color:#fff}.btn.small{padding:4px 8px;font-size:12px}.btn.danger{color:var(--bad)}
.btn:disabled{opacity:.5}
input,select,textarea{width:100%;padding:9px 10px;font-size:16px;border:1px solid var(--line);border-radius:8px;background:var(--bg);color:var(--text);font:inherit}
#sigForm input[type=color]{width:64px;height:40px;padding:3px;cursor:pointer}
#sigForm input[type=range]{padding:0;border:0;background:transparent}
textarea{min-height:70px}label{display:block;font-size:12px;color:var(--muted);margin:8px 0 3px}
.form{display:grid;gap:4px 12px;grid-template-columns:repeat(auto-fit,minmax(200px,1fr))}.form .full{grid-column:1/-1}
table{width:100%;border-collapse:collapse;font-size:14px}th,td{padding:7px 8px;border-bottom:1px solid var(--line);text-align:left;vertical-align:top}
th{color:var(--muted);font-weight:600;font-size:12px}td.num,th.num{text-align:right;white-space:nowrap}
.tbl{overflow-x:auto}
/* Im Fenster darf nichts an die Seite dahinter durchrutschen: wer am Telefon ans
   Ende der Liste scrollt, schob sonst die ganze Seite darunter weg. */
.modal-box{overscroll-behavior:contain}
/* Vier oder fuenf Spalten passen auf kein Telefon. Statt seitwaerts zu scrollen -
   was man nicht sieht und deshalb nicht tut - wird jede Zeile zu einem Block. */
@media(max-width:700px){
  table.tabstapel,table.tabstapel tbody,tbody.tabstapel{display:block;width:100%}
  table.tabstapel tr,tbody.tabstapel tr{display:block;width:100%;padding:8px 0;
    border-bottom:1px solid var(--line)}
  table.tabstapel td,tbody.tabstapel td{display:block;width:auto;border:0;
    padding:2px 0;text-align:left}
  table.tabstapel td.num,table.tabstapel td.right,
  tbody.tabstapel td.num,tbody.tabstapel td.right{text-align:left}
  table.tabstapel thead,tbody.tabstapel~thead{display:none}
}tr.click{cursor:pointer}tr.click:hover td{background:rgba(126,200,180,.12)}
/* --- Statusfarben ------------------------------------------------------------
   Jeder Projektstatus hat seine eigene Farbe, und die Reihenfolge ergibt einen Weg:
   violett (Angebot) über blau (Auftrag, Konstruktion) und warm (Beschaffung bis
   Montage) nach grün (geliefert) und schliesslich Petrol – abgeschlossen.
   Die Farbe steht je Status einmal in --sf (Flaeche) und --st (Schrift); Chip,
   Registerkarte und Projektkachel greifen alle darauf zu. */
.st{--sf:var(--line);--st:var(--muted)}
.angebot       {--sf:#ede9fe;--st:#5b21b6}
.beauftragt    {--sf:#e0e7ff;--st:#3730a3}
.konstruktion  {--sf:#dbeafe;--st:#1d4ed8}
.beschaffung   {--sf:#e0f2fe;--st:#075985}
.fertigung     {--sf:#fef3c7;--st:#92400e}
.montage       {--sf:#ffedd5;--st:#9a3412}
.inbetriebnahme{--sf:#ecfccb;--st:#3f6212}
.geliefert     {--sf:#dcfce7;--st:#166534}
.abgerechnet   {--sf:#d1fae5;--st:#065f46}
.abgeschlossen {--sf:#ccfbf1;--st:#0f766e}   /* Petrol */
.storniert     {--sf:#fee2e2;--st:#991b1b}
@media(prefers-color-scheme:dark){
  .angebot       {--sf:#2e2454;--st:#c4b5fd}
  .beauftragt    {--sf:#23285c;--st:#a5b4fc}
  .konstruktion  {--sf:#17335c;--st:#93c5fd}
  .beschaffung   {--sf:#0d3b52;--st:#7dd3fc}
  .fertigung     {--sf:#4a3413;--st:#fcd34d}
  .montage       {--sf:#4a2c13;--st:#fdba74}
  .inbetriebnahme{--sf:#2e3d15;--st:#bef264}
  .geliefert     {--sf:#16351f;--st:#86efac}
  .abgerechnet   {--sf:#0d3b2e;--st:#6ee7b7}
  .abgeschlossen {--sf:#0b3b39;--st:#5eead4}
  .storniert     {--sf:#4a1f1f;--st:#fca5a5}
}
.chip{display:inline-block;padding:2px 8px;border-radius:999px;font-size:12px;background:var(--sf,var(--line));color:var(--st,inherit);white-space:nowrap}
/* Zustaende ausserhalb des Projektwegs (Belege, Bestellungen, Mahnwesen) */
.chip.bezahlt,.chip.verbaut,.chip.gefertigt,.chip.bestaetigt,.chip.angenommen{--sf:#dcfce7;--st:#166534}
.chip.ueberfaellig,.chip.mahnung,.chip.abgelehnt{--sf:#fee2e2;--st:#991b1b}
.chip.entwurf{--sf:#e5e7eb;--st:#374151}.chip.gesendet,.chip.rechnung{--sf:#dbeafe;--st:#1e40af}
.chip.offen,.chip.bestellt,.chip.angefragt{--sf:#fef3c7;--st:#92400e}
.chip.neu{--sf:#e0e7ff;--st:#3730a3}
/* Die Stufen einer Position – anklickbar, direkt in der Zeile der Stückliste.
   Eng gesetzt, weil sie in jeder Zeile stehen: die erreichte Stufe ist gefüllt, der
   Rest nur angedeutet. Die Schriftfarbe der gefüllten ist --card, nicht Weiß: in der
   dunklen Ansicht ist --primary hell, Weiß darauf wäre nicht zu lesen. */
.stufen{display:flex;flex-wrap:wrap;gap:3px;max-width:250px}
.stufen .stufe{border:1px solid var(--line);background:transparent;color:var(--muted);
  border-radius:999px;padding:2px 7px;font-size:11px;line-height:1.55;cursor:pointer;white-space:nowrap}
.stufen .stufe:hover:not(:disabled){border-color:var(--primary);color:var(--primary)}
.stufen .stufe.jetzt{background:var(--primary);border-color:var(--primary);color:var(--card);font-weight:600}
.stufen .stufe.jetzt.storniert{background:var(--bad);border-color:var(--bad)}
.stufen .stufe:disabled{cursor:default;opacity:.55}
@media(prefers-color-scheme:dark){
  .chip.bezahlt,.chip.verbaut,.chip.gefertigt,.chip.bestaetigt,.chip.angenommen{--sf:#16351f;--st:#86efac}
  .chip.ueberfaellig,.chip.mahnung,.chip.abgelehnt{--sf:#4a1f1f;--st:#fca5a5}
  .chip.entwurf{--sf:#2a3134;--st:#c3cbce}.chip.gesendet,.chip.rechnung{--sf:#17335c;--st:#93c5fd}
  .chip.offen,.chip.bestellt,.chip.angefragt{--sf:#4a3413;--st:#fcd34d}
  .chip.neu{--sf:#23285c;--st:#a5b4fc}
}
/* Projektkachel: die Statusfarbe als Kante – in einer langen Liste sieht man damit
   ohne Lesen, was laeuft, was in Fertigung ist und was fertig ist. */
.pkarte{border-left:5px solid var(--st,var(--line));position:relative}
/* Das Firmenprojekt ist kein Auftrag – ruhiger Rand statt Statusfarbe */
.pkarte.intern{--st:var(--muted);border-left-color:var(--line);border-left-style:dashed}
.pkarte .statuswahl{border-color:var(--sf,var(--line));background:var(--sf,var(--bg));color:var(--st,var(--text));font-weight:600}
.bar{height:8px;background:var(--line);border-radius:4px;overflow:hidden}.bar i{display:block;height:100%;background:var(--primary)}
.bar i.warn{background:var(--warn)}.bar i.bad{background:var(--bad)}

/* Der Fortschrittsbalken auf der Projektkarte. Er hat drei Zustaende, und zwei
   davon sollen ueber den Bildschirm hinweg auffallen: bezahlt leuchtet gruen,
   fertig-aber-unbezahlt leuchtet rot. Das Leuchten macht ein Farbverlauf plus
   ein Schein nach aussen - eine flache Farbe geht neben zwoelf Karten unter. */
.standbalken{height:10px;background:var(--line);border-radius:999px;overflow:hidden;margin-top:6px}
/* Der laufende Balken ist bewusst blau und nicht die Hausfarbe: die ist ein Gruen,
   und Gruen soll auf dieser Seite genau eine Sache heissen – das Geld ist da. */
.standbalken i{display:block;height:100%;border-radius:999px;background:#4a90d9;
  transition:width .5s ease, background .3s ease, box-shadow .3s ease}
.standbalken i.bezahlt{background:linear-gradient(90deg,#00e676,#39ff14);
  box-shadow:0 0 6px #39ff14,0 0 14px rgba(57,255,20,.55)}
.standbalken i.unbezahlt{background:linear-gradient(90deg,#ff1744,#ff073a);
  box-shadow:0 0 6px #ff073a,0 0 14px rgba(255,7,58,.55)}
.standbalken i.storniert{background:var(--muted);box-shadow:none;opacity:.5}
/* Wer das Blinken nicht mag oder braucht, bekommt die Farbe ohne Schein. */
@media (prefers-reduced-motion: reduce){
  .standbalken i{transition:none}
}
.warnlist li{margin:3px 0}.warn{color:var(--warn)}.bad{color:var(--bad)}.ok{color:var(--ok)}
.tabs{display:flex;gap:4px;border-bottom:1px solid var(--line);margin:10px 0;overflow-x:auto;scrollbar-width:none}.tabs a{padding:8px 12px;color:var(--muted);border-bottom:2px solid transparent;flex:0 0 auto;white-space:nowrap}
.tabs a.active{color:var(--text);border-color:var(--primary)}
.badge{background:var(--bad);color:#fff;border-radius:999px;font-size:11px;padding:1px 6px;margin-left:auto}
.dot{position:absolute;top:6px;right:18px;width:8px;height:8px;border-radius:50%;background:var(--bad)}
/* Oben bleibt die Statusleiste frei. Die App laeuft mit viewport-fit=cover, also
   unter der Uhr und der Dynamic Island hindurch - ohne dieses Polster lag das X
   am iPhone genau dort und war mit dem Daumen nicht zu treffen. */
.modal{position:fixed;inset:0;background:rgba(0,0,0,.5);display:flex;align-items:flex-end;justify-content:center;z-index:50;
  padding-top:calc(env(safe-area-inset-top, 0px) + 6px)}
.modal-box{background:var(--card);width:100%;max-width:640px;max-height:min(92vh, 100%);overflow:auto;border-radius:16px 16px 0 0;padding:16px}
/* Das X oben rechts. Es ist der einzige Weg, ein Fenster zuzumachen (neben
   „Abbrechen"): ein Klick auf das Graue daneben schliesst nichts mehr – wer eine
   Position anlegt und dabei einmal danebenklickt, hatte sonst alles Getippte weg.
   Der Kopf ist null hoch und klebt oben, damit das X auch bei einem langen
   Formular sichtbar bleibt, ohne Platz zu kosten. */
.modal-kopf{position:sticky;top:0;height:0;z-index:3}
.modal-x{position:absolute;right:0;top:0;width:40px;height:40px;padding:0;border:1px solid var(--line);
  background:var(--card);color:var(--muted);border-radius:10px;font-size:17px;line-height:1;cursor:pointer}
.modal-x:hover{color:var(--bad);border-color:var(--bad)}
.modal-box h2{padding-right:48px}
.toast{position:fixed;bottom:80px;left:50%;transform:translateX(-50%);background:#0e1416;color:#fff;padding:10px 16px;border-radius:8px;z-index:60;max-width:90vw}
.toast.bad{background:var(--bad)}
.login{min-height:100vh;display:flex;align-items:center;justify-content:center;padding:20px}.login .card{width:100%;max-width:360px;display:grid;gap:10px}
.chart{display:flex;align-items:flex-end;gap:4px;height:120px;padding-top:6px}.chart .col{flex:1;display:flex;flex-direction:column;justify-content:flex-end;align-items:center;gap:2px;font-size:10px;color:var(--muted);min-width:0}
.chart .col b{width:100%;display:flex;gap:1px;align-items:flex-end;height:100px}.chart .col b i{flex:1;background:var(--primary);border-radius:2px 2px 0 0}
.chart .col b i.k{background:var(--teal)}.chart .col span{white-space:nowrap;font-size:9px}
pre{background:var(--bg);padding:10px;border-radius:8px;overflow:auto;font-size:12px;white-space:pre-wrap}
.map{height:320px;border-radius:var(--r);overflow:hidden;border:1px solid var(--line)}
/* Registerkarten des Projektwegs: erreichte Schritte in ihrer Farbe, der aktuelle
   kraeftig ausgefuellt, die kommenden blass. Auf einen Blick sichtbar, wo es steht. */
.stepper{display:flex;gap:4px;flex-wrap:wrap}
.stepper a{padding:5px 10px;border-radius:7px;font-size:12px;font-weight:600;background:var(--line);
  color:var(--muted);border:1px solid transparent;transition:transform .08s ease}
.stepper a:hover{transform:translateY(-1px)}
.stepper a.done{background:var(--sf);color:var(--st);border-color:color-mix(in srgb,var(--st) 22%,transparent)}
.stepper a.cur{background:var(--st);color:var(--card);box-shadow:0 2px 8px color-mix(in srgb,var(--st) 40%,transparent)}
@supports not (color: color-mix(in srgb,#000 10%,#fff)){
  .stepper a.cur{box-shadow:0 2px 8px rgba(0,0,0,.25)}
}
.fab{position:fixed;right:18px;bottom:78px;width:52px;height:52px;border-radius:50%;background:var(--primary);color:#fff;font-size:28px;border:0;box-shadow:0 4px 14px rgba(0,0,0,.3);display:none;z-index:40}
@media(max-width:800px){
  .app{display:block}.side{display:none}main{padding:max(12px,env(safe-area-inset-top)) 12px calc(90px + env(safe-area-inset-bottom))}
  .gruppen{padding:max(8px,env(safe-area-inset-top)) 12px 0;overflow-x:auto}
  .modal-box{padding-bottom:calc(16px + env(safe-area-inset-bottom))}.toast{bottom:calc(80px + env(safe-area-inset-bottom))}.fab{bottom:calc(78px + env(safe-area-inset-bottom))}
  .bottom{display:flex;position:fixed;bottom:0;left:0;right:0;background:var(--nav);padding:6px 0 max(6px,env(safe-area-inset-bottom));justify-content:space-around;z-index:30}
  .bottom a{color:var(--navtext);font-size:11px;display:flex;flex-direction:column;align-items:center;gap:2px;position:relative;padding:2px 6px}
  .bottom a span{font-size:20px}.bottom a.active{color:var(--teal)}
  .fab{display:block}.modal-box{border-radius:16px 16px 0 0}
  table{font-size:13px}th,td{padding:6px 5px}
  .grid{grid-template-columns:repeat(2,1fr);gap:8px}.kpi .v{font-size:19px}.card{padding:10px 12px}
}
/* iPhone zoomt beim Antippen in jedes Feld unter 16 px hinein - danach steht die
   Seite vergroessert, rechts ueber, und die feste Leiste unten rutscht in die Mitte.
   Am Handy haben deshalb alle Felder mindestens 16 px, auch die kleinen Auswahlen. */
@media(max-width:800px),(pointer:coarse){input,select,textarea{font-size:16px!important}}
@media(min-width:801px){.modal{align-items:center}.modal-box{border-radius:16px}
  .modal-box.breit{max-width:1100px}}

.install{border-color:var(--teal);background:rgba(126,200,180,.15)}
.poslist{display:grid;gap:4px;max-height:220px;overflow:auto;border:1px solid var(--line);border-radius:8px;padding:8px;background:var(--bg)}
.posrow{display:flex;align-items:center;gap:6px;font-size:14px;color:var(--text);margin:0;cursor:pointer}
.badge.zeit,.dot.zeit{background:var(--ok)}
.uhr{font-size:44px;font-weight:700;font-variant-numeric:tabular-nums;letter-spacing:.02em;line-height:1}
.uhr.aus{color:var(--muted)}.bigbtn{padding:16px 22px;font-size:17px;border-radius:12px;min-width:150px}
.bigbtn.stop{background:var(--bad);border-color:var(--bad);color:#fff}.bigbtn.start{background:var(--ok);border-color:var(--ok);color:#fff}
.fahrtkarte{border-left:4px solid var(--teal)}.fahrtkarte.laeuft{border-left-color:var(--ok)}
.tatgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(120px,1fr));gap:6px}.tatgrid button{padding:8px 6px;font-size:13px}.tatgrid button.on{background:var(--primary);color:#fff;border-color:var(--primary)}
@media(max-width:800px){.uhr{font-size:40px}}

/* --- Benutzerverwaltung --- */
.nowrap{white-space:nowrap}
tr.inaktiv td{opacity:.55}
.rechtezeile{padding:6px 0;border-bottom:1px solid var(--line)}
.rechtezeile:last-child{border-bottom:0}
.rechtezeile label{margin:0;font-weight:500}
.rechtezeile select{min-width:170px;margin:0}
label.check{display:flex;align-items:center;gap:8px;font-weight:500;margin:10px 0}
label.check input{width:auto;margin:0}
#wer{font-weight:600;color:var(--text)}

/* --- Logo --- */
.brand{display:flex;align-items:center;gap:10px}
.brand img.logo{max-height:34px;max-width:120px;object-fit:contain}
#login img.logo{max-height:56px;max-width:200px;object-fit:contain;margin-bottom:10px}

/* --- Kundenportal ------------------------------------------------------------
   Das ist die einzige Seite, die ein Kunde je zu sehen bekommt. Sie soll aussehen
   wie ein Blatt Papier vom Briefkopf: Logo oben, eine Sache pro Karte, viel Luft,
   keine Knoepfe, die niemand braucht. Das Logo sitzt auf weisser Flaeche, damit es
   auch bei dunklem Erscheinungsbild sauber steht. */
body.portal .app{display:block}
body.portal main{padding:0}
body.portal{background:var(--bg)}
.portalseite{max-width:700px;margin:0 auto;padding:30px 18px 44px}
.portalkopf{display:flex;align-items:center;gap:14px;margin-bottom:22px;flex-wrap:wrap}
.logoplatte{background:#fff;border:1px solid var(--line);border-radius:12px;padding:9px 12px;
  display:inline-flex;align-items:center;box-shadow:0 1px 3px rgba(0,0,0,.06)}
.logoplatte img{height:44px;width:auto;max-width:210px;object-fit:contain;display:block}
/* Zwei Logos nebeneinander: unseres und das des Partners. Der Strich dazwischen
   sagt, dass hier zwei Absender stehen und nicht ein Zeichen aus zwei Teilen. */
.logotrenner{width:1px;height:30px;background:var(--line);flex:0 0 auto}
.portalkopf .kopftext{display:flex;flex-direction:column;line-height:1.3}
.portalkopf .kopftext b{font-size:16px;letter-spacing:-.01em}
.portalkarte{border-top:4px solid var(--st,var(--primary));padding:18px 18px 16px}
.portalzeile{align-items:flex-start;gap:12px}
.portalkarte .pnummer{font-size:12px;letter-spacing:.14em;text-transform:uppercase;color:var(--muted);font-weight:700}
.portalseite h1{margin:2px 0 10px;font-size:25px}
.portalseite .gross{font-size:18px;margin:0 0 14px}
.chip.gross{font-size:13px;padding:6px 14px;font-weight:700}
.portalstatus{display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin-top:6px}
.fortschritt{flex:1;min-width:160px;height:12px;border-radius:999px;background:var(--line);overflow:hidden}
.fortschritt i{display:block;height:100%;background:var(--st,var(--primary));transition:width .5s ease}
.portalstatus .prozent{font-weight:700;font-size:18px}
/* Der Weg des Projekts als Perlenkette – der Kunde sieht ohne Erklaerung, wo es steht */
.portalweg{list-style:none;display:flex;padding:0;margin:20px 0 4px;gap:0;overflow-x:auto;scrollbar-width:none}
.portalweg::-webkit-scrollbar{display:none}
.portalweg li{flex:1 1 62px;min-width:62px;text-align:center;position:relative;padding-top:16px;
  font-size:10.5px;line-height:1.25;color:var(--muted);padding-inline:2px}
.portalweg li::before{content:"";position:absolute;top:5px;left:0;right:50%;height:2px;background:var(--line)}
.portalweg li::after{content:"";position:absolute;top:5px;left:50%;right:0;height:2px;background:var(--line)}
.portalweg li:first-child::before,.portalweg li:last-child::after{display:none}
.portalweg li.erreicht::before,.portalweg li.erreicht::after{background:var(--st)}
.portalweg li.aktuell::after{background:var(--line)}
.portalweg .punkt{position:absolute;top:0;left:50%;transform:translateX(-50%);width:12px;height:12px;
  border-radius:50%;background:var(--card);border:2px solid var(--line)}
.portalweg li.erreicht .punkt{background:var(--st);border-color:var(--st)}
.portalweg li.aktuell .punkt{width:16px;height:16px;top:-2px;box-shadow:0 0 0 4px var(--sf)}
.portalweg li.erreicht{color:var(--text)}
.portalweg li.aktuell .wort{font-weight:800;color:var(--st)}
.portalweg .wort{display:block;overflow-wrap:anywhere;hyphens:auto}
.portalkarte .stand{margin:14px 0 0}
.portalseite .hinweis{margin-top:14px;padding:11px 13px;border-left:3px solid var(--st,var(--primary));
  background:var(--sf,var(--line));color:var(--text);border-radius:0 8px 8px 0}
.dateiliste{list-style:none;padding:0;margin:0}
.dateiliste li{border-bottom:1px solid var(--line)}
.dateiliste li:last-child{border-bottom:0}
.dateiliste a{display:flex;align-items:center;gap:10px;padding:11px 6px;border-radius:8px;color:var(--text)}
.dateiliste a:hover{background:var(--sf,var(--line))}
.dateiliste .dsym{font-size:18px;flex:0 0 auto}
.dateiliste .dname{flex:1;word-break:break-word}
.dateiliste .dgr{flex:0 0 auto;white-space:nowrap}
.portalfirma{margin-top:26px;padding-top:16px;border-top:1px solid var(--line);display:grid;gap:3px;
  color:var(--muted);text-align:center}
.portalfirma b{color:var(--text)}
.portalfuss{margin-top:14px;text-align:center}
@media print{
  .portalseite{max-width:none}.dateiliste a:hover{background:none}
  .card{break-inside:avoid;box-shadow:none}
}
h3.klein{margin:14px 0 4px;font-size:13px;text-transform:uppercase;letter-spacing:.04em;color:var(--muted)}

/* --- Status direkt in der Projektkachel aendern --- */
select.statuswahl{font-size:12px;padding:2px 6px;margin:0;width:auto;max-width:150px;border-radius:999px;
  background:var(--line);border:0;color:var(--text);cursor:pointer}
select.zstatus{font-size:12px;padding:2px 4px;margin:0;width:auto;min-width:130px}

select.fmodus{font-size:12px;padding:1px 4px;margin:0;width:auto;background:transparent;
  border:0;border-bottom:1px dotted var(--muted);color:var(--muted);cursor:pointer}

/* --- Datei per Drag & Drop ------------------------------------------------ */
.dropfeld{border:2px dashed var(--line);border-radius:var(--r);padding:20px 14px;margin:6px 0 4px;
  text-align:center;cursor:pointer;background:var(--bg);color:var(--muted);
  transition:border-color .15s,background .15s}
.dropfeld.klein{padding:12px}
.dropfeld:hover{border-color:var(--teal)}
.dropfeld.over{border-color:var(--teal);background:rgba(126,200,180,.18);color:var(--primary)}
.dropfeld.gefuellt{border-style:solid;border-color:var(--primary)}
.dropfeld .symbol{font-size:26px;line-height:1.1}
.dropfeld.klein .symbol{font-size:20px}
.dropfeld .haupt{font-weight:700;color:var(--text)}
.dropfeld .gewaehlt{margin-top:6px;font-size:13px;color:var(--primary);word-break:break-all}
.dropfeld .gewaehlt:empty{margin:0}
.dropfeld .nurtouch{display:none}
@media(hover:none){.dropfeld .nurmaus{display:none}.dropfeld .nurtouch{display:inline}}
/* Knopf, den es nur am Handy/Tablet gibt – am Schreibtisch gibt es keine Kamera am Geraet */
.touchknopf{display:none}
@media(hover:none){.touchknopf{display:inline-flex}}
/* Zieht jemand eine Datei ueber das Fenster, werden alle Felder sichtbar */
body.zieht .dropfeld{border-color:var(--teal)}
/* Projektseite: die Datei darf auch irgendwo daneben landen */
/* Nur ein Rahmen mit Hinweis: die Felder darunter bleiben sichtbar und treffbar. */
body.zieht.abwurfbereit::after{content:"Datei hier ablegen – Stückliste oder Lieferantenbeleg";
  position:fixed;inset:10px;z-index:70;pointer-events:none;border:3px dashed var(--teal);border-radius:16px;
  background:rgba(126,200,180,.12);color:var(--primary);display:flex;align-items:flex-start;justify-content:center;
  text-align:center;font-size:16px;font-weight:800;padding:14px}

/* Menge, die im Beleg keine Einheit hatte – bitte nachsehen */
input.unsicher{border-color:var(--warn);background:rgba(181,112,26,.10)}

/* Ordnerfreigabe: ein ganzer Ordner deckt die einzelnen Haken darin ab */
.ordnerblock{border-top:1px solid var(--line);padding-top:2px}
.ordnerblock:first-of-type{border-top:0}
label.check.ganzer{background:rgba(126,200,180,.14);border-radius:8px;padding:6px 10px;margin:6px 0}
.ordnerdateien{padding-left:14px}
.ordnerdateien.inaktiv{opacity:.45}

/* --- Dashboard als Aufgabenliste ----------------------------------------- */
.card.heute{border-left:4px solid var(--primary)}
ul.aufgaben{list-style:none;padding:0;margin:6px 0 0}
li.aufgabe{display:flex;gap:10px;align-items:flex-start;padding:10px 0;border-bottom:1px solid var(--line)}
li.aufgabe:last-child{border-bottom:0}
li.aufgabe .sym{width:22px;text-align:center;font-size:16px;line-height:1.3}
li.aufgabe .txt{flex:1;min-width:0}
li.aufgabe.dringend .sym{color:var(--bad)}
li.aufgabe.dringend .txt b{color:var(--bad)}
li.aufgabe.wichtig .sym{color:var(--warn)}
@media(max-width:800px){li.aufgabe{flex-wrap:wrap}li.aufgabe .row{width:100%;justify-content:flex-end}}

/* --- Glocke --------------------------------------------------------------- */
ul.meldeliste{list-style:none;padding:0;margin:0;max-height:55vh;overflow:auto}
ul.meldeliste li{padding:9px 0;border-bottom:1px solid var(--line)}
ul.meldeliste li:last-child{border-bottom:0}
ul.meldeliste li.neu{border-left:3px solid var(--primary);padding-left:9px}

/* --- Ampel im Posteingang ------------------------------------------------- */
.ampel{display:inline-block;width:10px;height:10px;border-radius:50%;background:var(--line);margin-right:6px}
.ampel.gruen{background:var(--ok)}.ampel.gelb{background:var(--warn)}.ampel.rot{background:var(--bad)}


/* --- Bezuege: Geflecht mit Tiefe ------------------------------------------ */
.bezkarte{overflow:hidden}
/* Bewusst KEIN rotateX mehr: eine 3D-gedrehte Ebene wird vom Browser einmal gerastert
   und dann gekippt – die Schrift wird dabei unscharf. Tiefe kommt jetzt aus Schatten,
   Staffelung und Bewegung, und das SVG bleibt bei jedem Zoom gestochen. */
.bezleiste{display:flex;align-items:center;gap:6px;justify-content:flex-end;margin-bottom:4px}
.bezbuehne{overflow:auto;padding:10px 6px 16px;max-height:72vh}
.bezbuehne svg{display:block;shape-rendering:geometricPrecision;text-rendering:optimizeLegibility}
.bezkopf{fill:var(--muted);font-size:12px;font-weight:700;text-anchor:middle;letter-spacing:.06em;text-transform:uppercase}
/* Die Position steckt im transform-Attribut des <g>. Eine CSS-Animation, die transform
   anfasst, ueberschreibt dieses Attribut – dann sitzen alle Knoten auf derselben Stelle
   links oben und man sieht nur den obersten. Deshalb blendet die Animation ausschliesslich
   die Deckkraft ein, und opacity:1 steht als Grundzustand da, damit ein Knoten auch dann
   sichtbar ist, wenn die Animation gar nicht erst laeuft. */
.bezknoten{cursor:pointer;outline:none;opacity:1;animation:bezauf .45s ease backwards;animation-delay:var(--v,0s)}
.bezknoten rect{fill:var(--card);stroke:var(--line);stroke-width:1.5;vector-effect:non-scaling-stroke;
  transition:stroke .18s ease,filter .18s ease}
.bezknoten.gut rect{stroke:var(--ok)}.bezknoten.offen rect{stroke:var(--warn)}.bezknoten.schlecht rect{stroke:var(--bad)}
.bezknoten .t1{fill:var(--text);font-size:13.5px;font-weight:700}
.bezknoten .t2{fill:var(--muted);font-size:11px}
.bezknoten.art-abschluss rect{stroke-dasharray:none;stroke-width:2}
.bezknoten:hover rect,.bezknoten.aktiv rect,.bezknoten:focus rect{stroke:var(--primary);stroke-width:2.5;
  filter:drop-shadow(0 0 7px rgba(126,200,180,.55))}
.bezkante{fill:none;stroke:var(--line);stroke-width:2;stroke-dasharray:7 5;stroke-linecap:round;
  vector-effect:non-scaling-stroke;animation:bezfluss 1.6s linear infinite;transition:stroke-width .18s ease,opacity .18s ease}
.bezkante.gut{stroke:var(--ok)}.bezkante.offen{stroke:var(--warn)}.bezkante.schlecht{stroke:var(--bad)}
.bezkante.auftrag{stroke:var(--primary);stroke-width:3}
.bezkante.einfluss{stroke-dasharray:2 6;opacity:.55}   /* laeuft in die Rechnung ein */
.bezkante.abschluss{stroke:var(--primary);stroke-width:2.5;stroke-dasharray:10 4}
.bezkante.aktiv{stroke-width:3.5;animation-duration:.8s}
svg.hebt .bezknoten:not(.aktiv),svg.hebt .bezkante:not(.aktiv){opacity:.16}
@keyframes bezfluss{to{stroke-dashoffset:-24}}
@keyframes bezauf{from{opacity:0}to{opacity:1}}
@media(prefers-reduced-motion:reduce){.bezkante{animation:none}.bezknoten{animation:none}}

tr.warnzeile td{background:rgba(245,158,11,.08)}

/* Verlauf einer Anfrage: zwei Sprecher, links und rechts – so liest man sofort,
   wer was gesagt hat, ohne jede Zeile mit einem Namen zu beginnen. */
.verlauf { max-height: 46vh; overflow: auto; margin: 10px 0; display: flex; flex-direction: column; gap: 8px }
/* Die Namen muessen zu denen oben passen: --karte/--rand/--akzent gibt es nicht,
   und dann blieb es bei den dunklen Festwerten - dunkle Blase, dunkle Schrift. */
.nachricht { border-radius: 10px; padding: 8px 10px; max-width: 85%; background: var(--card);
             color: var(--text); border: 1px solid var(--line) }
.nachricht.partner { align-self: flex-start }
.nachricht.wir { align-self: flex-end; border-color: var(--primary);
                 background: color-mix(in srgb, var(--primary) 8%, var(--card)) }
.nachricht .ntext { white-space: pre-wrap; margin: 4px 0 6px }
@media (max-width: 520px) { .nachricht { max-width: 100% } }

/* Ordnerbaum im Partnerbereich: die Einrueckung kommt aus dem Pfad, nicht aus
   verschachteltem Markup - so bleibt die Liste flach und laesst sich sortieren. */
.ordnerzeile { border-left: 2px solid var(--line); padding: 6px 0 6px 10px; margin-top: 6px }
.ordnerzeile .dateizeile { display: flex; gap: 8px; align-items: baseline; flex-wrap: wrap; padding: 2px 0 }
.ordnerzeile .dateizeile a { font-weight: 600 }
.ordnerzeile.ueber { background: color-mix(in srgb, var(--primary) 12%, transparent); border-left-color: var(--primary) }

/* Das Raster liegt hinter allem und faengt keine Klicks ab. Ohne die zweite Regel
   waere die halbe Seite nicht mehr bedienbar. */
#hgraster { position: fixed; inset: 0; width: 100%; height: 100%; z-index: 0;
            pointer-events: none; display: block }
body.portal .portalseite, .loginbox { position: relative; z-index: 1 }
/* Der Dialog braucht nur eine Ebene ueber dem Raster, nicht position:relative -
   das hat ihn im Portal aus dem Bild geschoben: statt fest im Fenster stand er
   unten im Dokument, und auf einer langen Seite sah man ihn nie. Ein Klick auf
   „+ Neue Anfrage" tat dann scheinbar nichts. */
body.portal #modal { z-index: 50 }

/* „Nur mit Maus" und „nur mit Finger" gab es bisher nur im Abwurffeld. Im
   Partnerbereich stehen Hochladen, Foto und Ziehen nebeneinander – da wird es
   ueberall gebraucht. */
.nurtouch { display: none }
@media (hover: none) { .nurmaus { display: none } .nurtouch { display: inline-flex } }

/* --- Chat im Partnerbereich --------------------------------------------------
   Ein Strang je Firma. Die eigene Seite rechts, die andere links - das liest man
   ohne jede Beschriftung, und deshalb steht der Name nur klein darueber. */
.chat{display:flex;flex-direction:column;gap:8px;max-height:44vh;min-height:120px;overflow:auto;
      padding:10px;background:var(--bg);border:1px solid var(--line);border-radius:10px}
.chatzeile{max-width:82%;align-self:flex-start;background:var(--card);border:1px solid var(--line);
           border-radius:12px 12px 12px 4px;padding:7px 11px}
.chatzeile.ich{align-self:flex-end;border-radius:12px 12px 4px 12px;border-color:var(--primary);
               background:color-mix(in srgb,var(--primary) 9%,var(--card))}
.chattext{white-space:pre-wrap;overflow-wrap:anywhere;font-size:14px;margin-top:2px}
.chatleiste{display:flex;gap:8px;align-items:flex-end;margin-top:8px}
.chatleiste textarea{min-height:0;height:40px;resize:none;overflow:auto}
.chatleiste .btn{flex:0 0 auto;height:40px;padding:0 16px;font-size:17px;line-height:1}
@media(max-width:520px){.chatzeile{max-width:92%}.chat{max-height:38vh}}

/* Unser Zeichen und das des Partners nebeneinander - nur in der Innensicht. So
   sieht man in der Liste sofort, bei wem man ist, ohne den Namen zu lesen. */
.logopaar{display:inline-flex;align-items:center;gap:5px;flex:0 0 auto}
.logopaar img{height:22px;width:auto;max-width:56px;object-fit:contain;display:block;
              background:#fff;border:1px solid var(--line);border-radius:5px;padding:2px}
.logopaar i{width:1px;height:16px;background:var(--line);display:block}

/* Fortschritt beim Hochladen. Bei 5 GB ist ein „wird geladen ..." zu wenig -
   man will sehen, dass sich etwas bewegt, und wie lange es noch dauert. */
.hochbalken{position:fixed;left:50%;bottom:78px;transform:translateX(-50%);z-index:61;width:min(92vw,420px);
            background:var(--card);border:1px solid var(--line);border-radius:10px;padding:10px 12px;
            box-shadow:0 8px 28px rgba(0,0,0,.22)}
.hochbalken .bar{margin-top:6px}

/* --- Portal: links die Vorgaenge, rechts der offene ---------------------------
   Vorher stand alles untereinander, und die Dateien zeigten immer dieselbe Ablage,
   egal welche Anfrage oben gewaehlt war. Jetzt gehoert die rechte Spalte dem, woran
   gerade gearbeitet wird - Verlauf und Dateien springen zusammen um. */
body.portal .portalseite { max-width: 1180px }
.ppspalten { display: grid; gap: 14px; grid-template-columns: minmax(300px, 380px) minmax(0, 1fr);
             align-items: start }
.ppliste, .pparbeit { min-width: 0 }
/* Klebt oben mit, bleibt aber im Bild: ist der Vorgang laenger als der Bildschirm,
   scrollt das Fenster selbst - sonst waere sein unteres Ende unerreichbar. */
.pparbeit { position: sticky; top: calc(env(safe-area-inset-top, 0px) + 14px);
            max-height: calc(100vh - env(safe-area-inset-top, 0px) - 28px); overflow: auto }
@media (max-width: 900px) {
  .ppspalten { grid-template-columns: 1fr }
  .pparbeit { position: static; max-height: none; overflow: visible }
  body.portal .portalseite { max-width: 700px }
}
/* Die gewaehlte Zeile bleibt markiert - sonst weiss man nach dem dritten Wechsel
   nicht mehr, was rechts eigentlich offen ist. */
.ppliste tr.hier td { background: color-mix(in srgb, var(--primary) 16%, transparent);
                      box-shadow: inset 3px 0 0 var(--primary) }
.ppwahl { cursor: pointer }
.ppwahl:hover { border-color: var(--primary) }
.ppwahl.hier { border-color: var(--primary);
               background: color-mix(in srgb, var(--primary) 8%, var(--card)) }
.ppleer { border-style: dashed }
.ppleer h2 { margin-top: 0 }
.pparbeit .ordnerzeile { border-left-color: var(--primary) }

/* --- Durchklicken: ein Beleg, zwei Spalten, Tastatur ------------------------
   Links das PDF in voller Hoehe, rechts das Ziel. Wer fuenfzig Belege sichtet,
   soll den Blick nicht wandern lassen muessen. */
.dkspalten { display: grid; gap: 14px; grid-template-columns: minmax(0, 1fr) minmax(360px, 460px);
             align-items: start }
.dklinks, .dkrechts { min-width: 0 }
.dkpdf { width: 100%; height: calc(100vh - 210px); min-height: 380px; border: 1px solid var(--line);
         border-radius: 10px; background: var(--card) }
.dktext { overflow: auto; padding: 12px }
.dktext pre { white-space: pre-wrap; word-break: break-word; margin: 6px 0 0; font-size: 12px }
.dkrechts { position: sticky; top: calc(env(safe-area-inset-top, 0px) + 14px);
            max-height: calc(100vh - env(safe-area-inset-top, 0px) - 28px); overflow: auto }
.dkbalken { height: 4px; border-radius: 3px; background: var(--line); margin: 6px 0 12px; overflow: hidden }
.dkbalken i { display: block; height: 100%; background: var(--primary); transition: width .2s }
@media (max-width: 1000px) {
  .dkspalten { grid-template-columns: 1fr }
  .dkrechts { position: static; max-height: none; overflow: visible }
  .dkpdf { height: 52vh }
}

/* Eine Zeile, die beim Aufräumen zum Entfernen angehakt ist: durchgestrichen und
   zurückgenommen, damit auf einen Blick klar ist, was verschwindet. */
tr.weg td { opacity: .62; text-decoration: line-through }
tr.weg td:first-child { opacity: 1; text-decoration: none }

/* Der Summenblock unter den Positionen eines Belegs: rechtsbündig, die letzte
   Zeile hervorgehoben - dasselbe Bild wie auf dem gedruckten Papier. */
table.summen { width: 100%; max-width: 420px; margin-left: auto; margin-top: 8px }
table.summen td { padding: 3px 6px; border: 0 }
table.summen tr:last-child td { border-top: 1px solid var(--line); font-size: 1.05em }

/* Umzugsliste: der erledigte Schritt tritt zurueck, der naechste steht vorne */
.umzugsliste { display: grid; gap: 2px; border: 1px solid var(--line); border-radius: 8px;
  padding: 4px 10px; background: var(--bg) }
.umzugschritt { padding: 8px 0; border-bottom: 1px solid var(--line); align-items: flex-start }
.umzugschritt:last-child { border-bottom: none }
.umzugschritt.fertig { opacity: .68 }

/* Der Kalkuel-Bestand in der Umzugskarte: eine Marke je Datenart */
.bestand { margin-top: 6px; display: flex; flex-wrap: wrap; gap: 4px; align-items: center }
.bestand .small { flex-basis: 100%; margin-top: 2px }

/* Die Warengruppen-Überschrift im Lager: klebt beim Rollen oben, damit man auch
   mitten in dreihundert Schrauben noch weiss, wo man ist. */
.lggruppe{position:sticky;top:0;z-index:2;background:var(--bg);margin:14px 0 6px;
  padding:6px 0;display:flex;gap:10px;align-items:baseline;flex-wrap:wrap}
.lggruppe:first-child{margin-top:0}
/* Das rote X am Ende der Lagerzeile. Klein, damit es nicht schreit – rot, damit
   klar ist, dass es entfernt und nicht bearbeitet. */
.btn.winzig{padding:2px 7px;font-size:12px;line-height:1.3;min-width:0}
.btn.weg{color:var(--bad);border-color:transparent;background:transparent}
.btn.weg:hover{border-color:var(--bad);background:rgba(220,60,60,.10)}

/* Die gewaehlte Zeile in der Modellstueckliste - dieselbe Farbe wie die
   Hervorhebung im Bild, damit Liste und Ansicht als eines gelesen werden. */
tr.gewaehlt > td{background:var(--tealzart,rgba(126,200,180,.18))}
tr.gewaehlt > td:first-child{box-shadow:inset 3px 0 0 var(--teal)}

/* --- Modell: Vollbild, Fahne am Bauteil, Ausblenden ---------------------------
   Beim Kunden steht er mit dem Tablet vor der Maschine und zeigt auf ein Teil.
   Dafuer muss das Fenster gross werden koennen, die Schrauben muessen weg, und
   das angeklickte Teil muss **dort** angeschrieben stehen, wo es liegt - nicht
   in einer Zeile darunter. */
.modal-box.voll{max-width:100%;width:100%;max-height:100%;height:100%;border-radius:0}
/* „Nur Modell" heisst wirklich nur Modell: die Stueckliste und alles, was zum
   Zuordnen gehoert, geht weg, und das Bild bekommt die ganze Seite. Was das
   angeklickte Bauteil ist, steht ohnehin als Fahne daneben. */
.modal-box.voll #mtListe, .modal-box.voll .mtnebensache{display:none}
.modal-box.voll .mtbuehne canvas{aspect-ratio:auto;height:calc(100vh - 150px)}
.mtbuehne{position:relative}
.mtfahne{position:absolute;transform:translate(-50%,calc(-100% - 12px));pointer-events:none;
  z-index:4;background:var(--card);border:1px solid var(--line);border-radius:10px;
  padding:6px 9px;box-shadow:0 8px 22px rgba(0,0,0,.18);max-width:240px;font-size:12px;
  line-height:1.35;color:var(--text)}
.mtfahne::after{content:'';position:absolute;left:50%;bottom:-6px;margin-left:-6px;width:0;height:0;
  border:6px solid transparent;border-top-color:var(--card);filter:drop-shadow(0 1px 0 var(--line))}
.mtfahne b{display:block}
.mtpunkt{position:absolute;width:11px;height:11px;margin:-6px 0 0 -6px;border-radius:50%;
  background:var(--primary);box-shadow:0 0 0 3px rgba(18,117,97,.25);pointer-events:none;z-index:4}
.mtauge{border:0;background:none;cursor:pointer;font-size:15px;line-height:1;padding:2px 4px;
  opacity:.75}
.mtauge:hover{opacity:1}
tr.mtaus td{opacity:.45}

/* Messen im Modell. Die Anzeige bleibt auch im Vollbild stehen - dort wird ja
   gemessen. Die drei Masse tragen die uebliche Farbgebung: X rot, Y gruen,
   Z blau, dieselbe wie die Treppe im Bild, damit man nicht zuordnen muss. */
.mtmass{border:1px solid var(--line);border-radius:10px;padding:8px 10px;margin:6px 0;
  font-size:13px;line-height:1.4;background:var(--card)}
.mtmasszeile{display:flex;align-items:baseline;gap:6px}
.mtmassnr{display:inline-flex;align-items:center;justify-content:center;flex:0 0 16px;
  width:16px;height:16px;border-radius:50%;background:var(--primary);color:#fff;
  font-size:10px;font-weight:700}
.mtdelta{display:flex;gap:10px;flex-wrap:wrap;align-items:baseline;margin-top:4px;
  font-variant-numeric:tabular-nums;font-size:15px;font-weight:600}
.mtdelta .mx{color:#d64545}
.mtdelta .my{color:#2f9e44}
.mtdelta .mz{color:#1c7ed6}
.mtmassbild{position:absolute;inset:0;pointer-events:none;z-index:3}
.mtmasslinie{position:absolute;inset:0;width:100%;height:100%;overflow:visible}
.mtmasspunkt{position:absolute;width:18px;height:18px;margin:-9px 0 0 -9px;border-radius:50%;
  background:var(--primary);color:#fff;font-size:11px;font-weight:700;display:flex;
  align-items:center;justify-content:center;box-shadow:0 0 0 3px rgba(18,117,97,.25)}

/* Die Vorschau vor dem Klicken: ein offener Ring am Messpunkt und ein Schild mit
   seinem Namen. Orange, nicht in der Hausfarbe - eine gesetzte Marke und ein
   Vorschlag duerfen nicht gleich aussehen. */
.mtmessring{position:absolute;width:16px;height:16px;margin:-8px 0 0 -8px;border-radius:50%;
  border:2.5px solid #e8590c;background:rgba(232,89,12,.14);box-sizing:border-box}
.mtmessschild{position:absolute;transform:translate(-50%,calc(-100% - 12px));white-space:nowrap;
  background:#e8590c;color:#fff;font-size:11px;font-weight:600;padding:2px 7px;
  border-radius:9px;box-shadow:0 3px 10px rgba(0,0,0,.2)}

@media(min-width:801px){.modal-box.voll{max-width:98vw;width:98vw;height:96vh;border-radius:16px}}

/* Die Stücklisten-Spalte der Modellmaske am Handy. Auf seinem Bildschirm lief
   sie über den Rand hinaus: ein Auswahlfeld mit langen Bezeichnungen und
   Vorschlagsknöpfe, die nicht umbrechen. Ein Balken zum Seitwärtsschieben ist in
   einer Liste, durch die man scrollt, keine Lösung. */
#mtListe select, #mtListe button{max-width:100%}
#mtListe button{white-space:normal;text-align:left;overflow-wrap:anywhere}
#mtListe td{overflow-wrap:anywhere}
#mtListe table{table-layout:auto}

/* Portalvorschau: dieselbe Seite von innen ansehen. Abgesetzt, damit man nie glaubt,
   man arbeite darin - hier wird nur geschaut, geschrieben wird nichts. */
.pvseite{border-left:3px solid var(--line);padding-left:12px;margin-top:6px}
.pvseite .card{margin:8px 0}
.pvseite .hinweis{margin-top:12px;padding:10px 12px;border-left:3px solid var(--st,var(--primary));
  background:var(--sf,var(--line));border-radius:0 8px 8px 0}
.pvseite .dateizeile{display:flex;gap:8px;justify-content:space-between;align-items:baseline;
  flex-wrap:wrap;padding:4px 0;border-bottom:1px solid var(--line)}
.pvseite .dateizeile:last-child{border-bottom:0}
.pvseite tr.hier>td{background:var(--sf,var(--line))}

/* Ein heikler Ordner in der Freigabemaske: er zeigt unsere Seite des Geschaefts.
   Verboten ist er nicht - aber er soll ins Auge fallen, bevor der Haken sitzt. */
.freigabezeile.heikel{background:rgba(220,38,38,.07);border-radius:6px}
.freigabezeile.heikel span{color:var(--warn,#b91c1c)}

/* Belegschule: das Muster als Blatt, auf dem angekreuzt wird. Die Kaesten stehen
   in Prozent - das Blatt ist am Handy schmaeler, die Stelle bleibt dieselbe. */
.bfspalten{display:grid;grid-template-columns:minmax(0,1.6fr) minmax(280px,1fr);gap:14px;align-items:start}
@media (max-width:900px){.bfspalten{grid-template-columns:1fr}}
.bfblatt{position:relative;display:block;touch-action:none;user-select:none;cursor:crosshair}
.bfblatt img{display:block;width:100%;border:1px solid var(--line);border-radius:6px}
.bfmarke{position:absolute;border:2px solid var(--primary);background:rgba(37,99,235,.14);
  border-radius:3px;cursor:pointer}
.bfmarke.wert{border-color:#b45309;background:rgba(180,83,9,.14)}
.bfmarke.wahl{border-style:dashed;border-color:#16a34a;background:rgba(22,163,74,.12);pointer-events:none}
/* Das Schild ragt ueber die Marke hinaus. Ohne pointer-events:none wuerde es den
   Klick auf die Nachbarspalte schlucken - und zu sehen waere davon nichts, weil
   die Marke darunter nur ihr eigenes Feld wieder entfernt. */
.bfmarke span{position:absolute;top:-16px;left:-2px;font-size:10px;font-weight:700;white-space:nowrap;
  background:var(--primary);color:#fff;padding:0 4px;border-radius:3px;pointer-events:none}
.bfmarke.wert span{background:#b45309}
.bfrahmen{position:absolute;border:2px dashed #16a34a;background:rgba(22,163,74,.12);pointer-events:none}
.bffenster{border-left:3px solid #16a34a}
.bffeld{padding:5px 0;border-bottom:1px solid var(--line);gap:8px;align-items:flex-start}
.bffeld.hat{background:rgba(22,163,74,.06);border-radius:4px;padding-left:6px}
/* Belege an den Kunden am Projekt: vier Spalten wie die Arbeit laeuft, am Handy untereinander */
.kbel{display:grid;gap:10px;grid-template-columns:repeat(4,minmax(0,1fr));margin-top:6px}
.kb-spalte{background:var(--bg,#f6f8f8);border-radius:10px;padding:8px;min-width:0}
.kb-kopf{margin-bottom:6px}
.kb-zeile{background:var(--card,#fff);border:1px solid var(--line,#e5e7eb);border-radius:8px;padding:6px 8px;margin-bottom:6px}
.kb-zeile .row{gap:6px;flex-wrap:nowrap}
.kb-zeile.storno{opacity:.55}.kb-zeile.storno b{text-decoration:line-through}
@media(max-width:900px){.kbel{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media(max-width:520px){.kbel{grid-template-columns:1fr}}
.kb-versand{margin-top:3px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}

/* Fett / kursiv / unterstrichen / Aufzählung am Beschreibungsfeld */
.textknoepfe { display: inline-flex; gap: 3px; margin-top: 3px; }
.textknoepfe button { min-height: 0; min-width: 26px; padding: 1px 6px; font-size: .78em; line-height: 1.4;
  border: 1px solid var(--line, #3a4248); border-radius: 5px; background: transparent; color: inherit; cursor: pointer; }
.textknoepfe button:hover { background: rgba(127,127,127,.15); }
.sandboxband{grid-column:1/-1;background:#fff3cd;color:#664d03;border-bottom:1px solid #e6d28a;padding:6px 14px;font-size:13px;text-align:center}

/* Sprache wählen – in „Mein Zugang" und auf der Anmeldeseite */
.sprachwahl { display: flex; align-items: center; gap: .5rem; margin-top: .75rem; font-size: .9rem; }
.sprachwahl select { width: auto; min-width: 10rem; }
#loginForm .sprachwahl { justify-content: center; }
