:root {
    --color-bg: #f4f6f8;
    --color-surface: #ffffff;
    --color-border: #e1e6ea;
    --color-text: #1c2b36;
    --color-muted: #66798a;
    --color-primary: #c00000;
    --color-primary-dark: #8f0000;
    --color-danger: #c0392b;
    --color-success: #1e7e45;
    /* Blau für rein hinweisende Elemente - z.B. das Symbol, das die
       Fahrzeugakte öffnet (siehe .akte-knopf). */
    --color-info: #2563a8;
    --color-info-dark: #17456f;

    --color-topbar-bg: #ffffff;
    --color-topbar-text: #1c2b36;
    --color-topbar-border: #eee0e0;

    --status-geplant: #6b7a89;
    --status-bestaetigt: #2563a8;
    --status-unterwegs: #c9781f;
    /* Kräftiges Gelb statt des ursprünglichen Grün - gilt überall, wo der
       Status "Abgeschlossen" auftaucht (Plantafel-Chip, Status-Badge,
       Dashboard-Kachel, Legende). Per Vorschlag/Screenshot mit Dennis
       abgestimmt ("Reines Gelb"); siehe .badge--abgeschlossen und
       .plan-chip--abgeschlossen für die zugehörigen Textfarb-Anpassungen
       (dunkler statt weißer Text, da Gelb mit weißer Schrift schlecht
       lesbar wäre - analog zum hellen Grün bei "Abgerechnet" unten). */
    --status-abgeschlossen: #ffd400;
    /* Helles Grün statt des ursprünglichen Lila - gilt überall, wo der
       Status "Abgerechnet" auftaucht (Plantafel-Chip, Status-Badge,
       Dashboard-Kachel, Legende). Per Vorschlag/Screenshot mit Dennis
       abgestimmt; siehe .badge--abgerechnet und .plan-chip--abgerechnet für
       die zugehörigen Textfarb-Anpassungen (dunkler statt weißer Text, da
       helles Grün mit weißer Schrift schlecht lesbar wäre). */
    --status-abgerechnet: #7bc47f;
    --status-storniert: #b23b3b;

    /* Termine (Plantafel-Erweiterung: Urlaub/Krankheit/private Termine der
       Mitarbeiter, siehe termine.py) - bewusst eigene Farben statt der
       --status-* Töne oben, damit ein Termin auf den ersten Blick von einem
       Auftrag zu unterscheiden ist. */
    --abw-urlaub: #0f8b8f;
    --abw-krank: #9c4f79;
    --priv: #5b5f97;

    --radius: 10px;
    --shadow: 0 1px 3px rgba(20, 30, 40, 0.08), 0 1px 2px rgba(20, 30, 40, 0.06);
    font-size: 16px;
}

* { box-sizing: border-box; }

body {
    margin: 0;
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    background: var(--color-bg);
    color: var(--color-text);
    -webkit-font-smoothing: antialiased;
    padding-bottom: 4.5rem;
}

a { color: var(--color-primary); text-decoration: none; }
a:hover { text-decoration: underline; }

h1 { font-size: 1.5rem; margin: 0 0 0.25rem; }
h2 { font-size: 1.05rem; margin: 0 0 0.75rem; }

.muted { color: var(--color-muted); }
.small { font-size: 0.82rem; }

/* ---------------------------------------------------------------- Topbar */
.topbar {
    background: var(--color-topbar-bg);
    color: var(--color-topbar-text);
    border-bottom: 1px solid var(--color-topbar-border);
    position: sticky;
    top: 0;
    z-index: 20;
    box-shadow: var(--shadow);
}
.topbar__inner {
    /* War frueher wie .page auf max-width:1100px begrenzt - damit die
       Kopfzeile (Logo/Navigation) links/rechts weiterhin buendig mit dem
       Seiteninhalt darunter abschliesst, hier dieselbe Fluid-Breite/
       Innenabstand wie .page (siehe dort). */
    max-width: none;
    margin: 0;
    display: flex;
    align-items: center;
    gap: 1.25rem;
    padding: 0.5rem 1.5rem;
}
.brand { display: flex; align-items: center; gap: 0.5rem; color: var(--color-topbar-text); font-weight: 700; }
.brand:hover { text-decoration: none; }
.brand__logo { height: 34px; width: auto; display: block; }

.nav--desktop { display: none; gap: 1.25rem; flex: 1; margin-left: 0.5rem; }
.nav--desktop a { color: var(--color-muted); font-weight: 600; font-size: 0.92rem; padding: 0.4rem 0.1rem; border-bottom: 2px solid transparent; }
.nav--desktop a.is-active, .nav--desktop a:hover { color: var(--color-primary); border-bottom-color: var(--color-primary); text-decoration: none; }
@media (min-width: 780px) { .nav--desktop { display: flex; } }

.topbar__user { margin-left: auto; display: flex; align-items: center; gap: 0.6rem; }
.user-chip { font-size: 0.85rem; color: var(--color-muted); display: none; }
@media (min-width: 560px) { .user-chip { display: inline; } }

/* Einstellungen-Menü (Zahnrad oben rechts): Logbuch/Mitarbeiter/Fahrzeuge */
.dropdown { position: relative; }
.icon-btn {
    list-style: none; cursor: pointer; user-select: none;
    display: inline-flex; align-items: center; justify-content: center;
    width: 2.15rem; height: 2.15rem; border-radius: var(--radius);
    border: 1px solid var(--color-border); font-size: 1.05rem; color: var(--color-text);
    text-decoration: none;
}
.icon-btn::-webkit-details-marker { display: none; }
.icon-btn::marker { content: ""; }
.icon-btn:hover, .dropdown[open] > .icon-btn { background: #eef2f6; }
.icon-btn.is-active { border-color: var(--color-primary); color: var(--color-primary); }
.dropdown__menu {
    position: absolute; top: calc(100% + 0.4rem); right: 0; z-index: 30;
    min-width: 170px; padding: 0.4rem;
    display: flex; flex-direction: column; gap: 0.1rem;
    background: var(--color-surface); border: 1px solid var(--color-border);
    border-radius: var(--radius); box-shadow: var(--shadow);
}
.dropdown__menu a {
    padding: 0.5rem 0.6rem; border-radius: calc(var(--radius) - 4px);
    color: var(--color-text); font-weight: 600; font-size: 0.9rem;
}
.dropdown__menu a:hover { background: #eef2f6; text-decoration: none; }
.dropdown__menu a.is-active { color: var(--color-primary); background: #eef2f6; }

.nav--mobile {
    position: fixed;
    bottom: 0; left: 0; right: 0;
    display: flex;
    background: var(--color-surface);
    border-top: 1px solid var(--color-border);
    z-index: 20;
    padding-bottom: env(safe-area-inset-bottom, 0);
}
.nav--mobile a {
    flex: 1;
    display: flex; flex-direction: column; align-items: center; gap: 0.1rem;
    padding: 0.5rem 0;
    color: var(--color-muted);
    font-size: 0.7rem;
}
.nav--mobile a span { font-size: 1.2rem; }
.nav--mobile a.is-active { color: var(--color-primary); }
/* Acht Einträge statt sieben (Admin/Disponent, die selbst mitfahren und
   dadurch zusätzlich "Feierabend" bekommen - siehe base.html): die
   Beschriftungen stoßen sonst aneinander. Etwas kleinere Schrift und ein
   kleineres Symbol schaffen den nötigen Zwischenraum. */
.nav--mobile--eng a { font-size: 0.63rem; }
.nav--mobile--eng a span { font-size: 1.1rem; }
@media (min-width: 780px) { .nav--mobile { display: none; } }

/* ------------------------------------------------------------------ Page */
/* War frueher auf 1100px, dann 1500px begrenzt - auf breiten Bildschirmen
   musste man in der Listenansicht der Auftraege (Spalten "Termin"/
   "Mitarbeiter"/"Status") trotzdem noch seitlich scrollen. Jetzt ganz ohne
   feste Obergrenze: die Seite nutzt die volle Fensterbreite (nur mit
   seitlichem Innenabstand), damit Tabellen so viel Platz wie moeglich
   bekommen. .topbar__inner (Kopfzeile) verwendet denselben Innenabstand,
   damit Logo/Navigation buendig mit dem Inhalt darunter abschliessen. */
.page { max-width: none; margin: 0; padding: 1rem 1.5rem; }

.page-head {
    display: flex; align-items: flex-start; justify-content: space-between;
    gap: 1rem; margin-bottom: 1rem; flex-wrap: wrap;
}
/* Kopfzeile einer zentrierten Formular-/Auswahlseite (siehe .form-card,
   .typ-choice unten): dieselbe maximale Breite und dieselbe Zentrierung,
   damit Überschrift und Karte/Auswahl auf einer gemeinsamen Achse liegen,
   statt dass die Überschrift (weiterhin im vollbreiten .page) links und die
   Karte darunter mittig stehen. Wird gezielt nur auf den Formular-/
   Auswahlseiten gesetzt (siehe die jeweiligen Templates), nicht auf
   Listen-/Detailseiten, deren page-head auch bei einer breiten Tabelle
   darunter volle Breite behalten soll. */
.page-head--card { max-width: 760px; margin-inline: auto; width: 100%; }

/* Dieselbe Zentrierung wie .page-head--card, aber für sonstige Inhalte, die auf
   einer zentrierten Formular-/Auswahlseite zwischen der Kopfzeile und der
   Karte/Auswahl stehen (z.B. ein erklärender Absatz oder ein Hinweis) und
   direkt im vollbreiten .page liegen, also ohne diese Klasse links stehen
   würden statt auf derselben Achse wie Kopfzeile und Karte darunter. */
.page-lead--card { max-width: 760px; margin-inline: auto; width: 100%; }

/* Mittige Bahn fuer eine ganze Seite: Kopfzeile, Hinweise und Karten stehen
   zusammen in der Mitte, statt dass der Inhalt links klebt und rechts eine
   leere Flaeche bleibt. Gesetzt ueber <body data-bahn> im jeweiligen Template
   (Block body_attribute in base.html), damit ein Blick in die Vorlage genuegt,
   um zu sehen, dass die Seite so laeuft - und damit es nicht in jeder Zeile
   einzeln stehen muss, auch nicht in Makros wie datenabgleich_hinweis.

   Warum ueberhaupt: Leistungsnachweis und Ist-Zeiten hatten 640 px Inhalt
   neben 1857 px Nichts, waehrend die Kopfleiste ueber den ganzen Bildschirm
   lief (Dennis, 17.09.2026). 1000 px ist die Breite, die er nach dem Vergleich
   dreier Varianten gewaehlt hat.

   Ausgenommen sind <dialog> und das Unterschrift-Vollbild: beide liegen fest
   ueber der Seite und muessen den ganzen Bildschirm behalten - eine
   Hoechstbreite wuerde das Zeichenfeld wieder klein machen, also genau den
   Fehler, der am 16.09. auf dem Tablet gesucht wurde. */
body[data-bahn] main.page > *:not(dialog):not(.signatur-vollbild) {
    max-width: 1000px;
    margin-inline: auto;
    width: 100%;
}

.section-title { margin: 0; }
.page-head__actions { display: flex; gap: 0.5rem; flex-wrap: wrap; }

.section-title-row {
    display: flex; align-items: center; justify-content: space-between;
    gap: 1rem; margin-top: 1.75rem; margin-bottom: 0.75rem; flex-wrap: wrap;
}

.view-toggle {
    display: inline-flex; border: 1px solid var(--color-border); border-radius: var(--radius);
    overflow: hidden; background: var(--color-surface);
}
.view-toggle__btn {
    padding: 0.4rem 0.7rem; background: transparent; border: none; cursor: pointer;
    color: var(--color-muted); font-size: 1rem; line-height: 1;
    /* Wie bei .btn: ein <button> erbt die Schrift des Dokuments nicht von
       selbst, sondern nimmt Arial vom Betriebssystem. */
    font-family: inherit;
}
.view-toggle__btn + .view-toggle__btn { border-left: 1px solid var(--color-border); }
.view-toggle__btn:hover { background: #f3f5f7; }
.view-toggle__btn.is-active { background: var(--color-primary); color: #fff; }

/* Ein Link mitten in einer Tabellenzelle (z.B. die Auftragsnummer in der
   Abrechnung). Bewusst NICHT rot wie ein normaler Link: Rot ist in dieser App
   für Aktionen reserviert, und eine rote Nummer in jeder Zeile wäre nur
   Lärm. Der Zusammenhang wird beim Überfahren deutlich. */
.zellen-link { color: inherit; }
.zellen-link:hover { color: var(--color-primary); text-decoration: underline; }

.table-row--clickable { cursor: pointer; }
.table-row--clickable:hover { background: #f8fafb; }

/* [hidden] muss auch Elemente mit eigenem display:grid/flex zuverlässig
   ausblenden (z.B. .auftrag-liste, .btn) - Browser-Vorrang für Autor-Styles
   gewinnt sonst gegen die UA-Regel "[hidden]{display:none}". Allgemein
   gehalten, damit das für jedes Element mit eigenem display-Wert gilt
   (z.B. die Aktivieren/Deaktivieren/Test-Buttons auf der
   Benachrichtigungen-Seite, die sonst trotz [hidden] als
   display:inline-flex sichtbar blieben). */
[hidden] { display: none !important; }

/* ----------------------------------------------------------------- Flash */
.flash-stack { display: flex; flex-direction: column; gap: 0.5rem; margin-bottom: 1rem; }
.flash { padding: 0.65rem 0.9rem; border-radius: var(--radius); font-size: 0.9rem; }
.flash--error { background: #fbe9e7; color: #8a2c22; border: 1px solid #f3c4bd; }
.flash--success { background: #e7f5ec; color: #1c5e34; border: 1px solid #bfe3cc; }
/* Hinweis, der nichts verhindert hat - z.B. Urlaub trotz zugewiesenem Auftrag
   (siehe termine.warne_bei_auftragskonflikt). Bewusst nicht rot: es ist kein
   Fehler, die Aktion wurde ausgeführt. Ohne diese Regel wäre die Meldung
   rahmenlos und praktisch unsichtbar. */
.flash--warning { background: #fdf3e0; color: #7a4c10; border: 1px solid #f0d9ac; }

/* ------------------------------------------------------------------ Btns */
.btn {
    display: inline-flex; align-items: center; justify-content: center;
    padding: 0.55rem 1rem; border-radius: var(--radius); border: 1px solid transparent;
    font-size: 0.92rem; font-weight: 600; cursor: pointer; background: none;
    /* Ohne diese beiden Zeilen sehen zwei nebeneinanderstehende Knöpfe
       unterschiedlich aus, je nachdem ob sie als <a> oder als <button> im
       HTML stehen: ein <button> erbt die Schrift NICHT vom Dokument, sondern
       nimmt die des Betriebssystems (Arial), und ist wegen der eigenen
       Zeilenhöhe zwei Pixel flacher. Genau das fiel in der Terminliste auf,
       wo "Verschieben" (Link) direkt neben "Absagen" (Knopf) steht - es galt
       aber überall, auch in Mitarbeiter- und Fahrzeugliste.
       input/select/textarea haben dieselbe Regel weiter unten schon. */
    font-family: inherit;
    line-height: 1.25;
}
.btn--primary { background: var(--color-primary); color: #fff; }
.btn--primary:hover { background: var(--color-primary-dark); text-decoration: none; }
.btn--secondary { background: #eef2f6; color: var(--color-text); border-color: var(--color-border); }
.btn--secondary:hover { background: #e3e9ee; text-decoration: none; }
.btn--ghost { background: transparent; color: var(--color-text); border-color: var(--color-border); }
.btn--ghost:hover { background: #eef2f6; text-decoration: none; }
/* Gefüllter blauer Knopf für Aktionen, die aus der Seite HERAUSFÜHREN oder ein
   Dokument liefern - "In Lexware Office öffnen", "Leistungsnachweis als PDF".
   Bewusst nicht rot: Rot gehört in dieser App der einen Hauptaktion je Seite
   (hier "Weiteren Rechnungsentwurf erstellen"), und drei rote Knöpfe
   nebeneinander heben sich gegenseitig auf. Blau ist in der App schon die
   Farbe für Hinweisendes (--color-info, siehe Info-Symbol der Fahrzeugakte) -
   gefüllt fällt es auf, ohne mit der Hauptaktion zu konkurrieren. */
.btn--info { background: var(--color-info); color: #fff; border-color: var(--color-info); }
.btn--info:hover { background: var(--color-info-dark); border-color: var(--color-info-dark); color: #fff; text-decoration: none; }
.btn--small { padding: 0.35rem 0.7rem; font-size: 0.8rem; }
.btn--block { width: 100%; }
/* Gegenstück zu btn--danger: derselbe helle Knopf, nur grün eingefärbt - für
   Aktionen, die etwas ABSCHLIESSEN ("✓ Erledigt"). Wie bei btn--danger nur
   Schrift und Rahmen, kein gefüllter Grund: gefüllt wäre es ein Hauptknopf,
   und der gehört in einer Tabellenzeile niemandem. */
.btn--erfolg { color: var(--color-success); border-color: #bfe3cc; }
.btn--erfolg:hover { background: #e7f5ec; text-decoration: none; }
.btn--danger { color: var(--color-danger); border-color: #e3b3ac; }
.btn--danger:hover { background: #fbeceb; text-decoration: none; }

.btn-link { background: none; border: none; color: var(--color-primary); font-size: 0.82rem; cursor: pointer; padding: 0; }
.btn-link--danger { color: var(--color-danger); }
.btn-link--muted { color: var(--color-muted); }
.btn-link:hover { text-decoration: underline; }

/* --------------------------------------------------------------- Badges */
.badge {
    display: inline-block; padding: 0.15rem 0.55rem; border-radius: 999px;
    font-size: 0.72rem; font-weight: 700; color: #fff; white-space: nowrap;
}
.badge--geplant { background: var(--status-geplant); }
.badge--bestaetigt { background: var(--status-bestaetigt); }
.badge--unterwegs { background: var(--status-unterwegs); }
/* Dunkler statt weißer Text (wie bei --status-abgerechnet unten) - Gelb
   mit weißer Schrift wäre schlecht lesbar. */
.badge--abgeschlossen { background: var(--status-abgeschlossen); color: #1c2b36; }
/* Helles Grün statt weißer Schrift (wie bei den anderen Badges) - siehe
   --status-abgerechnet oben, sonst schlecht lesbar. */
.badge--abgerechnet { background: var(--status-abgerechnet); color: #1c2b36; }
.badge--storniert { background: var(--status-storniert); }
.badge--fahrzeug-aktiv { background: var(--color-success); }
.badge--fahrzeug-werkstatt { background: var(--status-unterwegs); }
.badge--fahrzeug-ausser_dienst { background: var(--color-muted); }

/* ------------------------------------------------------------- Stat grid */

.date-filter {
    display: flex; align-items: flex-end; gap: 0.6rem; flex-wrap: wrap;
    margin-bottom: 1rem;
}
.date-filter label {
    flex-direction: row; align-items: center; gap: 0.4rem; font-weight: 600;
    font-size: 0.82rem; color: var(--color-muted);
}
.date-filter input[type="date"] {
    padding: 0.4rem 0.55rem; border-radius: var(--radius); border: 1px solid var(--color-border);
    font-size: 0.85rem;
}
.date-filter__reset { margin-left: 0.2rem; }

.notice {
    background: #fff6e6; border: 1px solid #f3d9a1; color: #7a5310;
    padding: 0.7rem 1rem; border-radius: var(--radius); margin-top: 1rem; font-size: 0.9rem;
}

/* --------------------------------------------------- Datenabgleich-Hinweis */
/* Auftragsdetailseite + Leistungsnachweis-Seite (siehe orders.py,
   datenabgleich_sichtbar, und _macros.html, datenabgleich_hinweis) -
   nutzt bewusst dieselbe Amber-Farbgebung wie .notice oben (Hinweis mit
   Handlungsbedarf), nicht die roten/grünen Töne von .locked-notice. */
.abgleich {
    background: #fff6e6; border: 1px solid #f3d9a1; color: #7a5310;
    border-radius: var(--radius); padding: 0.9rem 1rem 1rem; margin-bottom: 1.2rem;
}
.abgleich__head { display: flex; align-items: flex-start; gap: 0.55rem; }
.abgleich__glyph { font-size: 1rem; line-height: 1.4; }
.abgleich__title { font-weight: 700; font-size: 0.92rem; margin: 0; color: var(--color-text); }
.abgleich__sub { font-size: 0.84rem; margin: 0.15rem 0 0; }

.diff-list { list-style: none; margin: 0.8rem 0 0; padding: 0; display: flex; flex-direction: column; gap: 0.5rem; }
.diff-row {
    display: grid; grid-template-columns: auto 1fr; gap: 0.55rem; align-items: start;
    background: rgba(255,255,255,0.55); border-radius: 8px; padding: 0.5rem 0.65rem;
}
.diff-row input[type="checkbox"] { margin-top: 0.2rem; width: 16px; height: 16px; accent-color: var(--color-primary); }
.diff-row label { display: block; cursor: pointer; }
.diff-row__label {
    font-size: 0.7rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.03em;
    color: #7a5310; opacity: 0.85; margin: 0 0 0.15rem;
}
.diff-row__values { display: flex; align-items: center; gap: 0.4rem; flex-wrap: wrap; font-size: 0.88rem; color: var(--color-text); }
.diff-row__old { text-decoration: line-through; color: var(--color-muted); }
.diff-row__arrow { color: var(--color-muted); }
.diff-row__new { font-weight: 700; }

.abgleich__actions { display: flex; align-items: center; gap: 0.6rem; margin-top: 0.9rem; flex-wrap: wrap; }
.abgleich__hint { font-size: 0.74rem; color: #7a5310; opacity: 0.8; margin-left: auto; }

/* ---------------------------------------------------- Feierabend-Standort */

.feierabend-card { text-align: center; margin: 0 auto; }
.feierabend-card__glyph { font-size: 2.2rem; margin-bottom: 0.4rem; }
.feierabend-card__status { font-size: 0.86rem; color: var(--color-success); margin: 0.9rem 0 0; }

/* ----------------------------------------------------------- Auftragsliste */
.filter-bar { display: flex; gap: 0.5rem; margin-bottom: 1rem; flex-wrap: wrap; }
.filter-bar input[type="search"] { flex: 1; min-width: 180px; }
.filter-bar select { min-width: 160px; }
.filter-bar input, .filter-bar select {
    padding: 0.5rem 0.7rem; border-radius: var(--radius); border: 1px solid var(--color-border); font-size: 0.9rem;
}

.auftrag-liste { display: grid; grid-template-columns: 1fr; gap: 0.75rem; }
@media (min-width: 700px) { .auftrag-liste { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1050px) { .auftrag-liste { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 1400px) { .auftrag-liste { grid-template-columns: repeat(4, 1fr); } }

.auftrag-card {
    display: block; background: var(--color-surface); border-radius: var(--radius);
    box-shadow: var(--shadow); padding: 0.9rem; color: var(--color-text);
}
.auftrag-card:hover { text-decoration: none; box-shadow: 0 2px 8px rgba(20,30,40,0.14); }
.auftrag-card__top { display: flex; justify-content: space-between; align-items: center; margin-bottom: 0.4rem; }
.auftrag-card__nummer { font-weight: 700; font-size: 0.85rem; color: var(--color-muted); }
.auftrag-card__kunde { font-weight: 600; margin-bottom: 0.2rem; }
.auftrag-card__route { display: flex; align-items: center; gap: 0.4rem; font-size: 0.9rem; margin-bottom: 0.4rem; }
.auftrag-card__route .arrow { color: var(--color-muted); }
.auftrag-card__meta { display: flex; gap: 0.9rem; flex-wrap: wrap; font-size: 0.8rem; color: var(--color-muted); }

/* --------------------------------------------------------------- Detail */
.detail-grid { display: grid; grid-template-columns: 1fr; gap: 1rem; margin-top: 1rem; }
@media (min-width: 900px) { .detail-grid { grid-template-columns: 2fr 1fr; align-items: start; } }
.detail-main, .detail-side { display: flex; flex-direction: column; gap: 1rem; }

/* Seiten OHNE zweite Spalte (Leistungsnachweis, Ist-Zeiten).
   Vorher lag auf ihnen dieselbe 2fr/1fr-Aufteilung wie auf der Auftragsseite -
   nur gibt es dort kein <div class="detail-side">. Ein Drittel der Seite blieb
   damit fuer eine Spalte reserviert, die es gar nicht gibt, und die Karten
   waren zusaetzlich auf 640 px gedeckelt: auf Dennis' 2560er Monitor 640 px
   Inhalt und 1857 px Nichts, waehrend die Kopfleiste ueber die volle Breite
   ging (am 17.09.2026 nachgemessen). */
.detail-grid--einspaltig { grid-template-columns: 1fr; }
@media (min-width: 900px) { .detail-grid--einspaltig { grid-template-columns: 1fr; } }
.detail-grid--einspaltig .card--narrow { max-width: none; }

.card {
    background: var(--color-surface); border-radius: var(--radius); box-shadow: var(--shadow);
    padding: 1rem 1.1rem;
}
.card--narrow { max-width: 640px; }
.card--narrow + .card--narrow { margin-top: 1rem; }
.card__subtitle { margin: 0 0 0.6rem; font-size: 1rem; }

.key-form { display: flex; gap: 0.5rem; flex-wrap: wrap; margin-top: 0.75rem; }
.key-form input { flex: 1; min-width: 220px; }

.route-line { display: flex; gap: 0.5rem; align-items: center; font-weight: 600; margin-bottom: 0.6rem; }
.route-line .arrow { color: var(--color-muted); }

.kv { display: grid; grid-template-columns: max-content 1fr; gap: 0.3rem 1rem; margin: 0; }
.kv dt { color: var(--color-muted); font-size: 0.82rem; }
.kv dd { margin: 0; }
.kv--spaced { margin: 1rem 0; }

.import-hint { margin-top: 0.75rem; }

.tag {
    display: inline-block; background: #eef2f6; border-radius: 999px; padding: 0.05rem 0.5rem;
    font-size: 0.72rem; color: var(--color-muted); margin-left: 0.3rem;
}
.tag--kunde { background: #e5edf9; color: var(--status-bestaetigt); margin-left: 0; margin-right: 0.3rem; font-weight: 600; }
.tag--lieferant { background: #fdeee0; color: var(--status-unterwegs); margin-left: 0; margin-right: 0.3rem; font-weight: 600; }
.tag--lexoffice { background: #eef2f6; color: var(--color-primary); margin-left: 0; font-weight: 600; }
.tag--begleitauftrag { background: #e5edf9; color: var(--status-bestaetigt); font-weight: 600; }
.tag--kranauftrag { background: #ece3f7; color: #5b3aa3; font-weight: 600; }

.typ-choice { display: grid; grid-template-columns: 1fr; gap: 1rem; max-width: 640px; margin-inline: auto; }
@media (min-width: 560px) { .typ-choice { grid-template-columns: 1fr 1fr; } }
.typ-choice__card {
    display: flex; flex-direction: column; align-items: center; text-align: center; gap: 0.4rem;
    background: var(--color-surface); border-radius: var(--radius); box-shadow: var(--shadow);
    padding: 1.75rem 1.25rem; color: var(--color-text);
}
.typ-choice__card:hover { text-decoration: none; box-shadow: 0 2px 8px rgba(20,30,40,0.14); transform: translateY(-1px); }
.typ-choice__icon { font-size: 2.2rem; }
.typ-choice__label { font-weight: 700; font-size: 1.05rem; }
.typ-choice__hint { color: var(--color-muted); font-size: 0.82rem; }

.checkbox-row { flex-direction: row !important; gap: 1.5rem !important; align-items: center; }
.checkbox-item { display: inline-flex; align-items: center; gap: 0.4rem; font-weight: 400; color: var(--color-text); }
.checkbox-item input { width: auto; }

.attachment-list { list-style: none; margin: 0 0 0.75rem; padding: 0; display: flex; flex-direction: column; gap: 0.5rem; }
.attachment-list li { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; border-bottom: 1px solid var(--color-border); padding-bottom: 0.5rem; }
.upload-form { display: flex; gap: 0.5rem; flex-wrap: wrap; align-items: center; }
.upload-form select, .upload-form input[type="file"] {
    padding: 0.45rem 0.6rem; border-radius: var(--radius); border: 1px solid var(--color-border); font-size: 0.85rem;
}
.upload-form input[type="file"] { flex: 1; min-width: 160px; }

.timeline { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.75rem; }
.timeline li { border-left: 2px solid var(--color-border); padding-left: 0.75rem; }
.timeline__head { display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap; }
.timeline__comment { margin: 0.25rem 0 0; font-size: 0.9rem; }

.assignee-list { list-style: none; margin: 0 0 0.75rem; padding: 0; display: flex; flex-direction: column; gap: 0.6rem; }
.assignee-list li { display: flex; justify-content: space-between; align-items: flex-start; gap: 0.5rem; border-bottom: 1px solid var(--color-border); padding-bottom: 0.5rem; }
.assign-form { display: flex; flex-direction: column; gap: 0.5rem; }
.assign-form select, .assign-form input {
    padding: 0.5rem 0.7rem; border-radius: var(--radius); border: 1px solid var(--color-border); font-size: 0.9rem;
}

/* ------------------------------------------------------------------ Form */
.form-card {
    background: var(--color-surface); border-radius: var(--radius); box-shadow: var(--shadow);
    padding: 1.1rem; max-width: 760px; margin-inline: auto;
}
fieldset { border: none; padding: 0; margin: 0 0 1.25rem; }
legend { font-weight: 700; padding: 0 0 0.6rem; font-size: 0.95rem; }
.form-grid { display: grid; grid-template-columns: 1fr; gap: 0.8rem; }
@media (min-width: 620px) { .form-grid { grid-template-columns: 1fr 1fr; } }
.form-grid .span-2 { grid-column: 1 / -1; }

label { display: flex; flex-direction: column; gap: 0.3rem; font-size: 0.85rem; color: var(--color-muted); font-weight: 600; }
input, select, textarea {
    font: inherit; color: var(--color-text); padding: 0.55rem 0.7rem;
    border-radius: var(--radius); border: 1px solid var(--color-border); background: #fff;
}
input:focus, select:focus, textarea:focus { outline: 2px solid var(--color-primary); outline-offset: 1px; }
textarea { resize: vertical; font-weight: 400; }

/* Getrennte Datum/Uhrzeit-Felder (siehe auftrag_form.html,
   leistungsnachweis.html, ist_zeiten.html - ersetzt dort das frühere
   einzelne <input type="datetime-local">, dessen kombinierter Kalender+Uhr-
   Picker nur schwer gezielt Datum ODER Uhrzeit ansteuern ließ). Beide Felder
   teilen sich weiterhin die eine Beschriftung ("Start (Datum/Uhrzeit)" o.ä.)
   der umschließenden <label> und stehen nebeneinander in derselben Zeile. */
.dt-pair { display: flex; gap: 0.5rem; }
.dt-pair input[type="date"] { flex: 1.35; min-width: 0; }
.dt-pair input[type="time"] { flex: 1; min-width: 0; }

.assign-list { display: flex; flex-direction: column; gap: 0.5rem; }
.assign-row { display: flex; gap: 0.6rem; align-items: center; flex-wrap: wrap; }
.assign-row__check { flex-direction: row; align-items: center; font-weight: 400; color: var(--color-text); min-width: 200px; }
.assign-row input[type="text"] { flex: 1; min-width: 160px; }

.form-actions { display: flex; justify-content: flex-end; gap: 0.6rem; margin-top: 0.5rem; }

.inline-form { display: inline; }

/* ----------------------------------------------------------------- Table */
.table-wrap { overflow-x: auto; background: var(--color-surface); border-radius: var(--radius); box-shadow: var(--shadow); }
.table { width: 100%; border-collapse: collapse; font-size: 0.9rem; }
.table th, .table td { padding: 0.65rem 0.9rem; text-align: left; border-bottom: 1px solid var(--color-border); white-space: nowrap; }
.table th { color: var(--color-muted); font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.03em; }
.table tr.row--inactive { opacity: 0.5; }
.table td.wrap { white-space: normal; max-width: 420px; }
/* Knopfspalte am Zeilenende.
   ACHTUNG, hier stand früher `display: flex` - das war ein Fehler mit Folgen:
   ein <td> mit display:flex ist keine Tabellenzelle mehr. Es wird deshalb NICHT
   auf die Höhe der Zeile gestreckt, und seine untere Trennlinie sitzt ein paar
   Pixel höher als die der Nachbarzellen. In der Tabelle sieht das aus, als
   wäre der ganze Knopfblock gegen die Zeilen verschoben - besonders auffällig,
   sobald eine Zeile zweizeilig wird. Galt für jede Tabelle der App.
   Die Zelle bleibt jetzt eine echte Tabellenzelle; die Knöpfe stehen als
   Inline-Elemente nebeneinander. `.table td` steht ohnehin auf
   `white-space: nowrap`, sie bleiben also in einer Reihe und die Spalte wird
   so breit wie nötig, statt die Knöpfe umbrechen zu lassen. */
.table__actions { vertical-align: middle; }
.table__actions > * { vertical-align: middle; }
.table__actions > * + * { margin-left: 0.5rem; }
.table__actions form { display: inline-block; margin: 0; }

/* Erklärende Kleinschrift unter einer Plakette in einer Tabellenzelle
   ("14.09.2026 · Dennis · 1 nicht zugeordnet"). Wie .termin-verlauf: .table td
   steht auf nowrap, das muss hier zurückgenommen werden, sonst zieht der Text
   die Spalte unnötig breit. */
.zellen-notiz { white-space: normal; max-width: 18rem; margin-top: 0.2rem; }

/* Dateiname unter der Rechnungsnummer. Wird abgeschnitten statt die Spalte
   aufzublähen - der vollständige Name steht im title-Attribut. Die Breite ist
   so gewählt, dass die ganze Tabelle in ein rund 1050 px breites Fenster passt
   und nicht seitlich gescrollt werden muss. */
.dateiname {
    max-width: 9.5rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Umschaltknopf am Zeilenende, dessen Beschriftung je nach Zustand wechselt
   ("✓ Erledigt" / "Öffnen"). Ohne feste Mindestbreite wäre die rechte Kante
   der Tabelle von Zeile zu Zeile unterschiedlich lang - das sieht unruhig aus,
   obwohl nichts kaputt ist. */
.btn--umschalter { min-width: 5.4rem; }


/* ------------------------------------------------------------------ Login */
.login-wrap { display: flex; align-items: center; justify-content: center; min-height: 80vh; }
.login-card {
    background: var(--color-surface); border-radius: var(--radius); box-shadow: var(--shadow);
    padding: 2rem; width: 100%; max-width: 360px; text-align: center;
}
.login-card__logo { max-width: 100%; height: auto; margin-bottom: 0.75rem; }
.login-card h1 { font-size: 1.25rem; }
.login-card form { display: flex; flex-direction: column; gap: 0.9rem; margin-top: 1.25rem; text-align: left; }

/* -------------------------------------------------------------- Plantafel */
.week-nav { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; margin-bottom: 1rem; }
.week-nav__range { margin-left: 0.4rem; font-size: 0.85rem; }

.plantafel-wrap {
    overflow-x: auto; background: var(--color-surface); border-radius: var(--radius);
    box-shadow: var(--shadow); -webkit-overflow-scrolling: touch;
}
table.plantafel { border-collapse: collapse; width: 100%; min-width: 880px; font-size: 0.85rem; }
table.plantafel th, table.plantafel td {
    border: 1px solid var(--color-border); padding: 0.5rem; vertical-align: top; text-align: left;
}
table.plantafel thead th { background: #f8fafb; text-align: center; font-weight: 700; }
table.plantafel thead th.is-today { background: #e7effa; }
table.plantafel td.is-today { background: #f3f7fc; }
.plantafel__row-label {
    position: sticky; left: 0; z-index: 1; background: var(--color-surface);
    font-weight: 600; min-width: 150px; white-space: nowrap;
}
table.plantafel thead .plantafel__row-label { background: #f8fafb; z-index: 2; }
.plantafel__row--unassigned .plantafel__row-label { color: var(--color-danger); }
.plantafel__row--unassigned td:not(.plantafel__row-label) { background: #fdf4f2; }

table.plantafel td { min-width: 130px; }

.plan-chip {
    position: relative;
    display: flex; flex-direction: column; gap: 0.05rem; padding: 0.3rem 0.45rem;
    border-radius: 6px; margin-bottom: 0.3rem; color: #fff; font-size: 0.76rem; line-height: 1.25;
}
.plan-chip:hover { text-decoration: none; filter: brightness(1.08); }
.plan-chip strong { font-size: 0.76rem; padding-right: 1.1rem; }
.plan-chip__zeit { font-variant-numeric: tabular-nums; opacity: 0.85; }
.plan-chip span { opacity: 0.92; }
.plan-chip__route { font-size: 0.7rem; opacity: 0.85; }
.plan-chip--geplant { background: var(--status-geplant); }
.plan-chip--bestaetigt { background: var(--status-bestaetigt); }
.plan-chip--unterwegs { background: var(--status-unterwegs); }
/* Ursprünglich Grün, auf Wunsch von Dennis jetzt kräftiges Gelb (siehe
   --status-abgeschlossen oben). Dunkler statt weißer Text, weil Gelb mit
   weißer Schrift schlecht lesbar wäre - analog zu .plan-chip--abgerechnet
   unten. */
.plan-chip--abgeschlossen { background: var(--status-abgeschlossen); color: #1c2b36; }
/* Ursprünglich (Bugfix) hier Lila verwendet - auf Wunsch von Dennis jetzt
   helles Grün (siehe --status-abgerechnet oben). Dunkler statt weißer Text,
   weil ein wirklich helles Grün mit weißer Schrift (wie bei den anderen
   Status) schlecht lesbar wäre; das grenzt den Chip nebenbei klar vom
   dunkleren Grün von "Abgeschlossen" ab. */
.plan-chip--abgerechnet { background: var(--status-abgerechnet); color: #1c2b36; }
/* Der "Gesehen"-Haken unten ist standardmäßig auf dunklen Chips (halb-
   transparentes Weiß) ausgelegt - auf dem hellen Gelb bzw. Grün hier
   stattdessen ein dunkler, halbtransparenter Strich, damit er sichtbar
   bleibt. Der blaue "bereits gesehen"-Zustand (.is-seen) funktioniert
   unverändert auf allen Chip-Farben. */
.plan-chip--abgeschlossen .seen-badge:not(.is-seen) .tick,
.plan-chip--abgerechnet .seen-badge:not(.is-seen) .tick { stroke: rgba(28, 43, 54, 0.4); }

/* "Gesehen"-Häkchen (wie bei WhatsApp): grau = zugewiesen, blau = vom
   Mitarbeiter dieser Zeile bereits geöffnet - siehe orders.detail
   (gesehen_am) und planning.py (gesehen_map). Selektoren bewusst mit
   ".plan-chip " vorangestellt (höhere Spezifität als ".plan-chip span",
   das sonst z.B. die Tooltip-opacity:0 überschreiben und den Tooltip
   dauerhaft statt nur bei :hover sichtbar machen würde). */
.plan-chip .seen-badge { position: absolute; top: 0.3rem; right: 0.35rem; line-height: 0; opacity: 1; }
.plan-chip .seen-badge svg { width: 13px; height: 8px; display: block; }
.plan-chip .seen-badge .tick { stroke: rgba(255,255,255,0.55); transition: stroke .15s; }
.plan-chip .seen-badge.is-seen .tick { stroke: #3fa9f5; }
.plan-chip .seen-badge__tip {
    position: absolute; top: 130%; right: -0.3rem; background: #111820; color: #fff;
    font-size: 0.66rem; font-weight: 600; white-space: nowrap; padding: 0.28rem 0.5rem;
    border-radius: 6px; opacity: 0; transform: translateY(-3px); pointer-events: none;
    transition: opacity .12s, transform .12s; z-index: 5;
}
.plan-chip .seen-badge:hover .seen-badge__tip { opacity: 1; transform: translateY(0); }

.legend { display: flex; gap: 1rem; flex-wrap: wrap; margin-top: 1rem; font-size: 0.82rem; color: var(--color-muted); }
.legend__item { display: inline-flex; align-items: center; gap: 0.35rem; }
.legend__dot { width: 0.65rem; height: 0.65rem; border-radius: 50%; display: inline-block; }
.legend__dot--pill { border-radius: 999px; width: 1rem; }

/* ------------------------------------------------------- Termine (Plantafel) */
/* Kompakte Pille für Urlaub/Krankheit (siehe termine.py, planning.py) -
   bewusst rund statt eines rechteckigen .plan-chip, damit ein Termin auf
   den ersten Blick von einem Auftrag zu unterscheiden ist (Wunsch von
   Dennis). Ein Urlaub/Krankheit-Termin bekommt nie einen mehrtägigen
   Balken wie ein Auftrag, sondern erscheint als eigene Pille an jedem
   betroffenen Tag (siehe planning.py, "mehrtaegig": False für Termine). */
.abw-pill {
    display: flex; align-items: center; gap: 0.3rem;
    padding: 0.25rem 0.55rem; border-radius: 999px; margin-bottom: 0.3rem;
    color: #fff; font-size: 0.72rem; font-weight: 600; line-height: 1.2;
}
.abw-pill:hover { text-decoration: none; filter: brightness(1.08); }
.abw-pill--urlaub { background: var(--abw-urlaub); }
.abw-pill--krankheit { background: var(--abw-krank); }
.abw-pill__icon { font-size: 0.85rem; }

/* Privater Termin: abgerundetes Rechteck (nicht die volle Pille wie
   Urlaub/Krankheit oben) - grenzt sich damit sowohl von Aufträgen
   (.plan-chip, 6px) als auch von Urlaub/Krankheit (.abw-pill, volle
   Pille) ab, wie von Dennis gewünscht ("etwas rundlicher"). */
.priv-chip {
    display: flex; flex-direction: column; gap: 0.1rem;
    padding: 0.3rem 0.5rem; border-radius: 16px; margin-bottom: 0.3rem;
    background: var(--priv); color: #fff; font-size: 0.72rem; line-height: 1.25;
}
.priv-chip:hover { text-decoration: none; filter: brightness(1.08); }
.priv-chip__head { display: flex; align-items: center; gap: 0.35rem; }
.priv-chip__icon {
    display: inline-flex; align-items: center; justify-content: center;
    width: 1.1rem; height: 1.1rem; border-radius: 50%; flex-shrink: 0;
    background: rgba(255,255,255,0.22); font-size: 0.66rem;
}
.priv-chip__zeit { font-variant-numeric: tabular-nums; font-weight: 700; }
.priv-chip__kommentar { opacity: 0.92; }

/* Geburtstag in der Plantafel: eine Notiz zum Tag, kein Einsatz. Deshalb
   kein Link, keine kräftige Fläche und kleiner als die Auftragschips - er
   soll auffallen, ohne mit der Einsatzplanung zu konkurrieren. */
.geb-chip {
    display: inline-flex; align-items: center; gap: 0.25rem;
    margin-bottom: 0.3rem; padding: 0.15rem 0.45rem; border-radius: 16px;
    background: #fdf3d7; color: #7a5b00; border: 1px solid #f0dca6;
    font-size: 0.68rem; font-weight: 700; white-space: nowrap;
}

/* Konflikt: an einem Tag stehen sowohl ein Auftrag als auch ein
   Urlaub/Krankheit-Termin desselben Mitarbeiters (siehe
   planning._baue_zellen) - blockiert bewusst nichts, macht aber optisch
   auf die Überschneidung aufmerksam. Private Termine lösen bewusst KEINEN
   Konflikt-Hinweis aus (nur Urlaub/Krankheit betrifft die Verfügbarkeit). */
.konflikt-hinweis {
    display: flex; align-items: center; gap: 0.3rem;
    background: #fbeceb; color: #7a2b21; border: 1px solid #e3b3ac;
    border-radius: 6px; padding: 0.2rem 0.4rem; margin-bottom: 0.3rem;
    font-size: 0.66rem; font-weight: 700;
}
.plan-chip--konflikt { outline: 2px solid var(--color-danger); outline-offset: 1px; }
table.plantafel td.hat-konflikt { box-shadow: inset 0 0 0 2px rgba(192,57,43,0.35); }

/* --------------------------------------------------------- Termine (Anfragen) */
/* "Offene Anfragen" (Admin/Disponent, siehe termine_uebersicht.html) - nutzt
   bewusst dieselbe Amber-Farbgebung wie .abgleich/.notice (Hinweis mit
   Handlungsbedarf). */
.anfrage-liste { display: flex; flex-direction: column; gap: 0.75rem; }
.anfrage-card {
    background: #fff6e6; border: 1px solid #f3d9a1; border-radius: var(--radius);
    padding: 0.8rem 1rem; display: flex; flex-direction: column; gap: 0.7rem;
}
/* "Meine Anfragen" (Mitarbeiter, siehe termine_meine.html) - hier reine
   Statusübersicht ohne Handlungsbedarf, daher neutrale Kartenfarbe statt Amber. */
.anfrage-card--mine { background: var(--color-surface); border-color: var(--color-border); box-shadow: var(--shadow); gap: 0.3rem; }
.anfrage-card__head { display: flex; align-items: flex-start; gap: 0.6rem; }
.anfrage-card__icon { font-size: 1.3rem; line-height: 1.3; }
.anfrage-card__title { font-weight: 700; font-size: 0.92rem; margin: 0; color: var(--color-text); display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; }
.anfrage-card__zeitraum { font-size: 0.85rem; margin: 0.15rem 0 0; color: var(--color-text); }
.anfrage-card__kommentar { font-size: 0.82rem; margin: 0.25rem 0 0; color: var(--color-muted); font-style: italic; }

.anfrage-card__actions { display: flex; align-items: flex-start; gap: 0.6rem; flex-wrap: wrap; }
/* "Nein" öffnet über <details>/<summary> (wie das Einstellungen-Menü in
   base.html) ein optionales Kommentarfeld, statt sofort abzulehnen - so
   kann Admin/Dispo einen kurzen Ablehnungsgrund mitgeben, der dem
   Mitarbeiter per Push mitgeteilt wird (siehe termine.entscheiden). */
.anfrage-card__reject summary { list-style: none; }
.anfrage-card__reject summary::-webkit-details-marker,
.anfrage-card__reject summary::marker { display: none; content: ""; }
.anfrage-card__reject-form { display: flex; flex-direction: column; gap: 0.4rem; margin-top: 0.5rem; min-width: 240px; }
.anfrage-card__reject-form textarea { font-size: 0.85rem; }

.status-pill {
    display: inline-flex; align-items: center; padding: 0.15rem 0.55rem;
    border-radius: 999px; font-size: 0.7rem; font-weight: 700; color: #fff;
}
.status-pill--offen { background: var(--status-unterwegs); }
.status-pill--angenommen { background: var(--color-success); }
.status-pill--abgelehnt { background: var(--color-danger); }
/* Zurückgezogen, nicht abgelehnt - deshalb bewusst neutral grau statt rot.
   Ohne eigene Regel bliebe die Plakette ohne Hintergrund und die weiße
   Schrift aus .status-pill wäre unsichtbar. */
.status-pill--abgesagt { background: #6b7280; }

/* Verlauf eines Termins ("verschoben: ... → ... · Wer, wann"). Ohne diese
   Regel liefe der Text in einer einzigen langen Zeile aus der Tabelle
   heraus: .table td steht auf white-space: nowrap, das muss hier
   ausdruecklich zurueckgenommen werden - die Breitenbegrenzung allein
   genuegt nicht, der Text wuerde einfach ueber sie hinausragen. */
.termin-verlauf {
    max-width: 22rem;
    white-space: normal;
    margin-top: 0.15rem;
}

/* ---------------------------------------------------------- Leistungsnachweis */
/* Ankreuzfeld mit Erklärtext (Mitarbeitermaske: "Fährt auch selbst mit"). */
.form-haken {
    background: #f7f9fb; border: 1px solid var(--color-border); border-radius: 8px;
    padding: 0.7rem 0.85rem; margin-top: 0.9rem;
}
.form-haken label { display: flex; gap: 0.7rem; align-items: flex-start; cursor: pointer; }
.form-haken input { margin-top: 0.2rem; flex: none; width: auto; }
.form-haken small { display: block; color: var(--color-muted); margin-top: 0.2rem; }

.signatur-actions { display: flex; gap: 0.6rem; margin-top: 0.6rem; flex-wrap: wrap; }

/* Name unter der Unterschrift: steht durch Zuteilung bzw. Auftrag fest und
   wird nur noch angezeigt statt abgetippt (siehe leistungsnachweis.html). */
.signatur-name {
    background: #f7f9fb; border: 1px solid var(--color-border); border-radius: 8px;
    padding: 0.55rem 0.7rem; margin-bottom: 0.7rem;
    display: flex; justify-content: space-between; align-items: center;
    gap: 0.7rem; flex-wrap: wrap;
}
.signatur-vorschau { margin: 0.8rem 0 0; }
.signatur-vorschau p { margin: 0.3rem 0 0; }
/* Die noch nicht gespeicherte Unterschrift füllt die Breite, damit man sie
   auch auf dem Handy beurteilen kann, bevor man sie festschreibt. */
.signatur-vorschau .signatur-bild-vorschau {
    width: 100%; height: 110px; max-height: none; object-fit: contain;
}

/* Vollbild zum Unterschreiben: erst über "Unterschrift starten" aktiviert,
   nimmt dann den kompletten Bildschirm ein. 100dvh statt 100vh, damit auf dem
   Handy die ein- und ausblendende Browserleiste die Fläche nicht abschneidet. */
/* Vollbild zum Unterschreiben.
   top/right/bottom/left stehen ABSICHTLICH einzeln da und nicht nur als
   `inset: 0`: die Kurzschreibweise gibt es erst ab Chrome 87 (Ende 2020).
   Aeltere Android-Tablets ignorieren sie stillschweigend, das Fenster bleibt
   dann an seiner Stelle im Textfluss stehen und der Canvas faellt auf seine
   Standardgroesse von 300x150 Pixeln zurueck - genau das kleine Feld, das auf
   Dennis' Tablet zu sehen war. Dasselbe gilt fuer 100dvh (ab Chrome 108), 
   deshalb 100vh davor als Rueckfall. */
.signatur-vollbild {
    position: fixed;
    top: 0; right: 0; bottom: 0; left: 0;
    inset: 0;
    z-index: 200; background: #fff;
    width: 100%;
    height: 100vh; height: 100dvh;
    display: flex; flex-direction: column;
}
.signatur-vollbild[hidden] { display: none; }
body.signatur-offen { overflow: hidden; }

/* Unterschreiben immer im Querformat (Vorgabe Dennis, 17.09.2026).
   Erste Wahl ist das ECHTE Drehen: Vollbild anfordern und die Ausrichtung auf
   quer festhalten - das kann aber nur Android. Apple erlaubt weder das eine
   noch das andere, deshalb dieser Rueckfall: das Fenster wird per Software um
   90 Grad gedreht, das Geraet bleibt hochkant.

   Wie die Zahlen zustande kommen: das Element ist so breit wie der Bildschirm
   hoch ist (100vh) und so hoch wie er breit ist (100vw). Nach der Drehung um
   den Punkt oben links laege es links neben dem Bildschirm - translateY(-100%)
   schiebt es entlang der GEDREHTEN y-Achse wieder hinein und es deckt den
   Bildschirm genau ab.

   Achtung fuer spaeter: bei einem gedrehten Element liefert
   getBoundingClientRect() nur noch den umschliessenden Kasten, Breite und
   Hoehe sind darin vertauscht. Wer hier misst, nimmt offsetWidth/offsetHeight
   (siehe groesseSetzen im Template), und Fingerpositionen muessen umgerechnet
   werden (siehe position()). */
.signatur-vollbild--gedreht {
    /* 100dvh mit 100vh davor: auf dem iPhone zaehlt 100vh die Adressleiste mit,
       und weil hier die Breite zur Bildschirmhoehe wird, fehlte sonst rechts
       ein Streifen. dvh gibt es ab Chrome 108 / Safari 16.4. */
    width: 100vh;
    width: 100dvh;
    height: 100vw;
    transform-origin: top left;
    transform: rotate(90deg) translateY(-100%);
}
.signatur-vollbild__kopf {
    display: flex; justify-content: space-between; align-items: center; gap: 0.8rem;
    padding: 0.7rem 1rem; border-bottom: 1px solid var(--color-border);
}
.signatur-vollbild__titel { font-weight: 600; }
/* min-height: 0 gehoert zu flex: 1 - ohne die Null weigert sich ein
   Flex-Element, unter seine Inhaltshoehe zu schrumpfen. Eine Mindesthoehe
   waere hier falsch: im Querformat bliebe sonst fuer Kopf- und Fusszeile
   zu wenig Platz. */
.signatur-vollbild__flaeche {
    flex: 1; position: relative; touch-action: none; min-height: 0;
}
.signatur-vollbild__flaeche canvas {
    position: absolute;
    top: 0; right: 0; bottom: 0; left: 0;
    inset: 0;
    width: 100%; height: 100%;
    touch-action: none; cursor: crosshair; background: #fff;
}
/* Orientierungshilfe wie auf dem Papierformular: Grundlinie mit Kreuz. */
.signatur-vollbild__linie {
    position: absolute; left: 1.5rem; right: 1.5rem; bottom: 28%;
    border-top: 1px dashed #c9d2da; pointer-events: none;
}
.signatur-vollbild__linie::before {
    content: "×"; position: absolute; left: -2px; top: -1.35rem;
    font-size: 1.1rem; color: #c9d2da;
}
.signatur-vollbild__tipp {
    position: absolute; left: 0; right: 0; top: 42%; margin: 0; text-align: center;
    color: #b7c0c9; font-size: 0.85rem; pointer-events: none;
}
.signatur-vollbild__warnung {
    position: absolute; left: 1rem; right: 1rem; bottom: 1rem; margin: 0;
    background: #fdeaea; border: 1px solid #f2c2c2; color: var(--color-primary-dark);
    border-radius: 8px; padding: 0.5rem 0.7rem; font-size: 0.85rem;
}
.signatur-vollbild__fuss {
    display: flex; gap: 0.6rem; padding: 0.7rem 1rem;
    border-top: 1px solid var(--color-border);
}
.signatur-vollbild__fuss .btn { flex: 1; padding-top: 0.85rem; padding-bottom: 0.85rem; }
.signatur-bild-vorschau {
    max-width: 100%; height: auto; max-height: 160px; background: #fff;
    border: 1px solid var(--color-border); border-radius: var(--radius); padding: 0.4rem;
}
.locked-notice {
    background: #e7f5ec; border: 1px solid #bfe3cc; color: #1c5e34;
    padding: 0.7rem 1rem; border-radius: var(--radius); margin-bottom: 1rem; font-size: 0.9rem;
}
.locked-notice--teil {
    background: #fff6e6; border-color: #f3d9a1; color: #7a5310;
}
/* Knopf innerhalb eines Hinweiskastens: eigene Zeile mit etwas Abstand,
   damit er nicht als Fußnote im Fließtext untergeht. */
.notice-aktion { margin-top: 0.7rem; }
/* Abschließender Knopf am Fuß einer Karte - derselbe Abstand nach oben wie
   zwischen den Angaben darüber.
   Flex, damit auch ein Knopf in einem eigenen <form> (ein POST braucht eines,
   siehe "Aus den Abschnitten übernehmen") in der Reihe stehen bleibt statt in
   die nächste Zeile zu rutschen. */
.karten-aktion {
    margin-top: 0.9rem;
    display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center;
}
.karten-aktion form { margin: 0; }

.locked-notice--info {
    background: #eaf2fb; border-color: #bcd6f2; color: #234a72;
}
.locked-notice--danger {
    background: #fbeceb; border-color: #e3b3ac; color: #7a2b21;
    display: flex; align-items: center; gap: 0.75rem; flex-wrap: wrap;
}
.locked-notice--danger .btn-link { color: #7a2b21; font-weight: 700; text-decoration: underline; }

/* ------------------------------------------------------------------ Modal */
dialog.modal {
    border: none; border-radius: var(--radius); box-shadow: var(--shadow);
    padding: 0; max-width: 420px; width: calc(100% - 2.5rem);
}
dialog.modal::backdrop { background: rgba(28, 43, 54, 0.55); }
.modal__body { padding: 1.5rem; }
.modal__body h2 { margin: 0 0 0.6rem; font-size: 1.15rem; }
.modal__body p { margin: 0 0 1.3rem; color: var(--color-text); font-size: 0.92rem; }
.modal__actions { display: flex; justify-content: flex-end; gap: 0.6rem; }

/* Druckt nur den Inhalt der geöffneten Auftragsbestätigung, keine Navigation
   oder den Rest der Seite (siehe "Drucken"-Button in auftrag_detail.html).
   Hinweis: nur echte Geschwister des Dialogs werden ausgeblendet, nicht der
   Dialog selbst oder eines seiner Elternelemente - ein display:none auf
   einem Vorfahren würde auch den geöffneten <dialog> mit verstecken. */
@media print {
    header.topbar, .nav--mobile, .flash-stack { display: none !important; }
    main.page > *:not(#bestaetigung-dialog) { display: none !important; }
    #bestaetigung-dialog { position: static; margin: 0; box-shadow: none; border: none; width: 100%; max-width: 100%; }
    #bestaetigung-dialog::backdrop { display: none; }
    #bestaetigung-dialog .modal__actions { display: none !important; }
}

/* -------------------------------------------------------------- Abrechnung */
.abrechnung-grid { display: grid; grid-template-columns: 1fr; gap: 1rem; margin-top: 1rem; }
@media (min-width: 900px) { .abrechnung-grid { grid-template-columns: 1fr 1fr; align-items: start; } }

.doc-viewer-list { display: flex; flex-direction: column; gap: 1rem; margin-bottom: 0.75rem; }
.doc-viewer { border: 1px solid var(--color-border); border-radius: var(--radius); padding: 0.6rem; }
.doc-viewer__img { display: block; max-width: 100%; height: auto; border-radius: calc(var(--radius) - 4px); margin-bottom: 0.5rem; }
.doc-viewer__pdf { display: block; width: 100%; height: 480px; border: none; border-radius: calc(var(--radius) - 4px); margin-bottom: 0.5rem; }

.positionen-table input { width: 100%; padding: 0.4rem 0.5rem; font-size: 0.85rem; }
.positionen-table textarea { width: 100%; padding: 0.4rem 0.5rem; font-size: 0.85rem; }
.positionen-table td { white-space: normal; }
.positionen-table tbody tr:nth-child(odd) td { border-bottom: none; padding-bottom: 0.3rem; }
.positionen-table tbody tr:nth-child(even) td { padding-top: 0.3rem; }
/* Die Zebra-Regeln oben zählen in Paaren: Werte-Zeile ungerade,
   Beschreibungs-Zeile gerade. Der "+"-Knopf hängt deshalb immer BEIDE Zeilen
   an, sonst kippt die Zuordnung für alle folgenden Zeilen. */
.positionen-aktion { display: flex; align-items: center; gap: 0.8rem; flex-wrap: wrap; margin-top: 0.6rem; }

/* --------------------------------------------------------- Sammelrechnung */
.sammel-check-col { width: 2.2rem; white-space: nowrap; }
.sammel-check-col input[type="checkbox"] { width: 1.1rem; height: 1.1rem; }

.sammel-bar {
    display: flex; align-items: center; gap: 0.9rem; flex-wrap: wrap;
    position: sticky; bottom: 0.8rem; margin-top: 1rem; padding: 0.7rem 1rem;
    background: var(--color-surface); border: 1px solid var(--color-border);
    border-radius: var(--radius); box-shadow: var(--shadow);
}
.sammel-bar .js-sammel-count { font-weight: 700; }

.abgleich-status { display: flex; gap: 0.5rem; flex-wrap: wrap; margin-bottom: 1rem; }
.abgleich-chip {
    display: inline-flex; align-items: center; gap: 0.35rem; font-size: 0.78rem;
    font-weight: 700; padding: 0.3rem 0.65rem; border-radius: 999px; border: 1px solid;
}
.abgleich-chip--ok { background: #e7f5ec; border-color: #bfe3cc; color: #1c5e34; }
.abgleich-chip--warn { background: #fff6e6; border-color: #f3d9a1; color: #7a5310; }

.order-block { border: 1px solid var(--color-border); border-radius: var(--radius); background: var(--color-surface); box-shadow: var(--shadow); margin-bottom: 1rem; overflow: hidden; }
.order-block__head { display: flex; align-items: center; justify-content: space-between; gap: 0.6rem; padding: 0.7rem 0.9rem; border-bottom: 1px solid var(--color-border); flex-wrap: wrap; }
.order-block__title { font-weight: 700; font-size: 0.95rem; display: flex; align-items: center; gap: 0.5rem; }
.order-block__body { padding: 0.8rem 0.9rem; }

.doc-mini { display: flex; align-items: center; gap: 0.7rem; padding: 0.6rem 0.9rem; border-bottom: 1px solid var(--color-border); }
.doc-mini__icon {
    width: 2.2rem; height: 2.2rem; border-radius: 7px; background: #eef2f6; color: var(--color-muted);
    display: flex; align-items: center; justify-content: center; font-size: 1rem; flex-shrink: 0;
}
.doc-mini__body { flex: 1; min-width: 0; }
.doc-mini__name { font-size: 0.82rem; font-weight: 600; }
.doc-mini__meta { font-size: 0.72rem; color: var(--color-muted); }
.doc-mini--missing { background: #fffaf0; }
.doc-mini--missing .doc-mini__icon { background: #f6e6bd; color: #7a5310; }
.doc-mini--missing .doc-mini__name { color: #7a5310; }
.doc-mini__upload { flex-shrink: 0; display: flex; gap: 0.4rem; align-items: center; }
.doc-mini__upload input[type="file"] { max-width: 11rem; font-size: 0.78rem; }

.send-note {
    display: flex; align-items: flex-start; gap: 0.5rem; font-size: 0.82rem; color: #7a5310;
    background: #fff6e6; border: 1px solid #f3d9a1; border-radius: var(--radius);
    padding: 0.6rem 0.85rem; margin-top: 1rem;
}

/* ----------------------------------------------------------------- Error */
.error-page { text-align: center; padding: 4rem 1rem; }
.error-page__code { font-size: 3rem; font-weight: 800; color: var(--color-muted); }

/* ------------------------------------------------------------ Auswertung */
/* Auswertungsseite (siehe auswertung.py): Jahresmatrix Mitarbeiter × Monat,
   Rangliste für einen einzelnen Monat und die Detailliste der dahinter
   liegenden Aufträge. Nutzt bewusst die vorhandenen .table-/.table-wrap-
   Bausteine und ergänzt nur das, was eine Zahlentabelle zusätzlich braucht:
   rechtsbündige Zahlen mit gleicher Ziffernbreite, eine beim seitlichen
   Scrollen stehenbleibende Namensspalte und eine hervorgehobene Summe. */
.aus-tabs { display: flex; gap: 0.4rem; border-bottom: 1px solid var(--color-border); margin-bottom: 1rem; }
.aus-tab {
    padding: 0.55rem 0.9rem; color: var(--color-muted); text-decoration: none;
    border-bottom: 2px solid transparent; margin-bottom: -1px; font-size: 0.92rem;
}
.aus-tab:hover { text-decoration: none; color: var(--color-text); }
.aus-tab.is-active { color: var(--color-primary); border-bottom-color: var(--color-primary); font-weight: 600; }

.aus-table th.aus-zahl, .aus-table td.aus-zahl { text-align: right; font-variant-numeric: tabular-nums; }
.aus-table th.aus-name, .aus-table td.aus-name {
    position: sticky; left: 0; background: var(--color-surface); z-index: 1; font-weight: 600;
}
.aus-table td.aus-zahl a { display: block; color: inherit; }
.aus-table td.aus-zahl a:hover { color: var(--color-primary); }
.aus-table td.aus-zahl--leer { color: #b6c1c9; }
.aus-table th.aus-summe, .aus-table td.aus-summe { background: #f7f9fa; font-weight: 700; }
.aus-table td.is-selected { background: #fdf0f0; box-shadow: inset 0 0 0 2px var(--color-primary); }
.aus-table tfoot td, .aus-table tfoot td.aus-name { background: #f2f5f7; font-weight: 700; border-top: 2px solid var(--color-border); }
.aus-table tbody tr:hover td:not(.aus-summe):not(.is-selected) { background: #f8fafb; }

.aus-rang__head {
    display: flex; justify-content: space-between; align-items: baseline; gap: 1rem;
    flex-wrap: wrap; padding: 0.9rem 1rem; border-bottom: 1px solid var(--color-border);
}
.aus-rang__head h2 { margin: 0; }
.aus-rang {
    display: grid; grid-template-columns: 12rem 1fr 8rem; gap: 1rem; align-items: center;
    padding: 0.6rem 1rem; border-bottom: 1px solid var(--color-border); color: inherit;
}
.aus-rang:last-child { border-bottom: 0; }
.aus-rang:hover { background: #f8fafb; text-decoration: none; }
.aus-rang__name { font-weight: 600; font-size: 0.92rem; }
.aus-rang__balken { display: block; height: 0.7rem; }
.aus-rang__balken > span {
    display: block; height: 100%; min-width: 3px; border-radius: 999px;
    background: var(--status-abgerechnet);
}
.aus-rang__wert { text-align: right; font-weight: 700; font-variant-numeric: tabular-nums; font-size: 0.92rem; }
.aus-rang__wert small { display: block; font-weight: 400; font-size: 0.72rem; }
.aus-rang__leer { padding: 1.2rem 1rem; margin: 0; }
@media (max-width: 720px) {
    .aus-rang { grid-template-columns: 7.5rem 1fr 6rem; gap: 0.6rem; }
}

.aus-detail { margin-top: 1.25rem; }
.aus-detail td small { display: block; font-size: 0.72rem; }
.aus-anteil {
    font-size: 0.7rem; color: var(--color-muted); background: var(--color-bg);
    border-radius: 999px; padding: 0.1rem 0.4rem; margin-left: 0.3rem; white-space: nowrap;
}

/* --- Fahrzeugakte --------------------------------------------------------
   Kennzahlen-Kacheln, der Informationsknopf in der Fahrzeugliste und die
   Prüfansicht beim Einlesen der Tankkarten-Rechnung (siehe vehicles.py). */

.akte-kacheln {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
    gap: 0.8rem;
    margin-bottom: 1.4rem;
}

.akte-kachel {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: 8px;
    padding: 0.8rem 0.9rem;
}

.akte-kachel__label {
    font-size: 0.78rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--color-muted);
}

.akte-kachel__wert { font-size: 1.35rem; line-height: 1.25; }
.akte-kachel__fuss { font-size: 0.78rem; color: var(--color-muted); }

/* Der Informationsknopf ("i") in der Fahrzeugliste - schmale eigene Spalte
   ganz vorne, damit er nicht mit "Bearbeiten"/"Löschen" verwechselt wird. */
.spalte--akte { width: 2.6rem; }

.akte-knopf {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    line-height: 0;
    border-radius: 50%;
    text-decoration: none;
    /* Bewusst blau und nicht im Rot der Seite: das Symbol öffnet nur eine
       Ansicht, während Rot in dieser Tabelle für Aktionen steht. */
    color: var(--color-info);
}

.akte-knopf:hover,
.akte-knopf:focus-visible {
    color: var(--color-info-dark);
    text-decoration: none;
}

.visually-hidden {
    position: absolute;
    width: 1px; height: 1px;
    margin: -1px; padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}

/* --- Prüfansicht Tankrechnung -------------------------------------------- */

.card--warnung {
    border-color: #e7c37a;
    background: #fdf8ec;
}

.pruef-gruppe + .pruef-gruppe { margin-top: 1rem; }

.pruef-hinweis {
    margin-top: 0.2rem;
    font-size: 0.8rem;
    color: #8a5a00;
}

/* Dubletten bleiben sichtbar, aber zurückgenommen - man soll sehen, dass die
   Zeile in der Rechnung steht, und zugleich, dass sie nichts mehr tut. */
.zeile--still { opacity: 0.5; }
.zeile--achtung { background: #fdf8ec; }

.form-actions--sticky {
    position: sticky;
    bottom: 0;
    padding: 0.7rem 0;
    background: var(--color-bg);
    border-top: 1px solid var(--color-border);
}

.table .zahl { text-align: right; font-variant-numeric: tabular-nums; }

/* Auffälliger Verbrauchswert in der Fahrzeugakte - siehe vehicles.akte. */
.wert--achtung { color: #a05a00; font-weight: 600; }
/* Nur in der Tabelle darf der Wert nicht umbrechen - in der Kennzahlen-Kachel
   muss der Hinweis dagegen umbrechen duerfen, sonst laeuft er aus der Kachel. */
.table .wert--achtung { white-space: nowrap; }

/* In der Prüfansicht die beiden breitesten Zellen begrenzen, damit die
   Fahrzeugauswahl am rechten Rand nicht aus dem Bild läuft. */
.pruef-gruppe .pruef-hinweis { max-width: 26rem; }
.pruef-gruppe select { max-width: 13rem; }

/* Fahrzeugakte, Stand 13.09.2026 */

/* --- Beleg neben der Prüfansicht ------------------------------------------
   Das PDF der Tankrechnung liegt ÜBER der Tabelle und bleibt beim Scrollen
   stehen. Bewusst nicht daneben: die DKV-Rechnung ist im Querformat und wird
   in einer halben Bildschirmbreite unlesbar klein. */

.beleg {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: 8px;
    margin-bottom: 0.9rem;
    position: sticky;
    /* Die Kopfleiste der App klebt selbst schon oben (rund 51 px hoch). Ohne
       diesen Abstand rutscht der Beleg dahinter, und seine eigene Zeile mit
       den Seitenzahlen verschwindet. */
    top: 3.6rem;
    z-index: 5;
    box-shadow: 0 6px 18px -14px rgba(0, 0, 0, 0.5);
}

.beleg__kopf {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.6rem;
    padding: 0.4rem 0.7rem;
    border-bottom: 1px solid var(--color-border);
    font-size: 0.82rem;
    color: var(--color-muted);
}

.beleg--zu .beleg__kopf { border-bottom: none; }
.beleg__titel { font-variant-numeric: tabular-nums; }
.beleg__blaetter { display: flex; align-items: center; gap: 0.3rem; }

.beleg__blatt {
    width: 1.7rem;
    height: 1.7rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--color-border);
    border-radius: 4px;
    background: var(--color-surface);
    color: var(--color-muted);
    font: inherit;
    font-size: 0.78rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    cursor: pointer;
}

.beleg__blatt[aria-pressed="true"] {
    background: var(--color-info);
    border-color: var(--color-info);
    color: #fff;
}

.beleg__rahmen { padding: 0.4rem; }
.beleg--zu .beleg__rahmen { display: none; }

.beleg__rahmen iframe {
    display: block;
    width: 100%;
    /* Die Rechnung liegt im Querformat: bei weniger Höhe sieht man von einer
       Seite kaum mehr als die Kopfzeile. */
    height: 56vh;
    min-height: 260px;
    border: 1px solid var(--color-border);
    border-radius: 4px;
    background: var(--color-bg);
}

/* Die gerade angeklickte Zeile - macht sichtbar, wozu die aufgeschlagene
   Seite des Belegs gehört. */
.pruef-gruppe tbody tr { cursor: pointer; }
.pruef-gruppe tbody tr.ist-gewaehlt > td {
    background: #e8f0f9;
    box-shadow: inset 3px 0 0 var(--color-info);
}

/* Kleiner Verweis von der Tankung auf ihren Beleg (Fahrzeugakte). */
.beleg-verweis {
    display: inline-block;
    margin-left: 0.4rem;
    font-size: 0.74rem;
    font-weight: 600;
    color: var(--color-info);
    text-decoration: none;
    border-bottom: 1px dotted currentColor;
}
.beleg-verweis:hover { color: var(--color-info-dark); }

@media (max-width: 720px) {
    /* Auf dem Handy nimmt der Beleg sonst den halben Bildschirm - er bleibt
       aufrufbar, steht aber nicht mehr im Weg. */
    .beleg { position: static; }
    .beleg__rahmen iframe { height: 38vh; }
}

/* Warnende Marke - z.B. "nicht in der App" in der Prüfansicht oder "3 offen"
   in der Rechnungsliste. Ergänzt die Status-Marken um einen neutralen
   Hinweis-Ton, der zu keinem Auftrags- oder Fahrzeugstatus gehört. */
.badge--warnung { background: #b8860b; }

/* --- Fahrzeugakte, Teil 2: Reiter, Fristen, Papiere ---------------------- */

.reiter {
    display: flex;
    flex-wrap: wrap;
    gap: 0.15rem;
    border-bottom: 1px solid var(--color-border);
    margin-bottom: 1.1rem;
}

.reiter__blatt {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.55rem 0.9rem;
    margin-bottom: -1px;
    border-bottom: 2px solid transparent;
    font-size: 0.92rem;
    font-weight: 600;
    color: var(--color-muted);
    text-decoration: none;
}

.reiter__blatt:hover { color: var(--color-text); text-decoration: none; }

.reiter__blatt.is-active {
    color: var(--color-text);
    border-bottom-color: var(--color-primary);
}

.reiter__zaehler {
    font-size: 0.7rem;
    font-weight: 700;
    line-height: 1.4;
    padding: 0 0.35rem;
    border-radius: 999px;
    background: #fdf6e3;
    color: #9a6700;
    border: 1px solid #e7c37a;
}

/* Fristen-Marken. Eigene Farben, weil es weder ein Auftrags- noch ein
   Fahrzeugstatus ist: gelb ab 60 Tagen, kräftiger ab 30, rot ab Ablauf. */
.badge--frist-bald { background: #b8860b; }
.badge--frist-dringend { background: #c9781f; }
.badge--frist-abgelaufen { background: var(--color-danger); }
.badge--service { background: var(--status-bestaetigt); }

.frist-hinweis { margin-bottom: 1rem; }
.frist-liste { margin: 0.4rem 0 0; padding-left: 1.1rem; }
.frist-liste li { margin-bottom: 0.2rem; }



/* Zweite, stille Zeile in einer Tabellenzelle (Geburtstag unter dem Namen in
   der Mitarbeiterliste). .table td steht auf nowrap - deshalb hier ein
   eigener Block statt eines <br>. */
.zeile-zusatz { display: block; white-space: nowrap; }

/* --------------------------------------------------------------- Mängel */

/* Marke in Fahrzeugliste und Plantafel. Klein und ohne Fläche, solange nichts
   dringend ist - rot erst bei einem Sofort-Mangel, damit die Farbe etwas
   bedeutet. */
.mangel-marke {
    display: inline-flex; align-items: center; gap: 0.2rem;
    margin-left: 0.4rem; padding: 0.1rem 0.4rem; border-radius: 16px;
    background: var(--color-surface); border: 1px solid var(--color-border);
    color: var(--color-muted); font-size: 0.7rem; font-weight: 700;
    white-space: nowrap; text-decoration: none;
}
.mangel-marke:hover { text-decoration: none; filter: brightness(0.97); }
.mangel-marke--sofort {
    background: #fdecec; border-color: #f3b9b9; color: #a01414;
}

/* Die Mängelliste im Reiter: Karten statt Tabelle, weil vom Handy gemeldet
   wird. Der farbige Streifen links trägt die Dringlichkeit - so bleibt sie
   auch beim Überfliegen sichtbar. */
.mangel-liste { list-style: none; margin: 0.4rem 0 1.2rem; padding: 0; display: grid; gap: 0.6rem; }
.mangel {
    border: 1px solid var(--color-border); border-left: 4px solid var(--color-border);
    border-radius: var(--radius); background: var(--color-surface);
    padding: 0.7rem 0.9rem;
}
.mangel--sofort { border-left-color: #c00000; }
.mangel--bald { border-left-color: #e08600; }
.mangel--kosmetisch { border-left-color: var(--color-border); }
.mangel--erledigt { opacity: 0.66; }
.mangel__kopf { display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap; }
.mangel__stufe { font-size: 0.75rem; font-weight: 700; letter-spacing: 0.02em; }
.mangel__text { margin: 0.35rem 0 0.2rem; white-space: pre-line; }
.mangel__meta, .mangel__erledigt { margin: 0.1rem 0; }
.mangel__foto { display: inline-block; margin: 0.4rem 0; }
.mangel__foto img {
    max-width: 220px; max-height: 160px; border-radius: var(--radius);
    border: 1px solid var(--color-border); display: block;
}
/* Kommentarfeld und Knopf in einer Reihe, am Handy untereinander. */
.mangel__abhaken { display: flex; gap: 0.5rem; flex-wrap: wrap; margin-top: 0.5rem; }
.mangel__abhaken input { flex: 1 1 14rem; min-width: 0; }

/* Die drei Dringlichkeiten als Auswahl im Meldeformular. */
.dringlichkeit-wahl { border: none; padding: 0; margin: 0.6rem 0; }
.dringlichkeit-wahl legend { font-weight: 700; font-size: 0.8rem; padding: 0; }
.dringlichkeit-wahl .form-haken { margin-top: 0.3rem; align-items: flex-start; }

/* Der Haken "für Fahrer sichtbar" - ein Knopf, damit man ihn direkt in der
   Zeile umlegen kann, ohne ein Formular zu öffnen. */
.sicht-schalter {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    border: 1px solid var(--color-border);
    background: var(--color-surface);
    color: var(--color-muted);
    border-radius: 999px;
    padding: 0.1rem 0.6rem;
    font: inherit;
    font-size: 0.74rem;
    font-weight: 600;
    cursor: pointer;
    white-space: nowrap;
}

.sicht-schalter--an {
    color: var(--color-info);
    border-color: color-mix(in srgb, var(--color-info) 40%, var(--color-border));
    background: #eef4fb;
}

.zeile--frueher > td { background: var(--color-bg); font-size: 0.8rem; }

/* Kleines Formular innerhalb einer Tabellenzeile (Kosten nachtragen,
   Dokumentart bearbeiten). */
.nachtrag {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 0.7rem;
    padding: 0.3rem 0 0.5rem;
}
.nachtrag label { font-size: 0.8rem; }
.nachtrag input[type="text"],
.nachtrag input[type="file"] { max-width: 16rem; }

.intervall-form { margin-bottom: 1.1rem; }
.intervall-form .form-grid { max-width: 32rem; }

.akte-kachel--warnt {
    border-color: #e7c37a;
    background: #fdf8ec;
}
.akte-kachel--warnt .akte-kachel__fuss { color: #8a5a00; font-weight: 600; }

/* Feld "gültig bis", wenn die gewählte Art gar keine Frist hat. */
label.ist-gedimmt { opacity: 0.55; }

/* .form-haken war ursprünglich ein Block, der ein <label> umschließt (siehe
   mitarbeiter_form.html). In den neuen Masken sitzt die Klasse direkt am
   <label> - ohne diese Regel greift dort .form-grid label und stellt das
   Kästchen über den Text statt daneben. */
label.form-haken {
    display: flex;
    /* Die allgemeine label-Regel stellt flex-direction auf column - ohne das
       Zurücksetzen steht das Kästchen über dem Text statt daneben. */
    flex-direction: row;
    align-items: center;
    gap: 0.6rem;
    margin-top: 0;
    cursor: pointer;
    font-weight: 600;
}

label.form-haken input {
    margin: 0;
    width: auto;
    flex: none;
}

label.form-haken span { font-weight: 400; }

/* Fahrtabschnitte auf der Auftragsseite (siehe auftrag_detail.html).
   Bewusst eine Liste und keine Tabelle: am Handy bricht eine Tabelle mit
   sechs Spalten entweder quer aus dem Bild oder wird unleserlich schmal.
   Jeder Eintrag ist ein eigener Block mit einer Linie links, die Zeit steht
   oben, Ort und Kilometer darunter. */
.abschnitt-liste {
    list-style: none;
    margin: 0.9rem 0 0;
    padding: 0;
}

.abschnitt-liste li {
    border-left: 3px solid var(--color-border);
    padding: 0.15rem 0 0.55rem 0.7rem;
    margin-bottom: 0.55rem;
}

.abschnitt-liste li:last-child { margin-bottom: 0; }

.abschnitt-liste__zeit {
    display: block;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

.abschnitt-liste__ort,
.abschnitt-liste__km { display: block; }

/* Der laufende Abschnitt bekommt die Linie in der Statusfarbe "unterwegs",
   damit er sich beim Überfliegen von den abgeschlossenen abhebt. */
.abschnitt-liste li:has(em) { border-left-color: var(--status-unterwegs); }

/* Einsatzabschnitte im Leistungsnachweis (siehe leistungsnachweis.html).
   Die Kilometerspalte bekommt gleich breite Ziffern, damit die Zahlen der
   Zeilen untereinander stehen und ein Zahlendreher auffällt. */
.table--abschnitte .spalte--km { font-variant-numeric: tabular-nums; }
.table--abschnitte tfoot th {
    color: var(--color-text); background: var(--color-bg);
    /* Die Summenzeile enthaelt einen ganzen Satz ("reine Einsatzzeit
       28:15 h") - in Grossbuchstaben wie die Spaltenkoepfe waere das
       schlecht lesbar, und aus dem h wuerde ein H. */
    text-transform: none; font-size: 0.85rem; letter-spacing: 0;
}
.table--abschnitte th, .table--abschnitte td { padding: 0.55rem 0.6rem; }

/* Hinweis unter einem Eingabefeld (z.B. der Kilometerstand vom Fahrtbeginn,
   siehe abschnitt_form.html). Die allgemeine label-Regel macht alles im Label
   fett - ohne diese Ausnahme sieht der Hinweis aus wie die Beschriftung des
   naechsten Feldes. */
.feld-hinweis {
    font-weight: 400;
    font-size: 0.8rem;
    color: var(--color-muted);
    margin-top: 0.25rem;
}

.feld-hinweis--inline { margin-top: 0; }

/* Gefuellt gruen: die Hauptaktion des Begleitfahrers unterwegs
   (Fahrtbeginn / Zwischenziel / Weiterfahrt, siehe abschnitte.py). Rot ist je
   Seite fuer EINE Hauptaktion reserviert und auf der Auftragsseite bereits an
   "Status aktualisieren" vergeben - deshalb hier eine eigene Farbe, nach dem
   Muster von .btn--info. */
.btn--gruen {
    background: var(--color-success);
    color: #fff;
    border-color: var(--color-success);
}

.btn--gruen:hover {
    background: #176637;
    border-color: #176637;
    color: #fff;
    text-decoration: none;
}

/* Automatische Aktualisierung (siehe static/js/aktualisierung.js).
   Die Leiste erscheint nur, wenn gerade nicht ausgetauscht werden darf -
   also wenn jemand tippt, ein Haken gesetzt ist oder ein Fenster offen
   steht. Sie sitzt unten rechts und nimmt niemandem den Platz weg. */
.aktualisierung-hinweis {
    position: fixed;
    right: 1rem; bottom: 1rem;
    z-index: 150;
    display: flex; align-items: center; gap: 0.7rem;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-left: 4px solid var(--color-success);
    border-radius: var(--radius);
    box-shadow: 0 6px 18px rgba(28, 43, 54, 0.18);
    padding: 0.7rem 0.9rem;
    font-size: 0.9rem;
}

/* Am Handy steht unten die Navigationsleiste - darüber ausweichen. */
@media (max-width: 779px) {
    .aktualisierung-hinweis { bottom: 4.6rem; left: 1rem; right: 1rem; }
}

/* Frisch hinzugekommene Zeile oder Kachel: leuchtet kurz auf und geht dann
   in die normale Darstellung über. Ohne das tauscht sich die Seite lautlos
   aus und niemand merkt, dass die Kollegin etwas eingetragen hat. */
.frisch {
    animation: frisch-aufleuchten 3s ease-out;
}

@keyframes frisch-aufleuchten {
    0%, 55% { background-color: #fff6d8; }
    100% { background-color: transparent; }
}

/* Wer Animationen abgestellt hat, bekommt die Markierung trotzdem zu sehen -
   nur eben ohne Überblendung. */
@media (prefers-reduced-motion: reduce) {
    .frisch { animation: none; background-color: #fff6d8; }
}

/* Diagnoseseite „Lexware-Rohdaten": die unveränderte API-Antwort. Bewusst
   scrollbar statt umbrechend - eingerücktes JSON ist nur lesbar, solange die
   Einrückung stimmt. Das Scrollen bleibt im Kasten, die Seite selbst rutscht
   am Handy nicht seitlich weg. */
.rohdaten {
    background: var(--color-surface); border: 1px solid var(--color-border);
    border-radius: var(--radius); box-shadow: var(--shadow);
    padding: 0.9rem 1rem; margin: 0 0 1.2rem;
    font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
    font-size: 0.82rem; line-height: 1.5;
    overflow-x: auto; max-height: 34rem; overflow-y: auto;
}

.feld-liste { margin: 0.4rem 0 0; padding-left: 1.2rem; }
.feld-liste code { font-size: 0.9rem; }

/* Artikel & Kundenpreise (18.09.2026).
   Preisfelder in einer Tabellenspalte: rechtsbündig und schmal, damit die
   Beträge untereinander stehen. Kein flex auf der Zelle - siehe die Regel
   dazu in den Projektunterlagen. */
.preis-feld {
    width: 8.5rem; max-width: 100%; text-align: right;
    padding: 0.35rem 0.5rem; border-radius: var(--radius);
    border: 1px solid var(--color-border); font-size: 0.9rem;
    font-family: inherit;
}

/* Uneinheitliche Preise in der Übernahmeliste nutzen die vorhandene
   Klasse .zeile--achtung (siehe oben) - kein zweiter Stil für dieselbe Sache. */

.spalte--haken { width: 2.5rem; text-align: center; }
.spalte--haken input { width: 1.1rem; height: 1.1rem; }

@media (max-width: 600px) {
    .preis-feld { width: 6.5rem; }
}

/* =========================================================== Dashboard ==
   Umbau am 19.09.2026 (Wunsch Dennis: „strukturierter gegliedert, farbiger
   abgesetzt in meinen Firmenfarben"). Die Seite hat jetzt drei Abschnitte:
   Karte, „Was liegt an", Aufträge.

   Der Kern ist, dass ALLE Hinweise dieselbe Bauform haben (.meldung) - vorher
   war jeder anders gebaut, und genau das machte die Seite unruhig. Die Farbe
   am linken Rand kommt aus der Stufe und ist eine Aussage:

       handeln     Firmenrot   Da muss heute etwas passieren.
       entscheiden Bernstein   Jemand wartet auf eine Antwort.
       merken      Graublau    Reine Information.

   Rot bleibt deshalb knapp: leuchtet alles in Firmenfarbe, sieht man wieder
   nichts. Welche Meldung welche Stufe bekommt, steht in meldungen.py. */
.block-titel {
    font-size: 1.05rem; font-weight: 700; margin: 0 0 0.7rem;
    display: flex; align-items: center; gap: 0.45rem;
}
.block-titel--trenner {
    margin-top: 1.8rem; padding-top: 1.1rem;
    border-top: 1px solid var(--color-border);
}

/* Karte und Standortliste sitzen zusammen in EINEM Kasten - die Karte hat
   Vorrang und steht deshalb ganz oben, direkt unter der Überschrift. */
.karten-block {
    display: flex; gap: 1.6rem; align-items: flex-start; flex-wrap: wrap;
    background: var(--color-surface); border: 1px solid var(--color-border);
    border-radius: var(--radius); box-shadow: var(--shadow);
    padding: 1.1rem 1.2rem; margin-bottom: 1.2rem;
}
.karten-block__karte { flex: 0 0 auto; }
.karten-block__liste { flex: 1 1 320px; min-width: 260px; }

.meldungs-raster {
    display: grid; gap: 0.9rem;
    grid-template-columns: repeat(auto-fill, minmax(330px, 1fr));
}
.meldung {
    background: var(--color-surface); border: 1px solid var(--color-border);
    border-left: 5px solid var(--stufe-farbe, var(--color-border));
    border-radius: var(--radius); box-shadow: var(--shadow);
    padding: 0.85rem 1rem 0.7rem;
    display: flex; flex-direction: column;
}
.meldung--handeln {
    --stufe-farbe: var(--color-primary, #c00000);
    background: linear-gradient(90deg, #fdf3f3 0 40%, var(--color-surface) 100%);
}
.meldung--entscheiden { --stufe-farbe: #c9781f; }
.meldung--merken { --stufe-farbe: #6b7a89; }

.meldung__kopf { display: flex; align-items: baseline; gap: 0.55rem; }
.meldung__zahl {
    font-size: 1.65rem; font-weight: 800; line-height: 1;
    color: var(--stufe-farbe); font-variant-numeric: tabular-nums;
}
.meldung__titel {
    font-weight: 700; display: flex; flex-direction: column; line-height: 1.25;
}
.meldung__unter { font-weight: 400; font-size: 0.8rem; margin-top: 0.1rem; }

.meldung__liste { list-style: none; margin: 0.7rem 0 0; padding: 0; flex: 1; }
.meldung__liste li {
    display: flex; gap: 0.5rem; align-items: baseline;
    padding: 0.32rem 0; border-top: 1px solid var(--color-border);
    font-size: 0.87rem;
}
.meldung__was { font-weight: 600; flex: 0 0 auto; }
.meldung__text { flex: 1; min-width: 0; }
.meldung__wann { flex: 0 0 auto; font-size: 0.78rem; }
.meldung__mehr { margin: 0.45rem 0 0; }
.meldung__link {
    margin-top: 0.7rem; align-self: flex-start;
    font-size: 0.85rem; font-weight: 600; color: var(--stufe-farbe);
}

@media (max-width: 700px) {
    .karten-block { padding: 0.9rem; gap: 1rem; }
    .meldung__liste li { flex-wrap: wrap; }
    .meldung__wann { flex-basis: 100%; }
}

/* Feierabend-Standorte: schematische Karte + Liste (18.09.2026).
   Karte links, Liste rechts; am Handy untereinander. Die Karte wird von der
   App selbst gezeichnet (karte.py) - kein Kartendienst, keine externe Datei. */
/* Bild und Nadel-SVG liegen uebereinander. Das Bild bestimmt die Hoehe,
   das SVG legt sich per position:absolute genau darueber. */
.standort-karte__bild {
    position: relative; flex: 0 0 auto; width: 360px; max-width: 100%;
    line-height: 0;
}
.standort-karte__bild img { width: 100%; height: auto; display: block; }
.standort-karte__nadeln {
    position: absolute; top: 0; right: 0; bottom: 0; left: 0;
    width: 100%; height: 100%;
    filter: drop-shadow(0 1px 2px rgba(20, 40, 60, 0.35));
}
.standort-karte__fuss { margin: 0.9rem 0 0; }

.standort-nadel__schatten { fill: rgba(20, 40, 60, 0.18); }
.standort-nadel__form { fill: var(--color-primary, #b3202c); stroke: #fff; stroke-width: 2; }
.standort-nadel__nr {
    fill: #fff; font-family: inherit; font-size: 10px; font-weight: 700;
    text-anchor: middle;
}
/* Älter als FRISCH_STUNDEN: zurückgenommen, aber noch lesbar. Nicht
   ausblenden - der Standort ist ja bekannt, nur eben nicht von heute. */
.standort-nadel.ist-alt .standort-nadel__form { fill: #9aa7b2; }
.standort-nadel.ist-alt .standort-nadel__schatten { fill: rgba(20, 40, 60, 0.1); }
/* Außerhalb des Kartenausschnitts: am Rand, gestrichelter Rahmen als Hinweis,
   dass die Position nur die Richtung angibt. */
.standort-nadel.ist-draussen .standort-nadel__form {
    stroke-dasharray: 2.5 2; stroke-width: 1.2;
}

.standort-liste { list-style: none; margin: 0; padding: 0; flex: 1 1 300px; min-width: 260px; }
.standort-liste li {
    display: flex; gap: 0.7rem; align-items: center;
    padding: 0.55rem 0; border-bottom: 1px solid var(--color-border);
}
.standort-liste li:last-child { border-bottom: 0; }
.standort-liste li > div { flex: 1; min-width: 0; }
.standort-liste li.ist-alt .standort-liste__nr { background: #9aa7b2; }
.standort-liste__nr {
    display: inline-flex; align-items: center; justify-content: center;
    width: 1.55rem; height: 1.55rem; flex: none; border-radius: 50%;
    background: var(--color-primary, #b3202c); color: #fff;
    font-size: 0.78rem; font-weight: 700;
}

@media (max-width: 700px) {
    .standort-karte__bild { width: 100%; max-width: 330px; margin: 0 auto; }
}

/* Kundenanfragen (18.09.2026).
   Die oeffentliche Seite hat bewusst keine Navigation - ein Kunde soll von
   der App nichts sehen ausser seinem Formular (siehe base_oeffentlich.html). */
body.oeffentlich { background: var(--color-bg, #f4f6f8); }
.oeffentlich__kopf {
    background: #fff; border-bottom: 1px solid var(--color-border);
    padding: 0.8rem 1rem; text-align: center;
}
.oeffentlich__kopf .brand__logo { height: 2.4rem; width: auto; }
.oeffentlich__inhalt { padding-top: 1.2rem; padding-bottom: 2rem; }
.oeffentlich__fuss { text-align: center; padding: 0 1rem 2rem; }

/* Honigtopf gegen Bots: fuer Menschen nicht sichtbar, aber vorhanden -
   display:none wuerde von manchen Bots erkannt. */
.honigtopf {
    position: absolute; left: -9999px; width: 1px; height: 1px;
    overflow: hidden;
}

.anfrage-link { margin-bottom: 1.2rem; }
.anfrage-link__feld {
    width: 100%; font-family: ui-monospace, Menlo, Consolas, monospace;
    font-size: 0.8rem; padding: 0.5rem 0.6rem; border-radius: var(--radius);
    border: 1px solid var(--color-border); background: #fbfcfd;
}

.oeffentlich__fuss p { margin: 0.2rem 0; }
.oeffentlich__rechtliches a { margin: 0 0.15rem; }

/* ============================================================== Spesen ==
   Spesen je Mitarbeiter und Kalendertag (Wunsch Dennis, 19.09.2026).
   Zwei Ansichten derselben Daten - Kalender und Liste -, umgeschaltet mit
   demselben view-toggle wie bei den Aufträgen. Regeln stehen in spesen.py.

   Die Kalenderzelle heißt .spesen-tag und NICHT .tag: .tag ist in dieser
   App seit langem die kleine Plakette ("Begleit", "Kunde", Rolle,
   Funkart). Am 19.09.2026 hat ein .tag hier jede Plakette der App zu einem
   8,6 rem hohen Kasten gemacht - Dennis sah es auf dem Dashboard.

   Rot heißt hier nicht "Achtung", sondern "entschieden": ein gesetzter Tag
   ist gefüllt, ein offener nur umrandet. Beim Durchgehen eines Monats ist
   genau das die Frage - was fehlt noch. */
.spesen-leiste {
    display: flex; align-items: flex-end; justify-content: space-between;
    gap: 1.5rem; flex-wrap: wrap;
    background: var(--color-surface); border: 1px solid var(--color-border);
    border-radius: var(--radius); box-shadow: var(--shadow);
    padding: 0.9rem 1.2rem; margin-bottom: 1.2rem;
}
.spesen-leiste__wahl { display: flex; align-items: flex-end; gap: 1.4rem; flex-wrap: wrap; }
.feld-inline {
    display: flex; flex-direction: column; gap: 0.25rem;
    font-size: 0.8rem; color: var(--color-muted);
}
.feld-inline select, .feld-inline input[type="text"] {
    font: inherit; font-size: 0.95rem; color: var(--color-text);
    padding: 0.35rem 0.6rem; border: 1px solid var(--color-border);
    border-radius: 6px; background: #fff; min-width: 11rem;
}
.monatswahl {
    display: flex; align-items: center; gap: 0.6rem;
    font-size: 1.05rem; padding-bottom: 0.3rem;
}
.monatswahl__pfeil {
    display: inline-flex; align-items: center; justify-content: center;
    font: inherit; font-size: 1.1rem; line-height: 1; cursor: pointer;
    width: 1.9rem; height: 1.9rem; border-radius: 6px;
    border: 1px solid var(--color-border); background: #fff;
    color: var(--color-text); text-decoration: none;
}
.monatswahl__pfeil:hover { background: var(--color-bg); text-decoration: none; }
.spesen-summe { text-align: right; display: flex; flex-direction: column; gap: 0.1rem; }
.spesen-summe__zahl {
    font-size: 1.9rem; font-weight: 800; line-height: 1;
    color: var(--color-primary); font-variant-numeric: tabular-nums;
}
.spesen-summe__label { font-size: 0.82rem; color: var(--color-muted); }
.spesen-offen { font-size: 0.78rem; font-weight: 700; color: #c9781f; }
.spesen-fertig { font-size: 0.78rem; font-weight: 700; color: #3f7d4f; }

.ansicht-zeile {
    display: flex; justify-content: space-between; align-items: center;
    gap: 1rem; margin-bottom: 0.7rem; flex-wrap: wrap;
}
.nur-fahrten { font-size: 0.86rem; margin: 0; }

/* ----------------------------------------------------- Kalenderansicht -- */
.kalender { display: grid; grid-template-columns: repeat(7, 1fr); gap: 0.5rem; }
.kalender__kopf {
    font-size: 0.78rem; font-weight: 700; color: var(--color-muted);
    text-transform: uppercase; letter-spacing: 0.04em; padding-left: 0.2rem;
}
.spesen-tag {
    background: var(--color-surface); border: 1px solid var(--color-border);
    border-radius: var(--radius); padding: 0.45rem 0.5rem 0.5rem;
    min-height: 8.6rem; display: flex; flex-direction: column;
}
.spesen-tag--leer { background: transparent; border: 0; min-height: 0; }
.spesen-tag--wochenende { background: #f7f9fa; }
.spesen-tag--fahrt { border-color: #cdd6dd; }
.spesen-tag--gesetzt { border-left: 4px solid var(--color-primary); }
.spesen-tag--urlaub { background: #f4f7f3; }
/* Heute nur umranden, nicht fuellen: eine gefuellte rote Flaeche heisst auf
   dieser Seite "entschieden", und der heutige Tag ist erst einmal gar nichts. */
.spesen-tag.ist-heute .spesen-tag__nr {
    box-shadow: inset 0 0 0 1.5px var(--color-primary);
    border-radius: 4px; padding: 0 0.3rem; color: var(--color-primary);
}
.spesen-tag__kopf { display: flex; align-items: baseline; justify-content: space-between; gap: 0.4rem; }
.spesen-tag__nr { font-weight: 700; font-size: 0.95rem; font-variant-numeric: tabular-nums; }
.spesen-tag__betrag {
    font-size: 0.85rem; font-weight: 800; color: var(--color-primary);
    font-variant-numeric: tabular-nums;
}
.spesen-tag__fahrt {
    margin-top: 0.35rem; font-size: 0.74rem; line-height: 1.3;
    display: flex; flex-direction: column; flex: 1; min-width: 0;
}
.spesen-tag__fahrt strong { font-size: 0.76rem; }
.spesen-tag__fahrt span { color: var(--color-muted); overflow-wrap: anywhere; }
.spesen-spesen-tag__fahrt--keine { color: #a8b4bd; flex: 1; }
.spesen-tag__hinweis { margin-top: 0.35rem; font-size: 0.74rem; color: #4d7a58; flex: 1; }
/* Was die App über den Tag weiß - grau und klein, weil es eine Hilfe beim
   Entscheiden ist und kein Vorschlag. */
.spesen-tag__zeit { font-size: 0.7rem; color: #7d8b95; margin-top: 0.2rem; line-height: 1.25; }
.spesen-spesen-tag__zeit--fehlt { color: #c9781f; font-weight: 600; }

.satz-reihe { display: flex; gap: 0.25rem; margin-top: 0.4rem; }
.satz {
    flex: 1; font: inherit; font-size: 0.78rem; font-weight: 700; cursor: pointer;
    padding: 0.22rem 0; border-radius: 5px;
    border: 1px solid var(--color-border); background: #fff; color: #8c99a3;
    font-variant-numeric: tabular-nums;
}
.satz:hover { border-color: #b9c4cc; color: var(--color-text); }
.satz.ist-gewaehlt {
    background: var(--color-primary); border-color: var(--color-primary); color: #fff;
}
.spesen-fuss { margin-top: 1rem; }

/* ------------------------------------------------------- Listenansicht -- */
.spesen-tabelle .satz-reihe { margin-top: 0; width: 13rem; }
.spesen-tabelle__wahl { width: 13rem; }
.spesen-tabelle__zeit { font-size: 0.82rem; }
.spesen-tabelle tr.ist-leer td { color: #a8b4bd; }
.spesen-tabelle tr.ist-gesetzt td:first-child {
    box-shadow: inset 4px 0 0 var(--color-primary);
}
.spesen-tabelle tr.ist-heute td:first-child { font-weight: 800; }
.spesen-tabelle tr.ist-summe td {
    font-weight: 800; background: #fbfcfd; border-top: 2px solid var(--color-border);
}
.spesen-tabelle__summe {
    text-align: right; color: var(--color-primary); font-variant-numeric: tabular-nums;
}
.zeit-fehlt { color: #c9781f; font-weight: 600; }

.spesen-saetze { margin-top: 1.4rem; }
.spesen-saetze > summary { cursor: pointer; font-size: 0.88rem; color: var(--color-muted); }
.spesen-saetze__form {
    display: flex; align-items: flex-end; gap: 0.8rem; flex-wrap: wrap;
    margin-top: 0.7rem;
}
.spesen-saetze__form .feld-hinweis { flex: 1 1 18rem; margin: 0; }

/* Am Handy wird aus dem Kalender eine Liste: sieben Spalten auf 390 px sind
   nicht lesbar, und die Auswahl wäre nicht treffbar. */
@media (max-width: 760px) {
    .kalender { grid-template-columns: 1fr; }
    /* Am Handy ist der Kalender selbst eine Liste - da wirkt das Häkchen
       „nur Tage mit Fahrt" auch hier. Auf dem Rechner nicht: dort würde es
       Löcher in die Kalenderwoche reißen, und ein leerer Tag gehört in einen
       Kalender hinein. */
    .kalender.ist-gefiltert .spesen-tag[data-ohne-fahrt="1"] { display: none; }
    .kalender__kopf { display: none; }
    .spesen-tag { min-height: 0; }
    .spesen-tag--leer { display: none; }
    .spesen-summe { text-align: left; }
    .spesen-tabelle .satz-reihe, .spesen-tabelle__wahl { width: auto; }
}

/* --------------------------------------------------- Hinweis: neue Anfrage --
   Die Karte unten rechts, wenn während der Arbeit eine Kundenanfrage eingeht
   (siehe static/js/anfrage_karte.js).

   Der Name ist bewusst NICHT .anfrage-karte: .anfrage-card gibt es bereits für
   die Anfragen in der Kundenansicht, und zwei fast gleiche Namen für zwei
   verschiedene Dinge sind die Sorte Falle, die am 19.09. alle Plaketten der
   App zerlegt hat.

   Sie liegt fest über der Seite, nimmt aber keinen Klick weg: Wer gerade eine
   Zuweisung tippt, tippt weiter. Das ist dieselbe Haltung wie bei der
   automatischen Aktualisierung - wer arbeitet, wird nicht unterbrochen. */
.anfrage-hinweis {
    position: fixed; right: 1.2rem; bottom: 1.2rem; z-index: 90;
    width: 21rem; max-width: calc(100vw - 2rem);
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-top: 4px solid var(--color-primary);
    border-radius: var(--radius);
    box-shadow: 0 10px 28px rgba(20, 30, 40, 0.18), 0 2px 6px rgba(20, 30, 40, 0.10);
    padding: 0.9rem 1rem 1rem;
    animation: anfrage-hinweis-auf 0.25s ease-out;
}
@keyframes anfrage-hinweis-auf {
    from { opacity: 0; transform: translateY(0.6rem); }
    to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
    .anfrage-hinweis { animation: none; }
}
.anfrage-hinweis__kopf {
    display: flex; align-items: center; gap: 0.45rem;
    font-size: 0.78rem; font-weight: 600; letter-spacing: 0.04em;
    text-transform: uppercase; color: var(--color-primary);
    margin-bottom: 0.45rem;
}
.anfrage-hinweis__zu {
    margin-left: auto; background: none; border: 0; color: var(--color-muted);
    font-size: 1rem; line-height: 1; cursor: pointer; font-family: inherit;
    padding: 0 0.1rem;
}
.anfrage-hinweis__kunde { font-size: 1.05rem; font-weight: 600; margin-bottom: 0.15rem; }
.anfrage-hinweis__zeile { font-size: 0.87rem; color: var(--color-muted); line-height: 1.45; }
.anfrage-hinweis__zeile:empty { display: none; }
.anfrage-hinweis__knoepfe { display: flex; gap: 0.5rem; margin-top: 0.85rem; }
/* Der Ausschalter ist bewusst klein und steht unten: Er soll da sein, wenn er
   stört, und sonst nicht auffallen. */
.anfrage-hinweis__ton {
    margin-top: 0.6rem; background: none; border: 0; padding: 0;
    font-family: inherit; font-size: 0.78rem; color: var(--color-muted);
    text-decoration: underline; cursor: pointer;
}
.anfrage-hinweis__ton[disabled] { text-decoration: none; cursor: default; }

/* Am Handy steht unten die Navigationsleiste der App - darüber ausweichen,
   mit denselben Werten wie .aktualisierung-hinweis weiter oben. Sonst deckt
   die Karte die Navigation zu, und genau das soll sie nicht: sie nimmt
   keinen Klick weg. */
@media (max-width: 779px) {
    .anfrage-hinweis {
        left: 1rem; right: 1rem; bottom: 4.6rem; width: auto;
    }
}

/* Beide Hinweise sitzen unten rechts. Taucht die Anfragekarte auf, rückt die
   Aktualisierungsleiste darüber, statt sich mit ihr zu stapeln. Die Höhe
   kommt aus dem Skript (--anfrage-hoehe), weil sie je nach Text schwankt. */
body.hat-anfrage-hinweis .aktualisierung-hinweis {
    bottom: calc(1.2rem + var(--anfrage-hoehe, 11rem) + 0.7rem);
}
@media (max-width: 779px) {
    body.hat-anfrage-hinweis .aktualisierung-hinweis {
        bottom: calc(4.6rem + var(--anfrage-hoehe, 11rem) + 0.7rem);
    }
}
