/*
 * terXtic - (c) Jucama KG, proprietaer.
 *
 * Handgeschrieben, kein Framework, kein Build-Schritt - dieselbe Minimallinie
 * wie in den beiden Website-Projekten.
 *
 * MOBIL ZUERST: Alle Grundregeln gelten fuer das schmale Fenster, die
 * Media Queries schalten erst nach oben. Grund ist die Vorgabe: Das System
 * soll am Handy genauso bedienbar sein - und das ist es nur, wenn der schmale
 * Fall der Normalfall im Stylesheet ist und nicht der nachtraeglich
 * zurechtgebogene Sonderfall.
 */

/*
 * FARBEN AUS DEM LOGO (branding/Logo_mwork.svg).
 *
 * Die Marke ist ein kräftiges Rot: #e20000. Es ist die einzige Farbe im
 * Logo neben Schwarz, Weiss und einem hellen Grau - deshalb ist das Schema
 * hier bewusst schwarz/weiss/grau MIT rotem Akzent und nicht bunt.
 * Dieselbe Linie wie bei paXCry.
 *
 * Rot ist damit die Farbe der Marke UND die Farbe für Fehler. Das ist kein
 * Versehen: Ein Fehler steht in einem Meldungskasten mit hellem Grund, eine
 * Hauptschaltfläche ist eine gefüllte rote Fläche - verwechseln kann man
 * beides nicht. Für Fehler wird ausserdem das dunklere #b00000 verwendet.
 */
:root {
  --dunkel:      #1c1c1c;   /* Kopfzeile */
  --dunkler:     #0f0f0f;
  --rand:        #d0d0d0;
  --rand-hell:   #e6e6e6;
  --grund:       #f4f4f4;
  --flaeche:     #ffffff;
  --text:        #171717;
  --text-leise:  #6b6b6b;
  --akzent:      #e20000;   /* die Markenfarbe */
  --akzent-tief: #b00000;   /* für Text auf hellem Grund und beim Überfahren */
  --akzent-hell: #fff2f2;
  /* Das Zweitblau der Marke - im Logo stehen die Buchstaben "work" in
     #0096ff. Fuer eine Flaeche mit weisser Schrift ist genau dieser Ton zu
     hell (nur 3,1:1, gemessen), deshalb eine Stufe tiefer: 5,0:1. Erkennbar
     dieselbe Familie, aber im Sonnenlicht noch lesbar. */
  --blau:        #0077a8;
  --blau-tief:   #005f87;
  --gut:         #15803d;
  --gut-hell:    #f0fdf4;
  --schlecht:    #b00000;
  --schlecht-hell: #fff2f2;
  --warn-hell:   #fffbeb;
  --intern:      #b8860b;   /* interne Notizen - bewusst NICHT rot, sonst
                               liefe es mit der Markenfarbe zusammen */
  --radius:      8px;

  /* Die Breite des Inhalts. Als Variable, weil sie an DREI Stellen gilt
     (Kopfzeile, Inhalt, Fusszeile) - stuenden dort drei Zahlen, liefe eine
     davon frueher oder spaeter auseinander, und dann sitzt die Kopfzeile
     anders als der Inhalt darunter.

     Gestaffelt statt einer Zahl: "FullHD ist fast die Mindestaufloesung"
     (Nutzer, 2026-08-05) - auf 1920 blieben von 1200px zwei Handbreit
     Rand. Ab 1720px ist Schluss: Dieser Rechner hat 3840 Punkte Breite,
     und ein Kalender ueber die volle Wand ist nicht mehr ueberblickbar,
     sondern nur noch weit. */
  --breite:      1200px;

  /* Trifft die Systemschrift des jeweiligen Geraets. Keine Webfonts:
     Das waere eine externe Abhaengigkeit und zusaetzliche Ladezeit im
     Mobilfunknetz - fuer nichts, was ein Ticket lesbarer machte. */
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  font-size: 16px;
  line-height: 1.5;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--grund);
  color: var(--text);
  -webkit-text-size-adjust: 100%;
}

h1, h2, h3, h4, h5 { line-height: 1.25; margin: 0 0 .5em; }
h1 { font-size: 1.5rem; }
h2 { font-size: 1.15rem; }
h3 { font-size: 1rem; }

/* EINE ÜBERSCHRIFT DIREKT NACH EINEM FORMULAR KLEBTE AN DESSEN SCHALTFLÄCHE.
   Gemessen im Browser: 0 Punkte Abstand - die Zeile darüber gibt h1..h5
   bewusst nur einen UNTEREN Abstand, und das ist fast überall richtig.
   Betrifft „Zuletzt getankt" im Fahrtenbuch und „Verbrauch" in der
   Fuhrparkverwaltung; beide lasen sich wie eine Beschriftung des Knopfes. */
form + h3 { margin-top: 1.2rem; }

a { color: var(--akzent); }
a:hover { color: var(--dunkel); }

code {
  background: var(--grund);
  padding: .1em .3em;
  border-radius: 4px;
  font-size: .9em;
}

/* ==========================================================================
   Kopf und Navigation
   ========================================================================== */

/*
 * WEISSE KOPFZEILE, nicht dunkel.
 *
 * Der dunkle Balken war meine Erfindung, nicht die der Marke. Das Logo ist
 * für weissen Grund gezeichnet: Rot #e20000 auf Fast-Schwarz käme auf rund
 * 3,4:1 Kontrast - zu wenig, und die roten Striche des M würden matt.
 * Auf Weiss stehen Rot und Blau so, wie sie gemeint sind.
 *
 * Der rote Abschlussstrich unten trennt die Kopfzeile vom Inhalt und
 * nimmt die Markenfarbe auf, ohne sie aufzudrängen.
 */
.kopf {
  background: var(--flaeche);
  color: var(--text);
  border-bottom: 3px solid var(--akzent);
  /* Bleibt beim Rollen oben stehen: Am Handy ist eine lange Ticketliste
     schnell mehrere Bildschirme hoch, und "Neues Ticket" soll erreichbar
     bleiben, ohne ganz nach oben zurückzurollen. */
  position: sticky;
  top: 0;
  z-index: 20;
}

.kopf-innen {
  max-width: var(--breite);
  margin: 0 auto;
  padding: .6rem 1rem;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .5rem 1rem;
}

.marke {
  display: flex;
  align-items: center;
  gap: .5rem;
  color: var(--text);
  text-decoration: none;
  white-space: nowrap;
}
/* 30 Punkte: die Höhe, bei der die dünnen Buchstabenstriche nachgemessen
   noch sauber stehen. Darunter verblasst "work" gegenüber dem M. */
.marke img { height: 30px; width: auto; display: block; }
.marke small {
  font-weight: 600;
  color: var(--text-leise);
  font-size: .8rem;
  border-left: 1px solid var(--rand);
  padding-left: .5rem;
}

/* --------------------------------------------------------------------------
   Das Menü am Handy
   --------------------------------------------------------------------------
   Bis 2026-08-07 rollte die Leiste hier waagrecht. Das war platzsparend und
   ein Fehler: Wer nicht auf die Idee kommt zu wischen, sieht die hinteren
   Punkte nie - vom Nutzer im Betrieb beobachtet.

   Jetzt klappt sie auf. Das Kästchen ist unsichtbar, aber NICHT
   `display: none` - sonst wäre es mit der Tastatur nicht mehr erreichbar und
   das Menü ohne Maus nicht zu öffnen.
   -------------------------------------------------------------------------- */
.menue-schalter {
  position: absolute;
  opacity: 0;
  margin: 0;
  /* WINZIG UND UNANTASTBAR, und beides aus einem gemessenen Grund: Mit 44x44
     lag das unsichtbare Kästchen bei 375px Breite auf y=202 - mitten auf dem
     DRITTEN Menüpunkt. Weil es `position: absolute` trägt, liegt es über der
     Leiste; ein Tipp auf die linke Hälfte von "Kalender" hätte also das Menü
     zugeklappt, statt dorthin zu gehen. Im Bild ist davon nichts zu sehen.
     `pointer-events: none` schliesst das ein für alle Mal aus - bedient wird
     es ohnehin über die Beschriftung, und mit der Tastatur bleibt es
     erreichbar (Leertaste). */
  width: 1px;
  height: 1px;
  pointer-events: none;
}

/* Die drei Schnellzugriffe, links vom Hamburger. Nur am Handy - am
   Rechner steht die ganze Leiste offen da (Regel weiter unten). */
.schnellzugriff {
  display: flex;
  gap: .3rem;
  margin-left: auto;
  order: 1;
}

.schnell-knopf {
  display: flex;
  align-items: center;
  justify-content: center;
  /* Dieselben 44px wie ueberall. Quadratisch, weil nur das Sinnbild
     darinsteht - eine Beschriftung passt neben "Menue" nicht mehr in die
     Zeile. */
  width: 44px;
  height: 44px;
  border: 1px solid var(--rand);
  border-radius: var(--radius);
  color: var(--text-leise);
  text-decoration: none;
}
.schnell-knopf:hover { background: var(--grund); color: var(--text); }
.schnell-knopf.an {
  background: var(--akzent);
  border-color: var(--akzent);
  color: #fff;
}

/* Das Sinnbild nimmt die Schriftfarbe an - deshalb stimmt es auch auf dem
   roten, markierten Knopf, ohne zweite Fassung. */
.sym {
  width: 22px;
  height: 22px;
  flex: 0 0 auto;
}

/* In der aufgeklappten Leiste steht das Sinnbild vor dem Namen. */
.nav a .sym { margin-right: .5rem; }

.menue-knopf {
  display: flex;
  align-items: center;
  gap: .45rem;
  /* Kein margin-left:auto mehr: Diesen Platz schiebt jetzt die
     Schnellzugriffsleiste, und beide zusammen wuerden die Gruppe
     auseinanderreissen. */
  order: 2;
  /* Dieselben 44px wie überall sonst. */
  min-height: 44px;
  padding: 0 .6rem;
  border: 1px solid var(--rand);
  border-radius: var(--radius);
  color: var(--text-leise);
  font-size: .85rem;
  font-weight: 600;
  cursor: pointer;
  user-select: none;
}
.menue-knopf:hover { background: var(--grund); color: var(--text); }

/* Den freien Platz schiebt IMMER GENAU EINER, sonst reisst er die Gruppe
   auseinander: Haben beide `margin-left: auto`, teilen sie ihn sich und
   zwischen den Knoepfen klafft eine Luecke. Gibt es die Leiste (sie fehlt,
   wenn alle drei Plaetze leer sind), schiebt sie; sonst der Hamburger.

   AB 2.22.0.0 KANN EIN DRITTER DAZUKOMMEN: der feste Posteingang-Knopf.
   Steht er da, schiebt ER - er ist der linkeste der drei. Die beiden
   anderen muessen dann still sein, sonst ist die Luecke wieder da.

   UND ES IST EIN VIERTER: DIE GLOCKE. Sie traegt seit 2.10.0.0 ebenfalls
   `margin-left: auto` (weiter unten bei `.glocke`), stand aber nie in
   dieser Aufzaehlung - beim Einbau des Posteingang-Knopfs hat sie deshalb
   niemand still gestellt. Am Rechner teilten sich beide den Platz, und die
   Glocke stand mitten in der Kopfzeile (vom Nutzer gemeldet 2026-09-22,
   nachgemessen: je 501,97px Aussenabstand). Behoben in der Regel fuer
   breitere Fenster; siehe `.glocke { order: 1 }` dort. */
.menue-knopf { margin-left: auto; }
.schnellzugriff ~ .menue-knopf { margin-left: 0; }

.fix-zugriff { display: flex; gap: .3rem; margin-left: auto; order: 1; }
.fix-zugriff ~ .schnellzugriff { margin-left: .3rem; }
.fix-zugriff ~ .menue-knopf { margin-left: 0; }

/* Der Knopf traegt ein Abzeichen - dafuer braucht er einen eigenen
   Bezugspunkt; .schnell-knopf hat von sich aus keinen. */
.schnell-knopf.fest { position: relative; }

/* Dieselben Masse und Farben wie an der Glocke: Zwei verschieden aussehende
   Abzeichen fuer dieselbe Sache ("da liegt etwas") waeren nur verwirrend. */
.schnell-zahl {
  position: absolute;
  top: -6px;
  right: -6px;
  min-width: 18px;
  padding: 0 4px;
  border-radius: 9px;
  background: var(--akzent);
  color: #fff;
  font-size: .7rem;
  font-weight: 700;
  line-height: 18px;
  text-align: center;
}

/* Sichtbar, wohin die Tastatur gerade zeigt - der Knopf ist ja nur eine
   Beschriftung, er bekommt den Fokusrahmen nicht von selbst. */
.menue-schalter:focus-visible + .menue-knopf {
  outline: 2px solid var(--akzent);
  outline-offset: 2px;
}

/* Die drei Striche aus einem Element: der mittlere ist der Kasten selbst,
   die äusseren sind seine beiden Schatten. Spart zwei leere <span>. */
.menue-striche,
.menue-striche::before,
.menue-striche::after {
  display: block;
  width: 20px;
  height: 2px;
  background: currentColor;
  border-radius: 2px;
}
.menue-striche { position: relative; }
.menue-striche::before,
.menue-striche::after { content: ""; position: absolute; left: 0; }
.menue-striche::before { top: -6px; }
.menue-striche::after  { top: 6px; }

/* Offen: aus den Strichen wird ein Kreuz. Damit ist am Zeichen selbst
   abzulesen, dass derselbe Knopf wieder schliesst. */
.menue-schalter:checked + .menue-knopf .menue-striche { background: transparent; }
.menue-schalter:checked + .menue-knopf .menue-striche::before { top: 0; transform: rotate(45deg); }
.menue-schalter:checked + .menue-knopf .menue-striche::after  { top: 0; transform: rotate(-45deg); }

.nav {
  display: none;
  flex-direction: column;
  gap: .15rem;
  order: 4;
  width: 100%;
  margin-top: .4rem;
  padding-top: .4rem;
  border-top: 1px solid var(--rand);
  /* DIE KOPFZEILE KLEBT OBEN (position: sticky), und mit sieben offenen
     Punkten wurde sie 452 von 812 Punkten hoch - nachgemessen bei 375x812.
     Wer das Menü aufmacht und dann rollt, statt etwas auszuwählen, hätte
     mehr als die halbe Anzeige verloren; auf einem kleinen Telefon fast
     alles. Deshalb ein Deckel: Was darüber hinausgeht, rollt innerhalb der
     Leiste. */
  max-height: calc(100vh - 12rem);
  overflow-y: auto;
}

.menue-schalter:checked ~ .nav { display: flex; }

.nav a {
  color: var(--text-leise);
  text-decoration: none;
  padding: .45rem .7rem;
  border-radius: var(--radius);
  white-space: nowrap;
  font-size: .95rem;
  /* Dieselben 44px wie bei den Schaltflächen. Mit blossem padding kamen die
     Punkte auf 37px - nachgemessen bei 375px Fensterbreite. Zu wenig für
     einen Fingertipp, und ausgerechnet die Navigation trifft man dann
     daneben. */
  display: flex;
  align-items: center;
  min-height: 44px;
}
.nav a:hover { background: var(--grund); color: var(--text); }
.nav a.an { background: var(--akzent); color: #fff; }

.wer {
  margin-left: auto;
  text-align: right;
  line-height: 1.2;
  font-size: .8rem;
}
.wer-name { display: block; font-weight: 600; }
.wer-firma { display: block; color: var(--text-leise); }

/* DER NAME WIRD AM HANDY GEDECKELT (2.11.0.0) - und das ist der eigentliche
   Fix am gemeldeten Fehler, nicht das kleinere "Abmelden".

   Die Kopfzeile teilt sich per `order` bewusst in zwei Zeilen: oben wer man
   ist, unten wohin man kann. Fuer die obere bleiben bei 375 Punkten 343
   uebrig, und davon brauchen Logo (97), Glocke (44), Abmelden (44) und die
   drei Luecken (48) schon 233. Fuer den Namen sind es also 110.

   GEMESSEN: "Markus Gspandl" ist 96 Punkte breit und passt knapp.
   "Maximilian Obermayr-Tschofen" braucht 187 - damit brach die Zeile
   AUSEINANDER und Abmelden rutschte wieder nach unten, genau der gemeldete
   Fehler. Ohne Deckel haengt die Kopfzeile also davon ab, wie der
   Mitarbeiter heisst.

   Gekuerzt wird mit Auslassungspunkten statt umgebrochen: Der Name ist hier
   eine Erinnerung daran, als wer man angemeldet ist - vollstaendig steht er
   unter Konto. */
@media (max-width: 40rem) {
  .wer { max-width: 6.5rem; }
  .wer-name, .wer-firma {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
}

/* NUR NOCH DAS SYMBOL (2.11.0.0): Am Handy rutschte "Abmelden" in eine
   zweite Zeile - vom Nutzer gemeldet. Der Text brauchte gut 75 Punkte, das
   Quadrat braucht 44, und mit dem entfallenen "Tickets" neben dem Logo
   passt die Zeile wieder.
   Dieselben 44 Punkte wie .schnell-knopf und .tw-knopf, und bewusst dieselbe
   ZURUECKHALTENDE Farbe wie die Schnellzugriffe: Abmelden ist nichts, was
   man anstrebt - es soll auffindbar sein, nicht einladend. */
.abmelden {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 44px;
  height: 44px;
  color: var(--text-leise);
  text-decoration: none;
  border: 1px solid var(--rand);
  border-radius: var(--radius);
}
.abmelden .sym { width: 20px; height: 20px; }
.abmelden:hover { background: var(--grund); color: var(--text); }

.inhalt {
  max-width: var(--breite);
  margin: 0 auto;
  padding: 1rem;
}

.fuss {
  max-width: var(--breite);
  margin: 2rem auto 0;
  padding: 1rem;
  color: var(--text-leise);
  font-size: .8rem;
  border-top: 1px solid var(--rand-hell);
}

/* --------------------------------------------------------------------------
   `hidden` muss staerker sein als jede Anzeigeregel
   --------------------------------------------------------------------------
   Der Browser bringt `[hidden] { display: none }` selbst mit - aber JEDE
   eigene Regel mit einer Klasse schlaegt sie, weil die des Browsers die
   schwaechste ist. `.anhang-liste { display: grid }` hat genau das getan:
   Beim Zuklappen der Anhaenge stand `hidden` am Element, und die Liste war
   trotzdem 473 Punkte hoch - nachgemessen am 2026-08-09.

   Am Zahlenwert war das nicht zu sehen; das Element MELDETE `hidden = true`.
   Nur die gemessene Hoehe hat es verraten.

   `!important` ist hier richtig und nicht faul: "versteckt" ist keine
   Gestaltungsfrage, ueber die eine spaetere Regel abstimmen darf.
   -------------------------------------------------------------------------- */
[hidden] { display: none !important; }


/* ==========================================================================
   Bausteine
   ========================================================================== */

.karte {
  background: var(--flaeche);
  border: 1px solid var(--rand-hell);
  border-radius: var(--radius);
  padding: 1rem;
  margin-bottom: 1rem;
}

.karte-kopf {
  display: flex;
  /* UMBRECHEN, nicht ueberstehen (2026-09-12, am Handy gemeldet): Der Kopf
     traegt links eine Ueberschrift und rechts eine .knopf-reihe. Bei
     "Beschreibung" steckt in dieser Reihe das Aufklappformular "PDF mailen" -
     also ein ganzes Formular mit Adressfeld, Textfeld und der Liste der
     Anhaenge. Auf 375 Punkten blieben daneben 216 uebrig, gebraucht wurden
     316: die Seite liess sich waagrecht schieben, die Ueberschrift stand
     links ausserhalb.
     Ohne flex-wrap kann die Reihe nicht auf eine eigene Zeile ausweichen -
     ein Flex-Element mit min-width:auto behaelt seine Inhaltsbreite und
     schiebt stattdessen den Rahmen auf. .seiten-kopf hat diese Zeile seit
     jeher, hier fehlte sie.
     GEMESSEN (375x812, Ticket mit vier Anhaengen): vorher 475 Punkte Inhalt,
     danach genau 375. Die naheliegende Gegenmassnahme - min-width:0 auf
     Reihe, details, form und fieldset - hat NICHTS gebracht, solange diese
     Zeile fehlte; mit ihr braucht es keine davon. */
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: .5rem;
  margin-bottom: .5rem;
}
.karte-kopf h2 { margin: 0; }

/* Und die Reihe darf auch schmaler werden als ihr Inhalt (2026-09-12).
   Gemessen: Ohne das blieb sie 316 Punkte breit, obwohl im Kartenkopf nur
   309 Platz sind - sie ragte in die Innenpolsterung der Karte. Nichts
   Sichtbares zerbrach daran, aber der rechte Rand war um 7 Punkte schmaler
   als der linke. Ein Flex-Element traegt von sich aus min-width:auto und
   behaelt damit seine Inhaltsbreite; hier ist das das Aufklappformular. */
.karte-kopf > .knopf-reihe { min-width: 0; }

.seiten-kopf {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: .75rem;
  margin-bottom: 1rem;
}
.seiten-kopf h1 { margin: 0; }

.zurueck {
  display: inline-block;
  font-size: .85rem;
  text-decoration: none;
  margin-bottom: .2rem;
}

.klein { font-size: .85rem; color: var(--text-leise); }
.mitte { text-align: center; }
.hinweis-zeile { margin-top: -.5rem; }

.meldung {
  padding: .7rem .9rem;
  border-radius: var(--radius);
  margin-bottom: 1rem;
  border: 1px solid transparent;
  font-size: .95rem;
}
.meldung.ok     { background: var(--gut-hell);      border-color: #bbf7d0; color: var(--gut); }
.meldung.fehler { background: var(--schlecht-hell); border-color: #f0bcbc; color: var(--schlecht); }
.meldung.info   { background: var(--akzent-hell);   border-color: #f5c2c2; color: var(--akzent-tief); }
/* Die Warnung - neu am 2026-08-09 fuer den Hinweis auf den fehlenden
   Anhang bei der Abfahrt. Gelb statt rot, und das ist der Punkt: Sie haelt
   nichts auf, sie macht aufmerksam. Rot stuende fuer "das geht nicht". */
.meldung.warnung { background: var(--warn-hell); border-color: #f5d98b; color: var(--intern); }

/* --- Schaltflächen ------------------------------------------------------ */

.knopf {
  display: inline-block;
  background: var(--flaeche);
  color: var(--text);
  border: 1px solid var(--rand);
  border-radius: var(--radius);
  /* 44px Höhe ist die übliche Mindestgrösse für einen Fingertipp. Darunter
     trifft man am Handy mit Handschuhen nichts mehr - und genau das ist der
     Anwendungsfall. */
  padding: .6rem 1rem;
  min-height: 44px;
  font: inherit;
  font-size: .95rem;
  text-decoration: none;
  cursor: pointer;
  text-align: center;
  white-space: nowrap;
}
.knopf:hover { background: var(--grund); color: var(--text); }

.knopf.haupt {
  background: var(--akzent);
  border-color: var(--akzent);
  color: #fff;
  font-weight: 600;
}
.knopf.haupt:hover { background: var(--akzent-tief); color: #fff; }

.knopf.leise { color: var(--text-leise); }
.knopf.breit { width: 100%; }
/* Auch die kleinen Schaltflächen bleiben bei 44px Höhe - nur schmaler.
   Nachgemessen kamen sie sonst auf 34px, und "Bearbeiten" ist am Handy keine
   Nebensache, sondern der Weg zur Korrektur. */
.knopf.klein { padding: .35rem .7rem; min-height: 44px; font-size: .85rem; }

/* Aufklapper sind Bedienelemente, keine Überschriften.
   Gemessen kamen sie auf 19-22px - mit dem Finger kaum zu treffen, und
   dahinter steckt unter anderem die ursprüngliche Fassung eines Tickets. */
details > summary {
  min-height: 44px;
  display: flex;
  align-items: center;
  gap: .4rem;
  flex-wrap: wrap;
  cursor: pointer;
  /* display:flex nimmt dem <summary> das eingebaute Aufklapp-Dreieck. Ohne
     Ersatz sieht man dem Element nicht mehr an, dass sich etwas öffnet -
     ausgerechnet bei "Ursprüngliche Fassung ansehen" wäre das fatal, weil
     der Nachweis dann unauffindbar dahinterläge. Deshalb ein eigenes
     Zeichen, das sich beim Öffnen dreht. */
  list-style: none;
}
details > summary::-webkit-details-marker { display: none; }

details > summary::before {
  content: "▸";
  flex: none;
  color: var(--text-leise);
  font-size: .9em;
  transition: transform .15s ease;
}
details[open] > summary::before { transform: rotate(90deg); }

/* Der Aufklapper der Löschen-Rückfrage ist als Schaltfläche gestaltet und
   soll nicht über die ganze Breite laufen. */
details > summary.knopf { display: inline-flex; }

.knopf-reihe {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
  align-items: center;
}

/* ==========================================================================
   Die Werkzeugleiste unter dem Tickettitel (2.11.0.0)
   ==========================================================================
   AUFTRAG: "Buttons damit man nicht immer scrollen muss ... Alle nur mit
   Symbol statt Text. Die Buttons sollen eine andere Farbe haben als die
   neben dem Menü."

   BLAU, und das ist die zweite Markenfarbe (rotes "M" + blaues "work" im
   Logo) - sie war bis dahin fast ungenutzt. Sie trennt die Leiste von beidem,
   was ihr sonst gleichen könnte: von den neutralen Schnellzugriffen neben dem
   Menü, die aus dem Ticket HINAUSFÜHREN, und von den roten Hauptknöpfen, die
   etwas abschicken. Diese hier bleiben im Ticket und schicken nichts ab.

   Weiss auf --blau ergibt 4,99:1 - nachgerechnet, nicht geschätzt; WCAG AA
   verlangt 4,5:1 für Text und 3:1 für Sinnbilder.

   44 Punkte wie überall. Das ist keine Zierde, sondern die kleinste Fläche,
   die sich am Telefon zuverlässig treffen lässt - und bei sechs Symbolen
   nebeneinander die Grenze, unter der man das falsche erwischt.
   ========================================================================== */
/* DIE KLEBENDE KOPFZEILE MUSS BEIM SPRINGEN MITGERECHNET WERDEN
   (2.11.0.1, vom Nutzer gemeldet: "beim klick auf die buttons wird etwas zu
   weit gescrollt. Die überschrift des jeweiligen Bereichs sollten sichtbar
   sein").

   .kopf ist `position: sticky`. Ein Sprungziel landet damit oben am
   Fensterrand - also HINTER der Kopfzeile, und genau die Überschrift, die man
   sehen will, ist verdeckt. Es wurde nie zu weit gerollt, sondern zu hoch.

   scroll-margin-top ist dafür gebaut und der richtige Ort: Es wirkt für
   scrollIntoView UND für den gewöhnlichen Ankersprung ohne JavaScript - und
   der hatte denselben Fehler, seit es Sprungmarken gibt.

   GEMESSEN ist die Kopfzeile 118 Punkte hoch, bei 768 aber 165 (dort bricht
   die Navigation anders um). Ein einziger Wert trägt also nicht; der hier ist
   die GROSSZÜGIGE Seite. Zu weit nach oben zu rollen kostet nur ein paar
   Punkte Luft über der Überschrift, zu wenig verdeckt sie - und das ist der
   gemeldete Fehler. Das Skript schreibt die wirklich gemessene Höhe in
   --klebe-hoehe nach (siehe app.js); diese Werte sind der Rückfall. */
:root { --klebe-hoehe: 126px; }

@media (min-width: 48rem) and (max-width: 61.999rem) {
  :root { --klebe-hoehe: 172px; }
}

.karte[id] { scroll-margin-top: calc(var(--klebe-hoehe) + .6rem); }

.ticket-werkzeuge {
  display: flex;
  flex-wrap: wrap;
  gap: .4rem;
  margin-top: .6rem;
}

.tw-knopf {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 44px;
  height: 44px;
  background: var(--blau);
  border: 1px solid var(--blau);
  border-radius: var(--radius);
  color: #fff;
  text-decoration: none;
}
.tw-knopf:hover { background: var(--blau-tief); border-color: var(--blau-tief); }
.tw-knopf:focus-visible { outline: 2px solid var(--text); outline-offset: 2px; }
.tw-knopf .sym { width: 22px; height: 22px; }

/* Der Papierkorb-Knopf am Ticket (2.12.0.0). Dieselbe Form wie die
   Werkzeugleiste - es ist derselbe Griff -, aber in Rot: Er nimmt etwas weg,
   und das soll man an der Farbe sehen, bevor man drauftippt. */
.tw-knopf.tw-gefahr {
  background: var(--schlecht);
  border-color: var(--schlecht);
}
.tw-knopf.tw-gefahr:hover { background: var(--akzent-tief); border-color: var(--akzent-tief); }

/* Ohne Erklaertext (Nutzervorgabe) steht der Knopf allein in seiner Karte -
   ohne diese Regel klebte er am oberen Rand. */
.pk-weg { margin: 0; }

/* Die Auswahlliste im Papierkorb. */
.pk-tabelle .pk-haken { width: 2.4rem; text-align: center; }
.pk-tabelle .pk-haken input { width: 1.15rem; height: 1.15rem; }
.pk-tabelle label { cursor: pointer; }
.pk-knoepfe { margin-top: .8rem; }

/* Drei Arten, drei Schildchen - damit in einer gemischten Liste auf einen
   Blick klar ist, was da liegt. Die Farben sind die schon vorhandenen: Blau
   wie die Werkzeugleiste, Gelb wie interne Notizen, Grau fuer Dateien.

   EIGENE KLASSE UND NICHT .marke, obwohl es die gibt - und das ist ein
   ausgewichenes Problem, kein Geschmack: `.marke` steht in dieser Datei
   ZWEIMAL mit verschiedener Bedeutung. Zeile ~135 ist der Logo-Behaelter der
   Kopfzeile (`display: flex`), Zeile ~1209 das runde Schildchen. Wer .marke
   benutzt, erbt das `display: flex` der ersten - im Papierkorb spannte das
   Schildchen dadurch die ganze Spalte -, und die spaetere Regel ueberschreibt
   ausserdem jede Farbe, die vorher gesetzt wurde. Beides am Bildschirm
   gesehen, nicht am Code.

   Die Doppelung selbst bleibt unangetastet: Sie aufzuloesen hiesse, jede
   Stelle im System zu pruefen, die `.marke` benutzt. */
.pk-art {
  display: inline-block;
  border-radius: 999px;
  padding: .05rem .5rem;
  font-size: .72rem;
  white-space: nowrap;
  margin-right: .3rem;
}
.pk-art-ticket    { background: var(--blau); color: #fff; }
.pk-art-kommentar { background: var(--intern); color: #fff; }
.pk-art-anhang    { background: var(--text-leise); color: #fff; }

/* ==========================================================================
   Das Fenster fuer eine Sperrmeldung (2.13.0.0)
   ==========================================================================
   "Aktuell steht die Meldung oben und man wundert sich, warum nichts
   passiert." Ein <dialog> koennte man uebersehen, wenn es aussieht wie eine
   Karte - deshalb der rote Rand oben und das abgedunkelte Dahinter.

   ::backdrop statt eines eigenen Ueberzugs: Das macht der Browser selbst,
   und Escape schliesst von Haus aus. Ein nachgebautes Fenster muesste
   Tastaturbedienung, Fokusfang und das Schliessen selbst mitbringen.
   ========================================================================== */
.sperr-dialog {
  max-width: 32rem;
  width: calc(100% - 2rem);
  border: 1px solid var(--rand);
  border-top: 4px solid var(--schlecht);
  border-radius: var(--radius);
  padding: 1.2rem;
  background: var(--flaeche);
  color: var(--text);
}
.sperr-dialog::backdrop { background: rgba(0, 0, 0, .45); }
.sperr-dialog h2 { margin: 0 0 .5rem; font-size: 1.15rem; }
.sperr-text { margin-bottom: 1rem; line-height: 1.5; }

/* Die Meldung wird geklont - der Rahmen der Zeile oben gehoert hier nicht
   hin, der Dialog ist schon der Rahmen. */
.sperr-text .meldung { border: 0; padding: 0; margin: 0; background: none; }

.sperr-knoepfe {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
  justify-content: flex-end;
}

/* Die Rueckfrage (2.15.2.0) - dasselbe Fenster wie die Sperrmeldung, damit
   das System einheitlich aussieht. Blauer Rand fuer gewoehnliche Fragen,
   roter fuer alles, was etwas wegnimmt. */
.frage-dialog {
  max-width: 28rem;
  width: calc(100% - 2rem);
  border: 1px solid var(--rand);
  border-top: 4px solid var(--blau);
  border-radius: var(--radius);
  padding: 1.1rem 1.2rem;
  background: var(--flaeche);
  color: var(--text);
}
.frage-dialog.gefahr { border-top-color: var(--schlecht); }
.frage-dialog::backdrop { background: rgba(0, 0, 0, .45); }
.frage-dialog h2 { margin: 0 0 .5rem; font-size: 1.1rem; }
.frage-dialog p { margin: 0 0 1rem; line-height: 1.5; overflow-wrap: anywhere; }
.frage-dialog .knopf { min-height: 44px; }

/* Eine Wahl in einer Meldung (2.15.3.0). Ohne JavaScript steht sie in der
   Meldung oben, mit JavaScript wandert sie in die Knopfreihe des Fensters. */
.meldung-wahl { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: .6rem; }
.meldung-wahl form { margin: 0; }
.sperr-knoepfe .meldung-wahl { margin-top: 0; justify-content: flex-end; }
.sperr-knoepfe .knopf { min-height: 44px; }

/* Der Verweis in der Meldung selbst (ohne JavaScript sichtbar, mit
   JavaScript wandert er als Knopf in das Fenster). */
.meldung-weg { white-space: nowrap; }

/* ==========================================================================
   Kalender als Auswahldialog (2.15.0.0)
   ==========================================================================
   Dieselbe Familie wie .sperr-dialog: <dialog> mit ::backdrop, Escape
   schliesst von Haus aus. Die Stundenknoepfe sind .frei-feld - dieselben
   Farben wie im Kalender, damit "knapp" dort und hier gleich aussieht.

   NUR DER INHALT ROLLT: Kopf, Wochenwechsel und Fuss bleiben stehen. Ein
   Dialog, dessen "Abbrechen" am Handy unten hinausragt, liesse sich nur noch
   mit der Zuruecktaste verlassen.
   ========================================================================== */
.kw-anzeige { cursor: pointer; }

/* Bis-Feld mit "+1 h" / "+2 h" (2.15.1.0). Das Feld darf schrumpfen, die
   Knoepfe nicht - sonst stuende "+2 h" am Handy in zwei Zeilen. */
.kw-zeile { display: flex; gap: .3rem; align-items: stretch; }
.kw-zeile .kw-anzeige { flex: 1 1 auto; min-width: 0; }
.kw-plus { flex: 0 0 auto; white-space: nowrap; padding: .3rem .5rem; font-size: .85rem; }

/* KOMPAKTER SEIT 2.15.1.0 (Nutzerwunsch: Zahl, Raender der Felder, Tag und
   Datum und die Wochenknoepfe kleiner). Die Knoepfe liegen damit unter der
   44-Punkt-Empfehlung - bei acht bis zehn Stunden je Tag ist eine Woche auf
   einen Blick wichtiger, und daneben liegt nichts, was man versehentlich
   trifft. */
.kw-dialog {
  max-width: 34rem;
  width: calc(100% - 1rem);
  max-height: calc(100vh - 2rem);
  max-height: calc(100dvh - 2rem);
  border: 1px solid var(--rand);
  border-top: 3px solid var(--blau);
  border-radius: var(--radius);
  padding: .6rem .7rem;
  background: var(--flaeche);
  color: var(--text);
}
.kw-dialog[open] { display: flex; flex-direction: column; gap: .4rem; }
.kw-dialog::backdrop { background: rgba(0, 0, 0, .45); }
.kw-dialog h2 { margin: 0; font-size: .95rem; }
.kw-kopf p { margin: .1rem 0 0; font-size: .75rem; }

.kw-nav { display: flex; align-items: center; gap: .4rem; }
.kw-nav .knopf { min-width: 2.2rem; min-height: 2rem; padding: .1rem .5rem; font-size: 1rem; line-height: 1; }
.kw-woche { flex: 1 1 auto; text-align: center; font-weight: 700; font-size: .85rem; }

.kw-inhalt { overflow-y: auto; min-height: 5rem; }

.kw-tag { padding: .25rem 0; border-top: 1px solid var(--rand-hell); }
.kw-tag:first-child { border-top: 0; }
.kw-tag h3 {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: .3rem;
  margin: 0 0 .15rem; font-size: .75rem;
}
.kw-tag h3 .marke-feiertag { font-size: .7rem; }
.kw-tag.heute h3 { color: var(--akzent); }
.kw-geschlossen { margin: 0; font-size: .75rem; color: var(--text-leise); }

.kw-stunden { display: flex; flex-wrap: wrap; gap: 2px; }
/* DIE STUNDEN TEILEN SICH DIE ZEILE (flex 1 1 0) statt fester Breite: Mit
   2.2rem standen am Handy neun in der Reihe und die zehnte allein darunter -
   ein Tag in zwei Zeilen, und die Woche war doppelt so hoch. Die Unter- und
   Obergrenze halten die Knoepfe lesbar und auf breitem Schirm nicht riesig. */
.kw-stunden .frei-feld {
  flex: 1 1 0;
  min-width: 1.9rem;
  max-width: 2.6rem;
  min-height: 2.1rem;
  padding: .05rem 0;
  border-radius: 3px;
  font: inherit;
  line-height: 1.05;
  cursor: pointer;
}
.kw-stunden .frei-feld .fz { font-size: .55rem; }
.kw-stunden .frei-feld .fa { font-size: .78rem; }
.kw-stunden .frei-feld:hover,
.kw-stunden .frei-feld:focus-visible { outline: 2px solid var(--blau); outline-offset: 0; }
.kw-stunden .frei-feld.gewaehlt { outline: 2px solid var(--blau); outline-offset: 1px; }
.kw-tag.vorbei, .kw-stunden .frei-feld.vorbei { opacity: .5; }

/* Zustellfenster: Die Zahl zaehlt Monteure und sagt ueber eine Tour nichts -
   dort nur die offenen Stunden, ohne Farbe und ohne Zahl. */
.kw-ohne-zahl .frei-feld .fa { display: none; }
.kw-ohne-zahl .frei-feld.frei,
.kw-ohne-zahl .frei-feld.knapp,
.kw-ohne-zahl .frei-feld.voll {
  background: var(--grund); border-color: var(--rand-hell); color: var(--text);
}
.kw-ohne-zahl .kw-stunden .frei-feld { display: flex; align-items: center; justify-content: center; }
.kw-ohne-zahl .kw-stunden .frei-feld .fz { font-size: .78rem; font-weight: 700; opacity: 1; }

.kw-fuss { display: flex; flex-wrap: wrap; gap: .5rem; justify-content: space-between; }

/* Die Stunden im Kalender sind seit 2.15.0.0 Links. */
a.frei-feld { text-decoration: none; cursor: pointer; }
a.frei-feld:hover, a.frei-feld:focus-visible { outline: 2px solid var(--blau); outline-offset: 1px; }

/* Neues oder vorhandenes Ticket */
.kt-wahl { display: flex; flex-wrap: wrap; gap: .5rem; }
.kt-wahl .knopf { flex: 1 1 10rem; justify-content: center; text-align: center; min-height: 44px; }
.kt-suche { display: flex; flex-direction: column; gap: .5rem; min-height: 0; }
.kt-suche input { width: 100%; }
.kt-liste { list-style: none; margin: 0; padding: 0; overflow-y: auto; }
.kt-liste li { border-top: 1px solid var(--rand-hell); }
.kt-liste li.klein { padding: .5rem 0; }
.kt-liste a { display: grid; gap: .1rem; padding: .55rem .2rem; color: inherit; text-decoration: none; }
.kt-liste a:hover, .kt-liste a:focus-visible { background: var(--grund); }
.kt-dialog .kt-suche[hidden] { display: none; }

/* Die Logo-Probe in den Betreiberangaben (2.14.0.0). Der dunkle Grund ist
   kein Schmuck: Das Logo steht in der Kopfzeile auf --dunkel, und ein
   freigestelltes PNG sieht auf weiss ganz anders aus als dort. Wer es hier
   auf hellem Grund prueft, laedt womoeglich eines mit weisser Schrift hoch
   und sieht es erst danach. */
.logo-probe {
  display: flex;
  align-items: center;
  gap: 1rem;
  flex-wrap: wrap;
  background: var(--dunkel);
  border-radius: var(--radius);
  padding: .8rem 1rem;
  margin-bottom: 1rem;
}
.logo-probe .klein { color: #d8d8d8; margin: 0; flex: 1 1 12rem; min-width: 0; }
.logo-vorschau { height: 40px; width: auto; display: block; flex: 0 0 auto; }

/* ==========================================================================
   Zum Anfang - der schwebende Knopf im Ticket (2.14.1.0)
   ==========================================================================
   Dieselbe Familie wie die Werkzeugleiste: 44 Punkte, Blau, weil er im
   Ticket bleibt. Der Schatten ist das Einzige, was ihn davon unterscheidet -
   er muss als UEBER dem Inhalt schwebend erkennbar sein, sonst liest er sich
   wie ein Knopf, der zu der Karte darunter gehoert.

   env(safe-area-inset-*): Auf Telefonen mit Gestenleiste laege er sonst auf
   der Leiste und liesse sich kaum treffen.

   SICHTBARKEIT UEBER [hidden], nicht ueber opacity. Ein nur durchsichtiger
   Knopf bleibt per Tabulator erreichbar und wird vorgelesen - man landet
   dann auf etwas, das man nicht sieht.
   ========================================================================== */
.zum-anfang {
  position: fixed;
  right: max(1rem, env(safe-area-inset-right));
  bottom: max(1rem, env(safe-area-inset-bottom));
  z-index: 15;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  background: var(--blau);
  border: 1px solid var(--blau);
  border-radius: var(--radius);
  color: #fff;
  text-decoration: none;
  box-shadow: 0 2px 10px rgba(0, 0, 0, .28);
}
.zum-anfang:hover { background: var(--blau-tief); border-color: var(--blau-tief); }
.zum-anfang:focus-visible { outline: 2px solid var(--text); outline-offset: 2px; }
.zum-anfang .sym { width: 22px; height: 22px; }

/* Platz am Seitenende, damit die letzte Zeile - dort steht der
   Papierkorb-Knopf - unter dem schwebenden Knopf hervorgerollt werden kann.
   44 Punkte Knopf + 1rem Abstand + etwas Luft. */
.zum-anfang-platz { height: 4.5rem; }

.verweis-knopf {
  background: none;
  border: none;
  color: var(--text-leise);
  font: inherit;
  font-size: .8rem;
  text-decoration: underline;
  cursor: pointer;
  padding: .2rem;
  /* Auch dieser unscheinbare Verweis ist ein Tippziel - beim Nachmessen kam
     er auf 26px. Er öffnet allerdings nur eine Rückfrage und löscht nichts;
     deshalb reichen hier 36px statt der 44px der übrigen Schaltflächen, und
     die Anhangskachel bleibt kompakt. */
  min-height: 36px;
}
.verweis-knopf:hover { color: var(--schlecht); }

.karte.gefahr { border-color: #f0bcbc; }
.gefahr-knopf {
  color: var(--schlecht);
  border-color: #f0bcbc;
  background: var(--schlecht-hell);
  display: inline-block;
}
.gefahr-knopf:hover { background: #ffe6e6; color: var(--schlecht); }

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

.formular label {
  display: block;
  margin-bottom: .9rem;
}
.formular label > span:first-child {
  display: block;
  font-weight: 600;
  font-size: .9rem;
  margin-bottom: .25rem;
}
.formular label em { color: var(--schlecht); font-style: normal; }
.formular small {
  display: block;
  color: var(--text-leise);
  font-size: .8rem;
  margin-top: .25rem;
}

/* input[type=url] gehoert MIT in diese Liste. Es fehlte, seit
   public/installation.php das Feld base_url so ausgibt - ein Feld ohne diese
   Regel ist schmal, randlos und sieht auf einer Seite voller gestalteter
   Felder wie ein Fehler aus. Aufgefallen erst mit den Adressfeldern der
   Kopplung; am Code ist es nicht zu sehen, nur im Fenster. */
input[type=text], input[type=email], input[type=password], input[type=tel],
input[type=search], input[type=number], input[type=datetime-local],
input[type=url],
select, textarea {
  width: 100%;
  padding: .6rem .7rem;
  border: 1px solid var(--rand);
  border-radius: var(--radius);
  font: inherit;
  /* 16px verhindert, dass iOS beim Antippen hineinzoomt. Bei kleinerer
     Schrift springt die Ansicht - und man tippt daneben. */
  font-size: 16px;
  background: var(--flaeche);
  color: var(--text);
  min-height: 44px;
}
textarea { resize: vertical; min-height: 6rem; line-height: 1.5; }

input:focus, select:focus, textarea:focus {
  outline: 2px solid var(--akzent);
  outline-offset: 1px;
  border-color: var(--akzent);
}

input[type=color] {
  width: 100%;
  height: 44px;
  padding: .2rem;
  border: 1px solid var(--rand);
  border-radius: var(--radius);
  background: var(--flaeche);
}

.feld-paar { display: grid; gap: 0; }

label.haken {
  display: flex;
  align-items: flex-start;
  gap: .5rem;
  margin-bottom: .6rem;
  cursor: pointer;
}
label.haken input {
  /* Grössere Kästchen: mit dem Finger sonst kaum zu treffen. */
  width: 1.25rem;
  height: 1.25rem;
  margin: .15rem 0 0;
  flex: none;
}
label.haken > span:first-child { font-weight: 400; }
label.haken span { font-size: .9rem; }

.datei-feld input[type=file] {
  width: 100%;
  padding: .6rem;
  border: 1px dashed var(--rand);
  border-radius: var(--radius);
  background: var(--grund);
  font-size: .9rem;
}

.eingerueckt {
  margin-top: .75rem;
  padding: .75rem;
  background: var(--grund);
  border-radius: var(--radius);
}

/* ==========================================================================
   Anmeldung und Einladung
   ========================================================================== */

body.schmal {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
  padding: 1rem;
  /* Grauer statt schwarzer Grund: Das Logo steht auf der weissen Karte,
     und ein schwarzer Rand darum liess die Seite wie ein Fremdkoerper
     neben dem Rest der Anwendung wirken. */
  background: var(--grund);
}
.karte-mitte { border-top: 3px solid var(--akzent); }

.karte-mitte {
  background: var(--flaeche);
  border-radius: var(--radius);
  padding: 1.5rem;
  width: 100%;
  max-width: 26rem;
}
.karte-mitte h1 { font-size: 1.25rem; }

.marke-gross {
  display: block;
  height: 50px;
  width: auto;
  margin-bottom: 1rem;
}

/* ==========================================================================
   Statusleiste (Zahlen + Filter)
   ========================================================================== */

.status-leiste {
  display: flex;
  gap: .5rem;
  overflow-x: auto;
  padding-bottom: .5rem;
  margin-bottom: .75rem;
  scrollbar-width: thin;
}

.status-kachel {
  flex: none;
  min-width: 5.5rem;
  background: var(--flaeche);
  border: 1px solid var(--rand-hell);
  border-bottom: 3px solid var(--rand);
  border-radius: var(--radius);
  padding: .5rem .7rem;
  text-decoration: none;
  color: var(--text);
  text-align: center;
}
.status-kachel:hover { background: var(--grund); color: var(--text); }
.status-kachel.an { border-color: var(--akzent); background: var(--akzent-hell); }
.status-kachel .zahl { display: block; font-size: 1.4rem; font-weight: 700; line-height: 1.1; }
.status-kachel .was  { display: block; font-size: .75rem; color: var(--text-leise); }

.filter-leiste {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
  margin-bottom: 1rem;
}
.filter-leiste .suchfeld { flex: 1 1 100%; }
.filter-leiste .filter-feld { flex: 1 1 10rem; min-width: 0; }

.status-schild {
  display: inline-block;
  padding: .15rem .55rem;
  border-radius: 999px;
  font-size: .78rem;
  font-weight: 600;
  white-space: nowrap;
}

/* ==========================================================================
   Ticketliste
   ========================================================================== */

.ticket-liste { list-style: none; margin: 0; padding: 0; }

.ticket-zeile {
  background: var(--flaeche);
  border: 1px solid var(--rand-hell);
  border-radius: var(--radius);
  margin-bottom: .6rem;
}
.ticket-zeile:hover { border-color: var(--akzent); }
.ticket-zeile.erledigt { opacity: .72; }

.ticket-link {
  display: block;
  padding: .8rem;
  text-decoration: none;
  color: inherit;
}

.zeile-kopf {
  display: flex;
  align-items: center;
  gap: .5rem;
  margin-bottom: .3rem;
}
.nummer {
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: .8rem;
  color: var(--text-leise);
}
.nummer-gross {
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  color: var(--text-leise);
  font-size: .9em;
}

.zeile-titel { font-size: 1.02rem; margin: 0 0 .2rem; }
.zeile-anriss {
  margin: 0 0 .5rem;
  color: var(--text-leise);
  font-size: .88rem;
}

.zeile-fuss {
  display: flex;
  flex-wrap: wrap;
  gap: .3rem .8rem;
  font-size: .8rem;
  color: var(--text-leise);
  align-items: center;
}
.marke-kunde {
  background: var(--grund);
  border-radius: 4px;
  padding: .05rem .4rem;
  font-weight: 600;
  color: var(--text);
}
.zeile-fuss .zeit { margin-left: auto; }

/* Betrag am Ticket (2.47.0.0), nur mit dem Recht rexla. Fett, damit er sich
   beim Ueberfliegen der Liste vom Rest der Fusszeile abhebt. */
.zeile-betrag {
  color: var(--text);
  font-variant-numeric: tabular-nums;
}
.zeile-betrag strong { white-space: nowrap; }
.betrag-wahl { margin: 0 0 .2rem; }
.betrag-kunde { display: flex; gap: .4rem; align-items: center; }
.betrag-kunde select { max-width: 16rem; }
.betrag-kunde.auto [type=submit] { display: none; }
.betrag-summe { font-variant-numeric: tabular-nums; }
.betrag-umfang { margin: 0 0 .6rem; color: var(--text-leise); }
/* Knopf "Brutto -> Netto" am Betragsfeld (2.48.0.0), entsteht in app.js. */
.brutto-netto-knopf { margin-top: .35rem; align-self: flex-start; }
.brutto-netto-hinweis:empty { display: none; }

.blaettern {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .5rem;
  margin: 1rem 0;
}

.leer-hinweis { text-align: center; padding: 2rem 1rem; }

/* ==========================================================================
   Ticketseite
   ========================================================================== */

.zwei-spalten { display: block; }
.spalte-seite .karte { background: var(--flaeche); }

.fliesstext p { margin: 0 0 .7rem; }
.fliesstext ul { margin: 0 0 .7rem; padding-left: 1.2rem; }
.fliesstext li { margin-bottom: .2rem; }
.fliesstext:last-child p:last-child { margin-bottom: 0; }
.fliesstext.alt { color: var(--text-leise); }

dl.daten {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: .3rem .8rem;
  margin: 1rem 0 0;
  padding-top: .8rem;
  border-top: 1px solid var(--rand-hell);
  font-size: .9rem;
}
dl.daten dt { font-weight: 600; color: var(--text-leise); }
dl.daten dd { margin: 0; }

ul.schlicht { margin: 0; padding-left: 1.1rem; font-size: .9rem; }
ul.schlicht li { margin-bottom: .35rem; }

/* --- ursprüngliche Fassung ---------------------------------------------- */

details.original {
  margin-top: 1rem;
  padding-top: .8rem;
  border-top: 1px solid var(--rand-hell);
}
details.original > summary {
  cursor: pointer;
  font-weight: 600;
  font-size: .9rem;
  color: var(--akzent);
}
.original-feld {
  background: var(--grund);
  border-left: 3px solid var(--rand);
  padding: .6rem .8rem;
  margin-top: .6rem;
  border-radius: 0 var(--radius) var(--radius) 0;
}
.original-feld h4 { font-size: .85rem; color: var(--text-leise); margin-bottom: .3rem; }
.original-feld .leer { color: var(--text-leise); font-style: italic; margin: 0; }

/* --- Kommentare --------------------------------------------------------- */

.kommentare { list-style: none; margin: 0 0 1rem; padding: 0; }

.kommentar {
  border-left: 3px solid var(--rand);
  padding: .1rem 0 .1rem .8rem;
  margin-bottom: 1rem;
}
.kommentar.intern {
  border-left-color: var(--intern);
  background: var(--warn-hell);
  border-radius: 0 var(--radius) var(--radius) 0;
  padding: .5rem .8rem;
}

.kommentar-kopf {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: .5rem;
  font-size: .85rem;
  margin-bottom: .3rem;
}
.kommentar-kopf .zeit { color: var(--text-leise); font-size: .8rem; }

.marke-intern {
  background: var(--intern);
  color: #fff;
  font-size: .7rem;
  font-weight: 700;
  padding: .05rem .4rem;
  border-radius: 4px;
  text-transform: uppercase;
}

details.kommentar-aendern > summary {
  cursor: pointer;
  font-size: .8rem;
  color: var(--text-leise);
  margin-top: .3rem;
}

.neuer-kommentar {
  border-top: 1px solid var(--rand-hell);
  padding-top: 1rem;
}

/* --- Anhänge ------------------------------------------------------------ */

.anhang-liste {
  list-style: none;
  margin: .5rem 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(8.5rem, 1fr));
  gap: .6rem;
}

.anhang {
  border: 1px solid var(--rand-hell);
  border-radius: var(--radius);
  padding: .4rem;
  background: var(--flaeche);
  font-size: .8rem;
}
.anhang.intern { border-color: var(--intern); background: var(--warn-hell); }

.anhang img {
  width: 100%;
  height: 6rem;
  object-fit: cover;
  border-radius: 4px;
  display: block;
  background: var(--grund);
}

.pdf-kachel {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 6rem;
  background: var(--grund);
  border-radius: 4px;
  text-decoration: none;
  color: var(--text);
  padding: .3rem;
  text-align: center;
}
.pdf-symbol {
  font-weight: 700;
  color: var(--schlecht);
  font-size: 1.1rem;
  letter-spacing: .05em;
}
.pdf-name {
  font-size: .7rem;
  color: var(--text-leise);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 100%;
}

.anhang-fuss {
  display: flex;
  flex-wrap: wrap;
  gap: .2rem .4rem;
  align-items: center;
  margin-top: .3rem;
}

/* Umschalter "nur intern" / "für Kunden sichtbar".
   Steht bewusst über dem Löschen und ohne Rückfrage: Es geht nichts verloren,
   es wechselt nur die Seite des Vorhangs - und lässt sich sofort wieder
   zurückstellen. */
.anhang-sicht button, .kommentar-sicht button {
  text-align: left;
  padding-left: 0;
}
.kommentar-sicht { margin-top: .2rem; }
.anhang-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 100%;
}
.anhang-weg { margin-top: .1rem; }

.anhang-formular {
  border-top: 1px solid var(--rand-hell);
  padding-top: .8rem;
  margin-top: .8rem;
}
.anhang-formular label { display: block; margin-bottom: .6rem; }
.anhang-formular label > span:first-child {
  display: block;
  font-weight: 600;
  font-size: .9rem;
  margin-bottom: .25rem;
}

/* --- Änderungsverlauf --------------------------------------------------- */

.verlauf {
  list-style: none;
  margin: 0;
  padding: 0;
  font-size: .85rem;
  /* Bei einem lange laufenden Auftrag wird der Verlauf lang. Er soll die
     Seite nicht dominieren, aber vollständig erreichbar bleiben. */
  max-height: 24rem;
  overflow-y: auto;
}
.verlauf li {
  padding: .5rem 0;
  border-bottom: 1px solid var(--rand-hell);
}
.verlauf li:last-child { border-bottom: none; }
.verlauf li.intern { border-left: 3px solid var(--intern); padding-left: .5rem; }
.verlauf-zeit { color: var(--text-leise); font-size: .75rem; }

details.verlauf-werte > summary {
  cursor: pointer;
  color: var(--akzent);
  font-size: .8rem;
  margin-top: .2rem;
}
.verlauf-werte h5 {
  margin: .4rem 0 .1rem;
  font-size: .72rem;
  text-transform: uppercase;
  color: var(--text-leise);
  letter-spacing: .03em;
}
.verlauf-werte pre {
  margin: 0;
  padding: .4rem .5rem;
  background: var(--grund);
  border-radius: 4px;
  font-size: .78rem;
  /* Umbrechen statt waagrecht rollen: Ein alter Beschreibungstext ist lang,
     und in einer schmalen Spalte will ihn niemand seitlich schieben. */
  white-space: pre-wrap;
  word-break: break-word;
  max-height: 12rem;
  overflow-y: auto;
}
.verlauf-werte .vorher pre  { border-left: 3px solid var(--schlecht); }
.verlauf-werte .nachher pre { border-left: 3px solid var(--gut); }

/* ==========================================================================
   Verwaltung
   ========================================================================== */

.kachel-gitter {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  gap: 1rem;
  margin-bottom: 1rem;
}
.kachel { text-decoration: none; color: inherit; margin: 0; }
a.kachel:hover { border-color: var(--akzent); background: var(--akzent-hell); }
.kachel.still { background: var(--grund); }
.zahl-gross { font-size: 2rem; font-weight: 700; margin: 0 0 .2rem; line-height: 1; }

.benutzer-liste { list-style: none; margin: 0; padding: 0; }
.benutzer-liste > li {
  border-bottom: 1px solid var(--rand-hell);
  padding: .2rem 0;
}
.benutzer-liste > li:last-child { border-bottom: none; }
.benutzer-liste > li.stillgelegt { opacity: .6; }

.benutzer-liste summary {
  padding: .6rem .2rem;
  gap: .4rem .6rem;
}
.benutzer-liste summary:hover { background: var(--grund); }

/* ZWEI BEDEUTUNGEN, EIN KLASSENNAME - und die obere gewann.
   `.marke` weiter oben (Zeile ~142) ist die MARKE IM SEITENKOPF: ein
   flex-Kasten fuer Logo und Zusatz. Diese Regel hier ist das ABZEICHEN
   ("fällt aus", "Teilbetankung", "offen") und setzte `display` nicht - also
   erbte jedes Abzeichen `display: flex` und lief ueber die ganze Zeile.
   Gemessen: 773 statt 89 Punkte breit, quer durch das ganze System.
   `inline-flex` statt `inline-block`, damit die obere Regel fuer das Logo
   unveraendert gilt: Als Flex-Element im Seitenkopf wird es ohnehin
   blockiert, das Logo aendert sich also nicht (nachgemessen). */
.marke {
  display: inline-flex;
  background: var(--grund);
  border: 1px solid var(--rand-hell);
  border-radius: 999px;
  padding: .05rem .5rem;
  font-size: .72rem;
  color: var(--text-leise);
  white-space: nowrap;
}
.marke.aus  { background: var(--schlecht-hell); border-color: #f0bcbc; color: var(--schlecht); }
.marke.warn { background: var(--warn-hell); border-color: #fde68a; color: #92400e; }

.link-kasten .link-feld {
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: .78rem;
  background: var(--flaeche);
}

/* ==========================================================================
   Breitere Fenster
   ========================================================================== */

@media (min-width: 40rem) {
  .inhalt { padding: 1.5rem 1rem; }
  h1 { font-size: 1.75rem; }

  /* Ab hier ist Platz für die ganze Leiste - der Knopf verschwindet, und
     das Menü steht offen da, unabhängig vom Kästchen. Deshalb steht die
     Regel NICHT unter `:checked`: Ein am Handy geöffnetes Menü darf am
     grossen Bildschirm nicht als "geschlossen" wieder zuklappen, nur weil
     jemand das Fenster grösser zieht. */
  .menue-schalter,
  .menue-knopf,
  /* Am Rechner steht jeder Punkt ohnehin in der Leiste - drei Knoepfe
     daneben waeren dieselben Ziele ein zweites Mal. */
  .schnellzugriff { display: none; }

  /* BENUTZER UND ABMELDEN GEHOEREN NACH OBEN RECHTS, auch im Querformat
     (Nutzerwunsch 2026-08-09). Vorher stand die Navigation in der ersten
     Zeile neben dem Logo und schob beides in eine zweite Zeile darunter -
     am Telefon quer sah der Kopf dadurch ganz anders aus als hochkant.

     Geloest ueber `order`, nicht ueber eine Umstellung im HTML: Die
     Reihenfolge im Quelltext bleibt die vorlesbare (Marke, Navigation,
     wer angemeldet ist, abmelden), und die Anzeige richtet sich danach,
     was oben stehen soll. */
  .wer      { order: 1; }
  .abmelden { order: 2; }

  /* DIE GLOCKE GEHOERT IN DIESELBE GRUPPE (2.24.0.1, Nutzermeldung
     2026-09-22: "Die Benachrichtigungsglocke ist auf der Desktopversion
     mittig. Bitte nach rechts").

     Sie hatte hier bisher gar kein `order` - also 0, und damit stand sie
     in der LINKEN Gruppe neben dem Logo. Nach rechts kam sie nur ueber
     ihren eigenen `margin-left: auto`, und genau das ging schief, sobald
     der feste Posteingang-Knopf (2.22.0.0) daneben dasselbe tat: Zwei
     automatische Aussenabstaende TEILEN SICH den freien Platz, sie
     verdoppeln ihn nicht. Ergebnis war eine Glocke in der Mitte.

     Jetzt gehoert sie zur rechten Gruppe und schiebt nur noch, wenn sie
     deren linkestes Stueck ist - steht der Posteingang-Knopf davor,
     schiebt ER. Dieselbe Regel wie bei Leiste und Hamburger darueber.

     Die Reihenfolge bleibt dabei die gewollte: Glocke LINKS vom Namen
     (so steht es in inc/layout.php begruendet). */
  .glocke { order: 1; }
  .fix-zugriff ~ .glocke { margin-left: 0; }

  .nav {
    display: flex;
    flex-direction: row;
    /* Eigene Zeile unter Logo und Benutzer - damit steht die Kopfzeile in
       jeder Breite gleich. */
    order: 3;
    width: 100%;
    margin-top: 0;
    padding-top: 0;
    border-top: 0;
    /* Der Deckel von oben gilt nur für die aufgeklappte Fassung. */
    max-height: none;
    overflow: visible;
    /* UMBRECHEN STATT UEBERLAUFEN. Vor den Sinnbildern trug die Leiste
       `overflow-x: auto` und rollte notfalls waagrecht - und genau das war
       der Fehler, den das Hamburger-Menue behoben hat: Wer nicht wischt,
       sieht die hinteren Punkte nie. Mit Sinnbild ist jeder Punkt breiter;
       bei sieben Punkten (Admin) und einem schmalen Fenster passt die Zeile
       nicht mehr. Sie bricht dann um - zwei lesbare Zeilen sind besser als
       eine, deren Ende niemand findet. */
    flex-wrap: wrap;
  }

  /* AM RECHNER OHNE SINNBILD. Gewuenscht waren sie fuer die drei Knoepfe am
     Handy; in der Leiste waren sie meine Zutat - und sie kosteten dort
     Breite: Mit Sinnbild brauchte die Leiste eines Admins (sieben Punkte)
     bis 1100 Punkte Fensterbreite ZWEI Zeilen, vorher genuegte eine ab 640.
     Nachgemessen bei 640/760/900/1100/1400. Im aufgeklappten Menue am Handy
     bleiben sie: Dort hat jeder Punkt ohnehin eine eigene Zeile, und das
     Sinnbild ist genau das, was den Knopf daneben wiedererkennbar macht. */
  .nav a .sym { display: none; }

  .feld-paar {
    grid-template-columns: 1fr 1fr;
    gap: 0 1rem;
  }

  .filter-leiste .suchfeld { flex: 2 1 16rem; }

  .anhang-liste { grid-template-columns: repeat(auto-fill, minmax(10rem, 1fr)); }

  .knopf.breit { width: auto; min-width: 12rem; }
}

@media (min-width: 62rem) {
  .zwei-spalten {
    display: grid;
    /* Der Auftrag bekommt den Platz, die Bearbeitung die Seitenspalte. */
    grid-template-columns: minmax(0, 2fr) minmax(17rem, 1fr);
    gap: 1rem;
    align-items: start;
  }
}

/* ==========================================================================
   Drucken
   ==========================================================================
   Ein Ticket wird durchaus ausgedruckt und auf die Baustelle mitgenommen.
   Ohne diese Regeln stünde die halbe Seite voller Schaltflächen, die auf
   Papier nichts tun.
*/

@media print {
  .kopf, .fuss, .filter-leiste, .status-leiste, .spalte-seite,
  form, .knopf, .zurueck, .anhang-weg,
  .zum-anfang, .zum-anfang-platz { display: none !important; }

  body { background: #fff; }
  .karte { border: none; padding: 0; margin-bottom: 1rem; }
  .zwei-spalten { display: block; }
  /* Aufgeklappt drucken: Sonst fehlt auf dem Ausdruck ausgerechnet das,
     was den Nachweis ausmacht. */
  details { display: block; }
  details > summary { display: none; }
  .verlauf { max-height: none; overflow: visible; }
  a[href]::after { content: ""; }
}

/* Wer Bewegung im System abgeschaltet hat, bekommt keine. */
@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; }
}

/* ==========================================================================
   Termine und Kalender
   ========================================================================== */

.termin-liste { list-style: none; margin: 0 0 .8rem; padding: 0; }
.termin-liste > li {
  border-left: 3px solid var(--akzent);
  padding: .5rem 0 .5rem .8rem;
  margin-bottom: .8rem;
}
/* Vergangene Termine bleiben stehen - sie sind Teil des Nachweises -, treten
   aber zurück, damit der nächste anstehende ins Auge fällt. */
.termin-liste > li.vorbei { border-left-color: var(--rand); opacity: .65; }
.termin-zeit { font-weight: 600; }

.termin-leute {
  display: flex;
  flex-wrap: wrap;
  gap: .3rem 1rem;
  margin-top: .25rem;
  font-size: .85rem;
}
.termin-leute .person {
  display: flex;
  flex-wrap: wrap;
  gap: .1rem .6rem;
  align-items: baseline;
}

.mini-formular { margin-top: .5rem; }
details.termin-neu > summary { display: inline-flex; }

.wunsch-marke {
  background: var(--warn-hell);
  border: 1px solid #fde68a;
  color: #92400e;
  border-radius: 4px;
  padding: .05rem .4rem;
}

/* --- die Wochenansicht -------------------------------------------------- */

/* Am Handy untereinander, am breiten Fenster sieben Spalten. Ein echtes
   Stundenraster mit absolut platzierten Terminen wäre am Telefon nicht mehr
   zu treffen - deshalb je Tag eine Karte mit Leiste und Liste. */
.kalender { display: grid; gap: .6rem; margin-bottom: 1rem; }

.ktag {
  background: var(--flaeche);
  border: 1px solid var(--rand-hell);
  border-radius: var(--radius);
  padding: .6rem .7rem;
}
.ktag.heute { border-color: var(--akzent); box-shadow: 0 0 0 1px var(--akzent); }
.ktag.wochenende { background: var(--grund); }

.ktag-kopf {
  display: flex;
  align-items: baseline;
  gap: .4rem;
  margin: 0 0 .4rem;
  font-size: .95rem;
}
.ktag-name  { font-weight: 700; }
.ktag-datum { color: var(--text-leise); font-size: .85rem; }
.ktag-leer  { margin: .2rem 0 0; }

.frei-leiste {
  display: flex;
  gap: 2px;
  margin-bottom: .5rem;
  /* Bei zehn Stunden und schmalem Telefon lieber rollen als quetschen. */
  overflow-x: auto;
  scrollbar-width: thin;
}
.frei-feld {
  flex: 1 0 2.1rem;
  text-align: center;
  border-radius: 4px;
  padding: .15rem .1rem .2rem;
  line-height: 1.1;
  border: 1px solid transparent;
}
.frei-feld .fz { display: block; font-size: .6rem; color: var(--text-leise); }
.frei-feld .fa { display: block; font-weight: 700; font-size: .95rem; }
.frei-feld.frei  { background: var(--gut-hell);      border-color: #bbf7d0; color: var(--gut); }
.frei-feld.knapp { background: var(--warn-hell);     border-color: #fde68a; color: #92400e; }
.frei-feld.voll  { background: var(--schlecht-hell); border-color: #f0bcbc; color: var(--schlecht); }
.frei-feld.voll .fz, .frei-feld.knapp .fz, .frei-feld.frei .fz { color: inherit; opacity: .75; }

.ktermine { list-style: none; margin: 0; padding: 0; }
.ktermine li { margin-bottom: .3rem; }
/* NUR DER DIREKTE KIND-LINK - das ist die Terminkarte selbst.
   Vorher stand hier ".ktermine a", und das traf ab dem 2026-08-05 auch die
   Schaltflaeche "Anrufen" darunter: Sie bekam den Kartenrahmen mit
   border-radius 0 4px 4px 0 und eigenem Innenabstand und sah dadurch anders
   aus als "Anfahrt" (ein <button>, den die Regel nicht traf). Gemeldet als
   "nicht 2 verschiedene Formen", nachgemessen: 8px gegen 0 4px 4px 0. */
.ktermine > li > a {
  display: block;
  border-left: 3px solid var(--rand);
  background: var(--grund);
  border-radius: 0 4px 4px 0;
  padding: .35rem .5rem;
  text-decoration: none;
  color: var(--text);
  font-size: .85rem;
}
.ktermine > li > a:hover { background: var(--akzent-hell); color: var(--text); }

/* Die eigene Abwesenheit im Kalender - aufgebaut wie eine Terminkarte, damit
   sie sich einreiht, aber mit eigenem Grund statt des grauen (Wunsch vom
   2026-08-07: "wie einen Termin vom Ticket anzeigen aber statt grauen
   Hintergrund einen anderen").

   KEIN LINK, sondern ein <div>: Dahinter steckt kein Ticket, das man
   aufschlagen koennte. Eine Karte, die aussieht wie ein Link und auf nichts
   fuehrt, ist aergerlicher als eine, die gar nicht erst danach aussieht.

   Farbe: derselbe Ton wie die internen Notizen (--intern). Bewusst nicht rot
   (das ist die Markenfarbe und heisst hier "Handlung") und nicht gruen
   (heisst "erledigt"). */
.kabwesenheit {
  display: block;
  border-left: 3px solid var(--intern);
  background: var(--warn-hell);
  border-radius: 0 4px 4px 0;
  padding: .35rem .5rem;
  color: var(--text);
  font-size: .85rem;
}
.kzeit   { font-weight: 700; margin-right: .4rem; }
.ktitel  { font-weight: 600; }
.kkunde, .kleute { display: block; color: var(--text-leise); font-size: .78rem; }

.legende {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .4rem 1rem;
  /* Ohne das setzt der Browser zusaetzlich zum Farbfeld noch seinen eigenen
     Aufzaehlungspunkt - zwei Marken je Eintrag. */
  list-style: none;
  padding-left: 0;
  margin: 0 0 .5rem;
}
.legende li { display: flex; align-items: center; }
.legende .frei-feld { flex: 0 0 2.1rem; }

@media (min-width: 62rem) {
  .kalender { grid-template-columns: repeat(7, minmax(0, 1fr)); }
  .frei-leiste { flex-wrap: wrap; overflow-x: visible; }
  .frei-feld { flex: 1 0 1.6rem; }
}

/* Zusammengehörende Felder in einem <fieldset> - Wunschtermin, "wer fährt
   hin". Ohne eigene Regel setzt der Browser seinen alten Standardrahmen,
   der mit nichts anderem auf der Seite zusammenpasst. */
.feld-gruppe {
  border: 1px solid var(--rand-hell);
  border-radius: var(--radius);
  padding: .7rem .8rem .3rem;
  margin: 0 0 .9rem;
  /* Ein fieldset bekommt vom Browser eine Mindestbreite nach seinem Inhalt
     und sprengt damit schmale Fenster. min-width:0 stellt das ab. */
  min-width: 0;
}
.feld-gruppe > legend {
  font-weight: 600;
  font-size: .9rem;
  padding: 0 .3rem;
}
.feld-gruppe > legend em { color: var(--schlecht); font-style: normal; }
.feld-gruppe > label:last-child,
.feld-gruppe > p:last-child { margin-bottom: .5rem; }

/* --- Abwesenheiten ------------------------------------------------------ */

/* Die Abwesenheitsliste im Kalender ist am 2026-08-03 entfallen (siehe
   kalender_woche()); ihre Regeln .kabwesend/.kaname/.kagrund sind mit ihr
   weg. Die Anzeige der Abwesenheiten selbst steht jetzt im Dienstplan. */

.abw-zeile {
  display: flex;
  flex-wrap: wrap;
  gap: .3rem .6rem;
  align-items: center;
  padding: .6rem .2rem;
  min-height: 44px;
}

/* ==========================================================================
   Einrichtung und Update
   ========================================================================== */

.schritt {
  display: flex;
  align-items: center;
  gap: .5rem;
  font-size: 1rem;
  margin: 1.4rem 0 .6rem;
  padding-top: 1rem;
  border-top: 1px solid var(--rand-hell);
}
.schritt:first-of-type { border-top: none; padding-top: 0; }
.schritt-nr {
  flex: none;
  width: 1.7rem;
  height: 1.7rem;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: .85rem;
  font-weight: 700;
  background: var(--grund);
  color: var(--text-leise);
  border: 1px solid var(--rand);
}
.schritt.erledigt .schritt-nr { background: var(--gut); border-color: var(--gut); color: #fff; }
.schritt.dran     .schritt-nr { background: var(--akzent); border-color: var(--akzent); color: #fff; }
.schritt.offen              { color: var(--text-leise); }

/* Prüfliste der Voraussetzungen. Drei Zustände statt zwei: Ein fehlendes
   gd ist ärgerlich, aber kein Grund abzubrechen - ein fehlendes pdo_mysql
   schon. Das muss man auf einen Blick unterscheiden können. */
.pruefliste { list-style: none; margin: 0 0 1rem; padding: 0; }
.pruefliste li {
  display: flex;
  gap: .5rem;
  align-items: flex-start;
  padding: .4rem .5rem;
  border-radius: 4px;
  margin-bottom: .25rem;
  font-size: .9rem;
}
.pruefliste li > strong { flex: none; width: 1rem; text-align: center; }
.pruefliste li small { display: block; color: var(--text-leise); font-size: .8rem; }
.pruefliste li.ja   { background: var(--gut-hell);      color: var(--gut); }
.pruefliste li.nein { background: var(--schlecht-hell); color: var(--schlecht); }
.pruefliste li.warn { background: var(--warn-hell);     color: #92400e; }
.pruefliste li.ja span, .pruefliste li.nein span, .pruefliste li.warn span { color: var(--text); }

/* Der Inhalt von config.php zum Abtippen, wenn inc/ nicht beschreibbar ist. */
.config-text {
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: .78rem;
  white-space: pre;
  overflow-x: auto;
  background: var(--grund);
}

.dateiliste {
  list-style: none;
  margin: .3rem 0 1rem;
  padding: 0;
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: .8rem;
  /* Bei einem grossen Paket sind das schnell hundert Zeilen. */
  max-height: 16rem;
  overflow-y: auto;
}
.dateiliste li {
  padding: .15rem .4rem;
  border-bottom: 1px solid var(--rand-hell);
  word-break: break-all;
}
.dateiliste li:last-child { border-bottom: none; }
.dateiliste li.ja   { color: var(--gut); }
.dateiliste li.nein { color: var(--schlecht); }

/* --- Zeiterfassung ------------------------------------------------------ */

.zeit-summe {
  font-weight: 700;
  font-size: 1.05rem;
  background: var(--grund);
  border-radius: var(--radius);
  padding: .15rem .6rem;
}

/* Die zwei Stempelknöpfe stehen ganz oben und dürfen nicht zu suchen sein -
   sie werden mit Handschuhen im Stiegenhaus gedrückt. */
.zeit-stempel {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .5rem .8rem;
  padding: .6rem;
  margin-bottom: .8rem;
  background: var(--grund);
  border-radius: var(--radius);
}

.zeit-liste { list-style: none; margin: 0 0 .8rem; padding: 0; }
.zeit-liste > li {
  border-bottom: 1px solid var(--rand-hell);
  padding: .5rem 0;
}
.zeit-liste > li:last-child { border-bottom: none; }
/* Ein laufender Einsatz sticht heraus - sonst vergisst man die Abfahrt. */
.zeit-liste > li.offen {
  border-left: 3px solid var(--intern);
  padding-left: .6rem;
  background: var(--warn-hell);
  border-radius: 0 4px 4px 0;
}

.zeit-zeile {
  display: flex;
  flex-wrap: wrap;
  gap: .2rem .8rem;
  align-items: baseline;
  font-size: .9rem;
}
.zeit-wer    { font-weight: 600; }
.zeit-spanne { color: var(--text-leise); }
.zeit-dauer  { margin-left: auto; font-weight: 700; }

details.zeit-neu > summary { display: inline-flex; }
details.zeit-aendern > summary { font-size: .8rem; color: var(--text-leise); }

/* --- Rechtstexte -------------------------------------------------------- */

/* Etwas schmaler als der Rest: Eine Datenschutzerklärung über die volle
   Breite eines 1200-Punkte-Fensters liest niemand - das Auge verliert beim
   Zeilenwechsel den Anschluss. */
.rechtstext { max-width: 46rem; }
.rechtstext h2 {
  font-size: 1.05rem;
  margin-top: 1.6rem;
  padding-top: .8rem;
  border-top: 1px solid var(--rand-hell);
}
.rechtstext h2:first-of-type { margin-top: 0; padding-top: 0; border-top: none; }
.rechtstext h3 { font-size: .95rem; margin-top: 1rem; color: var(--text-leise); }
.rechtstext p, .rechtstext ul { font-size: .92rem; }
.rechtstext ul { padding-left: 1.2rem; }
.rechtstext li { margin-bottom: .4rem; }
.rechtstext dl.daten { border-top: none; padding-top: 0; }

.fuss-schmal { margin-top: 1.2rem; }

/* Die Referenz des Kunden in der Liste. Auffällig genug, um sie beim
   Überfliegen zu finden - das ist ihr einziger Zweck. */
.zeile-referenz {
  margin: 0 0 .3rem;
  font-size: .8rem;
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  color: var(--text-leise);
}

.zurueck-formular { display: inline; }
.zurueck-formular button { font-size: .75rem; min-height: 0; }

/* ==========================================================================
   Dienstplan, Öffnungszeiten, Arbeitszeiten
   ========================================================================== */

/* Eine Tabelle mit sieben Tagesspalten passt auf kein Telefon. Statt sie
   umzubrechen (dann steht Montag über Dienstag und niemand erkennt eine
   Woche), rollt sie waagrecht - INNERHALB ihres Rahmens, damit die Seite
   selbst nicht mitrollt. */
.tabelle-rollt {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  border: 1px solid var(--rand);
  border-radius: var(--radius);
  background: var(--flaeche);
  margin-bottom: 1rem;
}
.tabelle-rollt > .tabelle { margin: 0; border: none; }

/* DIE WOCHENUEBERSICHT DER ZUSTELLUNG TEILT SICH DIESE REGELN.
   Sie ist genau dieselbe Bauart - Zeilen sind Fahrzeuge statt Personen,
   Spalten sind dieselben sieben Tage, und die erste Spalte muss beim
   waagrechten Rollen genauso stehenbleiben.

   ALS ZWEITER SELEKTOR UND NICHT DURCH MITBENUTZEN VON .dienstplan: Eine
   Klasse namens "dienstplan" auf der Zustellseite waere eine unsichtbare
   Kopplung - wer den Dienstplan umbaut, aendert dann unbemerkt eine ganz
   andere Ansicht mit. So steht die zweite Verwendung daneben und faellt
   beim Lesen auf. */
.dienstplan, .wochen-tabelle { min-width: 46rem; width: 100%; border-collapse: collapse; }
.dienstplan th, .dienstplan td,
.wochen-tabelle th, .wochen-tabelle td {
  border: 1px solid var(--rand-hell);
  padding: .45rem .5rem;
  vertical-align: top;
  font-size: .84rem;
}
.dienstplan thead th,
.wochen-tabelle thead th { background: var(--grund); text-align: center; font-size: .8rem; }
.dienstplan thead th small,
.wochen-tabelle thead th small { display: block; font-weight: 400; color: var(--text-leise); }

/* Die Namensspalte bleibt beim waagrechten Rollen stehen - ohne sie weiß
   nach zwei Spalten niemand mehr, wessen Zeile er liest. */
.dienstplan tbody th,
.wochen-tabelle tbody th,
.wochen-tabelle tfoot th {
  position: sticky;
  left: 0;
  background: var(--flaeche);
  text-align: left;
  white-space: nowrap;
  z-index: 1;
  box-shadow: 1px 0 0 var(--rand-hell);
}

.dienstplan .heute, .wochen-tabelle .heute { box-shadow: inset 0 3px 0 var(--akzent); }
.dienstplan .tag-zu, .wochen-tabelle .tag-zu { background: var(--grund); color: var(--text-leise); }

/* Die drei Zustände. Sie müssen sich auch OHNE Farbe unterscheiden - deshalb
   trägt jeder zusätzlich eine eigene Textform ("frei", die Marke, die
   Notiz). Farbe allein wäre für Farbenblinde keine Auskunft. */
.dienst-frei     { background: var(--grund); }
.dienst-anders   { background: var(--warn-hell); }
.dienst-abwesend { background: var(--schlecht-hell); }

.dienst-zeit  { display: block; font-variant-numeric: tabular-nums; }
.dienst-frei .dienst-zeit { color: var(--text-leise); }
.dienst-notiz { display: block; color: var(--text-leise); font-size: .74rem; margin-top: .15rem; }

.marke-abwesend {
  display: inline-block;
  background: var(--schlecht);
  color: #fff;
  border-radius: 4px;
  padding: .05rem .3rem;
  font-size: .72rem;
  margin-bottom: .2rem;
}

.dienst-aendern { font-size: .74rem; margin-top: .2rem; display: inline-block; }

.dienst-formular { display: grid; gap: .3rem; margin-top: .3rem; }
.dienst-formular input[type="time"],
.dienst-formular input[type="text"] { width: 100%; font-size: .8rem; }
.dienst-formular button { font-size: .8rem; }

.legende-punkt {
  display: inline-block;
  width: .85rem;
  height: .85rem;
  border: 1px solid var(--rand);
  border-radius: 3px;
  vertical-align: -2px;
  margin-right: .2rem;
}

.wochen-blaettern { display: flex; flex-wrap: wrap; gap: .4rem; }

/* Öffnungs- und Arbeitszeiten */
.zeiten-tabelle th[scope="row"] { white-space: nowrap; }
.zeiten-tabelle input[type="time"] { min-width: 7rem; }
.zeiten-tabelle .tag-zu { background: var(--grund); color: var(--text-leise); }

.schalter { display: inline-flex; align-items: center; gap: .35rem; min-height: 44px; }
.schalter input { min-height: 0; }

.warnzeichen { color: var(--text-leise); font-style: italic; }

.person-wahl { display: flex; flex-wrap: wrap; gap: .4rem; }

/* ==========================================================================
   Terminkarte, Feiertage, Dienstplan-Marken
   ==========================================================================
   DIESE REGELN STANDEN ZWEIMAL DA - einmal in `@media (max-width: 40rem)`
   und einmal in `@media (min-width: 62rem)`, Zeile fuer Zeile gleich.
   Dazwischen, also von 640 bis 992 Punkten Fensterbreite, galt KEINE davon:
   Notiz am Termin, Feiertagsname und die Marken des Dienstplans standen dort
   unformatiert - genau die Breite eines Tablets im Querformat und eines
   kleinen Notebooks.

   Gefunden am 2026-08-08 beim Einbauen der Adresszeile, weil `.knotiz` in
   der Datei zweimal auftauchte. Keiner dieser Selektoren haengt an einer
   Fensterbreite; sie gehoeren auf die oberste Ebene und stehen dort jetzt
   EINMAL.
   ========================================================================== */
/* Wenn ein freiwilliges Feld leer geblieben ist. Bewusst NICHT .leer-hinweis:
   das ist die zentrierte Meldung fuer leere Listen und bringt 2rem Polsterung
   mit - mitten im Ticket saehe das aus wie ein eigener Abschnitt. */
.ohne-text {
  color: var(--text-leise);
  font-style: italic;
  font-size: .88rem;
  margin: 0 0 .8rem;
}

/* Feiertage. Sie wirken wie ein Wochenende (keine freien Zeitfenster), sind
   aber ausdruecklich benannt - "Keine Termine" liesse offen, ob niemand
   arbeitet oder nur nichts ansteht. */
.marke-feiertag {
  display: inline-block;
  background: var(--intern);
  color: #fff;
  border-radius: 4px;
  padding: .05rem .35rem;
  font-size: .72rem;
  font-weight: 600;
  margin-bottom: .2rem;
}
.marke-feiertag.offen { background: var(--text-leise); }

.dienst-feiertag { background: #fdf6e3; }
.feiertag-name {
  display: block;
  font-weight: 400;
  font-size: .68rem;
  color: var(--intern);
  /* Lange Namen wie "Christi Himmelfahrt" duerfen die Spalte nicht
     auseinanderziehen - die Tabelle hat sieben davon. */
  overflow-wrap: anywhere;
}

/* Die Notiz zum Termin im Kalender. Kleiner als alles andere in der Karte:
   Zeit, Titel und wer hinfaehrt sind das, wonach man zuerst sucht. */
.knotiz {
  display: block;
  color: var(--text-leise);
  font-size: .74rem;
  font-style: italic;
  margin-top: .15rem;
}

/* Adresse und Ansprechperson, die letzte Zeile der Terminkarte
   (Wunsch vom 2026-08-08). Wie die Notiz klein und zurueckhaltend - sie ist
   das, was man NACH dem Finden des Termins braucht, nicht davor. Aufrecht
   statt kursiv, damit sie sich von der Notiz darueber unterscheidet.

   `overflow-wrap: anywhere`, weil eine Strasse mit langem Namen die schmale
   Tagesspalte sonst auseinanderzieht - dieselbe Falle wie bei
   "Christi Himmelfahrt" im Dienstplan. */
.kadresse {
  display: block;
  color: var(--text-leise);
  font-size: .74rem;
  margin-top: .15rem;
  overflow-wrap: anywhere;
}

/* Die uebliche Arbeitszeit an einem gesperrten Feiertag: sichtbar, aber
   erkennbar ausser Kraft. Durchgestrichen statt ausgeblendet - der Admin
   sieht so weiterhin, was normalerweise gaelte, wenn er fuer einen Notdienst
   doch jemanden einteilen will. */
.zeit-ruht {
  text-decoration: line-through;
  color: var(--text-leise);
}

/* "am 04.08.2026" neben dem Statusschild. Bewusst unauffaellig: Es ist eine
   Zusatzangabe fuers Rechnungschreiben, nicht die Hauptsache der Zeile. */
.status-seit {
  font-size: .78rem;
  color: var(--text-leise);
  white-space: nowrap;
}

/* Umschalter "Nur meine" / "Alle Termine" im Kalender. */
.ansicht-wahl {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .4rem .8rem;
  margin-bottom: .8rem;
}

/* Die eigene Arbeitszeit und Abwesenheit ueber der Verfuegbarkeitsleiste. */
.mein-dienst {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .3rem .6rem;
  margin: 0 0 .4rem;
  font-size: .84rem;
  font-variant-numeric: tabular-nums;
}

/* "2 weitere Termine von Kollegen - alle anzeigen". Steht ueber der
   Terminliste eines Tages, damit man nicht erst bis ans Ende lesen muss. */
.verborgen-hinweis {
  margin: 0 0 .3rem;
  color: var(--text-leise);
}

@media (max-width: 40rem) {
  .dienstplan { min-width: 40rem; }
}


/* Die beiden Schaltflaechen unter einem Termin: Anfahrt/Ankunft/Abfahrt und
   Anrufen. Sie stehen ausserhalb des Karten-Links (siehe kalender.php) und
   brauchen deshalb die Einrueckung der Karte von Hand.

   NEBENEINANDER AM HANDY, UNTEREINANDER AM DESKTOP - so ausdruecklich
   gewuenscht (2026-08-05). Das ist umgekehrt zur ueblichen Regel, hat aber
   seinen Grund: Am Telefon zaehlt jede Zeile Hoehe, weil sieben Tage
   untereinander stehen; am Bildschirm ist die Tagesspalte schmal, und zwei
   Schaltflaechen nebeneinander waeren dort gequetscht. */
.termin-knoepfe {
  display: flex;
  flex-direction: row;
  gap: .4rem;
  margin: .2rem 0 0;
  padding: 0 .5rem .45rem 1.1rem;
}
.einsatz-form { display: contents; }

/* AUCH DER KNOPF IM FORMULAR. Das <form> traegt display:contents, ist also
   selbst keine Box - Flex-Element ist der <button> darin. Eine Regel nur auf
   ".termin-knoepfe > *" traf das Formular und ging damit ins Leere: "Anfahrt"
   war dreimal so breit wie "Anrufen". Im Screenshot sofort zu sehen. */
.termin-knoepfe > *,
.termin-knoepfe .einsatz-form > * { flex: 1 1 0; min-width: 0; }

.einsatz-knopf {
  /* 44px Zielflaeche - das sind die Schaltflaechen, die mit dem Daumen im
     Auto oder im Stiegenhaus getroffen werden. */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  width: 100%;
  font-size: .84rem;
  white-space: nowrap;
}

/* "Anrufen" ist blau gefuellt, nicht weiss.
   ANLASS (2026-08-05): Vorher war der benutzbare Knopf weiss (#ffffff) und
   der ausgegraute hellgrau (#f4f4f4) - zwei Toene, die sich um vier
   Helligkeitsstufen unterscheiden. Am Telefon, im Sonnenlicht, mit einem
   Blick: nicht zu unterscheiden. Genau so gemeldet.

   Jetzt sind es drei klar getrennte Zustaende:
     Anfahrt (rot gefuellt)         die Haupthandlung
     Anrufen (blau gefuellt)        die zweite Handlung
     ausgegraut (hell, gestrichelt) geht nicht

   Blau statt gruen: Gruen heisst in dieser Anwendung "erledigt" (der Haken
   am Ticket). Zwei Bedeutungen fuer eine Farbe waeren schlimmer als eine
   unauffaellige. Das Blau ist ausserdem keine willkuerliche Wahl - es ist
   die zweite Farbe des Logos. */
.einsatz-knopf.anrufen {
  background: var(--blau);
  border-color: var(--blau);
  color: #fff;
  font-weight: 600;
}
.einsatz-knopf.anrufen:hover { background: var(--blau-tief); color: #fff; }

/* Ausgegraut, wenn die Angabe fehlt. Bewusst KEIN <button disabled>, sondern
   ein <span>: Ein deaktivierter Knopf gibt keinen Tooltip aus, und genau der
   sagt hier, WARUM er nicht geht.

   Der GESTRICHELTE Rand ist der Unterschied, der ohne Farbe auskommt - fuer
   alle, die Helligkeitsunterschiede schlecht trennen, und fuer jeden bei
   Sonnenlicht. Die Textfarbe bleibt --text-leise (4,9:1 auf diesem Grund);
   sie weiter aufzuhellen wuerde die Lesbarkeit opfern, um etwas zu zeigen,
   das der Rand schon sagt. */
.einsatz-knopf.deaktiviert {
  background: var(--grund);
  color: var(--text-leise);
  border: 1px dashed var(--rand);
  cursor: not-allowed;
  font-weight: 400;
}
.einsatz-knopf.deaktiviert:hover { background: var(--grund); color: var(--text-leise); }

@media (min-width: 62rem) {
  .termin-knoepfe { flex-direction: column; }
}

/* Das Zeichen oben rechts an der Terminkarte: was gerade am Auftrag laeuft. */
.ktermine > li > a { position: relative; }
.kzeichen {
  position: absolute;
  top: .3rem;
  right: .4rem;
  font-size: 1.1rem;
  line-height: 1;
}


/* Die Zeile .ktermin-fuss mit Ort und Telefon als Text ist am 2026-08-05
   durch .termin-knoepfe ersetzt worden (Schaltflaechen statt Links). */

/* Beim Sprung zum heutigen Tag (app.js). Der Wert hier ist nur der Rueckfall
   fuer den Fall, dass das Skript nicht laeuft - app.js MISST die klebende
   Kopfzeile und setzt den Abstand danach. Ein fester Wert reicht nicht: die
   Kopfzeile ist am Handy 147 Punkte hoch und bricht je nach Geraet anders um. */
.ktag { scroll-margin-top: 9rem; }

/* ==========================================================================
   Breite auf grossen Bildschirmen
   ========================================================================== */

/* 1400px: Der uebliche Laptop am Schreibtisch. */
@media (min-width: 87.5rem) {
  :root { --breite: 1500px; }
}

/* 1760px: FullHD und alles darueber. Mehr wird es nicht - siehe --breite. */
@media (min-width: 110rem) {
  :root { --breite: 1720px; }
}

/* DIE BESCHREIBUNG BEKOMMT EINE LESEBREITE.
   Ohne sie laeuft ein Absatz auf 1720px ueber gut 130 Zeichen - beim
   Zeilenwechsel findet das Auge die naechste Zeile nicht mehr zuverlaessig.
   Die Karten, Tabellen und der Kalender duerfen die Breite dagegen voll
   nutzen; dort steht kein Fliesstext, sondern Spalten. */
.fliesstext { max-width: 62rem; }

/* ==========================================================================
   Fliesstext: lange Woerter und lange Beschreibungen
   (Nutzermeldungen 2026-10-02)
   ========================================================================== */

/* LANGE WOERTER BRECHEN UM, auch mitten im Wort. Eine kopierte Adresse, eine
   Fehlermeldung oder ein Link ohne Leerzeichen schob den Text sonst waagrecht
   aus dem Feld: "wenn ein sehr langes wort steht, kann man waagrecht
   scrollen."

   `anywhere` UND NICHT `break-word`, und das ist der Unterschied, auf den es
   hier ankommt: Nur `anywhere` zaehlt beim Berechnen der MINDESTBREITE mit.
   Mit `break-word` laeuft der Text nicht mehr ueber, das lange Wort macht die
   Karte aber weiterhin breiter als das Fenster - in einer Tabelle oder einem
   Flex-Kasten sieht das genauso aus wie vorher. Dieselbe Wahl wie bei
   .frage-dialog p. */
.fliesstext { overflow-wrap: anywhere; }

/* Gekuerzt auf 20 Zeilen.

   DIE KLASSE SETZT DAS SKRIPT, NICHT DAS HTML. Ohne JavaScript steht der Text
   vollstaendig da - gekuerzt im HTML und ohne Knopf waere der Rest
   unerreichbar, und das ist schlimmer als langes Scrollen.

   20 Zeilen bei line-height 1.5 sind 30em. DIE ZAHL STEHT NUR HIER: Das
   Skript misst bloss, ob der Text hineinpasst, und kennt sie nicht.

   NICHT AN .fliesstext GEBUNDEN (ab 2.44.0.0): Die Kuerzung gilt fuer alles
   mit data-mehr. Die mobilen Nachrichten standen in einem nackten <div>, und
   ein Kuerzungsstil, der eine fremde Klasse voraussetzt, haette dort still
   nichts getan. */
.mehr-zu {
  max-height: 30em;
  overflow: hidden;
  position: relative;
}

/* Der Verlauf sagt "es geht weiter" - ein hart abgeschnittener Satz sieht wie
   ein Datenfehler aus.

   DIE ZIELFARBE KOMMT AUS --mehr-grund, Vorgabe --flaeche (die Karte). Ein
   fest eingebautes Weiss waere in einem dunklen Farbschema falsch - und
   INTERNE KOMMENTARE liegen auf --warn-hell, dort haette ein weisser Verlauf
   wie ein Schleier ueber dem gelben Grund gelegen. Wer die Kuerzung auf einem
   anderen Hintergrund einsetzt, setzt die Variable mit.

   pointer-events: none, damit er den Text darunter nicht vom Markieren
   abhaelt. */
.mehr-zu::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 3em;
  background: linear-gradient(to bottom, transparent, var(--mehr-grund, var(--flaeche)));
  pointer-events: none;
}

/* Interne Kommentare liegen auf gelbem Grund - der Verlauf muss dorthin
   laufen, nicht auf Weiss. */
.kommentar.intern { --mehr-grund: var(--warn-hell); }

.mehr-knopf { margin-top: .4rem; }

/* ==========================================================================
   Sammeländerung in der Übersicht
   ========================================================================== */

/* Das Kästchen steht ausserhalb des Zeilen-Links (siehe index.php) und LINKS
   davor, als eigene Spalte.

   Der erste Versuch liess es mit float: right oben rechts einschwimmen - dort
   lief es dem Statusdatum in die Quere, "am 02.08.2026" und "markieren"
   ueberlagerten einander. Im Screenshot sofort zu sehen, im HTML nicht.

   Als eigene Spalte kann sich nichts ueberlagern, und es ist die Anordnung,
   die man von Auswahllisten kennt: erst abhaken, dann lesen. */
.ticket-zeile { display: flex; align-items: stretch; }
.ticket-zeile > .ticket-link { flex: 1 1 auto; min-width: 0; }

.zeile-haken {
  display: flex;
  align-items: flex-start;
  justify-content: center;
  flex: 0 0 auto;
  /* 44px Zielflaeche wie ueberall - hier ueber die Breite, die Hoehe gibt
     die Zeile vor. */
  min-width: 44px;
  padding: .85rem .2rem 0 .5rem;
  cursor: pointer;
}
.zeile-haken input { min-height: 0; width: 1.25rem; height: 1.25rem; margin: 0; }
/* Die Beschriftung braucht es nur fuer Vorleseprogramme - das Kaestchen in
   einer Auswahlliste erklaert sich selbst, und der Platz fehlt am Telefon. */
.zeile-haken span { position: absolute; left: -9999px; }

/* Bleibt beim Rollen unten stehen: Bei einer langen Liste soll man nicht
   erst ans Ende rollen muessen, um die Auswahl anzuwenden. */
.sammel-leiste {
  position: sticky;
  bottom: 0;
  z-index: 10;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .5rem .8rem;
  margin-top: .6rem;
  padding: .6rem;
  background: var(--flaeche);
  border: 1px solid var(--rand);
  border-radius: var(--radius);
  box-shadow: 0 -2px 8px rgba(0, 0, 0, .08);
}
.sammel-leiste select { min-width: 12rem; flex: 1 1 8rem; }

/* Der Haken. Quadratisch und genau so hoch wie das Auswahlfeld daneben -
   eine Schaltflaeche, die einen halben Zentimeter aus der Zeile ragt, sieht
   aus wie ein Fehler. */
.sammel-los {
  flex: 0 0 auto;
  width: 44px;
  min-width: 44px;
  padding: 0;
  font-size: 1.2rem;
  line-height: 1;
}

/* Zahl und "Alle auf dieser Seite" in die erste Zeile, Auswahl und Haken in
   die zweite - das sind zwei Zeilen statt drei. Im Querformat zaehlt jede. */
.sammel-zahl { flex: 0 0 auto; }
.sammel-alle { flex: 1 1 auto; }
.sammel-zahl { font-weight: 600; }
.sammel-alle { display: inline-flex; align-items: center; gap: .3rem; min-height: 44px; }
.sammel-alle input { min-height: 0; width: 1.15rem; height: 1.15rem; }

/* ==========================================================================
   Aufgabenliste am Ticket
   ==========================================================================
   Der Haken ist eine Schaltfläche, kein Kontrollkästchen: Jeder Klick ist
   ein eigener Vorgang mit CSRF-Prüfung. Ein echtes <input type="checkbox">
   bräuchte ein Skript oder ein "Speichern" darunter - und Letzteres wird
   vergessen, gerade auf dem Weg zwischen zwei Aufträgen.
   ========================================================================== */
.todo-liste {
  list-style: none;
  margin: 0 0 .8rem;
  padding: 0;
}

.todo-liste > li {
  display: flex;
  align-items: center;
  gap: .6rem;
  padding: .35rem 0;
  border-bottom: 1px solid var(--rand);
}
.todo-liste > li:last-child { border-bottom: 0; }

.todo-haken, .todo-weg { margin: 0; flex: 0 0 auto; }
.todo-weg { margin-left: auto; }

.todo-knopf {
  width: 28px;
  height: 28px;
  /* 28 statt 44: Der Punkt daneben ist mitanzutippen zu klein, aber die
     Zeile selbst ist 44 hoch - der Finger trifft also den Streifen, nicht
     nur das Kästchen. */
  padding: 0;
  border: 2px solid var(--rand);
  border-radius: var(--radius);
  background: var(--flaeche);
  color: #fff;
  font-size: 1rem;
  line-height: 1;
  cursor: pointer;
}
.todo-knopf.leer:hover { border-color: var(--akzent); }
.todo-knopf:not(.leer) {
  background: var(--gut);
  border-color: var(--gut);
}

.todo-text { flex: 1 1 auto; min-width: 0; }

.todo-erledigt .todo-text {
  text-decoration: line-through;
  color: var(--text-leise);
}

.todo-neu {
  display: flex;
  gap: .5rem;
  margin: 0;
}
.todo-neu input[type="text"] { flex: 1 1 auto; min-width: 0; }

/* Die Zahl in der Kartenüberschrift. Farbe UND Wort - wer Farben schlecht
   unterscheidet, liest "3 von 5 offen" genauso. */
.todo-offen  { color: var(--intern); font-weight: 600; }
.todo-fertig { color: var(--gut); font-weight: 600; }

/* In der Übersicht: die Zahl neben dem Betreff. */
.todo-marke {
  display: inline-block;
  margin-left: .4rem;
  padding: 0 .35rem;
  border-radius: var(--radius);
  background: var(--grund);
  border: 1px solid var(--rand);
  color: var(--text-leise);
  font-size: .75rem;
  white-space: nowrap;
}

/* Die Auswahl der Schnellzugriffe im Konto. Das Sinnbild steht neben der
   Auswahlliste, damit man sieht, was auf dem Knopf landet - der Name allein
   sagt es nicht. */
.schnell-wahl {
  display: grid;
  gap: .6rem;
  margin-bottom: .8rem;
}

.schnell-wahl .feld { display: grid; gap: .2rem; }
.schnell-wahl .feld select { min-width: 0; }

.schnell-vorschau {
  display: flex;
  align-items: center;
  gap: .4rem;
  min-height: 24px;
  color: var(--text-leise);
}

@media (min-width: 40rem) {
  .schnell-wahl { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* ==========================================================================
   Aufklappbare Filter in der Übersicht (ab 2026-08-09)
   ==========================================================================
   Sie standen immer offen und kosteten am Telefon eine halbe Bildschirmhöhe,
   bevor das erste Ticket kam. Jetzt zugeklappt - AUSSER es filtert gerade
   etwas, dann steht die Leiste offen und trägt die Marke "aktiv". Eine
   versteckte Filterung ist schlimmer als eine sichtbare Leiste: Man sucht
   sonst nach Tickets, die es gibt, die aber gerade weggefiltert sind.
   ========================================================================== */
.filter-block {
  margin-bottom: .8rem;
  border: 1px solid var(--rand);
  border-radius: var(--radius);
  background: var(--flaeche);
}

.filter-knopf {
  display: flex;
  align-items: center;
  gap: .5rem;
  min-height: 44px;
  padding: 0 .8rem;
  cursor: pointer;
  font-weight: 600;
  color: var(--text-leise);
  /* Der Pfeil des Browsers bleibt - er sagt "hier geht etwas auf", und zwar
     in der Sprache, die der Nutzer von seinem Gerät kennt. */
}
.filter-knopf:hover { color: var(--text); }

.filter-marke {
  padding: .05rem .4rem;
  border-radius: var(--radius);
  background: var(--akzent);
  color: #fff;
  font-size: .72rem;
  font-weight: 600;
}

/* Die Leiste selbst sitzt jetzt IM Kasten - deshalb kein eigener Rahmen und
   kein doppelter Abstand mehr. */
.filter-block .filter-leiste {
  margin: 0;
  border: 0;
  padding: 0 .8rem .8rem;
}

/* Ein schmaler, mittiger Block fuer Seiten mit genau einer Entscheidung -
   die Abfahrt zum Beispiel. Ueber die volle Breite gezogen stuenden die
   zwei Zeilen verloren da. */
.schmal-mitte {
  max-width: 42rem;
  margin: 0 auto;
}

/* ==========================================================================
   Reihenfolge der Ticket-Abschnitte am Handy (ab 2026-08-09)
   ==========================================================================
   VORGABE des Nutzers: Beschreibung, Aufgabenliste, Nachrichten, Status,
   Zeiten, Anhänge, Termine, Zugewiesen an, Änderungsverlauf.

   Diese Folge mischt beide Spalten - Status und "Zugewiesen an" stehen im
   HTML in der Seitenspalte, sollen am Telefon aber zwischen den Abschnitten
   der Hauptspalte auftauchen. Zwei getrennte <div> lassen sich mit CSS nicht
   ineinanderschieben.

   DER KNIFF IST `display: contents`: Die beiden Spalten verschwinden als
   Kästen, ihre Abschnitte werden dadurch zu direkten Kindern von
   `.zwei-spalten` - und erst dann greift `order` über beide hinweg.

   Am Rechner (ab 62rem) bleibt alles wie bisher: dort ist `.zwei-spalten`
   ein Raster mit zwei Spalten, und die Regel hier gilt nicht.
   ========================================================================== */
@media (max-width: 61.999rem) {
  .zwei-spalten {
    display: flex;
    flex-direction: column;
    gap: 1rem;
  }

  .spalte-haupt,
  .spalte-seite { display: contents; }

  .ab-beschreibung  { order: 1; }
  .ab-todo          { order: 2; }
  .ab-nachrichten   { order: 3; }
  .ab-status        { order: 4; }
  .ab-zeiten        { order: 5; }
  /* Die Unterschrift gehoert neben die Zeiten: Beides entsteht am Ende
     eines Einsatzes, und beides sucht man dann gemeinsam. */
  .ab-material      { order: 6; }
  .ab-unterschrift  { order: 7; }
  .ab-anhaenge      { order: 8; }
  .ab-termine       { order: 9; }
  /* ------------------------------------------------------------------
     DIE STOPPS STANDEN AM HANDY GANZ OBEN, und zwar unbemerkt.

     Eine Karte ohne eigene Regel bekommt `order: 0` - und das ist KLEINER
     als jede Zahl hier. `.ab-stopps` (seit dem Zustellmodul) hatte keine
     und sprang damit vor die Beschreibung. Am Rechner faellt das nie auf:
     dort gilt dieser ganze Block nicht.

     MERKE: Eine neue Karte in ticket.php ist erst fertig, wenn sie hier
     eine Zahl hat. Dieselbe Sorte Versaeumnis wie ein fehlender Fall in
     verlauf_satz() - es sieht nicht nach einem Fehler aus, sondern nach
     einer Entscheidung.
     ------------------------------------------------------------------ */
  .ab-stopps        { order: 10; }
  .ab-zuweisung     { order: 11; }
  .ab-aenderungen   { order: 12; }
  /* Die Kopplung betrifft nicht den Auftrag, sondern seinen Weg - sie steht
     bei den Dingen, die man selten anfasst. */
  .ab-kopplung      { order: 13; }
  .ab-kunde         { order: 14; }
  .ab-markieren     { order: 15; }
  /* Nicht in der Vorgabe genannt - ganz nach unten, wo man nicht
     versehentlich hinkommt. */
  .ab-loeschen      { order: 16; }

  /* Die Abstände kommen jetzt vom `gap` der Spalte; die eigenen Ränder der
     Karten würden sich sonst dazuaddieren. */
  .zwei-spalten > .karte { margin-bottom: 0; }
}

/* Der Auf-/Zuknopf der klappbaren Ticket-Abschnitte. Er wird von app.js
   angelegt - im HTML steht er nicht, weil es ihn ohne JavaScript auch nicht
   braucht (dann ist ohnehin alles offen). */
.ab-schalter {
  margin-left: auto;
  min-width: 44px;
  min-height: 44px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--text-leise);
  font-size: 1.1rem;
  line-height: 1;
  cursor: pointer;
}
.ab-schalter:hover { color: var(--text); }

/* Eine Karte ohne Kopfzeile bekommt sie hier: Ohne sie stünde der Knopf
   unter der Überschrift statt daneben. */
.ab-klappbar > .karte-kopf { display: flex; align-items: center; gap: .5rem; }
.ab-klappbar > h2 { display: flex; align-items: center; gap: .5rem; }

/* ==========================================================================
   Unterschrift am Display (ab 2026-09-04)
   ========================================================================== */
.unterschrift-feld {
  border: 1px dashed var(--rand);
  border-radius: var(--radius);
  background: var(--flaeche);
  padding: .5rem;
}
.unterschrift-feld.hat-unterschrift { border-style: solid; border-color: var(--gut); }

.unterschrift-feld canvas {
  display: block;
  width: 100%;
  /* Hoch genug für einen Namenszug mit dem Finger, niedrig genug, dass am
     Telefon noch die Schaltflächen darunter sichtbar bleiben. */
  height: 160px;
  border-radius: var(--radius);
  background: #fff;
  /* OHNE DAS ROLLT DIE SEITE BEIM ZEICHNEN, und es entsteht eine Linie, die
     niemand gezogen hat. Der wichtigste Punkt an dieser ganzen Regel. */
  touch-action: none;
  cursor: crosshair;
}

/* Die Linie, auf der unterschrieben wird - wie auf Papier. */
.unterschrift-linie {
  margin: .2rem .5rem 0;
  border-top: 1px solid var(--rand);
  padding-top: .2rem;
  color: var(--text-leise);
  font-size: .78rem;
}

.unterschrift-knoepfe {
  display: flex;
  gap: .5rem;
  align-items: center;
  margin-top: .5rem;
}

/* Die gespeicherte Unterschrift in der Anzeige. Auf weissem Grund, damit sie
   aussieht wie auf Papier - und nicht wie ein Bedienelement. */
.unterschrift-bild {
  max-width: 100%;
  height: auto;
  background: #fff;
  border-radius: var(--radius);
  color: #171717;
}

/* ==========================================================================
   Rechtevergabe (ab 2026-09-04)
   ========================================================================== */
.rechte-block {
  border: 1px solid var(--rand);
  border-radius: var(--radius);
  padding: .6rem .8rem;
  margin: .6rem 0;
}
.rechte-block legend { font-weight: 600; padding: 0 .3rem; }

.recht {
  display: flex;
  align-items: flex-start;
  gap: .6rem;
  padding: .4rem 0;
  border-bottom: 1px solid var(--rand-hell);
}
.recht:last-of-type { border-bottom: 0; }
.recht > span { display: grid; gap: .1rem; }
.recht input { margin-top: .25rem; width: 1.15rem; height: 1.15rem; flex: 0 0 auto; }

/* Gesperrt heisst sichtbar, aber erkennbar ausser Reichweite - siehe die
   Begruendung in mitarbeiter.php. */
.recht-gesperrt { opacity: .55; }
.recht-gesperrt strong { font-weight: 400; }

/* ==========================================================================
   Materialeinkäufe (ab 2026-09-04)
   ========================================================================== */
.material-summe { font-weight: 700; }

.material-liste { list-style: none; margin: 0 0 .8rem; padding: 0; }

.material-liste > li {
  display: flex;
  align-items: center;
  gap: .7rem;
  padding: .45rem 0;
  border-bottom: 1px solid var(--rand-hell);
}
.material-liste > li:last-child { border-bottom: 0; }

/* Der Beleg als Daumennagel. Feste Größe, damit die Zeilen nicht springen -
   Baustellenfotos haben jedes Seitenverhältnis. */
.material-beleg {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  border: 1px solid var(--rand);
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--grund);
  color: var(--text-leise);
  text-decoration: none;
  font-size: .7rem;
}
.material-beleg img { width: 100%; height: 100%; object-fit: cover; display: block; }
.material-beleg.leer { border-style: dashed; }

.material-text { flex: 1 1 auto; min-width: 0; display: grid; gap: .1rem; }
.material-preis { flex: 0 0 auto; font-weight: 600; white-space: nowrap; }
.material-weg { margin: 0; flex: 0 0 auto; }

/* Die Auswahl der Anhänge beim Mailversand (ab 2026-09-04). */
.mail-anhaenge {
  border: 1px solid var(--rand);
  border-radius: var(--radius);
  padding: .5rem .7rem;
  margin: .6rem 0;
}
.mail-anhaenge legend { font-weight: 600; padding: 0 .3rem; }

.mail-anhang {
  display: flex;
  align-items: center;
  gap: .5rem;
  padding: .35rem 0;
  border-bottom: 1px solid var(--rand-hell);
}
.mail-anhang:last-of-type { border-bottom: 0; }

/* Seit 2.14.0.2 umschliesst das label nur noch den TEXT und ist dem Kaestchen
   ueber `for` zugeordnet. Die Vorschau steht ausserhalb und ist ein Link zum
   Oeffnen - ein Link INNERHALB eines label wuerde beim Antippen zusaetzlich
   das Kaestchen umlegen. "Ansehen" ist entfallen. */
.mail-anhang > label {
  flex: 1 1 auto;
  min-width: 0;
  cursor: pointer;
}

/* DIE FORMULARREGELN FUER FELDBESCHRIFTUNGEN GELTEN HIER NICHT - und das ist
   ein behobener Nebeneffekt aus 2.14.0.2, im Bild gesehen.
   Die Zeile steht in einem .formular. Dort macht `.formular label` jedes
   label zum Block mit margin-bottom: .9rem, und `.formular label >
   span:first-child` das erste span zur fetten Feldueberschrift. Solange die
   Vorschau im label steckte, war SIE das erste span - ohne sichtbare Folge.
   Seit das label nur noch den Text umschliesst, ist es der DATEINAME: Er
   wurde fett, und jede Zeile bekam Abstand dazu.
   `.mail-anhang-text { display: grid }` allein verlor dagegen, weil
   `.formular label` spezifischer ist (Klasse + Element). Die Selektoren hier
   sind deshalb bewusst spezifischer als beide Formularregeln - statt sich
   auf die Reihenfolge in dieser Datei zu verlassen, die beim naechsten
   Umsortieren kippt. */
.mail-anhang > label.mail-anhang-text {
  display: grid;
  gap: .05rem;
  margin: 0;
}
.mail-anhang > label.mail-anhang-text > .mail-anhang-name {
  font-weight: normal;
  font-size: inherit;
  margin: 0;
}
.mail-anhang input { width: 1.15rem; height: 1.15rem; flex: 0 0 auto; }

/* 64 Punkte: Bei 48 waren zwei Baustellenfotos nicht auseinanderzuhalten -
   und genau dafuer ist die Vorschau da. Feste Groesse, damit die Zeilen
   nicht springen; Fotos haben jedes Seitenverhaeltnis. */
.mail-vorschau {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 64px;
  height: 64px;
  border: 1px solid var(--rand);
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--grund);
  color: var(--text-leise);
  font-size: .7rem;
}
.mail-vorschau img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Die Vorschau ist seit 2.14.0.2 der Weg zum Oeffnen. Ein Rahmen in der
   Farbe der Verweise beim Ueberfahren und ein sichtbarer Fokusrahmen - sonst
   ist nicht zu erkennen, dass das Bild etwas tut. */
a.mail-vorschau { text-decoration: none; }
a.mail-vorschau:hover { border-color: var(--blau); }
a.mail-vorschau:focus-visible { outline: 2px solid var(--blau); outline-offset: 2px; }

/* Ein Anhang, dessen Datei nicht mehr da ist: sichtbar, aber nicht
   auswaehlbar - siehe die Begruendung in ticket.php. */
.mail-anhang.fehlt { opacity: .55; }
.mail-anhang.fehlt .mail-vorschau { border-style: dashed; }

.mail-anhang-text { display: grid; gap: .05rem; min-width: 0; }
/* Der Dateiname hat seit 2.14.0.1 eine eigene Klasse. VORHER STAND HIER
   ".mail-anhang-text > :first-child" - und der Name war ein blosser
   Textknoten. :first-child trifft aber nur ELEMENTE, also die Groessenangabe
   darunter. Die Regel sah richtig aus und hat den Namen nie erreicht; bei
   einem Kameranamen ohne Umbruchstelle wurde die Seite am Handy zu breit.

   EINE ZEILE MIT AUSLASSUNGSPUNKTEN, NIE UMGEBROCHEN. Der erste Anlauf
   setzte hier "overflow-wrap: anywhere" - die Seite passte danach, aber die
   Namen brachen mitten im Wort, sogar kurze ("ticketfoto.jp" / "g"). Im Bild
   gesehen, nicht an den Zahlen: Die Breitenmessung war gruen.

   PHP kuerzt auf 20 Zeichen (text_kurz). Reicht der Platz auch dafuer nicht,
   schneidet das Stylesheet weiter ab, ebenfalls mit "...". Der volle Name
   steht im title. Mit "Ansehen" waren am Telefon nur 8-13 Zeichen zu sehen;
   der Knopf ist seit 2.14.0.2 weg. */
.mail-anhang-name {
  display: block;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ==========================================================================
   Verschickte Mails am Ticket (ab 2026-09-04)
   ========================================================================== */
.mail-liste { list-style: none; margin: .5rem 0 0; padding: 0; }

.mail-liste > li {
  padding: .5rem .6rem;
  margin-bottom: .4rem;
  border: 1px solid var(--rand);
  border-left: 3px solid var(--gut);
  border-radius: var(--radius);
}
/* Was der Mailserver nicht angenommen hat, ist rot markiert - und zwar am
   Rand, damit es in einer Liste auffällt, ohne den Text einzufärben. */
.mail-liste > li.mail-fehlgeschlagen { border-left-color: var(--schlecht); }

.mail-kopf { display: flex; flex-wrap: wrap; gap: .3rem .6rem; align-items: baseline; }

.mail-text > summary { cursor: pointer; color: var(--text-leise); }

/* Der verschickte Text, unverändert. `pre` mit Umbruch: Eine Mail hat
   eigene Zeilenenden, die sollen stehen bleiben - aber sie darf die Karte
   nicht seitlich aufreissen. */
.mail-inhalt {
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  margin: .3rem 0 0;
  padding: .4rem .5rem;
  background: var(--grund);
  border-radius: var(--radius);
  font-size: .82rem;
  font-family: inherit;
}

/* --------------------------------------------------------------------------
   Der Balken der Erweiterungsfassung.

   Auffaellig mit Absicht: Er soll stoeren. Ein dezenter Hinweis wird nach
   drei Tagen nicht mehr gelesen - und genau dann verwechselt man die beiden
   Faelle. In der Produktivfassung erscheint er gar nicht (siehe
   installations_balken() in inc/layout.php).
   -------------------------------------------------------------------------- */
.testbalken {
  background: #7c2d12;
  color: #fff;
  text-align: center;
  padding: .45rem .8rem;
  font-size: .9rem;
  letter-spacing: .02em;
  position: sticky;
  top: 0;
  z-index: 100;
}
.testbalken strong { letter-spacing: .06em; text-transform: uppercase; }

/* --------------------------------------------------------------------------
   Zustellung: Stopps (Modul 'zustellung')
   --------------------------------------------------------------------------
   EIGENE KLASSEN, OBWOHL .zeit-liste FAST PASST - und der erste Anlauf hat
   genau das falsch gemacht.

   Die Zeitliste ist fuer die Zeiterfassung gebaut: Zeitstempel, ein Name,
   eine Dauer. Eine Stoppzeile traegt Fenster, Richtung, Titel, Kunde,
   Adresse, Notiz und zwei Formulare - unter .zeit-wer (font-weight: 600)
   wurde die Adresse fett, und die Zeile fiel auseinander.

   Es ist derselbe Fehler wie seinerzeit im Testerbereich der Website:
   Klassen von woanders uebernommen, statt nachzusehen, was sie dort tragen.

   UND EINE FALLE IM BESTAND, die dabei aufgefallen ist: `.marke` ist ZWEIMAL
   definiert - oben als Logo-Link der Kopfzeile (mit display: flex), unten
   als rundes Etikett. Das flex aus der ersten Regel wirkt auf jedes Etikett
   mit, weil die zweite es nicht ueberschreibt. Bisher folgenlos, weil ein
   Etikett meist allein in seiner Zeile steht; in einer Stoppzeile bricht es
   den Umbruch auf. Deshalb hier .stopp-richtung statt .marke - und die
   Doppelung selbst bleibt unangetastet, sie zu entwirren traefe jede Seite.
   -------------------------------------------------------------------------- */

.stopp-liste { list-style: none; margin: 0 0 .8rem; padding: 0; }

.stopp-liste > li {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: .35rem .8rem;
  padding: .55rem 0;
  border-bottom: 1px solid var(--rand-hell);
}
.stopp-liste > li:last-child { border-bottom: none; }

/* Ein abgehakter Stopp bleibt LESBAR, nur zurueckgenommen. Ihn auszublenden
   waere falsch: Der Fahrer will sehen, was er schon hat, und der Disponent
   soll die Tour vollstaendig vor sich haben. */
.stopp-liste > li.stopp-fertig { opacity: .62; }

/* Feste Breite und Ziffern gleicher Laufweite: So stehen die Fenster
   untereinander buendig, und man liest die Tour als Zeitleiste statt als
   Fliesstext. */
.stopp-zeit {
  min-width: 7.5rem;
  font-weight: 700;
  font-size: .85rem;
  font-variant-numeric: tabular-nums;
  color: var(--text-leise);
}

.stopp-inhalt { flex: 1 1 18rem; min-width: 0; }

/* DER TITEL IST EIN TEXTLINK, KEINE KLICKFLAECHE - und der erste Anlauf hat
   dafuer .ticket-link genommen. Die Klasse ist fuer die Ticketliste gebaut:
   display: block mit 12,8px Polsterung ringsum, damit die ganze Zeile am
   Telefon zu treffen ist. In einer Stoppzeile sprengte sie den Umbruch, und
   Titel und Adresse standen versetzt untereinander - es sah zentriert aus.
   Am Markup war das nicht zu sehen; erst die gemessenen linken Kanten
   (180 zu 196) haben es gezeigt. */
.stopp-titel {
  font-weight: 600;
  color: var(--text);
  text-decoration: none;
}
.stopp-titel:hover { color: var(--akzent-tief); text-decoration: underline; }
.stopp-kunde  { color: var(--text-leise); font-size: .8rem; }

.stopp-ort {
  display: block;
  font-size: .8rem;
  margin-top: .1rem;
}

/* Die Rechnung einer Tankzeile (Strecke und Verbrauch) auf einer EIGENEN
   Zeile. Hinter den Litern angehängt liest sie sich sonst wie ein weiterer
   Wert derselben Tankung - sie beschreibt aber die Strecke DAVOR. */
.tank-rechnung {
  display: block;
  margin-top: .1rem;
}

/* Werkzeuge (Auswahlliste, Schaltflaechen) rutschen ans Ende der Zeile und
   bleiben beieinander - auf einem schmalen Fenster fallen sie geschlossen
   in die naechste Zeile statt einzeln zu zerfasern. */
.stopp-werkzeug {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .35rem;
  margin-left: auto;
}

/* Formulare in der Werkzeugleiste sind EINZEILIG, und ihre Auswahlliste
   nimmt nicht die volle Breite.

   Die Grundregel weiter oben setzt `select { width: 100% }` - richtig fuer
   ein Formular, falsch fuer eine Schaltflaechenreihe: Die Liste sprengte die
   Zeile, und "Umhaengen" rutschte darunter. Nachgemessen bei 785 und
   1400 Punkten. */
.stopp-werkzeug .mini-formular {
  margin-top: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .3rem;
}
.stopp-werkzeug select { width: auto; max-width: 13rem; }

/* DAS ZEICHEN IST ZUGABE, NICHT DIE AUSKUNFT. Neben dem Pfeil steht immer
   das Wort - wer Pfeilrichtungen oder Farben schlecht unterscheidet, weiss
   genauso viel. Dieselbe Ueberlegung wie beim Pruefbericht der pc-app, wo
   neben jedem Balken die Bitzahl im Klartext steht. */
.stopp-richtung {
  display: inline-block;
  border-radius: 999px;
  border: 1px solid var(--rand-hell);
  background: var(--grund);
  color: var(--text-leise);
  font-size: .72rem;
  padding: .05rem .5rem;
  white-space: nowrap;
}
/* Eine Abholung macht den Laderaum VOLLER statt leerer - der Unterschied,
   an dem die Kapazitaet haengt. Deshalb hebt er sich ab. */
.stopp-richtung.abholung { background: var(--warn-hell); border-color: #fde68a; color: #92400e; }
.stopp-richtung.beides   { background: var(--akzent-hell); border-color: #f0bcbc; color: var(--akzent-tief); }

/* ------------------------------------------------------------------------
   DER STAND EINES STOPPS (2026-09-09)

   Vorgabe: "Auch soll man es in der Uebersicht sehen, zu welcher Adresse
   der Zusteller gerade unterwegs ist und welche erledigt sind. Wie im
   Kalender mit den Symbolen."

   ES STEHT IMMER EIN WORT NEBEN DEM ZEICHEN, und die Farbe ist Zugabe.
   Dieselbe Linie wie bei .stopp-richtung darueber und bei der Legende des
   Balkenrasters: Wer Farben oder Bildzeichen schlecht unterscheidet, liest
   "unterwegs" und weiss genauso viel.
   ------------------------------------------------------------------------ */
.stopp-stand {
  display: inline-block;
  border-radius: 999px;
  border: 1px solid var(--rand-hell);
  background: var(--grund);
  color: var(--text-leise);
  font-size: .72rem;
  font-weight: 600;
  padding: .05rem .5rem;
  white-space: nowrap;
  margin-right: .25rem;
}

/* UNTERWEGS IST DER EINZIGE STAND, DER SICH BEWEGT - und der einzige, den
   der Disponent im Vorbeigehen suchen muss. Deshalb traegt er als einziger
   die Akzentfarbe. */
.stopp-stand.unterwegs {
  background: var(--akzent-hell);
  border-color: #f0bcbc;
  color: var(--akzent-tief);
}
.stopp-stand.fertig   { background: var(--gut-hell); border-color: #bbf7d0; color: var(--gut); }
.stopp-stand.abwesend { background: var(--warn-hell); border-color: #fde68a; color: #92400e; }

/* Ein Stopp, zu dem gerade jemand faehrt, hebt sich von der Liste ab -
   sonst muesste man die Marke suchen. Der Streifen links ist dafuer
   billiger als eine Hintergrundfarbe: Er stoert den Text nicht. */
/* Der Balken, zu dem gerade jemand faehrt. Ein RAHMEN und keine
   Hintergrundfarbe: Die Farbe traegt schon die Richtung (Zustellung,
   Abholung, beides), und zwei Bedeutungen auf einer Flaeche sind keine
   mehr. */
.raster-balken.unterwegs {
  outline: 2px solid var(--akzent);
  outline-offset: 1px;
}

.stopp-liste > li.stopp-unterwegs {
  border-left: 3px solid var(--akzent);
  padding-left: .55rem;
  background: var(--akzent-hell);
}

/* Der Hinweis, dass etwas nicht zusammenpasst - Fenster ausserhalb der
   Tourzeit, Fahrzeug in der Werkstatt, niemand eingeteilt. KEINE Sperre:
   Bei der Zustellung entscheidet ein Mensch, das System informiert ihn. */
.stopp-hinweis {
  display: block;
  font-size: .78rem;
  color: #92400e;
  margin-top: .15rem;
}

/* Eine Tour innerhalb der Fahrzeugkarte. */
.tour-block {
  border: 1px solid var(--rand-hell);
  border-radius: var(--radius);
  padding: .6rem .8rem;
  margin-top: .7rem;
  background: var(--grund);
}
.tour-block > h3 { margin: 0 0 .4rem; font-size: 1rem; }
.tour-block > h3 > span { font-weight: 400; }

/* --------------------------------------------------------------------------
   Zustellung: das Balkenraster der Tagesansicht (Studie 4.5)
   --------------------------------------------------------------------------
   WOZU ES DA IST: Der ganze Grund fuer dieses Modul ist, dass sich
   Zeitfenster ueberschneiden duerfen - vier Adressen 8-10, eine 8-12, zwei
   10-12. In der Liste daneben steht das untereinander und muss im Kopf
   zusammengerechnet werden. Hier sieht man es.

   ==========================================================================
   DIE LAGE DER BALKEN STEHT IN KLASSEN, NICHT IN style-ATTRIBUTEN - und das
   ist die wichtigste Entscheidung an dieser Stelle.

   Erlaubt waeren sie: public/.htaccess setzt style-src 'self' 'unsafe-inline',
   und index.php faerbt damit die Statuskacheln. ABER derselbe Kommentar dort
   sagt ausdruecklich, dass 'unsafe-inline' bei style wieder WEG soll, sobald
   die Statusfarben anders geloest sind.

   Wer das eines Tages aufraeumt, wuerde ein Raster mit style-Attributen
   stillschweigend zerstoeren: Die Balken haetten dann alle dieselbe Lage.
   GENAU DAS IST IM SCHWESTERPROJEKT PASSIERT - dort sahen alle Balken der
   Statistikseite gleich lang aus, und es sah nach Daten aus, nicht nach
   einem Fehler.

   Deshalb sind der Grundwert `left: 0` und `width: 0` und nicht `auto`:
   Fehlt eine Klasse, ist der Balken LEER und damit sichtbar kaputt - statt
   voll und damit wie eine echte Angabe aussehend. Die teure Verwechslung
   soll gar nicht erst moeglich sein.

   Ein Prozent sind bei einem Zehnstundentag rund sechs Minuten - feiner als
   jedes Zeitfenster, das jemand von Hand eintraegt.
   ========================================================================== */

.raster { margin: .6rem 0 .9rem; }

/* Waagrecht rollbar statt gestaucht: Auf einem Telefon sind zehn Stunden auf
   340 Punkten nicht mehr zu treffen. Der Rahmen darin behaelt seine
   Mindestbreite. */
.raster-rollt { overflow-x: auto; }
.raster-innen { min-width: 32rem; }

.raster-leiste {
  position: relative;
  height: 1.1rem;
  border-bottom: 1px solid var(--rand);
  margin-bottom: .25rem;
}
.raster-stunde {
  position: absolute;
  top: 0;
  /* Grundwert 0 aus demselben Grund wie beim Balken: Ohne Lageklasse steht
     die Marke ganz links und faellt auf - statt an einer beliebigen Stelle
     zu stehen und wie eine Angabe auszusehen. */
  left: 0;
  font-size: .68rem;
  color: var(--text-leise);
  font-variant-numeric: tabular-nums;
  /* Die Marke sitzt AUF ihrer Linie, nicht rechts daneben - sonst zeigt die
     8 auf halb neun. Die letzte wuerde dabei rechts hinauslaufen, deshalb
     die Ausnahme darunter. */
  transform: translateX(-50%);
  white-space: nowrap;
}
.raster-stunde:first-child { transform: none; }
.raster-stunde:last-child  { transform: translateX(-100%); }

.raster-tour { margin-bottom: .5rem; }
.raster-tour > h4 {
  margin: 0 0 .2rem;
  font-size: .78rem;
  font-weight: 600;
  color: var(--text-leise);
}

/* Das Band zeigt, WO die Tour liegt. Damit wird der Hinweis "Fenster
   ausserhalb der Tourzeit" sichtbar, statt nur dazustehen. */
.raster-band {
  position: relative;
  height: .35rem;
  /* Sehr hell, damit sich der Tourabschnitt darauf abhebt. Mit
     var(--rand-hell) war der Unterschied zum Band selbst so gering, dass
     eine Tour ueber den ganzen Tag gar nicht zu sehen war. */
  background: var(--grund);
  border-radius: 999px;
  margin-bottom: .2rem;
}
/* EIGENE KLASSE UND KEIN KINDSELEKTOR - und das ist ein behobener Fehler,
   kein Geschmack.

   `.raster-band > span` hat die Spezifitaet (0,1,1), `.bal-b-40` nur (0,1,0).
   Damit gewann die Grundregel, und JEDES Tourband war 0 Punkte breit -
   obwohl die richtige Klasse daranstand.

   AUFGEFALLEN IST ES NUR, WEIL DER GRUNDWERT 0 IST UND NICHT auto. Genau
   dafuer steht er da: Ein Balken ohne Wirkung ist LEER und damit sichtbar
   kaputt. Mit `auto` waeren die Baender ueber die volle Breite gelaufen und
   haetten gemeldet, jede Tour dauere den ganzen Tag - plausibel, falsch und
   von niemandem zu bemerken. Das ist der Fehler, an dem im Schwesterprojekt
   die Statistikbalken haengengeblieben sind.

   MERKE: Jede Regel, die `left` oder `width` eines Rasterteils setzt, muss
   die Spezifitaet (0,1,0) haben und VOR den .bal-*-Klassen stehen. Bei
   gleicher Spezifitaet gewinnt die spaetere - und die .bal-* stehen am Ende
   der Datei. */
.raster-bandteil {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 0;
  background: var(--text-leise);
  border-radius: 999px;
}

.raster-spur {
  position: relative;
  height: 1.45rem;
  margin-bottom: .18rem;
}

.raster-balken {
  position: absolute;
  top: 0;
  bottom: 0;
  /* SIEHE OBEN: 0 und nicht auto. Ein Balken ohne Lageklasse ist leer. */
  left: 0;
  width: 0;
  overflow: hidden;
  display: flex;
  align-items: center;
  padding: 0 .3rem;
  border-radius: 4px;
  border: 1px solid var(--rand);
  background: var(--flaeche);
  color: var(--text);
  font-size: .7rem;
  line-height: 1;
  white-space: nowrap;
  text-decoration: none;
}
.raster-balken:hover { border-color: var(--akzent); }

/* Dieselbe Farbfamilie wie die Etiketten in der Liste darunter - zwei
   Anordnungen derselben Sache sollen nicht verschieden aussehen. */
/* EINE REGEL FUER BALKEN UND LEGENDE. Zwei getrennte Faerbungen fuer
   dieselbe Sache laufen frueher oder spaeter auseinander - und dann erklaert
   die Legende eine Farbe, die es nicht gibt. */
.raster-balken.zustellung, .legende-punkt.zustellung { background: #eef4fb; border-color: #bcd4ea; }
.raster-balken.abholung,   .legende-punkt.abholung   { background: var(--warn-hell); border-color: #fde68a; }
.raster-balken.beides,     .legende-punkt.beides     { background: var(--akzent-hell); border-color: #f0bcbc; }
.raster-balken.fertig      { opacity: .55; }

/* Die noch nicht eingeteilten Stopps - abgesetzt, damit man auf einen Blick
   sieht, WO am Tag sie hinpassen wuerden. */
.raster-offen {
  border-top: 1px dashed var(--rand);
  padding-top: .35rem;
  margin-top: .35rem;
}
/* Damit die Legende zeigt, WOVON sie spricht - ein leeres Feld neben
   "grauer Streifen = Tourzeit" erklaert nichts. */
.legende-punkt.tourzeit { background: var(--text-leise); border-color: var(--text-leise); }

.raster-balken.offen, .legende-punkt.offen {
  background: repeating-linear-gradient(45deg, var(--grund), var(--grund) 4px,
              var(--flaeche) 4px, var(--flaeche) 8px);
  border-style: dashed;
}

/* Der angesprungene Stopp in der Liste darunter. :target braucht kein
   JavaScript - der Balken ist ein Anker, und die Zeile hebt sich hervor. */
.stopp-liste > li:target {
  background: var(--akzent-hell);
  border-radius: 4px;
  box-shadow: 0 0 0 .35rem var(--akzent-hell);
}

/* --------------------------------------------------------------------------
   Lage und Breite in ganzen Prozent.

   ERZEUGT, NICHT VON HAND GESCHRIEBEN (scripts/raster-klassen.php) - und
   deshalb hier am Stueck, damit niemand versucht, dazwischen etwas zu
   pflegen. Wer die Schrittweite aendern will, aendert das Skript.
   -------------------------------------------------------------------------- */
.bal-l-0{left:0} .bal-l-1{left:1%} .bal-l-2{left:2%} .bal-l-3{left:3%} .bal-l-4{left:4%} .bal-l-5{left:5%} .bal-l-6{left:6%} .bal-l-7{left:7%} .bal-l-8{left:8%} .bal-l-9{left:9%}
.bal-l-10{left:10%} .bal-l-11{left:11%} .bal-l-12{left:12%} .bal-l-13{left:13%} .bal-l-14{left:14%} .bal-l-15{left:15%} .bal-l-16{left:16%} .bal-l-17{left:17%} .bal-l-18{left:18%} .bal-l-19{left:19%}
.bal-l-20{left:20%} .bal-l-21{left:21%} .bal-l-22{left:22%} .bal-l-23{left:23%} .bal-l-24{left:24%} .bal-l-25{left:25%} .bal-l-26{left:26%} .bal-l-27{left:27%} .bal-l-28{left:28%} .bal-l-29{left:29%}
.bal-l-30{left:30%} .bal-l-31{left:31%} .bal-l-32{left:32%} .bal-l-33{left:33%} .bal-l-34{left:34%} .bal-l-35{left:35%} .bal-l-36{left:36%} .bal-l-37{left:37%} .bal-l-38{left:38%} .bal-l-39{left:39%}
.bal-l-40{left:40%} .bal-l-41{left:41%} .bal-l-42{left:42%} .bal-l-43{left:43%} .bal-l-44{left:44%} .bal-l-45{left:45%} .bal-l-46{left:46%} .bal-l-47{left:47%} .bal-l-48{left:48%} .bal-l-49{left:49%}
.bal-l-50{left:50%} .bal-l-51{left:51%} .bal-l-52{left:52%} .bal-l-53{left:53%} .bal-l-54{left:54%} .bal-l-55{left:55%} .bal-l-56{left:56%} .bal-l-57{left:57%} .bal-l-58{left:58%} .bal-l-59{left:59%}
.bal-l-60{left:60%} .bal-l-61{left:61%} .bal-l-62{left:62%} .bal-l-63{left:63%} .bal-l-64{left:64%} .bal-l-65{left:65%} .bal-l-66{left:66%} .bal-l-67{left:67%} .bal-l-68{left:68%} .bal-l-69{left:69%}
.bal-l-70{left:70%} .bal-l-71{left:71%} .bal-l-72{left:72%} .bal-l-73{left:73%} .bal-l-74{left:74%} .bal-l-75{left:75%} .bal-l-76{left:76%} .bal-l-77{left:77%} .bal-l-78{left:78%} .bal-l-79{left:79%}
.bal-l-80{left:80%} .bal-l-81{left:81%} .bal-l-82{left:82%} .bal-l-83{left:83%} .bal-l-84{left:84%} .bal-l-85{left:85%} .bal-l-86{left:86%} .bal-l-87{left:87%} .bal-l-88{left:88%} .bal-l-89{left:89%}
.bal-l-90{left:90%} .bal-l-91{left:91%} .bal-l-92{left:92%} .bal-l-93{left:93%} .bal-l-94{left:94%} .bal-l-95{left:95%} .bal-l-96{left:96%} .bal-l-97{left:97%} .bal-l-98{left:98%} .bal-l-99{left:99%}
.bal-l-100{left:100%}

.bal-b-1{width:1%} .bal-b-2{width:2%} .bal-b-3{width:3%} .bal-b-4{width:4%} .bal-b-5{width:5%} .bal-b-6{width:6%} .bal-b-7{width:7%} .bal-b-8{width:8%} .bal-b-9{width:9%} .bal-b-10{width:10%}
.bal-b-11{width:11%} .bal-b-12{width:12%} .bal-b-13{width:13%} .bal-b-14{width:14%} .bal-b-15{width:15%} .bal-b-16{width:16%} .bal-b-17{width:17%} .bal-b-18{width:18%} .bal-b-19{width:19%} .bal-b-20{width:20%}
.bal-b-21{width:21%} .bal-b-22{width:22%} .bal-b-23{width:23%} .bal-b-24{width:24%} .bal-b-25{width:25%} .bal-b-26{width:26%} .bal-b-27{width:27%} .bal-b-28{width:28%} .bal-b-29{width:29%} .bal-b-30{width:30%}
.bal-b-31{width:31%} .bal-b-32{width:32%} .bal-b-33{width:33%} .bal-b-34{width:34%} .bal-b-35{width:35%} .bal-b-36{width:36%} .bal-b-37{width:37%} .bal-b-38{width:38%} .bal-b-39{width:39%} .bal-b-40{width:40%}
.bal-b-41{width:41%} .bal-b-42{width:42%} .bal-b-43{width:43%} .bal-b-44{width:44%} .bal-b-45{width:45%} .bal-b-46{width:46%} .bal-b-47{width:47%} .bal-b-48{width:48%} .bal-b-49{width:49%} .bal-b-50{width:50%}
.bal-b-51{width:51%} .bal-b-52{width:52%} .bal-b-53{width:53%} .bal-b-54{width:54%} .bal-b-55{width:55%} .bal-b-56{width:56%} .bal-b-57{width:57%} .bal-b-58{width:58%} .bal-b-59{width:59%} .bal-b-60{width:60%}
.bal-b-61{width:61%} .bal-b-62{width:62%} .bal-b-63{width:63%} .bal-b-64{width:64%} .bal-b-65{width:65%} .bal-b-66{width:66%} .bal-b-67{width:67%} .bal-b-68{width:68%} .bal-b-69{width:69%} .bal-b-70{width:70%}
.bal-b-71{width:71%} .bal-b-72{width:72%} .bal-b-73{width:73%} .bal-b-74{width:74%} .bal-b-75{width:75%} .bal-b-76{width:76%} .bal-b-77{width:77%} .bal-b-78{width:78%} .bal-b-79{width:79%} .bal-b-80{width:80%}
.bal-b-81{width:81%} .bal-b-82{width:82%} .bal-b-83{width:83%} .bal-b-84{width:84%} .bal-b-85{width:85%} .bal-b-86{width:86%} .bal-b-87{width:87%} .bal-b-88{width:88%} .bal-b-89{width:89%} .bal-b-90{width:90%}
.bal-b-91{width:91%} .bal-b-92{width:92%} .bal-b-93{width:93%} .bal-b-94{width:94%} .bal-b-95{width:95%} .bal-b-96{width:96%} .bal-b-97{width:97%} .bal-b-98{width:98%} .bal-b-99{width:99%} .bal-b-100{width:100%}

/* --------------------------------------------------------------------------
   Zustellung: die Wochenuebersicht (Studie 4.5)
   --------------------------------------------------------------------------
   Die Tabellengrundlage teilt sie sich mit dem Dienstplan (siehe dort). Was
   hier steht, ist nur die Zelle selbst.

   KEINE AMPEL, KEINE EINFAERBUNG NACH AUSLASTUNG - und das ist eine
   Entscheidung, keine Luecke: Was auf eine Tour passt, ist Freitext
   (kapazitaet_hinweis), keine Zahl. Eine Ampel daraus zu bauen hiesse, eine
   Obergrenze zu erfinden, die es bewusst nicht gibt. Die Studie sagt dazu:
   "Eine erzwungene Obergrenze waere eine Regel, die er im Zweifel taeglich
   uebergehen muesste - und uebergangene Regeln werden bald gar nicht mehr
   gelesen."
   -------------------------------------------------------------------------- */

/* DIE FAHRZEUGSPALTE BRICHT UM - im Gegensatz zum Dienstplan, der sich die
   Grundregeln mit dieser Tabelle teilt.

   Dort stehen Personennamen ("Markus Gspandl"), hier ganze Bezeichnungen mit
   Kennzeichen ("Fernwagen (GU-456CD)"). Mit dem geerbten `white-space:
   nowrap` nahm die erste Spalte auf einem Telefon fast den ganzen Bildschirm
   und liess zwei Tage uebrig - bei 375 Punkten nachgemessen.

   Genau dafuer traegt diese Tabelle einen EIGENEN Namen und benutzt nicht
   einfach .dienstplan mit: So laesst sich abweichen, ohne den Dienstplan
   anzufassen. */
.wochen-tabelle tbody th,
.wochen-tabelle tfoot th { white-space: normal; max-width: 11rem; }

.wochen-tabelle td { text-align: center; }
.wochen-tabelle thead th a { color: inherit; text-decoration: none; }
.wochen-tabelle thead th a:hover { color: var(--akzent-tief); }

.woche-zahl {
  display: block;
  font-size: 1.35rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
  color: var(--text);
  text-decoration: none;
}
a.woche-zahl:hover { color: var(--akzent-tief); }

/* Noch nicht eingeteilt ist die dringende Zahl - ein Tag mit 20 geplanten
   Stopps ist fertig, ein Tag mit 3 offenen ist Arbeit. */
.woche-offen { color: var(--akzent-tief); }

.woche-klein {
  display: block;
  font-size: .7rem;
  color: var(--text-leise);
  line-height: 1.25;
  margin-top: .1rem;
}

/* "-" heisst NICHT "null", sondern "diesen Fahrzeugtag hat noch niemand
   geoeffnet". Deshalb blass und nicht als Zahl gesetzt - der Unterschied
   muss man sehen, ohne den Hinweistext darunter gelesen zu haben. */
.woche-leer {
  display: block;
  font-size: 1.1rem;
  color: var(--rand);
  text-decoration: none;
}
a.woche-leer:hover { color: var(--text-leise); }

/* ==========================================================================
   Zu entscheiden (Kopplung, Studie 6.9)
   ========================================================================== */

.anfrage-liste { list-style: none; margin: 0; padding: 0; }

.anfrage {
  border: 1px solid var(--rand);
  border-radius: var(--radius);
  padding: .8rem 1rem;
  margin-bottom: .9rem;
  background: var(--flaeche);
}

/* DER ROTE RAND HAENGT AM TERMIN, NICHT AM EINGANG. Eine Bitte fuer morgen
   frueh ist dringend, auch wenn sie eben erst kam - genau das ist die
   Reihenfolge, in der die Liste ohnehin sortiert. */
.anfrage.dringend { border-left: 4px solid var(--akzent-tief); }

.anfrage-kopf {
  display: flex;
  align-items: center;
  gap: .5rem;
  flex-wrap: wrap;
  margin-bottom: .35rem;
}

/* Entschiedenes bleibt lesbar, tritt aber zurueck - es steht da, damit man
   nachlesen kann, wie etwas ausgegangen ist, nicht um zu handeln. */
.anfrage-liste.leise .anfrage {
  background: none;
  border-style: dashed;
  padding: .5rem .8rem;
}
.anfrage.erledigt p { margin: .2rem 0; }

/* Am Handy stehen die beiden Antworten untereinander. Nebeneinander sind sie
   dort so schmal, dass man beim Scrollen die falsche trifft - und eine
   versehentlich uebernommene Verschiebung ist ein verpasster Termin. */
@media (max-width: 560px) {
  .anfrage .knopf-reihe { flex-direction: column; align-items: stretch; }
}

/* --------------------------------------------------------------------------
   Die Glocke in der Kopfzeile (2.10.0.0)
   --------------------------------------------------------------------------
   Aufgeklappt wird mit <details> - kein Skript, wie beim Hamburger-Menue und
   aus demselben Grund: Die Inhaltsrichtlinie laesst kein Inline-Skript zu,
   und eine Seite, die ohne JavaScript nicht bedienbar ist, waere hier keine
   unbequeme, sondern eine kaputte.

   Die Liste liegt ABSOLUT ueber dem Inhalt. Im Fluss wuerde sie die
   Kopfzeile auseinanderschieben, und die Seite ruckte bei jedem Aufklappen.
   -------------------------------------------------------------------------- */
.glocke { position: relative; margin-left: auto; }
/* Steht die Glocke da, schiebt SIE den Block nach rechts - nicht der Name.
   Sonst haetten beide `margin-left: auto` und teilten den Platz auf. */
.glocke + .wer { margin-left: 0; }

.glocke > summary {
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  width: 44px;
  height: 44px;
  border: 1px solid var(--rand);
  border-radius: var(--radius);
  color: var(--text-leise);
  cursor: pointer;
  list-style: none;
}
.glocke > summary::before { content: none; }   /* kein Dreieck wie sonst */
.glocke > summary:hover { background: var(--grund); color: var(--text); }

/* Die Zahl sitzt AM Symbol, nicht daneben: Sie gehoert dazu und soll die
   Zeilenbreite nicht veraendern, wenn sie von 9 auf 10 springt. */
.glocke-zahl {
  position: absolute;
  top: -6px;
  right: -6px;
  min-width: 18px;
  padding: 0 4px;
  border-radius: 9px;
  background: var(--akzent);
  color: #fff;
  font-size: .7rem;
  font-weight: 700;
  line-height: 18px;
  text-align: center;
}

.glocke-liste {
  position: absolute;
  right: 0;
  top: calc(100% + .4rem);
  z-index: 30;
  width: min(22rem, calc(100vw - 2rem));
  max-height: 70vh;
  overflow-y: auto;
  background: var(--flaeche);
  border: 1px solid var(--rand);
  border-radius: var(--radius);
  box-shadow: 0 6px 20px rgba(0, 0, 0, .12);
  padding: .3rem;
  text-align: left;
}

.glocke-zeile { margin: 0; }
.glocke-knopf {
  display: block;
  width: 100%;
  background: none;
  border: 0;
  border-radius: var(--radius);
  padding: .5rem;
  text-align: left;
  font: inherit;
  color: var(--text);
  cursor: pointer;
}
.glocke-knopf:hover { background: var(--grund); }
.glocke-text { display: block; line-height: 1.3; }
.glocke-zeit { display: block; font-size: .75rem; color: var(--text-leise); }
.glocke-leer { padding: .5rem; margin: 0; }
.glocke-alle { border-top: 1px solid var(--rand); margin: .3rem 0 0; padding: .4rem .5rem 0; }

/* AM HANDY MITTIG AM BILDSCHIRM (2.17.0.1, Nutzermeldung). Die Liste hing mit
   `right: 0` an der Glocke - und die steht dort weit links vom Rand, also ragte
   die 22rem breite Blase links aus dem Bild.

   DER KNIFF IST DER BEZUGSRAHMEN, nicht eine feste Zahl: Wird die Glocke
   `static`, sucht sich die absolut gesetzte Liste den naechsten positionierten
   Vorfahren - das ist .kopf (`position: sticky`), und der ist so breit wie der
   Bildschirm. `left: 50%` + `translateX(-50%)` zentriert dann am Bildschirm,
   `top: 100%` setzt sie unter die ganze Kopfzeile. Eine feste Hoehe waere bei
   jedem Umbruch der Kopfzeile falsch.

   40rem wie die uebrigen Handy-Regeln der Kopfzeile. */
@media (max-width: 40rem) {
  .glocke { position: static; }
  .glocke-liste {
    left: 50%;
    right: auto;
    transform: translateX(-50%);
  }
}

/* Nur fuer Vorlesewerkzeuge: In der Tabelle sagt die Spaltenueberschrift, was
   das Kaestchen bedeutet - ohne sie stuende dort dreissigmal "Kaestchen". */
.nur-vorlesen {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.melde-tabelle { width: 100%; border-collapse: collapse; }
.melde-tabelle th, .melde-tabelle td { padding: .35rem .5rem; text-align: left; }
.melde-tabelle thead th { font-size: .8rem; color: var(--text-leise); }
.melde-tabelle tbody tr { border-top: 1px solid var(--rand); }
.melde-tabelle tbody th { font-weight: 400; }
.melde-tabelle td { width: 4.5rem; text-align: center; }
.melde-tabelle .haken { justify-content: center; margin: 0; }

/* Die Seite mit allen Benachrichtigungen (2.10.1.0). Dieselben Bausteine wie
   im Aufklappmenue - eine Zeile ist ein Knopf (offen) oder ein Link
   (gelesen), beide sehen gleich aus. */
/* --------------------------------------------------------------------------
   Zwei-Faktor-Anmeldung (2.21.0.0)

   Die Ersatzcodes stehen in Festbreite und gross genug zum Abschreiben - sie
   werden von Hand auf Papier uebertragen, und g/9 oder m/rn duerfen dabei
   nicht zur Ratefrage werden. Das Alphabet laesst l, o, 0 und 1 ohnehin weg.
   -------------------------------------------------------------------------- */
.ersatzcodes {
  list-style: none;
  margin: .6rem 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
  gap: .4rem;
}
.ersatzcodes code {
  display: block;
  padding: .35rem .5rem;
  font-size: 1.05rem;
  letter-spacing: .06em;
  text-align: center;
}

code.gross {
  display: inline-block;
  padding: .4rem .6rem;
  font-size: 1.15rem;
  letter-spacing: .12em;
  word-break: break-all;
}

.geraeteliste { list-style: none; margin: .5rem 0; padding: 0; }
.geraeteliste > li {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: .3rem;
  padding: .4rem 0;
  border-top: 1px solid var(--rand);
}
.geraeteliste > li:first-child { border-top: 0; }
.geraeteliste .klein { color: var(--text-leise); }

.hinweis-werkzeuge { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; }
.hinweis-werkzeuge .verweis-knopf.an { color: var(--text); font-weight: 600; }
.hinweis-werkzeuge .inline-form { margin: 0; }

.hinweis-liste { list-style: none; margin: .5rem 0 0; padding: 0; }
.hinweis-liste > li { border-top: 1px solid var(--rand); }
.hinweis-liste > li:first-child { border-top: 0; }
.hinweis-liste form { margin: 0; }

.hinweis-knopf {
  display: block;
  width: 100%;
  background: none;
  border: 0;
  border-radius: var(--radius);
  padding: .6rem .5rem;
  text-align: left;
  font: inherit;
  color: var(--text);
  text-decoration: none;
  cursor: pointer;
}
.hinweis-knopf:hover { background: var(--grund); }
/* Gelesene treten zurueck, ohne zu verschwinden: Es geht um "was war",
   nicht um "was ist offen". */
.hinweis-liste > li:not(.neu) .hinweis-text { color: var(--text-leise); }
.hinweis-text { display: block; line-height: 1.35; }
.hinweis-zeit {
  display: block;
  margin-top: .15rem;
  font-size: .75rem;
  color: var(--text-leise);
}

/* --------------------------------------------------------------------------
   Lizenz (2.17.0.0)
   --------------------------------------------------------------------------
   Der Balken steht VOR main.inhalt und traegt bewusst NICHT .meldung.fehler:
   app.js macht jede `main.inhalt > .meldung.fehler` zu einem Fenster, das man
   wegklicken muss - auf jeder Seite waere das eine Plage.
   -------------------------------------------------------------------------- */
.lizenz-balken {
  background: var(--schlecht);
  color: #fff;
  padding: .55rem 1rem;
  font-size: .95rem;
  text-align: center;
}
.lizenz-balken + .lizenz-balken { border-top: 1px solid rgba(255, 255, 255, .35); }
.lizenz-balken a { color: #fff; font-weight: 600; text-decoration: underline; white-space: nowrap; }

.lizenz-zustand {
  display: inline-block;
  padding: .15rem .6rem;
  border-radius: 999px;
  font-size: .85rem;
  font-weight: 600;
}
.lizenz-zustand.aktiv    { background: var(--gut-hell); color: var(--gut); }
.lizenz-zustand.lesen    { background: var(--warn-hell); color: var(--intern); }
.lizenz-zustand.gesperrt { background: var(--schlecht-hell); color: var(--schlecht); }

/* --------------------------------------------------------------------------
   Posteingang (Modul Maileingang, 2.19.0.0)
   -------------------------------------------------------------------------- */
.posteingang-reiter { display: flex; flex-wrap: wrap; gap: .5rem; margin: 0 0 1rem; }
.posteingang-liste { list-style: none; margin: 0; padding: 0; }
.posteingang-liste li + li { border-top: 1px solid var(--rand); }
.posteingang-liste a {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: .15rem 1rem;
  padding: .7rem .2rem;
  color: var(--text);
  text-decoration: none;
}
.posteingang-liste a:hover { background: var(--grund); }
.posteingang-von { font-weight: 600; overflow-wrap: anywhere; }
.posteingang-zeit { color: var(--text-leise); font-size: .85rem; white-space: nowrap; }
.posteingang-betreff { grid-column: 1 / -1; overflow-wrap: anywhere; }
.posteingang-marke {
  display: inline-block;
  margin-left: .4rem;
  padding: 0 .45rem;
  border-radius: 999px;
  background: var(--warn-hell);
  color: var(--intern);
  font-size: .75rem;
  font-weight: 600;
}
.mail-text {
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  font: inherit;
  margin: 0;
  max-height: 60vh;
  overflow-y: auto;
}

/* ---------------------------------------------------------------------
   Folgeticket (2.24.0.0): der Weg aus einem Ticket in ein neues, und die
   Liste der Aufgaben, die dabei mitgenommen werden.

   Die Liste steht bewusst ausgeschrieben da und nicht nur als Zahl - wer
   den Haken stehen lässt, soll vorher sehen, was gleich im neuen Ticket
   steht.
--------------------------------------------------------------------- */
.ticket-folge {
  margin: .9rem 0 0;
}
.vorlage-todos {
  margin: .3rem 0 .9rem 1.3rem;
  padding: 0;
}
.vorlage-todos li {
  margin: .15rem 0;
}

/* --------------------------------------------------------------------------
   Verwaltung -> Mobil (ab 2.25.0.0)

   Zwei kleine Regeln, mehr braucht die Seite nicht - Karten, Listen, Marken
   und Knoepfe kommen unveraendert von oben. Die Gestaltung der mobilen
   Fassung selbst steht in assets/mobil.css und wird NUR dort geladen; sie hat
   hier nichts verloren.
   -------------------------------------------------------------------------- */

/* Eine Zeile der Mitarbeiterliste: links Name und Zustand, rechts die
   Schaltflaechen. Bewusst KEIN <details> wie bei den Geraeten - es gibt
   nichts aufzuklappen, und ein Klappfach, in dem nur drei Knoepfe stehen,
   ist ein Klick zu viel. */
.zeile-mit-knoepfen {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .4rem .8rem;
  padding: .5rem .2rem;
}

.zeile-mit-knoepfen > div:first-child {
  flex: 1 1 14rem;
  min-width: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .3rem .6rem;
}

/* DER GERAETESCHLUESSEL STEHT GENAU EINMAL AUF DEM BILDSCHIRM - deshalb gross,
   gesperrt und in einer Schrift, in der 0 und O, 1 und l zu unterscheiden
   sind. Er wird abgetippt, nicht kopiert: Der Rechner, der ihn anzeigt, ist
   nicht das Telefon, das ihn braucht. */
.mobil-schluessel-anzeige {
  margin: .6rem 0;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 1.4rem;
  letter-spacing: .15em;
  word-break: break-all;
  -webkit-user-select: all;
  user-select: all;      /* ein Klick markiert alles - falls doch kopiert wird */
}

/* ==========================================================================
   Arbeitszeit (2.26.0.0)
   ========================================================================== */

/* Die vier Stempelknöpfe. Nebeneinander, solange Platz ist, danach
   untereinander - auf dem Telefon wird hier mit dem Daumen gedrückt. */
.az-knoepfe {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
  margin-top: .75rem;
}
.az-knoepfe .knopf { min-height: 2.75rem; }

.az-auswahl {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: .75rem;
  margin-bottom: .75rem;
}
.az-auswahl label { display: block; }
.az-auswahl select, .az-auswahl input { min-width: 0; }

.az-blaettern {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: .5rem;
  margin: .25rem 0 .75rem;
}

/* Die Tabelle selbst. `.tabelle` allein bringt keine Formatierung mit -
   sie ist nur der Haken für `.tabelle-rollt > .tabelle`. Deshalb hier
   dieselben Werte wie bei `.wochen-tabelle`, statt jene mitzubenutzen:
   Die ist auf gleich breite Wochentagsspalten ausgelegt und zentriert alles,
   was in einer Zeitliste falsch wäre. */
/* DIESE DREI REGELN SIND GENERISCH, nur ihr Name ist alt: Das Lenkprotokoll
   (.lp-tabelle) und der Arbeitszeitbericht teilen sie. Sie zu kopieren waere
   die zweite Fassung derselben Gestaltung - und dann sehen zwei Tabellen im
   selben Programm verschieden aus, ohne dass jemand es wollte. */
.az-tabelle, .lp-tabelle { min-width: 40rem; width: 100%; border-collapse: collapse; }
.az-tabelle th, .az-tabelle td,
.lp-tabelle th, .lp-tabelle td {
  border: 1px solid var(--rand-hell);
  padding: .35rem .5rem;
  vertical-align: top;
}
.az-tabelle thead th, .az-tabelle tfoot th,
.lp-tabelle thead th, .lp-tabelle tfoot th {
  background: var(--grund);
  text-align: left;
  font-size: .85rem;
}

/* Zahlen rechtsbündig - untereinander stehende Stunden lassen sich sonst
   nicht vergleichen. Tabellenziffern, damit die Spalten nicht wandern.

   DER NAME TAEUSCHT: `az-r` gehoert nicht zur Arbeitszeit, sondern ist die
   Zahlenspalte ueberhaupt - das Lenkprotokoll benutzt sie mit. Wer sie
   umbenennt, muss beide Seiten mitnehmen. */
.az-r {
  text-align: right;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.az-dienst { display: inline-block; margin-right: .4rem; white-space: nowrap; }

/* Ein Tag ohne Soll soll nicht aussehen wie ein Versäumnis. */
.az-frei td, .az-feiertag td { background: var(--grund); color: var(--text-leise); }
.az-heute td { box-shadow: inset 0 3px 0 var(--akzent); }

/* DIE FARBE IST ZUGABE, NICHT DIE AUSKUNFT: Daneben steht die Zahl mit
   Vorzeichen. Wer Farben schlecht unterscheidet, weiß genauso viel. */
.az-minus { color: var(--schlecht); }
.az-plus  { color: var(--gut); }

/* Ein Eingabefeld für eine kurze Zahl - "38,5" braucht keine 700 Punkte.
   Über die ganze Breite sieht es aus, als erwarte es einen Satz. */
.feld-kurz input { max-width: 9rem; }


/* --------------------------------------------------------------------------
   Die ausklappbare Tageszeile (2.38.0.0)

   AUFGEKLAPPT WIRD OHNE JAVASCRIPT: Der Tag ist ein Link auf die Kennung der
   Detailzeile, und `:target` zeigt sie. Der strenge CSP dieser Anwendung
   verwirft Ereignisattribute still - ein `onclick` hätte nichts getan, und
   zwar ohne Fehlermeldung.

   <details> ginge hier nicht: Es darf laut HTML kein <tr> enthalten, und eine
   Detailansicht in EINER Zelle wäre bei sieben Spalten unbenutzbar eng.

   VORGABE IST `display: none`, nicht etwa eine Höhe von null: Bleibt die
   Regel einmal aus, ist die Zeile SICHTBAR und damit offensichtlich kaputt -
   statt unsichtbar und scheinbar in Ordnung. Dieselbe Überlegung wie bei den
   Balken der Statistikseite im Schwesterprojekt, wo ein fehlerhafter Balken
   voll aussah und deshalb wie echte Daten.
   -------------------------------------------------------------------------- */
.az-detail { display: none; }
.az-detail:target { display: table-row; }

.az-detail > td {
  background: var(--grund);
  border-top: 2px solid var(--akzent);
  padding: .8rem 1rem 1rem;
}

.az-tag-link { color: inherit; text-decoration: none; border-bottom: 1px dotted var(--rand); }
.az-tag-link:hover { color: var(--akzent-tief); border-bottom-color: var(--akzent); }

.az-detail-kopf {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: .6rem;
  margin-bottom: .6rem;
}
.az-detail-kopf .klein { color: var(--text-leise); }
/* Das Zuklappen ganz rechts - dorthin greift niemand versehentlich, während
   er die Zeiten liest. */
.az-zu { margin-left: auto; font-size: .85em; }

.az-satz {
  background: var(--flaeche);
  border: 1px solid var(--rand-hell);
  border-radius: var(--radius);
  padding: .6rem .8rem;
  margin-bottom: .6rem;
}
.az-satz-kopf { margin: 0 0 .4rem; }

/* Eine Marke ist ein Hinweis, kein Alarm - deshalb keine Signalfarbe für das
   Stiftsymbol. Das automatische Dienstende dagegen IST einer: Dort fehlt eine
   Angabe, und das soll auffallen. */
.az-marke {
  display: inline-block; font-size: .8em; padding: 0 .35rem;
  border: 1px solid var(--rand); border-radius: 4px; color: var(--text-leise);
  white-space: nowrap;
}
.az-marke-auto { border-color: var(--intern); color: var(--intern); background: var(--warn-hell); }

/* DIE ROTE ZEILE (2.39.0.0): Tagesarbeitszeit über sechs Stunden ohne die
   vorgeschriebene Pause, oder über zehn Stunden insgesamt. Sie steht in JEDER
   Ansicht und nicht nur beim Monatsabschluss - wer den Monat durchsieht, soll
   die Tage finden, ohne erst abschließen zu wollen.

   DIE FARBE IST ZUGABE, NICHT DIE AUSKUNFT: Daneben steht eine Marke mit Text
   ("⚠ Pause", "⚠ 10 h") und im aufgeklappten Tag der ausgeschriebene Befund.
   Wer Farben schlecht unterscheidet, weiß genauso viel - dieselbe Regel wie
   bei .az-minus und .az-plus weiter oben. */
.az-azg td { background: var(--schlecht-hell); }
.az-frei.az-azg td, .az-feiertag.az-azg td { background: var(--schlecht-hell); }
/* Beide Befunde an einem Tag: Rot gewinnt über die Gelbmarkierung des
   fehlenden Dienstendes - eine überschrittene Grenze wiegt schwerer als eine
   fehlende Angabe. Deshalb steht diese Regel NACH .az-auto. */
.az-auto.az-azg td { background: var(--schlecht-hell); }
.az-marke-azg { border-color: var(--schlecht); color: var(--schlecht); background: var(--schlecht-hell); }

.az-pausen { margin: .3rem 0 .4rem; padding-left: 1.1rem; }
.az-pausen li { margin: .1rem 0; }
.az-nicht-anrechenbar { color: var(--text-leise); font-style: italic; }
.az-auto td { background: var(--warn-hell); }
/* Wochenende und Feiertag gewinnen NICHT über das fehlende Dienstende - eine
   Lücke an einem Samstag ist genauso eine Lücke. Deshalb steht diese Regel
   nach .az-frei und .az-feiertag. */
.az-frei.az-auto td, .az-feiertag.az-auto td { background: var(--warn-hell); }

.az-korrektur {
  display: flex; flex-wrap: wrap; gap: .5rem .8rem; align-items: flex-end;
  margin: .5rem 0 0;
}
.az-korrektur label { display: flex; flex-direction: column; gap: .15rem; }
/* Die BESCHRIFTUNG wird über die Klasse angesprochen, nicht über `label >
   span` allein - genau dieser Griff hat im Schwesterprojekt die Schriftgröße
   der Eingabefelder mitgenommen und sie sichtbar schrumpfen lassen. */
.az-korrektur label > span { font-size: .8em; color: var(--text-leise); }
.az-korrektur input[type="number"] { width: 6rem; }
.az-korrektur .az-weit { flex: 1 1 14rem; }
.az-korrektur .az-weit input { width: 100%; }
.az-neu { border-top: 1px dashed var(--rand); padding-top: .6rem; margin-top: .2rem; }

.az-gesperrt { color: var(--text-leise); font-style: italic; margin: .4rem 0 0; }

.az-prot { margin: .5rem 0 0; padding-left: 1.1rem; color: var(--text-leise); }
.az-prot li { margin: .1rem 0; }

.az-abschluss {
  display: flex; flex-wrap: wrap; align-items: center; gap: .6rem 1rem;
  margin-top: 1rem; padding: .7rem .9rem;
  border: 1px solid var(--rand); border-radius: var(--radius);
  background: var(--flaeche);
}
.az-abschluss p { margin: 0; }
.az-abschluss-zu { border-color: var(--gut); background: var(--gut-hell); }
/* Die Rückfrage vor dem Abschluss - sie WARNT, sie sperrt nicht. Deshalb der
   gelbe Rahmen und nicht der rote der Fehlermeldungen. */
.az-abschluss-warnung { border-color: var(--intern); background: var(--warn-hell); display: block; }
.az-befunde { margin: .4rem 0 .6rem; padding-left: 1.2rem; }
.az-abschluss-warnung .inline-form { display: inline; }
.az-auf { margin-left: auto; }
.az-auf input[type="text"] { width: 16rem; max-width: 100%; }

.az-prot-monat { margin-top: 1rem; }
.az-prot-monat summary { cursor: pointer; color: var(--text-leise); }

/* Ein deaktivierter Knopf ist hier ein <span>: Ein <button disabled> gibt in
   den meisten Browsern KEINEN Tooltip aus - und der Grund, warum das PDF noch
   nicht geht, ist das Einzige, was an dieser Stelle weiterhilft. Dieselbe
   Entscheidung wie bei .einsatz-knopf.deaktiviert. */
.knopf.deaktiviert {
  background: var(--grund); color: var(--text-leise);
  border-color: var(--rand-hell); cursor: not-allowed;
}
.knopf.deaktiviert:hover { background: var(--grund); color: var(--text-leise); }

@media (max-width: 640px) {
  /* Auf dem Telefon untereinander - drei Zeitfelder nebeneinander sind dort
     je 6 Zeichen breit und damit unbedienbar.

     MIT HOECHSTBREITE, und die ist nicht Kosmetik: Die Detailzelle ist so
     breit wie die TABELLE, und die ist auf einem schmalen Bildschirm breiter
     als das Fenster (sie rollt in ihrem eigenen Rahmen). Ohne Deckel nehmen
     die Felder diese Breite an und stehen zur Haelfte ausserhalb des
     Sichtbaren - im Browser bei 620px nachgemessen: Feld 578 Punkte breit,
     Fenster 620, Tabelle 640. */
  /* SPALTE STATT UMBRUCH. Mit `flex-wrap` und einer Hoechstbreite passen
     zwei Felder in die Zelle - die ist naemlich so breit wie die TABELLE und
     damit breiter als das Fenster, und das zweite Feld steht dann ausserhalb
     des Sichtbaren. `flex-direction: column` kennt dieses Problem nicht:
     Untereinander gibt es keine zweite Spalte, in die etwas rutschen koennte.
     Bei 620px nachgemessen - Feld 288 Punkte, rechte Kante bei 352 von 620. */
  .az-korrektur { flex-direction: column; align-items: stretch; }
  .az-korrektur label, .az-korrektur .az-weit { flex: 0 0 auto; max-width: 18rem; }
  .az-korrektur input { max-width: 18rem; }
  .az-korrektur button { align-self: flex-start; }
  .az-auf { margin-left: 0; }
}

/* ==========================================================================
   Hilfe (2.29.0.0)
   ========================================================================== */

/* Jeder Abschnitt ist eine aufklappbare Karte. Die Überschrift steckt IM
   <summary>, damit die ganze Zeile anklickbar ist und Vorlesewerkzeuge die
   Gliederung mitbekommen - eine <h2> daneben wäre für sie ein zweites,
   unverbundenes Ding. */
.hilfe > details > summary {
  cursor: pointer;
  list-style: none;
  display: flex;
  align-items: center;
  gap: .5rem;
}
.hilfe > details > summary::-webkit-details-marker { display: none; }
.hilfe > details > summary h2 { margin: 0; font-size: 1.05rem; }

/* Ein eigenes Dreieck statt des eingebauten: Das voreingestellte sitzt je
   nach Browser woanders, und mit `display: flex` verschwindet es ganz. */
.hilfe > details > summary::before {
  content: "▸";
  color: var(--akzent);
  font-size: 1.1rem;
  line-height: 1;
  flex: 0 0 auto;
}
.hilfe > details[open] > summary::before { content: "▾"; }

.hilfe > details > summary:hover h2 { color: var(--akzent-tief); }
.hilfe > details > *:not(summary) { margin-top: .6rem; }
.hilfe ol, .hilfe ul { margin: .4rem 0 0; padding-left: 1.2rem; }
.hilfe li { margin-bottom: .35rem; }

/* --------------------------------------------------------------------------
 * ANFAHRT ABBRECHEN am Ticket (2.30.0.0). Zugeklappt eine unscheinbare
 * Zeile, aufgeklappt das Pflichtfeld fuer den Grund - siehe mobil.css.
 */
.zeit-abbruch { margin: -.4rem 0 .8rem; }
.zeit-abbruch > summary { cursor: pointer; color: var(--text-leise); }
.zeit-abbruch > form {
  margin: .5rem 0 0;
  padding: .6rem;
  border: 1px solid var(--rand);
  border-radius: var(--radius);
  max-width: 34rem;
}

/* Der Grund, warum die Anfahrt gerade nicht geht - unter dem grauen Knopf
   (2.31.0.2). Siehe stopp_anfahrt_sperre()/zeit_anfahrt_sperre(). */
.anfahrt-sperre { margin: .3rem 0 0; color: var(--intern); max-width: 26rem; }

/* ==========================================================================
   Lenkprotokoll (2.41.0.0)
   ========================================================================== */

/* DIE FARBEN KOMMEN AUS DEN VARIABLEN, keine eigenen Werte: Bei einem
   Farbwechsel muesste man sie sonst hier vergessen - und zwei Rottoene
   nebeneinander sehen nach einem Fehler aus. */

/* NICHT ALLE SPALTEN OHNE UMBRUCH: Der erste Entwurf setzte `nowrap` auf
   jede Zelle, und die Fahrzeugspalte schob dadurch die Spalte „Stand" - also
   den wichtigsten Wert der Zeile - aus dem Sichtfeld. Im Browser gesehen, am
   Code nicht. Die Zahlen bleiben ungebrochen, das Fahrzeug darf umbrechen. */
.lp-tabelle th { white-space: nowrap; }
.lp-tabelle td { white-space: normal; }
.lp-tabelle .az-r { white-space: nowrap; }

/* Ein Tag ohne Fahrtaetigkeit tritt zurueck, verschwindet aber NICHT: Eine
   Luecke in der Woche liest sich wie ein fehlender Tag, und genau das soll ein
   Protokoll nicht. */
.lp-tabelle tr.lp-leer td { color: var(--text-leise); }

/* Ein unterschriebener Tag, dessen Zahlen sich danach geaendert haben. Rot,
   weil es bei einer Kontrolle erklaert werden muss. */
.lp-tabelle tr.lp-abweichung td { background: var(--schlecht-hell); }
.lp-tabelle tr.lp-abweichung strong { color: var(--schlecht); }

.lp-fahrzeug { display: inline-block; margin-right: 0.6em; }
.lp-fahrzeug:last-child { margin-right: 0; }

/* „max" hinter einer Lenkzeit, die aus Zustellstopps stammt und damit eine
   Obergrenze ist. Klein und leise - es ist ein Vorbehalt, keine Warnung. */
.lp-marke {
  display: inline-block;
  margin-left: 0.35em;
  padding: 0 0.35em;
  border: 1px solid var(--rand);
  border-radius: 3px;
  background: var(--grund);
  color: var(--text-leise);
  font-size: 0.78em;
  font-weight: 600;
  cursor: help;
}

/* Das Tagesformular: umbrechende Reihe, jedes Feld beschriftet. Die
   Beschriftung wird ueber die LABELS angesprochen, nicht ueber `> span` -
   Letzteres traf bei der paXCry-App auch die Eingabefelder daneben und liess
   sie sichtbar schrumpfen. */
.lp-form {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6em 1em;
  align-items: flex-end;
  margin: 0.6em 0;
}

.lp-form label {
  display: flex;
  flex-direction: column;
  gap: 0.2em;
  font-size: 0.85em;
  color: var(--text-leise);
}

.lp-form label input {
  font-size: 1rem;
  color: var(--text);
}

/* Die Bemerkung darf wachsen, die Zahlenfelder nicht - sonst schiebt ein
   langer Text die Zeitfelder aus der Reihe. */
.lp-bemerkung { flex: 1 1 14em; min-width: 0; }
.lp-bemerkung input { width: 100%; }

.lp-knoepfe { display: flex; flex-wrap: wrap; gap: 0.6em; margin: 0.6em 0; }

/* Unter 700px rollt die Tabelle ohnehin (.tabelle-rollt); das Formular faellt
   hier auf eine Spalte, sonst stehen sechs Felder zu je 4em nebeneinander. */
@media (max-width: 700px) {
  .lp-form { flex-direction: column; align-items: stretch; }
  .lp-bemerkung { flex: 1 1 auto; }
}
