/* ============================================================
   Ergänzungen zum Designsystem.

   app.css ist die unveränderte Übernahme aus dem Prototyp und bleibt
   das auch – wird der Prototyp einmal überarbeitet, lässt er sich neu
   herausziehen, ohne dass hier etwas verlorengeht.

   Alles, was der Prototyp nicht kennt, steht deshalb in dieser Datei:
   Anmeldung, Fehlerseiten, Meldungen, Formulare, Kundenportal und
   Fahrer-App. Dieselben Variablen, dieselbe Formensprache.
   ============================================================ */

/* --- Knöpfe, die Links sind ----------------------------------
   Im Prototyp sind Knöpfe <button> und erben deshalb color:inherit.
   Hier sind viele davon echte Adressen und damit <a> – die brächten
   sonst Unterstreichung und Linkfarbe mit.

   :where() nimmt der Regel die Spezifität, damit .btn-primary mit
   seiner eigenen Farbe gewinnt – auch im dunklen Schema, wo sie eine
   andere ist. */

a.btn, a.brand, a.counter{text-decoration:none}
a:where(.btn), a:where(.brand), a:where(.counter){color:var(--ink)}
a.brand:hover{opacity:.85}

/* --- Navigation als Links ------------------------------------
   Im Prototyp sind die Menüpunkte <button>, weil dort alles auf einer
   Seite lag. Hier sind es echte Adressen und damit <a> – mittlere
   Maustaste, "in neuem Tab öffnen" und die Statuszeile des Browsers
   funktionieren nur so. Aussehen unverändert. */

.nav a{width:100%;display:flex;align-items:center;gap:10px;padding:7px 10px;border:0;border-radius:9px;
  background:transparent;color:var(--ink-2);font-weight:500;cursor:pointer;text-align:left;text-decoration:none}
.nav a:hover{background:var(--surface-2);color:var(--ink)}
.nav a.is-active{background:var(--accent-soft);color:var(--accent-ink);font-weight:600}
.nav a.is-active .n{color:var(--accent-ink)}
.rail .nav a{justify-content:center;padding:9px 0}

/* --- Listen --------------------------------------------------
   Im Prototyp sortiert ein Klick auf den Spaltenkopf im Browser. Hier
   ist es ein echter Link auf dieselbe Seite mit anderer Sortierung –
   damit ein Lesezeichen zur selben Ansicht zurückführt. Aussehen
   unverändert: der Link füllt den ganzen Kopf aus. */

.grid thead th > a.thlink{display:block;color:inherit;text-decoration:none;margin:-8px -10px;padding:8px 10px}
.grid td > a.icon-btn{display:grid}
.grid td[hidden], .grid th[hidden]{display:none}

/* Zelle im Bearbeitungsmodus (Doppelklick) */
.zellfeld{width:100%;border:1px solid var(--accent);border-radius:6px;padding:3px 6px;
  background:var(--input);color:var(--ink);font:inherit;font-size:12.5px;
  box-shadow:0 0 0 3px rgba(79,70,229,.12);outline:none}
select.zellfeld{padding-right:22px}

/* Reiter im Detailfenster sind echte Adressen (?reiter=…), damit ein
   Lesezeichen zurückfindet und ein Neuladen bleibt, wo man war. */
.tabs a{border:0;background:transparent;padding:6px 12px;border-radius:8px;cursor:pointer;
  color:var(--ink-2);white-space:nowrap;font-weight:500;text-decoration:none}
.tabs a:hover{background:var(--surface)}
.tabs a.is-active{background:var(--surface);color:var(--accent-ink);font-weight:600;
  box-shadow:0 1px 2px rgba(16,24,40,.08)}

/* --- Meldungen (Flash) --------------------------------------- */

.meldungen{display:flex;flex-direction:column;gap:8px;margin-bottom:14px}
.meldung{display:flex;align-items:flex-start;gap:10px;padding:11px 13px;border-radius:11px;
  border:1px solid var(--line);background:var(--surface-2);line-height:1.45}
.meldung svg{width:17px;height:17px;flex:none;margin-top:1px;stroke:currentColor;fill:none;stroke-width:1.8}
.meldung b{font-weight:650}
.meldung.erfolg{border-color:#bfe3c9;background:#eef9f1;color:#1f5b30}
.meldung.fehler{border-color:var(--err-line);background:var(--err-bg);color:var(--err-ink)}
.meldung.warnung{border-color:#f3ddb0;background:#fdf6e8;color:#7a4d05}
.meldung.hinweis{border-color:#c7d4f5;background:#eef3ff;color:#1c3b86}
.meldung .zu{margin-left:auto;border:0;background:transparent;cursor:pointer;color:inherit;opacity:.6;padding:0 2px}
.meldung .zu:hover{opacity:1}

:root[data-theme="dark"] .meldung.erfolg{border-color:#2c5a3a;background:#132b1c;color:#8fd7a4}
:root[data-theme="dark"] .meldung.warnung{border-color:#5c4718;background:#2b2110;color:#f0c874}
:root[data-theme="dark"] .meldung.hinweis{border-color:#33407a;background:#151b33;color:#a9bdf0}

/* --- Schlichte Seiten: Anmeldung, Fehler, Einrichtung -------- */

.schlicht{min-height:100vh;display:grid;place-items:center;padding:28px 18px;background:var(--bg)}
.schlicht-box{width:100%;max-width:430px}
.schlicht-box.breit{max-width:760px}
.schlicht .brand{justify-content:center;padding:0 0 20px}
.schlicht .card{padding:26px 26px 24px}
.schlicht h1{font-size:19px;margin:0 0 4px}
.schlicht .unter{color:var(--muted);font-size:13px;margin:0 0 20px}
.schlicht .fuss{text-align:center;color:var(--muted);font-size:12px;margin-top:16px}
.schlicht .fuss a{color:var(--muted)}

/* --- Formulare ----------------------------------------------- */

/* align-items MUSS hier stehen: app.css definiert .form als
   12-Spalten-Raster mit align-items:start. Diese Regel überschreibt
   display und flex-direction, aber align-items bliebe sonst auf "start"
   – und ein Feld direkt unter .form wäre nur so breit wie sein Inhalt
   statt so breit wie das Formular. */
.form{display:flex;flex-direction:column;gap:14px;align-items:stretch}
.form-reihe{display:flex;gap:12px;flex-wrap:wrap}
.form-reihe > .feld{flex:1 1 200px;min-width:0}
.feld{display:flex;flex-direction:column;gap:5px}
.feld > label{font-size:10.5px;letter-spacing:.05em;text-transform:uppercase;color:var(--muted);font-weight:600}
.feld input[type=text],.feld input[type=email],.feld input[type=password],.feld input[type=search],
.feld input[type=date],.feld input[type=time],.feld input[type=number],.feld input[type=tel],
.feld select,.feld textarea{
  appearance:none;border:1px solid var(--line-strong);background:var(--input);border-radius:9px;
  padding:9px 11px;width:100%;color:var(--ink)}
.feld select{padding-right:28px;background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'><path d='M2.5 4.5 6 8l3.5-3.5' fill='none' stroke='%237b859b' stroke-width='1.5' stroke-linecap='round'/></svg>");
  background-repeat:no-repeat;background-position:right 9px center}
:root[data-theme="dark"] .feld select{background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'><path d='M2.5 4.5 6 8l3.5-3.5' fill='none' stroke='%238c96ad' stroke-width='1.5' stroke-linecap='round'/></svg>")}
.feld textarea{min-height:88px;resize:vertical;line-height:1.5}
/* Ein Suchfeld INNERHALB eines .feld: app.css setzt dafür
   .search input{padding-left:32px}, damit die Lupe Platz hat. Die
   Regel oben ist spezifischer und steht in der später geladenen Datei –
   sie gewann, und die Lupe lag im Adressdialog auf dem ersten
   Buchstaben. Deshalb hier noch einmal, im selben Kontext. */
.feld .search{width:100%;min-width:0}
.feld .search input{padding-left:32px}
.feld input:focus,.feld select:focus,.feld textarea:focus{
  border-color:var(--accent);box-shadow:0 0 0 3px rgba(79,70,229,.12);outline:none}
.feld .hilfe{font-size:11.5px;color:var(--muted);line-height:1.4}
.feld.fehlerhaft input,.feld.fehlerhaft select,.feld.fehlerhaft textarea{border-color:var(--bad)}
.feld .fehlertext{font-size:11.5px;color:var(--bad)}
/* --- Profilfoto ------------------------------------------------
   Oben links steht sonst ein Quadrat mit zwei Buchstaben. Liegt ein
   Foto vor, füllt es dasselbe Quadrat – gleiche Größe, gleicher Radius,
   gleicher Platz im Layout. Der Farbverlauf darunter muss weg, sonst
   schimmert er an den Rändern durch. */
.brand-mark.hat-foto{background:var(--surface-2);padding:0;overflow:hidden}
.brand-mark.hat-foto img{width:100%;height:100%;object-fit:cover;display:block}

.fotozeile{display:flex;align-items:center;gap:16px;flex-wrap:wrap}
.fotoschau{width:72px;height:72px;border-radius:16px;flex:none;overflow:hidden;
  border:1px solid var(--line);background:var(--surface-2);display:grid;place-items:center;
  font-weight:700;font-size:22px;color:var(--muted)}
.fotoschau img{width:100%;height:100%;object-fit:cover;display:block}
.fotowahl{display:flex;flex-direction:column;gap:8px;flex:1 1 240px;min-width:0}
.fotowahl .knoepfe{display:flex;gap:10px;align-items:center;flex-wrap:wrap}
.fotowahl input[type=file]{font-size:13px;max-width:100%}

.feld-check{display:flex;align-items:flex-start;gap:9px;font-size:13px}
.feld-check input{margin-top:2px;width:15px;height:15px;accent-color:var(--accent);flex:none}
.form-aktionen{display:flex;gap:10px;align-items:center;flex-wrap:wrap;padding-top:4px}
.form-aktionen .spacer{margin-left:auto}
.btn-block{width:100%;justify-content:center;padding:10px 12px}
.pflicht{color:var(--bad)}

fieldset.gruppe{border:1px solid var(--line);border-radius:12px;padding:14px 15px 16px;margin:0}
fieldset.gruppe > legend{padding:0 7px;font-size:11px;letter-spacing:.07em;text-transform:uppercase;
  color:var(--muted);font-weight:650}

/* --- Fehlerseite --------------------------------------------- */

.fehlerseite .code{font-family:var(--mono);font-size:44px;font-weight:700;letter-spacing:-.03em;
  color:var(--accent);line-height:1;margin-bottom:10px}
.fehlerseite pre{white-space:pre-wrap;word-break:break-word;background:var(--surface-2);
  border:1px solid var(--line);border-radius:10px;padding:12px;font-family:var(--mono);
  font-size:11.5px;line-height:1.55;max-height:340px;overflow:auto;margin:16px 0 0}

/* --- Prüfliste (Selbstprüfung, Einrichtung) ------------------ */

.pruefliste{display:flex;flex-direction:column;gap:0;border:1px solid var(--line);border-radius:12px;overflow:hidden}
.pruefzeile{display:flex;gap:12px;padding:12px 14px;border-bottom:1px solid var(--line);align-items:flex-start}
.pruefzeile:last-child{border-bottom:0}
.pruefzeile .zeichen{width:20px;height:20px;border-radius:50%;flex:none;display:grid;place-items:center;
  font-size:12px;font-weight:700;color:#fff;margin-top:1px}
.pruefzeile.ok .zeichen{background:var(--ok)}
.pruefzeile.warnung .zeichen{background:var(--warn)}
.pruefzeile.fehler .zeichen{background:var(--bad)}
.pruefzeile .text b{display:block;font-weight:600;margin-bottom:2px}
.pruefzeile .text span{color:var(--muted);font-size:12.5px;line-height:1.5;display:block}
.pruefzeile .wert{margin-left:auto;font-family:var(--mono);font-size:11.5px;color:var(--muted);
  white-space:nowrap;padding-top:2px}

/* --- Kundenportal und Fahrer-App: eigener, schlanker Rahmen --- */

.portal{min-height:100vh;display:flex;flex-direction:column;background:var(--bg)}
.portal-kopf{background:var(--surface);border-bottom:1px solid var(--line);position:sticky;top:0;z-index:20}
.portal-kopf .innen{max-width:1080px;margin:0 auto;padding:12px 18px;display:flex;align-items:center;gap:14px}
.portal-kopf .brand{padding:0}
.portal-nav{display:flex;gap:2px;overflow:auto;max-width:1080px;margin:0 auto;padding:0 12px 8px;width:100%}
.portal-nav a{padding:7px 12px;border-radius:9px;color:var(--ink-2);font-weight:500;white-space:nowrap;text-decoration:none}
.portal-nav a:hover{background:var(--surface-2);color:var(--ink)}
.portal-nav a.is-active{background:var(--accent-soft);color:var(--accent-ink);font-weight:600}
.portal-inhalt{flex:1;width:100%;max-width:1080px;margin:0 auto;padding:18px;display:flex;flex-direction:column;gap:14px}
.portal-fuss{text-align:center;color:var(--muted);font-size:12px;padding:18px}

.portal .card{padding:16px}
.portal h2{font-size:16px;margin:0 0 12px;font-weight:650;letter-spacing:-.01em}

/* Fahrer-App: mobil zuerst, groß genug für die Bedienung im Fahrzeug */
.fahrer-app .portal-inhalt{max-width:640px;gap:12px}
.fahrer-app .btn{padding:11px 15px;font-size:15px;border-radius:11px}
.fahrer-app .btn-sm{padding:7px 11px;font-size:13px}

/* --- Als installierte App (vom Home-Bildschirm gestartet) ------
   Dann gibt es keine Adressleiste mehr, die den Rand hält: Unten liegt
   auf neueren iPhones der Home-Balken, in Querlage links und rechts die
   abgerundete Ecke. env(safe-area-inset-*) ist im Browser null und
   ändert dort deshalb nichts – die Regeln stehen trotzdem hier und
   nicht in einer iOS-Weiche. */
@media (display-mode: standalone){
  .portal-kopf .innen,
  .portal-nav{
    padding-left:calc(18px + env(safe-area-inset-left));
    padding-right:calc(18px + env(safe-area-inset-right));
  }
  .portal-inhalt{
    padding-left:calc(18px + env(safe-area-inset-left));
    padding-right:calc(18px + env(safe-area-inset-right));
  }
  .portal-fuss{padding-bottom:calc(18px + env(safe-area-inset-bottom))}
}

/* --- Rückmeldungen zu einer Verfügbarkeitsanfrage --------------
   Die Tage stehen als Kette unter dem Fahrer. Umbrechen ist Absicht:
   Ein Zeitraum kann vier Wochen lang sein, und waagrecht scrollen
   müsste man dann bei jeder Zeile einzeln. */
.anfrage-tage > td{padding:6px 12px 12px;background:var(--surface-2);
  border-bottom:1px solid var(--line)}
.tagchip{display:inline-flex;align-items:baseline;gap:6px;margin:3px 5px 0 0;
  padding:3px 9px;border-radius:9px;font-size:12px;border:1px solid var(--line);
  background:var(--surface);white-space:nowrap}
.tagchip b{font-weight:650;font-family:var(--mono);font-size:11.5px}
.tagchip i{font-style:normal;font-size:10.5px;opacity:.7;text-transform:uppercase;letter-spacing:.03em}
.tagchip.ja{border-color:rgba(63,154,85,.4);color:var(--ok)}
.tagchip.nein{border-color:rgba(180,35,24,.35);color:var(--bad)}

/* --- Balken „App installieren" ---------------------------------
   Steht ÜBER der Kopfleiste, solange die App im Browser läuft; pwa.js
   blendet ihn aus, sobald sie installiert ist oder der Fahrer ihn
   weggeklickt hat.

   In der Akzentfarbe und nicht als weiße Karte: Er ist der einzige
   Hinweis, dessen Missachtung dazu führt, dass ein Fahrer nie eine
   Meldung über eine Zuteilung bekommt. Eine leise Karte an dieser
   Stelle liest niemand. */
.install-balken{display:flex;gap:12px;align-items:center;padding:10px 16px;
  background:var(--accent);color:#fff;font-size:13px;line-height:1.45;
  position:relative;z-index:60}
.install-balken .sinnbild{width:20px;height:20px;flex:none;opacity:.9}
.install-balken .text{flex:1;min-width:0}
.install-balken .text b{font-weight:650;margin-right:6px}
.install-balken .text span{opacity:.9}
.install-balken .teilen{display:inline-block;vertical-align:-3px;width:15px;height:15px}

/* Der Knopf steht auf farbigem Grund und braucht deshalb eigene Farben –
   .btn erbt sonst die Linien- und Flächenfarben der Seite und
   verschwindet im Blau. */
.install-balken .btn{flex:none;background:#fff;border-color:#fff;color:var(--accent-ink);font-weight:600}
.install-balken .btn:hover{background:#eef1ff;border-color:#eef1ff}
.install-balken .zu{flex:none;border:0;background:transparent;color:#fff;opacity:.75;
  cursor:pointer;padding:4px;border-radius:7px;display:grid;place-items:center}
.install-balken .zu:hover{opacity:1;background:rgba(255,255,255,.15)}
.install-balken .zu svg{width:16px;height:16px}

/* Auf dem Telefon läuft der Text über mehrere Zeilen. Er bekommt
   deshalb den Platz zwischen Sinnbild und Schließer, und „Installieren"
   rutscht in eine zweite Zeile nach rechts.

   OHNE order:4 AM KNOPF stünde er zwischen Text und Schließer und
   drückte den Text auf eine eigene Zeile – dann sind in der ersten nur
   noch ein Sinnbild und ein Kreuz zu sehen, und der Balken sieht aus
   wie ein Fehler. Auf iOS gibt es den Knopf gar nicht (dort steht die
   Anleitung), die zweite Zeile entfällt dann von selbst. */
@media (max-width:560px){
  .install-balken{flex-wrap:wrap;align-items:flex-start;padding:9px 12px;font-size:12.5px}
  .install-balken .sinnbild{margin-top:1px}
  .install-balken .text{flex:1 1 60%}
  .install-balken .btn{order:4;margin-left:auto}
}

/* --- Benachrichtigungen im Konto ------------------------------- */
.push-zustand{display:block;font-size:13.5px;color:var(--muted);margin-bottom:12px}
.push-zustand.gut{color:var(--ok)}
.push-zustand.warnt{color:var(--warn)}
.push-geraete{list-style:none;margin:12px 0 0;padding:0;display:flex;flex-direction:column;gap:6px}
.push-geraete li{display:flex;gap:8px;align-items:baseline;font-size:13px;color:var(--muted)}
.push-geraete li b{color:var(--ink);font-weight:600}
.auftrag-karte{border:1px solid var(--line);border-radius:14px;background:var(--surface);
  box-shadow:var(--shadow);overflow:hidden}
.auftrag-karte.ist-neu{border-color:var(--info);box-shadow:0 0 0 2px rgba(21,82,200,.14),var(--shadow)}
.auftrag-karte .kopf{display:flex;align-items:baseline;gap:10px;padding:13px 15px 9px}
.auftrag-karte .zeit{font-family:var(--mono);font-size:23px;font-weight:700;letter-spacing:-.02em}
.auftrag-karte .bereit{font-size:12px;color:var(--muted)}
.auftrag-karte .strecke{padding:0 15px 12px;display:flex;flex-direction:column;gap:6px}
.auftrag-karte .fuss{display:flex;gap:8px;padding:11px 15px;border-top:1px solid var(--line);
  background:var(--surface-2);flex-wrap:wrap;align-items:center}

/* Leerzustand eines Bereichs.
   NICHT ".leer" nennen: im Prototyp-CSS ist "leer" der Modifikator des
   Legendenkästchens (.vf-key.leer) und der leeren Kalenderzelle
   (.vf td.leer). Eine eigene Klasse mit demselben Namen hätte dem
   12-Pixel-Kästchen 38 Pixel Innenabstand verpasst – und genau das ist
   hier schon einmal passiert. */
.leerhinweis{padding:38px 18px;text-align:center;color:var(--muted)}
.leerhinweis b{display:block;color:var(--ink);font-size:15px;margin-bottom:5px;font-weight:600}

/* --- Dialoge -------------------------------------------------
   Das native <dialog> bringt Fokusfalle, Escape und Hintergrund von
   selbst mit – das alles nachzubauen wäre viel Code für nichts. */

dialog.dlg{border:0;padding:0;border-radius:var(--radius);background:var(--surface);color:var(--ink);
  box-shadow:0 34px 70px -26px rgba(16,24,40,.65);width:min(680px,calc(100vw - 28px));max-height:calc(100vh - 40px)}
dialog.dlg::backdrop{background:rgba(16,24,40,.5);backdrop-filter:blur(2px)}
dialog.dlg.schmal{width:min(520px,calc(100vw - 28px))}
.dlg-form{display:flex;flex-direction:column;max-height:calc(100vh - 40px)}
.dlg-kopf{padding:16px 18px 12px;border-bottom:1px solid var(--line);display:flex;gap:10px;
  align-items:flex-start;flex:none}
.dlg-kopf h3{margin:0;font-size:16px;letter-spacing:-.01em}
.dlg-kopf .sub{font-size:12px;color:var(--muted);margin-top:3px}
.dlg-kopf > .icon-btn{margin-left:auto}
.dlg-koerper{padding:16px 18px;overflow-y:auto;overscroll-behavior:contain;display:flex;
  flex-direction:column;gap:13px;flex:1 1 auto;min-height:0}
/* Flex-Kinder schrumpfen sonst auf null, sobald der Inhalt überläuft –
   die Trefferliste und die Karte wären dann unsichtbar, obwohl sie da
   sind. Derselbe Griff wie im Prototyp bei .drawer-body. */
.dlg-koerper > *{flex:0 0 auto}
.dlg-fuss{padding:12px 18px;border-top:1px solid var(--line);display:flex;gap:8px;align-items:center;
  background:var(--surface);flex:none}

/* Trefferliste in Such- und Adressdialogen */
.trefferliste{border:1px solid var(--line);border-radius:11px;max-height:230px;overflow:auto;
  display:flex;flex-direction:column;background:var(--surface-2)}
.treffer{display:flex;flex-direction:column;gap:2px;align-items:flex-start;text-align:left;
  border:0;border-bottom:1px solid var(--line);background:transparent;color:inherit;
  padding:9px 12px;cursor:pointer;width:100%}
.treffer:last-child{border-bottom:0}
.treffer:hover,.treffer:focus-visible{background:var(--row-hover)}
.treffer b{font-weight:600;font-size:13px}
.treffer span{font-size:12px;color:var(--muted)}
.treffer .rechts{margin-left:auto}

/* --- Karte --------------------------------------------------- */

.karte{width:100%;background:var(--surface-3);min-height:180px}
.karte .leaflet-container{font:inherit;background:var(--surface-3)}

/* --- Protokoll ------------------------------------------------ */

.protokoll{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:0}
.protokoll li{display:flex;gap:10px;align-items:flex-start;padding:9px 0;border-bottom:1px solid var(--line)}
.protokoll li:last-child{border-bottom:0}
.protokoll .marke{flex:none;min-width:96px;justify-content:center}

/* --- Kleinteile ---------------------------------------------- */

.marke{display:inline-flex;align-items:center;gap:5px;padding:2.5px 8px;border-radius:999px;
  font-size:11.5px;font-weight:600;line-height:1.5;border:1px solid transparent;white-space:nowrap}
.marke .punkt{width:7px;height:7px;border-radius:50%;background:currentColor;flex:none}
.marke.ok{color:var(--ok);background:rgba(63,154,85,.12);border-color:rgba(63,154,85,.25)}
.marke.warn{color:var(--warn);background:rgba(194,121,12,.12);border-color:rgba(194,121,12,.25)}
.marke.bad{color:var(--bad);background:rgba(180,35,24,.1);border-color:rgba(180,35,24,.24)}
.marke.info{color:var(--info);background:rgba(21,82,200,.1);border-color:rgba(21,82,200,.24)}
.marke.grau{color:var(--muted);background:var(--surface-3);border-color:var(--line)}

.stapel{display:flex;flex-direction:column;gap:3px;min-width:0}
.stapel .haupt{font-weight:550}
.stapel .neben{font-size:12px;color:var(--muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

.trenner{height:1px;background:var(--line);border:0;margin:2px 0}
.mono{font-family:var(--mono)}
.rechts{text-align:right}
.mitte{text-align:center}
.gedaempft{color:var(--muted)}
.nowrap{white-space:nowrap}
.visuell-versteckt{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0 0 0 0);white-space:nowrap;border:0}

@media (max-width:720px){
  .schlicht{padding:16px 12px}
  .schlicht .card{padding:20px 18px}
  .portal-kopf .innen{padding:10px 14px}
  .portal-inhalt{padding:14px}
}

/* --- Kopfleiste des Portals auf schmalen Telefonen -------------

   SIE LIEF ÜBER: Marke, Farbschema, Name und Abmelden brauchen
   zusammen rund 407 px, ein iPhone 15 hat 393. Die Folge war kein
   abgeschnittener Name, sondern eine Seite, die sich seitlich
   wegschieben ließ – auf genau dem Gerät, für das die Fahrer-App
   gedacht ist.

   ZWEI MASSNAHMEN, UND BEIDE WERDEN GEBRAUCHT:

   1. Der Name darf schrumpfen und wird notfalls abgeschnitten. Das ist
      die Sicherung, die IMMER hält – ein fester Umbruchpunkt kann es
      nicht, weil die Breite am Namen hängt: „Lukas Prantner" braucht
      94 px, „Maximilian Brandstätter" halb so viel mehr. Ohne
      min-width:0 nützt das nichts; .btn steht auf nowrap, und ein
      Flex-Kind schrumpft nicht unter seinen Inhalt, solange es das
      nicht darf.

   2. Unter 480 px verschwindet er ganz. Dort bliebe von ihm ohnehin
      nur „Lukas P…" übrig, und das ist keine Auskunft, sondern ein
      Rest. Er wird dabei NICHT ausgeblendet, sondern nur unsichtbar
      gestellt (dieselben Regeln wie .visuell-versteckt weiter oben):
      display:none nähme auch der Vorlesehilfe den Namen des Knopfes,
      und übrig bliebe ein Sinnbild ohne Beschriftung. */

.portal-kopf .innen > .btn,
.portal-kopf .brand{min-width:0}
.portal-kopf .lbl{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

@media (max-width:480px){
  .portal-kopf .lbl{position:absolute;width:1px;height:1px;padding:0;margin:-1px;
    overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
  .portal-kopf .innen{gap:10px}
}

/* --- Tagesplaner ----------------------------------------------
   Der Prototyp bringt die Zeitachse vollständig mit (app.css). Hier
   steht nur, was die serverseitig gezeichnete Fassung zusätzlich
   braucht: das Ein- und Ausblenden der Unterzeilen, die
   Auslastungsleiste und das Änderungsjournal.                     */

/* Unterzeilen stehen im Markup und sind zugeklappt versteckt.
   Ohne diese Regel gewönne .grow-row{display:flex} gegen [hidden]. */
.grow-row[hidden]{display:none}

/* Zugeklappt trägt die Gruppenzeile die Balken, aufgeklappt die
   Unterzeilen – sonst stünde jeder Auftrag zweimal da. */
.lane.grp.is-open > .track > .trip{display:none}

/* Ein stornierter Auftrag bleibt sichtbar, aber durchgestrichen: er
   ist Teil der Geschichte des Tages und darf nicht einfach fehlen. */
.trip.is-storniert .core{text-decoration:line-through;opacity:.75}

/* Die Seitenwahl im Filterkopf */
.tagwahl{display:flex;align-items:center;gap:4px}
.tagwahl input{flex:1;min-width:120px}

/* Umschalter aus Verweisen – .seg in app.css kennt nur Knöpfe */
.seg a{padding:5px 10px;font-size:12px;color:var(--ink-2);text-decoration:none;background:var(--surface);
  white-space:nowrap}
.seg a:hover{background:var(--surface-2)}
.seg a.is-active{background:var(--accent-soft);color:var(--accent-ink);font-weight:600}

/* Auslastungsleiste (§5.5) */
.auslastung .counters{padding:12px 14px;align-items:stretch}
.auslastung .counter{cursor:default;flex-direction:column;align-items:flex-start;gap:1px}
.auslastung .counter b{font-size:16px}
.auslastung .counter .hinweis{font-size:10.5px;color:var(--warn);font-weight:600}
.auslastung.is-eng{border-color:rgba(194,121,12,.45)}
.auslastung .spacer{margin-left:auto}
.auslastung-tat{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.hinweiskasten{font-size:12px;color:var(--ink-2);line-height:1.45;max-width:520px;
  border-left:3px solid var(--line-strong);padding-left:10px}
.hinweiskasten b{display:block;color:var(--ink);font-weight:600}
.hinweiskasten.warn{border-left-color:var(--warn)}
.hinweiskasten.warn b{color:var(--warn)}

/* Änderungsjournal */
.journal-zeile{display:flex;align-items:center;gap:10px;padding:9px 0;border-bottom:1px solid var(--line);
  font-size:12.5px;line-height:1.4}
.journal-zeile:last-child{border-bottom:0}
.journal-zeile span{flex:1;min-width:0}
.journal-zeile .btn{flex:none}

/* Beschreibungsliste im Detailfenster */
.beschreibung{display:grid;grid-template-columns:auto 1fr;gap:6px 16px;margin:0;font-size:12.5px}
.beschreibung dt{color:var(--muted);white-space:nowrap}
.beschreibung dd{margin:0;color:var(--ink)}

.schalterliste{display:flex;flex-direction:column;gap:9px}

/* Beim Ziehen der Beschriftungsspalte soll nichts markiert werden. */
body.is-resizing{cursor:col-resize;user-select:none}

/* Tagesliste */
.grid tr[data-auftrag]{cursor:pointer}
.grid tr.ist-storniert td{opacity:.6;text-decoration:line-through}
/* Eine Zahl, hinter der noch Arbeit steckt.
   NICHT ".ist-offen" nennen: eine unbeschränkte ist-/is-Klasse trifft
   jedes Element, das denselben Zustandsnamen trägt – hier war es das
   Tagesfeld .mr-tag.ist-offen im Fahrerkalender, dessen Ziffern
   dadurch orange wurden. Zustandsklassen immer mit ihrem Block. */
.offen-zahl{color:var(--warn)}
.lane-tx b a{color:inherit;text-decoration:none}
.lane-tx b a:hover{color:var(--accent-ink);text-decoration:underline}

/* --- Verfügbarkeitskalender -----------------------------------
   Die Matrix selbst (.vf, .vfwrap, .vf-key) steht im Prototyp-CSS.
   Hier nur, was die serverseitige Fassung ergänzt.               */

/* Umschalter aus Verweisen – .seg-in in app.css kennt nur Knöpfe */
.seg-in a{padding:7px 13px;font-size:12.5px;color:var(--ink-2);text-decoration:none;white-space:nowrap}
.seg-in a:hover{background:var(--surface-2)}
.seg-in a.is-active{background:var(--accent-soft);color:var(--accent-ink);font-weight:600}

.kalendertitel{font-size:13px;min-width:150px;text-align:center}
.vf-lbl{text-decoration:none;color:inherit}

/* Eine Absage an einem Tag, an dem schon Aufträge liegen: der Fall,
   den die Disposition sofort sehen muss. */
.vf td.ist-konflikt{box-shadow:inset 0 0 0 2px var(--bad)}
.vf tfoot td{position:sticky;bottom:0;background:var(--surface-3);border-top:1px solid var(--line-strong);
  font-family:var(--mono);font-size:11.5px}
.vf tfoot .vf-name{z-index:5}

.wochentage{display:flex;gap:6px;flex-wrap:wrap}
.wtag{position:relative;cursor:pointer}
.wtag input{position:absolute;opacity:0;width:0;height:0}
.wtag span{display:inline-flex;align-items:center;justify-content:center;min-width:38px;padding:6px 4px;
  border:1px solid var(--line-strong);border-radius:8px;background:var(--surface);font-size:12px}
.wtag input:checked + span{background:var(--accent-soft);border-color:var(--accent);
  color:var(--accent-ink);font-weight:600}
.wtag input:focus-visible + span{outline:2px solid var(--accent);outline-offset:2px}

/* --- Verfügbarkeit melden (Fahrer-App) ------------------------ */

.tagliste{display:flex;flex-direction:column;gap:10px}
.tagzeile{border:1px solid var(--line);border-radius:12px;padding:12px 14px;background:var(--surface)}
/* Wie im Monatsraster: das Wochenende nur am Rand, nicht in der
   Fläche – sonst liest sich derselbe Zustand am Samstag anders. */
.tagzeile.ist-wochenende{border-style:dashed}
.tagzeile.ist-gesperrt{opacity:.7}
.tagkopf{display:flex;align-items:baseline;gap:9px;margin-bottom:9px}
.tagkopf b{font-size:14px}
.tagkopf span{font-size:12px;color:var(--muted)}
.taggesperrt{display:flex;align-items:center;gap:9px;flex-wrap:wrap}
.tagwahl-gruppe{display:flex;gap:6px;flex-wrap:wrap}
.tagknopf{position:relative;flex:1 1 110px;cursor:pointer}
.tagknopf input{position:absolute;opacity:0;width:0;height:0}
.tagknopf span{display:flex;align-items:center;justify-content:center;padding:10px 8px;
  border:1px solid var(--line-strong);border-radius:10px;background:var(--surface);
  font-size:13px;text-align:center;line-height:1.25}
.tagknopf input:checked + span{background:var(--accent-soft);border-color:var(--accent);
  color:var(--accent-ink);font-weight:600}
.tagknopf input:focus-visible + span{outline:2px solid var(--accent);outline-offset:2px}
.tagzeiten{display:flex;flex-direction:column;gap:9px;margin-top:10px}

/* --- Fahrer-App: Tagesübersicht -------------------------------
   Alles hier ist für den Daumen gebaut, nicht für die Maus: große
   Trefferflächen, wenig nebeneinander, Uhrzeit vor allem anderen. */

.tagkopf-leiste{display:flex;align-items:center;gap:10px}
.tagkopf-mitte{flex:1;text-align:center;display:flex;flex-direction:column;gap:2px}
.tagkopf-mitte b{font-size:15px}

.tages-kopf{display:flex;flex-direction:column;gap:8px}
.tages-zahlen{display:flex;align-items:center;gap:6px;flex-wrap:wrap;font-size:13px;color:var(--ink-2)}
.tages-zahlen b{font-family:var(--mono);color:var(--ink)}
.tages-fahrzeug{display:flex;gap:8px;flex-wrap:wrap}
.punkt-trenner{color:var(--line-strong)}

.auftrag-karte{display:block;text-decoration:none;color:inherit}
.auftrag-karte:hover{border-color:var(--accent)}
.auftrag-karte .kopf{align-items:center;flex-wrap:wrap}
.auftrag-karte .kopf .spacer{margin-left:auto}
.auftrag-karte .strecke .ort{display:flex;align-items:center;gap:8px;font-size:14px}
.auftrag-karte .strecke .ort svg{width:16px;height:16px;stroke:var(--muted);fill:none;stroke-width:1.7;flex:none}
.auftrag-karte .fuss{font-size:12px;color:var(--muted)}
.auftrag-karte .fuss .spacer{margin-left:auto}
.karten-hinweis{padding:9px 15px;border-top:1px solid var(--line);font-size:12.5px;color:var(--warn);
  background:rgba(194,121,12,.07)}

.tagesgruppe{display:flex;flex-direction:column;gap:10px}
.tagesgruppe-kopf{display:flex;align-items:center;gap:9px;flex-wrap:wrap;padding:4px 2px;font-size:13px}
.tagesgruppe-kopf .spacer{margin-left:auto}

/* --- Fahrer-App: Auftragsdetail ------------------------------- */

.auftrag-titel{display:flex;align-items:flex-start;gap:10px}
.strecke-gross{display:flex;flex-direction:column;gap:8px;margin-top:14px;padding-left:4px;
  border-left:2px solid var(--line-strong)}
.ort-zeile{display:flex;align-items:baseline;gap:12px;padding-left:10px}
.ort-zeile .zeit{font-size:17px;font-weight:700;min-width:52px}
.ort-zeile .name{font-size:15px}

.kontaktkasten{display:flex;align-items:center;gap:12px;margin-top:14px;padding:12px 14px;
  border:1px solid var(--line);border-radius:12px;background:var(--surface-2);flex-wrap:wrap}
.kontaktkasten b{display:block;font-size:11px;letter-spacing:.05em;text-transform:uppercase;color:var(--muted)}
.kontaktkasten span{font-size:15px}
.kontaktkasten .btn{margin-left:auto}

.kommentarkasten{margin-top:14px;padding:12px 14px;border-left:3px solid var(--accent);
  background:var(--surface-2);border-radius:0 10px 10px 0;font-size:13.5px;line-height:1.5}
.kommentarkasten p{margin:0 0 8px}
.kommentarkasten p:last-child{margin:0}

.gastliste{list-style:none;margin:0;padding:0;display:flex;flex-direction:column}
.gastliste li{display:flex;align-items:center;gap:10px;padding:10px 0;border-bottom:1px solid var(--line)}
.gastliste li:last-child{border-bottom:0}
.gastliste .spacer{margin-left:auto}

.aktionen{display:flex;flex-direction:column;gap:12px}
.aktionen .btn-block{width:100%;justify-content:center}
.aktionen details.ablehnen{border-top:1px solid var(--line);padding-top:12px}
.aktionen details.ablehnen summary{cursor:pointer;font-size:13px;color:var(--muted);padding:4px 0}
.aktionen details.ablehnen summary:hover{color:var(--bad)}
.aktionen details.ablehnen[open] summary{color:var(--bad);font-weight:600;margin-bottom:10px}
.zurueck-leiste{display:flex;justify-content:center;padding:4px 0 8px}

/* --- Fahrer-App: Monatskalender ------------------------------- */

.monatsraster{display:grid;grid-template-columns:repeat(7,minmax(0,1fr));gap:4px}
.mr-kopf{text-align:center;font-size:10.5px;letter-spacing:.05em;text-transform:uppercase;
  color:var(--muted);font-weight:600;padding-bottom:2px}
.mr-leer{min-height:56px}
.mr-tag{position:relative;display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:2px;min-height:56px;border:1px solid var(--line);border-radius:10px;background:var(--surface);
  font:inherit;cursor:pointer;padding:4px 2px;text-align:center}
.mr-tag:hover{border-color:var(--accent)}
.mr-zahl{font-family:var(--mono);font-size:14px;font-weight:600;line-height:1}
.mr-text{font-size:9.5px;color:var(--muted);line-height:1.15;word-break:break-word}
.mr-fahrten{position:absolute;top:3px;right:4px;font-family:var(--mono);font-size:9px;
  background:var(--accent);color:#fff;border-radius:999px;padding:0 4px;line-height:1.5}
.mr-tag.ist-frei{background:rgba(63,154,85,.14);border-color:rgba(63,154,85,.3)}
.mr-tag.ist-frei .mr-text{color:#2f7a44}
.mr-tag.ist-nein{background:rgba(200,120,20,.15);border-color:rgba(200,120,20,.3)}
.mr-tag.ist-nein .mr-text{color:#a8620d}
/* Das Wochenende bekommt KEINEN eigenen Hintergrund. Vorher stand hier
   background-color:var(--surface-2) – das kam nach .ist-frei und
   .ist-nein und übermalte deren Farbe: derselbe Zustand sah samstags
   anders aus als dienstags, und die Farbe ist die Auskunft, um die es
   in diesem Kalender geht. Der Rand reicht als Hinweis; welcher Tag
   welcher ist, sagt ohnehin die Spalte darüber. */
.mr-tag.ist-wochenende{border-style:dashed}
.mr-kopf.ist-wochenende{opacity:.6}
.mr-tag.ist-heute{box-shadow:inset 0 0 0 2px var(--accent)}
.mr-tag.ist-gesperrt{background:repeating-linear-gradient(135deg,rgba(180,35,24,.14) 0 5px,transparent 5px 10px);
  cursor:default;color:var(--muted)}

.anfrage-karte .kopf{display:flex;align-items:center;gap:10px;margin-bottom:8px}
.anfrage-karte .kopf .spacer{margin-left:auto}
.anfrage-karte .nachricht{margin:0 0 10px;font-size:13.5px;line-height:1.5;color:var(--ink-2)}
.anfrage-karte .fuss{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.anfrage-karte .fuss .spacer{margin-left:auto}

@media (max-width:420px){
  .monatsraster{gap:3px}
  .mr-tag{min-height:50px}
  .mr-text{font-size:9px}
}

/* Der Fahrzeugwechsel nennt alle Kennzeichen des Tages und wird damit
   länger als eine Marke sonst. Auf dem Telefon muss er umbrechen
   dürfen – .marke hat sonst white-space:nowrap. */
.tages-fahrzeug .marke{white-space:normal;text-align:left;line-height:1.4}

/* --- Kundenportal ---------------------------------------------
   Ruhiger als das Backend: wenige Karten untereinander, keine
   Tabellen. Der Kunde sieht seine Buchung, nicht die Disposition. */

.portal-leiste{display:flex;align-items:center;gap:10px;flex-wrap:wrap;padding:2px 0}
.portal-leiste .spacer{margin-left:auto}
.portal-leiste .seg-in .n{font-family:var(--mono);font-size:10.5px;opacity:.7;margin-left:4px}

.buchung-karte{display:block;text-decoration:none;color:inherit;border:1px solid var(--line);
  border-radius:14px;background:var(--surface);box-shadow:var(--shadow);padding:14px 16px}
.buchung-karte:hover{border-color:var(--accent)}
.buchung-karte .kopf{display:flex;align-items:center;gap:10px;margin-bottom:6px}
.buchung-karte .kopf .spacer{margin-left:auto}
.buchung-karte .titelzeile{font-size:15px;font-weight:600;margin-bottom:4px}
.buchung-karte .daten{display:flex;gap:6px;flex-wrap:wrap;font-size:12.5px;color:var(--muted)}

.fahrtliste{list-style:none;margin:0;padding:0;display:flex;flex-direction:column}
.fahrtliste li{display:flex;gap:14px;align-items:flex-start;padding:12px 0;border-bottom:1px solid var(--line)}
.fahrtliste li:last-child{border-bottom:0}
.fahrtliste .zeit{flex:none;min-width:62px;display:flex;flex-direction:column;line-height:1.2}
.fahrtliste .zeit b{font-family:var(--mono);font-size:16px}
.fahrtliste .zeit span{font-size:11px;color:var(--muted)}
.fahrtliste .inhalt{flex:1;min-width:0}
.fahrtliste .strecke{font-size:14px;font-weight:550}
.fahrtliste .daten{font-size:12px;color:var(--muted);margin-top:3px}
.fahrtliste .kommentar{font-size:12.5px;color:var(--ink-2);margin-top:5px;
  border-left:2px solid var(--line-strong);padding-left:8px}

.verlaufliste{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:0}
.verlaufliste li{display:flex;gap:12px;align-items:baseline;padding:7px 0;border-bottom:1px solid var(--line);
  font-size:13px}
.verlaufliste li:last-child{border-bottom:0}
.verlaufliste .mono{color:var(--muted);font-size:11.5px;flex:none;min-width:118px}

details.stornieren summary{cursor:pointer;font-size:13px;color:var(--muted);padding:2px 0}
details.stornieren summary:hover{color:var(--bad)}
details.stornieren[open] summary{color:var(--bad);font-weight:600;margin-bottom:10px}

/* Der Assistent */
.assistent-schritte{list-style:none;margin:0 0 4px;padding:0;display:flex;gap:6px;flex-wrap:wrap}
.assistent-schritte li{display:flex;align-items:center;gap:7px;padding:7px 12px;border-radius:999px;
  border:1px solid var(--line);background:var(--surface);font-size:12.5px;color:var(--muted)}
.assistent-schritte .zahl{display:grid;place-items:center;width:19px;height:19px;border-radius:50%;
  background:var(--surface-3);font-family:var(--mono);font-size:11px;flex:none}
.assistent-schritte li.ist-aktiv{border-color:var(--accent);background:var(--accent-soft);
  color:var(--accent-ink);font-weight:600}
.assistent-schritte li.ist-aktiv .zahl{background:var(--accent);color:#fff}
.assistent-schritte li.ist-fertig{color:var(--ok)}
.assistent-schritte li.ist-fertig .zahl{background:rgba(63,154,85,.18);color:var(--ok)}

.wahlliste{display:flex;flex-direction:column;gap:8px}
.wahlfeld{position:relative;display:block;cursor:pointer}
.wahlfeld input{position:absolute;opacity:0;width:0;height:0}
.wahlfeld > span{display:flex;flex-direction:column;gap:2px;padding:11px 13px;border-radius:11px;
  border:1px solid var(--line-strong);background:var(--surface);line-height:1.35}
.wahlfeld .neben{font-size:12px;color:var(--muted)}
.wahlfeld input:checked + span{border-color:var(--accent);background:var(--accent-soft)}
.wahlfeld input:focus-visible + span{outline:2px solid var(--accent);outline-offset:2px}

.adresskarte .kopf{display:flex;align-items:center;gap:9px;flex-wrap:wrap;margin-bottom:9px}
.adresskarte .kopf .spacer{margin-left:auto}
.adresskarte .kopf form{display:inline}
.adresskarte .anschrift{font-size:13.5px;line-height:1.6;color:var(--ink-2)}

/* --- Buchungs-Wizard ------------------------------------------
   Zwei Spalten: links entwerfen, rechts das Ergebnis. Auf schmalen
   Bildschirmen untereinander – die Vorschau zuerst zu sehen wäre
   verwirrend, also bleibt die Reihenfolge wie im Markup. */

.wizard{display:grid;grid-template-columns:minmax(0,420px) minmax(0,1fr);gap:14px;align-items:start}
.wizard-entwurf,.wizard-vorschau{min-width:0;display:flex;flex-direction:column;gap:14px}
.wizard .card{padding:14px}
.wizard .tbar{margin:-14px -14px 0;padding:10px 14px}
.wizard .tblwrap{margin:0 -14px;border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
.wizard .empty{padding:34px 14px}
.wizard fieldset.gruppe{margin-top:2px}
.wizard .feld-check label{font-size:13px;cursor:pointer}

@media (max-width:1100px){
  .wizard{grid-template-columns:minmax(0,1fr)}
}

/* --- Suche über alles (KONZEPT §14) ---------------------------
   NICHT .trefferliste/.treffer benutzen: die gehören den Such- und
   Adressdialogen und haben dort feste Höhe mit eigenem Rollbalken.
   Hier soll die Liste so lang sein, wie sie ist. */

.suchkopf{display:flex;align-items:center;gap:8px;padding:11px 14px;border-bottom:1px solid var(--line)}
.suchkopf b{font-size:14px;font-weight:650}

.suchergebnis{list-style:none;margin:0;padding:0}
.suchergebnis li{border-bottom:1px solid var(--line)}
.suchergebnis li:last-child{border-bottom:0}
.suchergebnis a{display:flex;flex-direction:column;gap:2px;padding:10px 14px;
  color:inherit;text-decoration:none}
.suchergebnis a:hover,.suchergebnis a:focus-visible{background:var(--row-hover)}
.suchergebnis b{font-weight:600;font-size:14px}
.suchergebnis span{font-size:12.5px}

.suchmehr{margin:0;padding:9px 14px;border-top:1px solid var(--line);
  font-size:12.5px;color:var(--muted)}

/* --- Import aus Excel -----------------------------------------
   Der Assistent läuft in BEIDEN Oberflächen – im Backend mit
   Seitenleiste, im Portal ohne. Deshalb hier ausschließlich
   Abstände, Raster und Zustände; Farben kommen aus den Variablen
   und stimmen damit in beiden Farbschemata von selbst.

   Alles trägt das Präfix .imp-. Ohne das griffen Namen wie .gruppe
   oder .fuss in die Formularbausteine hinein, die überall sonst
   benutzt werden. */

.imp{display:flex;flex-direction:column;gap:14px}
.imp .assistent-schritte{margin:0}
.imp .assistent-schritte a{color:inherit;text-decoration:none}
.imp .assistent-schritte a:hover{text-decoration:underline}

.imp-datei{margin-left:auto;gap:6px !important;color:var(--muted);
  border-color:var(--line) !important;max-width:340px}
.imp-datei svg{width:14px;height:14px;fill:none;stroke:currentColor;stroke-width:1.7;flex:none}
.imp-datei span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

.imp-zwei{display:grid;grid-template-columns:minmax(0,1.55fr) minmax(300px,.45fr);
  gap:14px;align-items:start}
.imp-seite{display:flex;flex-direction:column;gap:14px}
.imp-seite h2{margin:0 0 10px}

/* Die Ablagefläche. Sie ist ein <label> um ein verstecktes
   Dateifeld – so funktioniert der Klick ohne eine Zeile Skript,
   und das Ziehen kommt in import.js dazu. */
.imp-drop{display:flex;flex-direction:column;align-items:center;gap:7px;
  margin:18px;padding:46px 20px;text-align:center;cursor:pointer;
  border:1.5px dashed var(--line-strong);border-radius:14px;
  background:var(--surface-2);color:var(--muted);
  transition:border-color .12s,background .12s,transform .12s}
.imp-drop input[type=file]{position:absolute;opacity:0;width:0;height:0}
.imp-drop b{color:var(--ink);font-size:16px}
.imp-drop span{font-size:12.5px;max-width:420px}
.imp-drop-symbol{width:34px;height:34px;fill:none;stroke:currentColor;
  stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round;opacity:.75}
.imp-drop-btn{margin-top:9px;pointer-events:none}
.imp-drop:hover,.imp-drop:focus-visible{border-color:var(--accent);background:var(--accent-soft)}
.imp-drop.ist-ueber{border-color:var(--accent);background:var(--accent-soft);transform:scale(1.01)}
.imp-drop.ist-gewaehlt{border-style:solid;border-color:var(--ok);background:var(--surface-2)}

.imp-erklaerung{margin:0;padding:0 0 0 20px;display:flex;flex-direction:column;gap:11px;
  font-size:13px;color:var(--ink-2);line-height:1.5}
.imp-erklaerung b{color:var(--ink);font-weight:600}

.imp-vorgaenge{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:8px}
.imp-vorgaenge li{display:flex;align-items:center;gap:10px;padding:9px 11px;
  border:1px solid var(--line);border-radius:11px;background:var(--surface-2)}
.imp-vorgaenge b{display:block;font-size:13px;font-weight:600;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:210px}
.imp-vorgaenge .neben{font-size:11.5px;color:var(--muted)}

.imp-laeuft{display:flex;align-items:center;gap:12px;padding:13px 16px}
.imp-laeuft svg{width:20px;height:20px;fill:none;stroke:var(--warn);stroke-width:1.7;flex:none}
.imp-laeuft b{display:block;font-size:14px}
.imp-laeuft .neben{font-size:12.5px;color:var(--muted)}

.imp-kopfkarte{display:flex;align-items:center;gap:12px;padding:13px 18px}
.imp-kopfkarte b{display:block;font-size:14.5px}
.imp-kopfkarte .neben{font-size:12.5px;color:var(--muted)}

/* Die Zuordnungsmaske: drei Spalten, damit dreißig Angaben auf
   einen Bildschirm passen. Wer scrollen muss, um zu vergleichen,
   vergleicht nicht. */
.imp-zuordnung{display:grid;grid-template-columns:repeat(auto-fill,minmax(268px,1fr));
  gap:12px;padding:14px 18px 18px}
.imp-feld{display:flex;flex-direction:column;gap:4px;padding:10px 11px;
  border:1px solid var(--line);border-radius:11px;background:var(--surface-2)}
.imp-feld > label{font-size:12px;font-weight:600;color:var(--ink-2)}
.imp-feld select{width:100%}
.imp-feld .hilfe{font-size:11.5px;line-height:1.4;min-height:2.3em}
.imp-feld.ist-belegt{border-color:rgba(63,154,85,.35);background:rgba(63,154,85,.05)}
.imp-feld.ist-offen{border-color:var(--bad);background:rgba(180,35,24,.06)}
.imp-beispiel{color:var(--ink-2);font-family:var(--mono);font-size:11px;font-weight:500}

.imp-frei{display:flex;flex-wrap:wrap;gap:5px}

.imp-fuss{display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  padding:12px 16px;border:1px solid var(--line);border-radius:14px;background:var(--surface)}

/* Die Gruppierungsregeln. Die Zahl rechts ist das Wesentliche –
   sie zeigt die Folge der Wahl, bevor man sie trifft. */
.imp-regel > span > b{display:flex;align-items:center;gap:8px}
.imp-zahl{margin-left:auto;font-family:var(--mono);font-size:11.5px;font-weight:600;
  color:var(--muted);background:var(--surface-3);border-radius:999px;padding:1px 8px;white-space:nowrap}
.imp-regel input:checked + span .imp-zahl{background:var(--accent);color:#fff}

.imp-unterfeld{margin:-2px 0 4px 13px;padding-left:11px;border-left:2px solid var(--accent-soft)}

.imp-vorschau .kpi div{background:var(--surface)}
.imp-kpi{padding:14px}
.imp-klein{font-size:13px !important;letter-spacing:-.2px}
.imp-meldung{margin:0}

.imp-gruppe{overflow:hidden}
.imp-gruppe .wz-h{gap:10px}
.imp-gruppe.ist-fehler .wz-h{background:rgba(180,35,24,.07);border-bottom-color:rgba(180,35,24,.22)}
.imp-gruppe.ist-entfernt{opacity:.72}
.imp-gruppe .tblwrap{border-top:0;max-height:none}

.imp-buchungkopf > svg{width:17px;height:17px;fill:none;stroke:var(--muted);stroke-width:1.6;flex:none}
.imp-buchungkopf .haupt{font-size:14px}
.imp-buchungkopf .neben{font-size:12px;color:var(--muted)}

/* Die bearbeitbare Tabelle. Die Felder sitzen randlos in der Zelle
   und bekommen ihren Rahmen erst bei Fokus – so liest sich die
   Tabelle als Tabelle und nicht als Formular mit 240 Kästchen. */
.imp-tabelle td{padding:3px 4px;vertical-align:middle}
.imp-tabelle th{white-space:nowrap}
.imp-tabelle input{width:100%;min-width:0;border:1px solid transparent;background:transparent;
  border-radius:7px;padding:5px 7px;font-size:12.5px;color:inherit;font-family:inherit}
.imp-tabelle input:hover{border-color:var(--line)}
.imp-tabelle input:focus{border-color:var(--accent);background:var(--surface);outline:none;
  box-shadow:0 0 0 3px var(--accent-soft)}
.imp-tabelle input[type=date],.imp-tabelle input[type=time],
.imp-tabelle input[type=number]{font-family:var(--mono);font-size:12px}
.imp-tabelle input.rechts{text-align:right}
.imp-tabelle input.ist-ort{font-weight:600}
.imp-tabelle input.ist-ort::after{content:""}
.imp-tabelle tr.ist-fehler > td{background:rgba(180,35,24,.05)}
.imp-tabelle tr.ist-entfernt input{text-decoration:line-through;color:var(--muted)}

/* Dauer und Endzeit NEBENEINANDER, nicht übereinander. Die Endzeit lag
   zuerst als überlagerte Beschriftung im Feld – bei dreistelligen
   Minuten schnitt sie die letzte Ziffer ab, und aus 120 wurde sichtbar
   eine 12. Ein Feld, das seinen eigenen Wert verdeckt, ist schlimmer
   als eine Spalte, die zwanzig Pixel breiter ist. */
.imp-dauer{display:flex;align-items:center;gap:3px}
.imp-dauer input{flex:1 1 auto;min-width:0}
.imp-bis{flex:none;pointer-events:none;font-family:var(--mono);font-size:10.5px;
  color:var(--muted);opacity:.85;white-space:nowrap}

.imp-notiz > td{padding:0 4px 6px 4px !important;background:transparent}
.imp-notiz .marke{margin-right:5px}
.imp-notiz.ist-fehler > td{background:rgba(180,35,24,.05)}

/* Die Leiste bleibt am unteren Rand stehen: bei 24 Zeilen ist der
   Knopf sonst drei Bildschirme entfernt von der Zeile, die man
   gerade geändert hat. */
.imp-sticky{position:sticky;bottom:0;z-index:5;display:flex;align-items:center;gap:12px;
  padding:11px 16px;border:1px solid var(--line);border-radius:14px;
  background:var(--surface);box-shadow:0 -2px 14px rgba(15,23,42,.07)}
.imp-sticky.ist-offen{border-color:var(--warn);box-shadow:0 -2px 18px rgba(194,121,12,.2)}
.imp-sticky svg{width:15px;height:15px;fill:none;stroke:currentColor;stroke-width:2;
  stroke-linecap:round;stroke-linejoin:round}

.imp-eintragen{display:flex;align-items:center;gap:14px;flex-wrap:wrap;padding:16px 18px}
.imp-eintragen .haupt{font-size:15px}
.imp-eintragen .neben{font-size:12.5px;color:var(--muted);max-width:640px;line-height:1.5}
.btn-lg{padding:11px 20px;font-size:14px;font-weight:650}
.btn-lg svg{width:16px;height:16px}

.imp-verwerfen{display:flex;justify-content:center;padding-bottom:6px}

@media (max-width:1100px){
  .imp-zwei{grid-template-columns:minmax(0,1fr)}
  .imp-datei{display:none}
}

/* ============================================================
   Tagesplaner: Schalter und Änderungsbox
   ============================================================ */

/* Die Erklärung, was „speichern" in dieser Box heißt. Sie steht im
   Klappteil und nicht in der Kopfzeile: zugeklappt zählt die Box nur,
   aufgeklappt entscheidet man – und erst dort ist der Satz die Antwort
   auf eine Frage, die man sich gerade stellt. */
.changes-hint{display:none;padding:9px 13px;border-top:1px solid var(--line);
  background:var(--surface-2);color:var(--muted);font-size:11.5px;line-height:1.5}
.changes.is-open .changes-hint{display:block}

/* Ein Schalter in der Werkzeugleiste steht bei schmalen Fenstern sonst
   allein in einer Zeile, weil white-space:nowrap ihn nicht brechen
   lässt – zwei Schalter nebeneinander sind schmal genug. */
.tbar .switch{font-size:12px}
.tbar .switch .track-sw{width:30px;height:17px}
.tbar .switch .track-sw::after{width:13px;height:13px}
.tbar .switch input:checked + .track-sw::after{transform:translateX(13px)}

/* Der Sammelversand ist ein Knopf mit Folgen. Solange Aufträge offen
   sind, sieht man das an ihm; sind es null, ist er stumm.

   Die Zahl ist DIESELBE Marke wie am Änderungsknopf daneben – nur in
   der Warnfarbe. Sie bekam vorher bloß einen anderen Hintergrund und
   blieb dabei eckig und ohne Luft: zwei Zähler nebeneinander, die
   verschieden aussehen, liest man als zwei verschiedene Dinge. */
#journalKnopf .n,
#fahrerInformieren .n{font-family:var(--mono);background:var(--accent);color:#fff;
  border-radius:999px;padding:1px 7px;font-size:10.5px;line-height:1.5;
  min-width:18px;text-align:center}
#fahrerInformieren .n{background:var(--warn)}
#fahrerInformieren[disabled]{opacity:.55;cursor:default}
#fahrerInformieren[disabled] .n{background:var(--line-strong);color:var(--muted)}

/* Der Fuß erscheint nur, solange etwas zu entscheiden ist. Ohne diese
   Zeile gewinnt die display:flex-Regel gegen das hidden-Attribut, und
   „Alle verwerfen" stünde auch dann da, wenn es nichts zu verwerfen
   gibt. */
.changes.is-open .changes-foot[hidden]{display:none}

/* DIE BOX MUSS ZU IHREN KNÖPFEN PASSEN, nicht umgekehrt.

   Bei 340 px Breite und zwei Knöpfen mit flex:1 bekam jeder 153 px –
   „Alle Änderungen speichern" braucht aber rund 200. Weil .btn auf
   white-space:nowrap steht, schrumpft er nicht unter seine Textbreite,
   und overflow:hidden am Kasten schnitt das Ende einfach ab. Ein
   Speicherknopf, dessen Beschriftung am Rand endet, sieht aus wie ein
   Fehler – und beim ersten Blick weiß man nicht, ob er noch weitergeht.

   Deshalb: der Kasten wird breiter, und die beiden Knöpfe teilen sich
   den Platz NACH BEDARF statt zu gleichen Teilen. Der Nebenknopf nimmt
   sich, was sein Text braucht; der Rest gehört dem Hauptknopf. */
.changes{width:404px}
.changes.is-open .changes-foot{gap:8px;padding:12px 14px}
.changes-foot .btn{flex:0 1 auto;min-width:0}
.changes-foot .btn-primary{flex:1 1 auto}

/* In der Passkey-Liste steht rechts ein „Entfernen". Ohne diese Zeile
   klebte es am Text: die Liste war für Push gebaut, und dort gibt es
   nichts zu drücken. */
.push-geraete li .btn{margin-left:auto;flex:none;align-self:center}

/* Der Anmeldeknopf ohne Passwort trägt eine Beschriftung, die je nach
   Gerät verschieden lang ist – „Face ID" gegen „Windows Hello". .btn
   steht auf white-space:nowrap, und ein zu langer Name schob auf dem
   Telefon die ganze Seite nach rechts. Hier darf er umbrechen. */
#passkeyAnmelden{white-space:normal;text-align:center}

/* --- Fahrerabrechnung ------------------------------------------
   Die Einzelfahrten stehen als eigene Zeilen unter ihrem Fahrer –
   eingerückt und ruhiger, damit die Fahrerzeile die Zeile bleibt, die
   man liest. */
#abrechnung .fahrerzeile:hover{background:var(--row-hover)}
#abrechnung .fahrerzeile .caret{border:0;background:transparent;cursor:pointer;
  color:var(--muted);display:grid;place-items:center;padding:2px}
#abrechnung .fahrerzeile .caret svg{width:15px;height:15px;fill:none;stroke:currentColor;
  stroke-width:2;transition:transform .15s}
#abrechnung .fahrerzeile.is-open .caret svg{transform:rotate(180deg)}
#abrechnung .fahrtzeile{background:var(--surface-2);font-size:12.5px}
#abrechnung .fahrtzeile td{color:var(--ink-2)}
#abrechnung .fahrtzeile .gedaempft{color:var(--muted);margin-left:6px}
#abrechnung .fahrtzeile .marke{margin-left:5px}
#abrechnung tfoot td{border-top:2px solid var(--line-strong);background:var(--surface)}
