/*
 * Bewusst handgeschrieben und kurz gehalten - kein Framework, kein Build.
 * Ziel ist Lesbarkeit im Praxisalltag: grosse Trefferflächen, ruhige Farben,
 * klare Tabellen.
 */

/*
 * Die Schrift: Onest, vom eigenen Server (siehe vendor/schrift/LIZENZEN.txt).
 * Rund und gut lesbar auch klein, mit klaren Ziffern für Uhrzeiten. Zwei
 * Teilmengen - der Browser lädt „latin-ext" nur, wenn ein Zeichen daraus
 * vorkommt. Bis die Datei da ist, steht die Systemschrift (`swap`).
 */
@font-face {
  font-family: 'Onest';
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url('/vendor/schrift/onest-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329,
    U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: 'Onest';
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url('/vendor/schrift/onest-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329,
    U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/*
 * Die Bausteine des Aussehens - jede Farbe, Schriftgrösse und Rundung steht
 * hier und nur hier. Weiter unten wird nur noch auf sie verwiesen.
 *
 * Bei den Farben gibt es zwei Sorten, und die Trennung ist der Grund, warum
 * der Dunkelmodus überhaupt geht:
 *
 *   - Schrift- und Randfarben (`--accent`, `--danger`, `--warn` …) stehen auf
 *     dem Seitengrund. Im Dunkeln werden sie heller, sonst liest man sie nicht.
 *   - Flächen hinter heller Schrift (`--accent-solid`, `--danger-solid`) sind
 *     Knöpfe und Marken. Sie bleiben kräftig, und `--on-solid` ist die
 *     Schrift darauf - in beiden Fällen weiss.
 *
 * Vorher hiess beides `--accent`; ein heller Akzent für Schrift im Dunkeln
 * hätte die grünen Knöpfe mit weisser Schrift unlesbar gemacht.
 */
:root {
  color-scheme: light dark;

  /* Grund und Schrift */
  --font: 'Onest', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --bg: #f4f5f2;
  --surface: #ffffff;
  --field: #ffffff;
  --border: #dde3e0;
  /* Karten stehen ohne Rahmen auf dem Grund - nur ein Hauch Kante, damit
     sie bei grellem Licht nicht im Weiss verschwimmen. */
  --card-rand: rgb(24 33 31 / 0.05);
  --text: #18211f;
  --muted: #5c6866;
  --inverse-bg: #18211f;
  --on-inverse: #ffffff;

  /* Praxisgrün - das Band oben auf „Heute", Knöpfe, aktive Reiter */
  --accent: #0e5e59;
  --accent-dark: #09423f;
  --accent-solid: #0e5e59;
  --accent-solid-hover: #09423f;
  --accent-schatten: rgb(14 94 89 / 0.16);
  --on-solid: #ffffff;
  --band: #0e5e59;
  --on-band: #ffffff;
  --on-band-leise: #cfe5e2;
  --gold: #f2c14e;
  --on-gold: #3a2a00;

  /* Die Leiste unten am Handy: dunkel, schwebend */
  --leiste: #18211f;
  --leiste-text: #aeb8b5;

  /* Bedeutungen: gut, Achtung, Fehler, Hinweis, bald */
  --ok: #1b6e3c;
  --ok-bg: #e2f1ee;
  --warn: #7a4a00;
  --warn-bg: #fdefcf;
  --warn-bg-leicht: #fffdf8;
  --warn-line: #e0a02a;
  --warn-mark: #c98a00;
  --danger: #b3261e;
  --danger-bg: #fdecea;
  --danger-solid: #b3261e;
  --danger-solid-hover: #8f1e17;
  --info: #18405f;
  --info-bg: #eaf3fb;
  --info-line: #b9d5ee;
  --soon: #1d4f8a;
  --soon-bg: #e6eef8;

  /* Planung: Auslastung, Puffer, Konflikt, Zonen auf der Karte */
  --seg-fahrt: #5b7fa6;
  --seg-puffer: #c9a227;
  --puffer: #785e00;
  --konflikt: #c99a06;
  --grau-marke: #8a94a0;
  --zone-nah: #2e7d32;
  --zone-mittel: #c99a06;
  --zone-weit: #e06a00;
  --zone-fern: #c62828;
  --karte-bg: #eef1ec;
  /* Die Karte bleibt auch im Dunkeln hell - ihre Marken brauchen den
     weissen Ring in beiden Fällen. */
  --marker-ring: #ffffff;

  /* Kamera und Kuh-Umriss */
  --scanner-bg: #101418;
  --scanner-text: #cfd6de;
  --kuh: #cfd6dd;
  --kuh-fern: #b6c0ca;

  /* Schatten und Abdunkeln hinter Schublade und Blatt */
  --schatten-rgb: 24 33 31;
  --overlay: rgb(24 33 31 / 0.4);
  --shadow: 0 1px 2px rgb(var(--schatten-rgb) / 0.05), 0 6px 20px rgb(var(--schatten-rgb) / 0.06);

  /* Schriftgrössen: sieben Stufen statt 35 Einzelwerte. */
  --fs-xs: 0.75rem;
  --fs-sm: 0.875rem;
  --fs-base: 1rem;
  --fs-md: 1.125rem;
  --fs-lg: 1.3rem;
  --fs-xl: 1.6rem;
  --fs-2xl: 2.2rem;

  /* Abstände */
  --sp-1: 0.25rem;
  --sp-2: 0.5rem;
  --sp-3: 0.75rem;
  --sp-4: 1rem;
  --sp-5: 1.5rem;
  --sp-6: 2rem;

  /* Rundungen und Tippfläche */
  --radius: 16px;
  --radius-lg: 20px;
  --radius-sm: 12px;
  --radius-pill: 999px;
  /* Mindestgrösse für alles, was man mit dem Daumen trifft (Apple: 44pt). */
  --tap: 2.75rem;
}

/*
 * Dunkelmodus: folgt der Einstellung des Geräts. Nachts im Stall oder im Auto
 * blendet eine weisse Seite - und viele haben ihr Handy ohnehin so gestellt.
 * Es werden nur die Bausteine umgefärbt; keine Regel weiter unten weiss, ob
 * es hell oder dunkel ist.
 */
@media (prefers-color-scheme: dark) {
  :root {
    --bg: #0f1517;
    --surface: #182124;
    --field: #11191b;
    --border: #2b3a3c;
    --card-rand: rgb(255 255 255 / 0.06);
    --text: #e4ebe9;
    --muted: #9db0ad;
    --inverse-bg: #e4ebe9;
    --on-inverse: #0f1517;

    --accent: #6fd0c5;
    --accent-dark: #9ce2d9;
    --accent-solid: #0f6b65;
    --accent-solid-hover: #148078;
    --accent-schatten: rgb(0 0 0 / 0.45);
    --band: #0b4a46;
    --on-band-leise: #b8d8d4;

    --leiste: #232e31;
    --leiste-text: #a7b6b3;

    --ok: #7dd39a;
    --ok-bg: #16312d;
    --warn: #f2c46b;
    --warn-bg: #3a2d14;
    --warn-bg-leicht: #231e14;
    --warn-line: #b8862a;
    --warn-mark: #d9a530;
    --danger: #ff8a7f;
    --danger-bg: #3a1d1b;
    --danger-solid: #c4362c;
    --danger-solid-hover: #a52d24;
    --info: #a9cdf0;
    --info-bg: #16283a;
    --info-line: #2c4a66;
    --soon: #a9c8f2;
    --soon-bg: #1a2a40;

    --seg-fahrt: #6f93ba;
    --puffer: #d9b84a;
    --konflikt: #d9ad2a;
    --grau-marke: #7d8894;
    --karte-bg: #1e2722;

    --kuh: #4a5560;
    --kuh-fern: #3c4650;

    --schatten-rgb: 0 0 0;
    --overlay: rgb(0 0 0 / 0.6);
    --shadow: 0 1px 2px rgb(0 0 0 / 0.4), 0 6px 20px rgb(0 0 0 / 0.25);
  }

  /* Der Klauenabdruck ist schwarz gezeichnet - im Dunkeln wird er hell. */
  .brand-mark {
    filter: invert(1);
  }
}

* {
  box-sizing: border-box;
}

/*
 * `hidden` muss `hidden` bleiben.
 *
 * Der Browser setzt für [hidden] `display: none`, aber jede eigene
 * display-Regel schlägt das - `.btn { display: inline-block }` genügt. Damit
 * waren Elemente sichtbar, die JavaScript erst einblenden sollte, sobald es
 * weiss, dass sie etwas tun können (Aufnahme, Kamera). Diese Regel stellt das
 * für alle klar, statt es an jeder Klasse einzeln nachzuziehen.
 */
[hidden] {
  display: none !important;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 16px/1.5 var(--font);
}

body.centered {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
  padding: 1.5rem;
}

a {
  color: var(--accent);
}

/* Überschriften kräftig und eng gesetzt - sie sind Wegweiser, kein Text. */
h1 {
  font-size: var(--fs-xl);
  font-weight: 800;
  letter-spacing: -0.02em;
  line-height: 1.15;
  margin: 0 0 0.25rem;
}
h2 {
  font-size: var(--fs-md);
  font-weight: 700;
  letter-spacing: -0.01em;
  margin: 2rem 0 0.75rem;
}
h3 {
  font-size: var(--fs-base);
  font-weight: 700;
  margin: 0 0 0.75rem;
}

.muted {
  color: var(--muted);
}

/* ---------------------------------------------------------------- Kopfzeile */

/* Ein Menü, drei Gestalten.

   Am Schreibtisch ist die Kopfzeile eine Leiste: Logo links, Verweise
   daneben, Name und Abmelden rechts. Auf dem Tablet wird derselbe Block zur
   Schublade, die von rechts hereinfährt. Am Handy liegen die wichtigsten
   Wege in einer Leiste unten, und derselbe Block wird zum Blatt, das „Mehr"
   von unten hereinholt.

   Dieselben Verweise für alle, nicht zwei Menüs nebeneinander: Zwei liefen
   früher oder später auseinander, und dann fehlte auf dem Handy genau der
   Eintrag, den man dort braucht.

   Umgeschaltet wird bei 1199px (Schublade) und 760px (Leiste unten), die
   Schublade nur, wenn menu.js gelaufen ist (`body.menu-ready`). Ohne
   JavaScript bleibt es oben bei der umbrechenden Leiste. */

.topbar {
  display: flex;
  align-items: center;
  gap: 1.5rem;
  padding: 0.75rem 1.5rem;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  flex-wrap: wrap;
  /* Bleibt beim Scrollen stehen: Im Stall ist die Seite lang, und der Weg
     zum Menü soll nicht am oberen Seitenende liegen. */
  position: sticky;
  top: 0;
  z-index: 30;
}

.brand {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-weight: 600;
  color: var(--text);
  text-decoration: none;
  /* Der Schriftzug soll nicht zwischen Logo und Menüknopf zerrissen werden. */
  flex-shrink: 0;
}

/* Der Klauenabdruck. Als Bild statt als Schriftzeichen: ein Emoji sieht auf
   jedem Betriebssystem anders aus, dieses Zeichen überall gleich. */
.brand-mark {
  display: block;
  width: 1.4rem;
  height: 1.4rem;
  flex-shrink: 0;
}
.brand-mark-lg {
  width: 3rem;
  height: 3rem;
  margin: 0 auto;
}

/* Der Block, der am Schreibtisch die Leiste ist und am Handy die Schublade. */
.menu-panel {
  display: flex;
  align-items: center;
  gap: 1rem;
  /* Grundbreite 0, nicht `auto`: Sonst nimmt der Block die Breite seines
     Inhalts als Wunsch, findet die auf der Zeile nicht und rutscht mitsamt
     Menü unter das Logo. Mit 0 schrumpft er stattdessen, und die Verweise
     brechen innerhalb um. */
  flex: 1 1 0;
  min-width: 0;
}

/* Überschrift und Schliessen-Kreuz gehören zur Schublade und stehen in der
   Leiste nur im Weg. */
.menu-head,
.menu-button,
.menu-backdrop {
  display: none;
}

.topnav {
  margin-right: auto;
  font-size: var(--fs-base);
  /* Wird der Platz knapp, gibt der Namensblock rechts nach und nicht die
     Navigation: Ein umgebrochener Menüeintrag fällt sofort auf, ein
     gekürzter Praxisname kaum. */
  flex-shrink: 0;
  /* Ohne Mindestbreite 0 weigert sich ein Flex-Element zu schrumpfen und
     schiebt die ganze Seite breiter als den Bildschirm. */
  min-width: 0;
}

.nav-list {
  display: flex;
  flex-wrap: wrap;
  /* Eng gesetzt, damit die Oberpunkte auf einem 1280er-Bildschirm in eine
     Zeile passen - ein einzelnes umgebrochenes "Verwaltung" sieht aus wie
     ein Versehen. */
  gap: 0.4rem 0.15rem;
  align-items: center;
  list-style: none;
  margin: 0;
  padding: 0;
}

/* Eine Gruppe ist der Bezugspunkt für ihr Untermenü. */
.nav-group {
  position: relative;
}

.topnav a,
.nav-trigger {
  /* Verweis und Gruppenknopf gleich hoch: Ein Verweis in der Zeile trägt
     seinen Innenabstand nicht in die Höhe, ein Knopf schon - die
     Oberpunkte stünden sonst treppenförmig nebeneinander. */
  display: inline-block;
  color: var(--muted);
  text-decoration: none;
  padding: 0.4rem 0.55rem;
  border-radius: var(--radius-pill);
  /* Der Strich unter dem aktiven Eintrag darf die Zeile nicht verschieben,
     wenn er auftaucht - deshalb steht er von Anfang an da, nur unsichtbar. */
  border-bottom: 2px solid transparent;
  white-space: nowrap;
}

.nav-trigger {
  font: inherit;
  font-size: inherit;
  border-width: 0 0 2px;
  border-style: solid;
  cursor: pointer;
  background: none;
}

.topnav a:hover,
.nav-trigger:hover {
  color: var(--text);
  background: var(--bg);
}

.topnav a.is-active,
.nav-trigger.is-active {
  color: var(--accent);
  background: var(--ok-bg);
  border-bottom-color: transparent;
  font-weight: 600;
}

/* Der kleine Pfeil sagt, dass unter dem Punkt noch etwas liegt. */
.nav-trigger::after {
  content: '';
  display: inline-block;
  width: 0.4rem;
  height: 0.4rem;
  margin-left: 0.45rem;
  vertical-align: 0.15em;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg);
}

/* ------------------------------------------- Untermenü am Schreibtisch --- */

/*
 * Aufgeklappt wird bei Hover, bei Tastaturfokus irgendwo in der Gruppe und
 * bei Klick auf den Auslöser (das setzt menu.js). Die ersten beiden gehen
 * ohne JavaScript; der Klick ist für den Finger am grossen Bildschirm, wo es
 * kein Hover gibt.
 */
.nav-sub {
  position: absolute;
  top: 100%;
  left: 0;
  z-index: 35;
  min-width: 11rem;
  margin: 0.35rem 0 0;
  padding: 0.35rem;
  list-style: none;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  /* `visibility` statt `display`, damit der Fokus nicht durch ein Menü
     läuft, das niemand sieht - und damit die Blende weich kommt. */
  visibility: hidden;
  opacity: 0;
  transition:
    opacity 0.12s ease,
    visibility 0.12s;
}

.nav-group:hover > .nav-sub,
.nav-group:focus-within > .nav-sub,
.nav-group[data-open] > .nav-sub {
  visibility: visible;
  opacity: 1;
}

/* Ein kleiner Steg zwischen Auslöser und Untermenü: Ohne ihn schliesst das
   Menü, sobald der Zeiger die Lücke überquert. */
.nav-group::after {
  content: '';
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  height: 0.4rem;
}

.nav-sub a {
  display: block;
  white-space: nowrap;
}

/* Zeichen, Kürzel und Griff gehören zur Schublade und zum Blatt am Handy. In
   der Leiste oben am Schreibtisch stünden sie nur im Weg - dort sind die
   Wörter kurz genug, um für sich zu stehen. */
.topbar .icon,
.kuerzel,
.menu-griff {
  display: none;
}

.topbar-user {
  display: flex;
  align-items: center;
  gap: 1rem;
  min-width: 0;
}

.whoami {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  line-height: 1.25;
  font-size: var(--fs-sm);
  min-width: 0;
}

.whoami-text {
  display: flex;
  flex-direction: column;
  text-align: right;
  min-width: 0;
}

/* Lieber abgeschnitten als umgebrochen: Wie lang der Name und die Praxis
   sind, weiss die Kopfzeile nicht - und ein einziger langer Name darf die
   ganze Leiste nicht in eine zweite Zeile zwingen. Vollständig steht beides
   auf der Übersicht. */
.whoami-text > strong,
.whoami-text > span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.whoami-text > span {
  color: var(--muted);
}

/* Der Name ist ein Verweis auf das eigene Konto, soll aber nicht wie einer
   aussehen - in der Kopfzeile stünde sonst ein blauer Namenszug zwischen
   lauter Menüpunkten. Erkennbar wird er beim Überfahren und beim Fokus. */
a.whoami {
  color: inherit;
  text-decoration: none;
  border-radius: var(--radius);
  padding: 0.15rem 0.35rem;
}

a.whoami:hover,
a.whoami:focus-visible,
a.whoami.is-active {
  background: var(--bg);
}

a.whoami:hover .whoami-text > strong,
a.whoami:focus-visible .whoami-text > strong {
  text-decoration: underline;
}

.topbar-user form {
  flex-shrink: 0;
}

/* ------------------------------------------------------- Menü am Handy --- */

.menu-button {
  align-items: center;
  gap: 0.5rem;
  margin-left: auto;
  padding: 0.5rem 0.8rem;
  font: inherit;
  font-weight: 500;
  color: var(--text);
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  cursor: pointer;
}

.menu-button:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* Die drei Striche. Gezeichnet statt als Zeichen "☰": Das Zeichen sieht auf
   jedem Gerät anders aus und sitzt selten mittig. */
.menu-icon,
.menu-icon::before,
.menu-icon::after {
  display: block;
  width: 1.15rem;
  height: 2px;
  background: currentColor;
  border-radius: 2px;
}

.menu-icon {
  position: relative;
}

.menu-icon::before,
.menu-icon::after {
  content: '';
  position: absolute;
  left: 0;
}

.menu-icon::before {
  top: -0.36rem;
}
.menu-icon::after {
  top: 0.36rem;
}

.menu-head {
  align-items: center;
  justify-content: space-between;
  padding-bottom: 0.75rem;
  border-bottom: 1px solid var(--border);
}

.menu-head-title {
  font-weight: 600;
}

.menu-close {
  padding: 0.1rem 0.6rem;
  font-size: 1.6rem;
  line-height: 1.2;
  color: var(--muted);
  background: none;
  border: 0;
  border-radius: var(--radius-sm);
  cursor: pointer;
}

.menu-close:hover {
  color: var(--text);
  background: var(--bg);
}

.menu-close:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

@media (max-width: 1199px) {
  .topbar {
    gap: 0.75rem;
    padding: 0.6rem 1rem;
    /* Quer gehalten liegt am iPhone die Kamera-Aussparung über dem Rand. */
    padding-left: max(1rem, env(safe-area-inset-left));
    padding-right: max(1rem, env(safe-area-inset-right));
  }

  /* Ohne JavaScript: die Leiste bricht um wie bisher. Mit JavaScript wird
     daraus die Schublade. */
  .menu-panel {
    flex-wrap: wrap;
    gap: 0.75rem;
  }

  /* Ohne JavaScript bricht die Liste der Oberpunkte innerhalb der Zeile um,
     statt die Seite breiter als den Bildschirm zu machen. */
  body:not(.menu-ready) .topnav {
    flex: 1 1 100%;
    flex-shrink: 1;
  }

  /* Ein zugeklapptes Untermenü ist unsichtbar, nimmt aber Platz ein - am
     rechten Rand genug, um die Seite seitwärts scrollen zu lassen. */
  body:not(.menu-ready) .nav-sub {
    display: none;
  }

  body:not(.menu-ready) .nav-group:hover > .nav-sub,
  body:not(.menu-ready) .nav-group:focus-within > .nav-sub {
    display: block;
  }

  .menu-ready .menu-button {
    display: inline-flex;
  }

  .menu-ready .menu-head {
    display: flex;
    /* Vor dem Namen, der mit `order: -1` nach oben rückt. */
    order: -2;
    flex-shrink: 0;
  }

  .menu-ready .menu-panel {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    width: min(20rem, 86vw);
    flex-direction: column;
    flex-wrap: nowrap;
    align-items: stretch;
    gap: 0.75rem;
    padding: 1rem;
    background: var(--surface);
    border-left: 1px solid var(--border);
    box-shadow: -10px 0 30px rgb(var(--schatten-rgb) / 0.18);
    overflow-y: auto;
    overscroll-behavior: contain;
    z-index: 45;
    /* Ausgefahren wird mit transform, nicht mit display: Nur so lässt sich
       die Bewegung zeigen. `visibility` hält die geschlossene Schublade
       zugleich aus der Tabulator-Reihenfolge heraus - sonst liefe der Fokus
       durch ein Menü, das niemand sieht. */
    transform: translateX(100%);
    visibility: hidden;
  }

  /* Die Fahrt erst, wenn die Seite steht (`menu-animiert` setzt menu.js
     einen Augenblick nach dem Laden). Sonst führe die Schublade bei jedem
     Seitenwechsel einmal sichtbar aus dem Bild - aus der Kopfzeile, in der
     sie ohne Skript steht, an ihren Platz ausserhalb. */
  .menu-animiert .menu-panel {
    transition:
      transform 0.24s cubic-bezier(0.2, 0.8, 0.2, 1),
      visibility 0.24s;
  }

  /* Beim Öffnen sofort sichtbar, beim Schliessen erst am Ende der Fahrt:
     Sonst wäre die Schublade im ersten Augenblick noch `hidden`, und der
     Fokus käme nicht hinein. */
  .menu-animiert .menu-panel[data-open] {
    transition:
      transform 0.24s cubic-bezier(0.2, 0.8, 0.2, 1),
      visibility 0s;
  }

  .menu-ready .menu-panel[data-open] {
    transform: none;
    visibility: visible;
  }

  /* Beim Wegziehen am Handy folgt das Blatt dem Finger, nicht der Fahrt. */
  .menu-ready .menu-panel.wird-gezogen {
    transition: none;
  }

  .menu-ready .menu-panel .topnav {
    margin-right: 0;
    flex-shrink: 0;
  }

  .menu-ready .menu-panel .nav-list {
    flex-direction: column;
    flex-wrap: nowrap;
    gap: 0.15rem;
  }

  /* Die Verweise sind Zeilen: volle Breite, Daumenhöhe, ein Zeichen davor
     und ein Pfeil dahinter. Als Block und nicht als Text in der Zeile - nur
     so liegen die Flächen nicht übereinander, wenn eine hervorgehoben ist. */
  .menu-ready .menu-panel .topnav a {
    display: flex;
    align-items: center;
    gap: 0.85rem;
    min-height: 3rem;
    padding: 0.4rem 0.6rem;
    border: 0;
    border-radius: 12px;
    color: var(--text);
    font-size: var(--fs-base);
    font-weight: 500;
    white-space: normal;
    touch-action: manipulation;
  }

  .menu-ready .menu-panel .topnav a::after {
    content: '';
    flex-shrink: 0;
    width: 0.45rem;
    height: 0.45rem;
    margin: 0 0.35rem 0 auto;
    border-top: 2px solid var(--border);
    border-right: 2px solid var(--border);
    transform: rotate(45deg);
  }

  .menu-ready .menu-panel .topnav a:hover {
    background: var(--bg);
  }

  .menu-ready .menu-panel .icon {
    display: block;
    flex-shrink: 0;
    box-sizing: content-box;
    width: 1.3rem;
    height: 1.3rem;
    padding: 0.45rem;
    border-radius: var(--radius);
    background: var(--bg);
    color: var(--muted);
  }

  .menu-ready .menu-panel .topnav a.is-active {
    background: var(--ok-bg);
    color: var(--accent-dark);
    font-weight: 600;
  }

  .menu-ready .menu-panel .topnav a.is-active .icon {
    background: var(--surface);
    color: var(--accent);
  }

  .menu-ready .menu-panel .topnav a.is-active::after {
    border-color: var(--accent);
  }

  /* Der Oberpunkt einer Gruppe wird zur Zwischenüberschrift, die
     Unterpunkte stehen immer darunter. Es sind wenige - aufklappen müsste
     man nur, um zu sehen, was es gibt, und genau das soll das Menü auf einen
     Blick zeigen. */
  .menu-ready .menu-panel .nav-group {
    position: static;
  }

  .menu-ready .menu-panel .nav-group::after {
    content: none;
  }

  .menu-ready .menu-panel .nav-trigger,
  .menu-ready .menu-panel .nav-trigger.is-active {
    display: block;
    width: 100%;
    padding: 0.9rem 0.6rem 0.3rem;
    border: 0;
    border-radius: 0;
    background: none;
    color: var(--muted);
    font: inherit;
    font-size: var(--fs-xs);
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    text-align: left;
    white-space: normal;
    cursor: default;
  }

  .menu-ready .menu-panel .nav-trigger::after {
    content: none;
  }

  .menu-ready .menu-panel .nav-sub {
    position: static;
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    min-width: 0;
    margin: 0;
    padding: 0;
    background: none;
    border: 0;
    box-shadow: none;
    /* `inherit` und nicht `visible`: Ein Kind mit `visible` bliebe sichtbar
       und per Tabulator erreichbar, auch wenn die Schublade selbst
       geschlossen (`hidden`) ist. */
    visibility: inherit;
    opacity: 1;
    transition: none;
  }

  /* Name und Abmelden sind in der Leiste ein Block. In der Schublade gehört
     der Name nach oben - wer bin ich, in welcher Praxis - und das Abmelden
     ganz nach unten, weit weg von dem, was man oft antippt. */
  .menu-ready .menu-panel .topbar-user {
    display: contents;
  }

  .menu-ready .menu-panel .whoami {
    order: -1;
    flex-shrink: 0;
    gap: 0.8rem;
    padding: 0.7rem 0.8rem;
    border-radius: 14px;
    background: var(--bg);
    font-size: var(--fs-sm);
  }

  .menu-ready .menu-panel .whoami::after {
    content: '';
    flex-shrink: 0;
    width: 0.45rem;
    height: 0.45rem;
    margin: 0 0.35rem 0 auto;
    border-top: 2px solid var(--muted);
    border-right: 2px solid var(--muted);
    transform: rotate(45deg);
  }

  .menu-ready .menu-panel .whoami.is-active {
    background: var(--ok-bg);
  }

  .menu-ready .menu-panel .whoami-text {
    text-align: left;
  }

  .menu-ready .menu-panel .whoami-text > strong {
    font-size: var(--fs-base);
  }

  /* Das Kürzel: der Anfangsbuchstabe von Vor- und Nachname im Kreis, wie
     man es aus jedem Konto kennt. Ein Foto gibt es nicht und braucht es
     nicht. */
  .menu-ready .menu-panel .kuerzel {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 2.6rem;
    height: 2.6rem;
    border-radius: 50%;
    background: var(--accent-solid);
    color: var(--on-solid);
    font-size: var(--fs-base);
    font-weight: 600;
    letter-spacing: 0.02em;
    text-transform: uppercase;
  }

  .menu-ready .menu-panel .topbar-user form {
    order: 10;
    margin-top: auto;
    padding-top: 0.75rem;
    border-top: 1px solid var(--border);
  }

  .menu-ready .menu-panel .topbar-user .btn {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.6rem;
    width: 100%;
    min-height: 3rem;
    padding: 0.6rem 1rem;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 12px;
    color: var(--danger);
    font-weight: 500;
  }

  .menu-ready .menu-panel .topbar-user .btn .icon {
    width: 1.2rem;
    height: 1.2rem;
    padding: 0;
    background: none;
    color: inherit;
  }

  .menu-ready .menu-backdrop {
    display: block;
    position: fixed;
    inset: 0;
    background: var(--overlay);
    z-index: 40;
  }

  /* Hinter der offenen Schublade soll die Seite nicht mitscrollen. */
  body.menu-offen {
    overflow: hidden;
  }
}

/* ------------------------------------------------- Leiste unten am Handy --- */

/*
 * Am Handy liegen die vier Wege, die im Stall zählen, unten im Daumenbereich:
 * Übersicht, Einsätze, Scannen, Behandlung. Alles andere liegt hinter „Mehr"
 * in einem Blatt, das von unten hereinfährt - dort, wo der Daumen schon ist,
 * statt oben rechts in einer Ecke, an die man mit einer Hand nicht kommt.
 *
 * Die Grenze ist die Breite eines Handys im Hochformat. Ein Tablet und ein
 * quer gehaltenes Handy behalten die Schublade von rechts: Dort ist eine
 * Leiste unten Platzverschwendung, und die Hand liegt anders.
 */
.tableiste {
  display: none;
}

@media (max-width: 760px) {
  /* Eine dunkle Leiste, die über der Seite schwebt - mit Abstand zum Rand
     und runden Ecken. Sie hebt sich von jedem Seiteninhalt ab, auch von
     hellen Karten, und der gewählte Reiter ist eine grüne Pille darin. */
  .tableiste {
    display: flex;
    position: fixed;
    left: max(0.75rem, env(safe-area-inset-left));
    right: max(0.75rem, env(safe-area-inset-right));
    bottom: calc(0.75rem + env(safe-area-inset-bottom));
    z-index: 35;
    padding: 0.45rem 0.3rem;
    background: var(--leiste);
    border-radius: 22px;
    box-shadow: 0 10px 30px rgb(0 0 0 / 0.22);
  }

  .tab {
    flex: 1 1 0;
    min-width: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.15rem;
    padding: 0;
    color: var(--leiste-text);
    /* Eine Spur kleiner als die kleinste Stufe: „Behandlung" muss bei 360 px
       Breite noch ganz in seinen Reiter passen. */
    font-size: 0.72rem;
    font-weight: 600;
    line-height: 1.2;
    text-decoration: none;
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
  }

  .tab-zeichen {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 2.9rem;
    height: 1.9rem;
    border-radius: var(--radius-pill);
    transition: background-color 0.15s ease;
  }

  .tab .icon {
    display: block;
    width: 1.3rem;
    height: 1.3rem;
  }

  .tab-text {
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  /* Der aktive Reiter: weisse Schrift und die grüne Pille hinter dem
     Zeichen - auch bei Sonne im Hof eindeutig. */
  .tab.is-active {
    color: var(--on-solid);
  }

  .tab.is-active .tab-zeichen {
    background: var(--accent-solid);
    color: var(--on-solid);
  }

  .tab:active .tab-zeichen {
    background: rgb(255 255 255 / 0.1);
  }

  .tab:focus-visible {
    outline: none;
  }

  .tab:focus-visible .tab-zeichen {
    outline: 2px solid var(--on-solid);
    outline-offset: 2px;
  }

  /* Platz für die Leiste, damit das Seitenende nicht unter ihr liegt. */
  body.mit-tableiste {
    padding-bottom: calc(6rem + env(safe-area-inset-bottom));
  }

  /* Solange die Tastatur offen ist, säße die Leiste über ihr und nähme dem
     Formular die Hälfte des Platzes. menu.js setzt `tastatur`, solange ein
     Eingabefeld den Fokus hat. */
  body.tastatur .tableiste {
    display: none;
  }

  body.mit-tableiste.tastatur {
    padding-bottom: 0;
  }

  /* Die Kopfzeile trägt am Handy nur noch das Logo - das Menü liegt unten.
     Deshalb darf sie mitscrollen und gibt den Platz der Seite zurück. */
  .mit-tableiste .topbar {
    position: static;
  }

  .menu-ready.mit-tableiste .menu-button {
    display: none;
  }

  /* Was unten in der Leiste liegt, steht im Blatt nicht noch einmal - und
     ohne JavaScript auch nicht in der Liste oben. */
  .mit-tableiste .menu-panel .in-tableiste {
    display: none;
  }

  /* Das Blatt: von unten, über die volle Breite, oben gerundet. */
  .menu-ready .menu-panel {
    top: auto;
    left: 0;
    width: auto;
    max-height: 88vh;
    max-height: 88dvh;
    padding: 0.25rem 1rem calc(1rem + env(safe-area-inset-bottom));
    border-left: 0;
    border-radius: 20px 20px 0 0;
    box-shadow: 0 -10px 34px rgb(var(--schatten-rgb) / 0.2);
    transform: translateY(100%);
  }

  .menu-ready .menu-head {
    position: relative;
    padding: 1.1rem 0 0.25rem;
    border-bottom: 0;
  }

  .menu-ready .menu-griff {
    display: block;
    position: absolute;
    top: 0.45rem;
    left: 50%;
    width: 2.6rem;
    height: 5px;
    margin-left: -1.3rem;
    border-radius: var(--radius-pill);
    background: var(--border);
  }

  .menu-ready .menu-head-title {
    font-size: var(--fs-md);
  }

  .menu-ready .menu-close {
    width: 2.25rem;
    height: 2.25rem;
    padding: 0;
    border-radius: 50%;
    background: var(--bg);
    font-size: 1.4rem;
    line-height: 1;
  }

  /* Das Abmelden schliesst das Blatt ab und braucht keinen Abstand nach
     oben, um unten zu stehen - das Blatt ist so hoch wie sein Inhalt. */
  .menu-ready .menu-panel .topbar-user form {
    margin-top: 0.25rem;
  }
}

/* Wer Bewegung abbestellt hat, bekommt Schublade und Blatt ohne Fahrt -
   sichtbar oder unsichtbar, nichts dazwischen. */
@media (prefers-reduced-motion: reduce) {
  .menu-animiert .menu-panel,
  .tab-zeichen {
    transition: none;
  }
}

/* ------------------------------------------------------------------- Layout */

.page {
  max-width: 1080px;
  margin: 0 auto;
  padding: 2rem 1.5rem 3rem;
  /* Mit `viewport-fit=cover` reicht die Seite quer gehalten bis unter die
     Kamera-Aussparung - der Inhalt soll dort nicht anfangen. */
  padding-left: max(1.5rem, env(safe-area-inset-left));
  padding-right: max(1.5rem, env(safe-area-inset-right));
}

.footer {
  padding: 1.5rem;
  text-align: center;
  color: var(--muted);
  font-size: var(--fs-sm);
}

.card {
  background: var(--surface);
  border: 1px solid var(--card-rand);
  border-radius: var(--radius-lg);
  padding: 1.25rem;
  box-shadow: var(--shadow);
}

.card-narrow {
  width: 100%;
  max-width: 24rem;
}

.grid {
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
}

.stack {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

/* ------------------------------------------------------------------ Zahlen */

.stats {
  display: grid;
  gap: 1rem;
  /* 8,5rem statt 11rem: Auf einem 360-Pixel-Display passen so zwei Kennzahlen
     nebeneinander statt vier untereinander - der Rest der Seite bleibt in
     Sichtweite. */
  grid-template-columns: repeat(auto-fill, minmax(8.5rem, 1fr));
  margin: 1.5rem 0;
}

.stat {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1rem 1.25rem;
}

.stat-value {
  display: block;
  font-size: var(--fs-xl);
  font-weight: 600;
  line-height: 1.1;
}

.stat-label {
  color: var(--muted);
  font-size: var(--fs-sm);
}

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

label {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  font-size: var(--fs-sm);
  font-weight: 500;
}

/* Die Schriftgrösse der Felder ist nicht nur Geschmack: Safari am iPhone
   zoomt beim Antippen in jedes Feld hinein, das kleiner als 16px schreibt -
   und danach steht die Seite verschoben da und muss von Hand wieder
   herausgezogen werden. `label` schreibt 0.9rem, `font: inherit` gab das an
   die Felder weiter, und damit waren es 14.4px: Im Stall hiess das bei jedem
   Feld einmal rein- und wieder rauszoomen.

   Die Beschriftung bleibt klein, die Felder selbst nicht. `max()` statt
   glatter 16px, damit eine grössere Schrifteinstellung im Browser weiterhin
   gilt - kleiner wird es nur nicht mehr. */
input[type='text'],
input[type='email'],
input[type='tel'],
input[type='password'],
select {
  font: inherit;
  font-size: max(1rem, 16px);
  /* Eine lange Auswahl ("Stoffwechsel, Infusionen, Notfall") machte das Feld
     sonst breiter als seine Karte und schob es auf dem Handy aus dem Bild. */
  max-width: 100%;
  padding: 0.6rem 0.7rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--field);
  color: var(--text);
}

select:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* Formulare mit mehreren Feldern untereinander. */
.form-grid {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.form-grid h3 {
  margin: 0.5rem 0 0;
  padding-top: 0.75rem;
  border-top: 1px solid var(--border);
}

.form-grid h3:first-child {
  border-top: none;
  padding-top: 0;
  margin-top: 0;
}

/* Mehrere Felder nebeneinander, die auf schmalen Geräten umbrechen. */
.row-fields {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
}

.row-fields > label {
  flex: 1 1 12rem;
}

.row-fields > label.grow {
  flex: 3 1 14rem;
}

.row-fields > label.narrow {
  flex: 0 1 7rem;
}

/* Reihe aus Schaltflächen bzw. kleinen Formularen. */
.row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem;
}

/* Bearbeitungsformular innerhalb einer Tabellenzeile. */
.row-form {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
}

.row-form select,
.row-form input[type='text'] {
  padding: 0.4rem 0.5rem;
}

.short {
  max-width: 8rem;
}

/* Kontrollkästchen mit Beschriftung daneben statt darüber. */
label.inline {
  flex-direction: row;
  align-items: center;
  gap: 0.5rem;
  font-weight: 400;
}

.hint,
.small {
  font-size: var(--fs-sm);
  color: var(--muted);
  font-weight: 400;
}

button[disabled] {
  opacity: 0.5;
  cursor: not-allowed;
}

/* --------------------------------------------------------------- Reiter */

.tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 1.25rem;
  margin: 1.25rem 0 1.5rem;
  border-bottom: 1px solid var(--border);
}

.tabs a {
  color: var(--muted);
  text-decoration: none;
  padding: 0.4rem 0;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
}

.tabs a:hover {
  color: var(--text);
}

.tabs a.is-active {
  color: var(--accent);
  border-bottom-color: var(--accent);
}

/* HTMX blendet Elemente mit dieser Klasse während einer Anfrage ein. */
.htmx-indicator {
  opacity: 0;
  transition: opacity 0.2s;
}

.htmx-request .htmx-indicator,
.htmx-request.htmx-indicator {
  opacity: 1;
}

/* Ladebalken: „die KI arbeitet gerade".
 *
 * Eine Zeile Text allein reicht dafür nicht - im Stall, mit dem Handy in der
 * einen und der Flasche in der anderen Hand, sieht man sie schlicht nicht.
 * Der Balken läuft, solange gewartet wird, und steht direkt beim Knopf, den
 * man gedrückt hat.
 *
 * Er behält seinen Platz auch im Ruhezustand (`opacity`, nicht `display`):
 * Sonst rutschte beim Erscheinen alles darunter nach unten - genau das
 * Springen, das hier vermieden werden soll.
 *
 * Zwei Auslöser, weil es zwei Wege gibt: `htmx-request` setzt htmx selbst auf
 * das Element aus `hx-indicator`, `laeuft` setzen die eigenen Skripte. */
.ladebalken {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  width: 100%;
  min-height: 1.5rem;
  opacity: 0;
  transition: opacity 0.2s;
}

.ladebalken.htmx-request,
.ladebalken.laeuft {
  opacity: 1;
}

.ladebalken-schiene {
  position: relative;
  flex: 1 1 5rem;
  min-width: 3rem;
  max-width: 14rem;
  height: 0.5rem;
  overflow: hidden;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
}

.ladebalken-lauf {
  position: absolute;
  top: 0;
  bottom: 0;
  left: -45%;
  width: 45%;
  background: var(--accent-solid);
  border-radius: var(--radius-pill);
}

/* Die Bewegung läuft nur während der Wartezeit - ein Balken, der im
   Unsichtbaren weiterwandert, kostet auf einem Handy Akku ohne Nutzen. */
.ladebalken.htmx-request .ladebalken-lauf,
.ladebalken.laeuft .ladebalken-lauf {
  animation: ladebalken-lauf 1.1s ease-in-out infinite;
}

.ladebalken-text {
  font-size: var(--fs-sm);
  color: var(--muted);
}

@keyframes ladebalken-lauf {
  from {
    left: -45%;
  }
  to {
    left: 100%;
  }
}

@media (prefers-reduced-motion: reduce) {
  /* Ohne Bewegung: die Schiene füllt sich halb und bleibt stehen. Das sagt
     immer noch "es passiert etwas", ohne zu wandern. */
  .ladebalken.htmx-request .ladebalken-lauf,
  .ladebalken.laeuft .ladebalken-lauf {
    animation: none;
    left: 0;
    width: 60%;
  }

  .ladebalken {
    transition: none;
  }
}

input:focus-visible,
.btn:focus-visible,
a:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* Der zweite Weg, aus Versehen zu zoomen: Doppeltippen. Wer eine Liste von
   Bausteinen durchgeht oder auf dem Kuh-Bild zwei Segmente nacheinander
   antippt, tippt schneller, als der Browser es für zwei einzelne Tipper
   hält - und zoomt statt zu klicken.

   `manipulation` nimmt genau diese Geste weg. Wischen, Scrollen und das
   Aufziehen mit zwei Fingern bleiben; wer hineinzoomen will, kann es
   weiterhin. Deshalb steht am `<meta viewport>` auch kein `user-scalable=no`
   - jemandem das Vergrössern zu verbieten, wäre die falsche Antwort auf ein
   Versehen. */
button,
.btn,
a,
summary,
label,
select,
[role='button'] {
  touch-action: manipulation;
}

.btn {
  display: inline-block;
  font: inherit;
  font-weight: 600;
  padding: 0.55rem 1.05rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text);
  cursor: pointer;
  text-decoration: none;
  text-align: center;
}

/* Ein Link, der wie ein Knopf aussieht, muss auch nach dem Besuch lesbar
   bleiben. Ohne diese Regel faerbt der Browser ihn violett ein - auf dem
   dunkelgruenen Knopf war die Beschriftung danach kaum noch zu erkennen,
   und zwar ausgerechnet bei dem Reiter, auf dem man gerade steht. */
.btn:visited {
  color: var(--text);
}

.btn-primary:visited {
  color: var(--on-solid);
}

.btn-quiet:visited {
  color: var(--muted);
}

.btn:hover {
  border-color: var(--muted);
}

.btn-primary {
  background: var(--accent-solid);
  border-color: var(--accent-solid);
  color: var(--on-solid);
  font-weight: 700;
}

.btn-primary:hover {
  background: var(--accent-solid-hover);
  border-color: var(--accent-solid-hover);
}

/* Leise heisst nicht klein: gleich hoch wie jeder andere Knopf, sonst trifft
   man „Woche" oder „Einstellungen" im Kopf der Planung mit dem Daumen nicht. */
.btn-quiet {
  background: transparent;
  border-color: transparent;
  color: var(--muted);
}

.btn-quiet:hover {
  color: var(--text);
  border-color: var(--border);
}

/* ------------------------------------------------------------------ Hinweise */

.alert {
  padding: 0.7rem 0.9rem;
  border-radius: var(--radius-sm);
  margin: 0 0 1rem;
  font-size: var(--fs-sm);
}

.alert-error {
  background: var(--danger-bg);
  color: var(--danger);
}

.alert-ok {
  background: var(--ok-bg);
  color: var(--ok);
}

.badge {
  display: inline-block;
  padding: 0.15rem 0.55rem;
  border-radius: var(--radius-pill);
  background: var(--bg);
  border: 1px solid var(--border);
  color: var(--muted);
  font-size: var(--fs-xs);
}

.badge-ok {
  background: var(--ok-bg);
  border-color: transparent;
  color: var(--ok);
}

.badge-off {
  background: var(--danger-bg);
  border-color: transparent;
  color: var(--danger);
}

/* ------------------------------------------------------------------ Tabellen */

.table-wrap {
  overflow-x: auto;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--fs-sm);
}

th,
td {
  text-align: left;
  padding: 0.65rem 0.9rem;
  border-bottom: 1px solid var(--border);
}

th {
  font-size: var(--fs-sm);
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--muted);
}

tbody tr:last-child td {
  border-bottom: none;
}

td.num,
th.num {
  text-align: right;
}

.nowrap {
  white-space: nowrap;
}

.slug {
  display: block;
  font-size: var(--fs-sm);
}

code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.85em;
  background: var(--bg);
  padding: 0.1rem 0.35rem;
  border-radius: 5px;
}

/* --------------------------------------------------------------- Anmeldung */

.login-head {
  text-align: center;
  margin-bottom: 1.5rem;
}

.login-head h1 {
  margin: 0.5rem 0 0;
}

.error-status {
  font-size: 2.5rem;
  font-weight: 600;
  color: var(--muted);
  margin: 0;
}

.back {
  text-decoration: none;
  font-size: var(--fs-sm);
}

@media (max-width: 640px) {
  .topbar {
    gap: 0.75rem;
  }
  .topnav {
    gap: 0.4rem 0.9rem;
    font-size: var(--fs-base);
  }
  /* In der schmalen Leiste ist für Name und Praxis kein Platz. In der
     Schublade schon - deshalb gilt das nur, solange es keine gibt. */
  body:not(.menu-ready) .whoami {
    display: none;
  }
  .page {
    padding: 1.25rem 1rem 2rem;
  }
}

/* =========================================================== Fachmodule === */

/* Dieselbe Sache wie oben bei den Textfeldern: unter 16px zoomt das iPhone
   beim Hineintippen. */
input[type='number'],
input[type='date'],
input[type='datetime-local'],
input[type='search'],
textarea {
  font: inherit;
  font-size: max(1rem, 16px);
  padding: 0.6rem 0.7rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--field);
  color: var(--text);
}

textarea {
  resize: vertical;
  min-height: 3rem;
}

textarea:focus-visible,
input[type='number']:focus-visible,
input[type='date']:focus-visible,
input[type='datetime-local']:focus-visible,
input[type='search']:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.filter-row {
  margin: 1rem 0 1.5rem;
}

.alert-warn {
  background: var(--warn-bg);
  color: var(--warn);
}

.alert ul {
  margin: 0.5rem 0 0;
  padding-left: 1.2rem;
}

/* Ohrmarken und andere kurze Kennungen. */
.chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: 1rem;
}

.chip {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.15rem 0.55rem;
  border-radius: var(--radius-pill);
  background: var(--bg);
  border: 1px solid var(--border);
  font-size: var(--fs-sm);
  /* Ein Chip ist eine Zeile, bis er nicht mehr auf eine passt. Der Tier-Chip
     trägt Ohrmarke, Rufname, Tierart, mitunter "nicht lebensmittelliefernd"
     und ein Gewichtsfeld; das sind am Telefon über 460 Pixel und schob die
     ganze Seite nach rechts. Umbrechen ist hier richtig - abschneiden würde
     ausgerechnet den Zusatz verschlucken, der die Ausnahme benennt. */
  flex-wrap: wrap;
  max-width: 100%;
}

.chip-lg {
  padding: 0.4rem 0.75rem;
  font-size: var(--fs-sm);
}

.chip-remove {
  border: none;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  font-size: 1.1rem;
  line-height: 1;
  padding: 0 0.1rem;
}

.chip-remove:hover {
  color: var(--danger);
}

/* Auswahl der Tiere beim Start einer Behandlung. */
.animal-picker {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 0.75rem 1rem 1rem;
  display: grid;
  gap: 0.4rem;
  grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr));
}

.animal-picker legend {
  font-size: var(--fs-sm);
  color: var(--muted);
  padding: 0 0.35rem;
}

/* Wortlaut der Aufnahme: umbrechen statt scrollen. */
.transcript {
  white-space: pre-wrap;
  word-break: break-word;
  font: inherit;
  background: var(--bg);
  border-radius: var(--radius-sm);
  padding: 0.9rem 1rem;
  margin: 0 0 0.75rem;
  max-height: 24rem;
  overflow-y: auto;
}

/* Angaben als Beschriftung/Wert-Paare. */
.facts {
  display: grid;
  grid-template-columns: minmax(12rem, auto) 1fr;
  gap: 0.35rem 1.25rem;
  margin: 0;
  font-size: var(--fs-sm);
}

.facts dt {
  color: var(--muted);
}

.facts dd {
  margin: 0;
}

/* ------------------------------------------------------------- Beleg --- */

.document {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 2rem;
  margin-top: 1.5rem;
}

.document h1 {
  font-size: var(--fs-lg);
}

.document h2 {
  font-size: var(--fs-base);
  margin: 1.75rem 0 0.5rem;
  padding-bottom: 0.25rem;
  border-bottom: 1px solid var(--border);
}

.document h3 {
  font-size: var(--fs-base);
  margin: 1rem 0 0.4rem;
}

.document-head {
  display: flex;
  flex-wrap: wrap;
  gap: 1.5rem;
  justify-content: space-between;
  align-items: flex-start;
  border-bottom: 2px solid var(--text);
  padding-bottom: 1rem;
}

.document-issuer {
  font-size: var(--fs-sm);
  text-align: right;
  line-height: 1.4;
}

.document-grid {
  display: grid;
  gap: 1.5rem;
  grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
}

.document-medication {
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 0.9rem 1rem;
  margin-bottom: 0.75rem;
}

.signatures {
  display: grid;
  gap: 2.5rem;
  grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
  margin-top: 3rem;
  font-size: var(--fs-sm);
  color: var(--muted);
}

.signature-line {
  display: block;
  border-top: 1px solid var(--text);
  margin-bottom: 0.35rem;
}

@media print {
  .topbar,
  .tableiste,
  .footer,
  .no-print {
    display: none !important;
  }
  body {
    background: #fff;
  }
  .page {
    max-width: none;
    padding: 0;
  }
  .document {
    border: none;
    border-radius: 0;
    padding: 0;
    box-shadow: none;
  }
  .table-wrap {
    border: none;
    overflow: visible;
  }
  .document-medication {
    break-inside: avoid;
  }
}

/* ============================================================== Scannen === */

.btn-lg {
  padding: 0.85rem 1.6rem;
  font-size: var(--fs-md);
}

/*
 * Der Sucher hat immer dieselbe Höhe - mit Kamerabild und ohne.
 *
 * Das ist der Grund, aus dem die Seite nach einem Treffer "nach unten
 * sprang": Beim Treffer geht die Kamera aus, das Videobild verschwand, und
 * die Bühne fiel von Bildhöhe auf ihre Mindesthöhe zusammen. Alles darunter
 * rutschte um ein paar hundert Pixel nach oben - wer herangescrollt hatte,
 * um das Bild gross zu sehen, schaute danach auf "Nummer eintippen". Nichts
 * war gescrollt; der Boden war unter der Ansicht weggezogen worden.
 *
 * Mit fester Höhe bleibt beim Umschalten alles stehen, wo es steht.
 */
.scanner-stage {
  position: relative;
  background: var(--scanner-bg);
  border-radius: var(--radius);
  overflow: hidden;
  margin-bottom: 1rem;
  /* Ein Mass, das in beiden Zuständen trägt: gross genug, um die Marke im
     Bild zu halten, klein genug, dass der schwarze Kasten vor dem Start
     nicht den halben Bildschirm füllt. */
  height: 34vh;
  min-height: 10rem;
  max-height: 20rem;
  display: flex;
  align-items: center;
  justify-content: center;
}

.scanner-video {
  width: 100%;
  height: 100%;
  display: block;
  /* Ausschnitt statt Verzerrung: Die Marke hält man ohnehin in die Mitte. */
  object-fit: cover;
}

/* Zielrahmen: hilft, die Marke mittig und nah genug zu halten. */
.scanner-frame {
  position: absolute;
  inset: 18% 12%;
  border: 2px solid rgba(255, 255, 255, 0.85);
  border-radius: var(--radius-sm);
  box-shadow: 0 0 0 100vmax rgba(0, 0, 0, 0.35);
  pointer-events: none;
}

.scanner-idle {
  color: var(--scanner-text);
  font-size: var(--fs-sm);
  margin: 0;
  padding: 3rem 1rem;
  text-align: center;
  /* Als Flex-Kind richtet sich der Absatz sonst nach seiner Wunschbreite und
     schiebt sich aus dem Sucher heraus. `min-width: 0` wäre zu viel des
     Guten - dann schrumpft er auf ein Zeichen je Zeile. */
  max-width: 100%;
}

/*
 * Die Rückmeldung am Sucher.
 *
 * Sie beantwortet die einzige Frage, die man beim Scannen hat: Hat er die
 * Marke gelesen? Deshalb steht sie unmittelbar unter der Kamera und nicht
 * im Ergebnis weiter unten - dorthin zu springen risse den Blick vom Tier
 * weg, und genau das soll die Anwendung nicht tun.
 */
.scan-meldung {
  margin: 0.75rem 0;
  padding: 0.6rem 0.85rem;
  border-radius: var(--radius-sm);
  border-left: 4px solid var(--border);
  background: var(--bg);
  font-weight: 600;
  /* Eine gelesene Ohrmarke ist eine Ziffernfolge, die man abgleicht. */
  font-variant-numeric: tabular-nums;
}

.scan-meldung.ist-treffer {
  border-left-color: var(--ok);
  background: var(--ok-bg);
  color: var(--ok);
}

.scan-meldung.ist-warten {
  /* Nicht rot: Es wird ja weiter versucht. Rot wäre hier ein Fehlalarm bei
     jeder Marke, die im ersten Anlauf schräg im Bild hängt. */
  border-left-color: var(--warn-mark);
  background: var(--warn-bg);
  color: var(--warn);
}

.scan-title {
  font-size: var(--fs-lg);
  margin: 0 0 0.75rem;
}

.scan-hit .facts {
  margin-bottom: 1rem;
}

/* Auf dem Handy sollen die Knöpfe nicht in einer Reihe zusammenschrumpfen. */
@media (max-width: 560px) {
  /* Zwei Spalten sind hier zu wenig Platz: Die Beschriftung steht dann über
     dem Wert statt daneben. */
  .facts {
    grid-template-columns: 1fr;
    gap: 0 0;
  }
  .facts dt {
    margin-top: 0.6rem;
    font-size: var(--fs-sm);
  }
  .facts dt:first-child {
    margin-top: 0;
  }

  .scanner .row .btn,
  .scan-hit .row .btn,
  .scan-hit .row form {
    flex: 1 1 100%;
  }
  .scan-hit .row form .btn {
    width: 100%;
  }
  .btn-lg {
    width: 100%;
  }
}

/* ------------------------------------------------- Schnellsuche Stamm --- */

/* Trefferliste der Schnellsuche im Artikelstamm.
   Jeder Treffer ist ein Knopf über die volle Breite: Im Stall wird mit einer
   Hand und in Handschuhen bedient, da ist eine grosse Fläche mehr wert als
   eine kompakte Liste. */
.picklist {
  list-style: none;
  margin: 0.5rem 0 0;
  padding: 0;
  max-height: 24rem;
  overflow-y: auto;
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

.picklist li + li {
  border-top: 1px solid var(--border);
}

.picklist form {
  margin: 0;
}

.picklist-item {
  display: block;
  width: 100%;
  padding: 0.7rem 0.9rem;
  border: 0;
  background: none;
  text-align: left;
  font: inherit;
  color: inherit;
  cursor: pointer;
}

.picklist-item:hover,
.picklist-item:focus-visible {
  background: var(--bg);
}

.picklist-name {
  display: block;
  font-weight: 600;
}

.picklist-meta {
  display: block;
  font-size: var(--fs-sm);
  color: var(--muted);
}

/* Ein Feld, das nicht getippt wird, aber wie eines aussehen soll -
   der Name eines Präparats aus dem Artikelstamm. */
.field-label {
  display: block;
  margin-bottom: 0.3rem;
  font-size: var(--fs-sm);
  color: var(--muted);
}

.field-fixed {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  margin: 0;
  padding: 0.5rem 0.7rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg);
}

/* Ausgelisteter Stammeintrag in der Verwaltungstabelle. */
.row-off td {
  opacity: 0.6;
}

@media (max-width: 560px) {
  .picklist-item {
    padding: 0.85rem 0.9rem;
  }
}

/* Hinweisband fuer die Plattform-Administration in einer fremden Praxis.
   Bewusst ueber der ganzen Seite und nicht in einer Karte: Es gilt fuer
   alles, was darunter steht. */
.guestbar {
  margin: 0;
  padding: 0.7rem 1.2rem;
  background: var(--warn-bg);
  border-bottom: 1px solid var(--warn-line);
  color: var(--warn);
  font-size: var(--fs-sm);
}

@media (max-width: 560px) {
  .guestbar {
    padding: 0.6rem 0.9rem;
  }
}

/* Umschalter zwischen den Ansichten einer Auswertung.
   Gleich breite Flaechen, die auf schmalen Geraeten sauber umbrechen -
   nebeneinandergequetschte Knoepfe trifft man mit dem Daumen nicht. */
.tabs .btn {
  flex: 1 1 8rem;
}

/* Ein Auswahlfeld in einer Filterzeile darf seine Karte nicht sprengen.
   Ohne `min-width: 0` waechst das Flex-Element auf die Breite der laengsten
   Option - "Milchviehstall Nord (Familie Bauer)" schob das Feld auf dem Handy
   aus dem Bild. */
.row-form label.inline {
  min-width: 0;
}

.row-form label.inline select,
.row-form label.inline input {
  min-width: 0;
  flex: 1 1 auto;
}

/* Kamera-Knopf neben den Feldern, die er fuellt.

   Ein Label, das wie ein Knopf aussieht: Das Dateifeld darin ist versteckt,
   weil "Choose File / No file chosen" nicht nach Kamera aussieht und im Stall
   auch niemand danach sucht. Auf dem Handy oeffnet `capture` direkt die
   Kamera. */
.camera-cell {
  flex: 1 1 14rem;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
}

.camera-btn {
  /* Bewusst kein Flex-Layout: Symbol und Beschriftung sollen als ein Satz
     umbrechen. Als Flex-Elemente schrumpfte der Text und landete unter dem
     Symbol statt daneben. */
  display: block;
  /* Ein Label ist kein Knopf - der Zeiger muss es trotzdem sagen. */
  cursor: pointer;
  font-weight: 500;
}

/* Tastaturbedienung: Das versteckte Dateifeld bekommt den Fokus, sichtbar ist
   aber nur das Label. Ohne diese Regel saehe man nicht, wo man steht. */
.camera-btn:focus-within {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

@media (max-width: 560px) {
  .camera-cell {
    flex: 1 1 100%;
  }
}

/* ------------------------------------------------- Abschnitte der Behandlung */

/* Zusammenklappbare Abschnitte.

   Die Behandlungsseite ist lang: Aufnahme, Wortlaut, Tiere, Befund,
   Arzneimittel, Abschluss. Am Handy im Stall ist davon immer nur einer
   gemeint - der Rest kostet Wischen. Deshalb ist die Überschrift zugleich
   der Schalter.

   Und weil sie ein Schalter ist, muss sie auch wie einer aussehen: hohe
   Zeile, deutlicher Pfeil in einem eigenen Kreis, sichtbarer Unterschied
   zwischen offen und zu. Der offene Abschnitt wächst mit seinem Inhalt
   zusammen - Kopfzeile und Karte sind dann ein Block und nicht zwei
   Kästchen übereinander.

   Aufgeklappt wird von <details> selbst; hier steht nur das Aussehen. */
summary {
  cursor: pointer;
}

.section {
  margin: 1rem 0;
}

.section > summary {
  /* `position: relative` wegen des Pfeils weiter unten.

     Und bewusst `block` statt `flex`: Ein <summary>, dessen display-Wert
     geändert wird, ist in WebKit seit jeher eine Sorgenstelle - je nach
     Version verschwindet das Dreieck, sitzt der Text daneben oder reagiert
     das Antippen nicht mehr. Die Anordnung übernimmt deshalb ein eigener
     Behälter darin (.section-head); das <summary> bleibt ein schlichter
     Block, der nichts weiter tut, als anklickbar zu sein. */
  position: relative;
  display: block;
  min-height: 3.5rem;
  padding: 0.85rem 4rem 0.85rem 1.1rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  transition:
    background 0.15s ease,
    border-color 0.15s ease;
  /* Der eigene Pfeil steht rechts und dreht sich; der eingebaute Marker
     stünde links und liesse sich nicht ausrichten. */
  list-style: none;
}

.section > summary::-webkit-details-marker {
  display: none;
}

/* Überschrift und Kennzeichen nebeneinander, bei Bedarf untereinander. */
.section-head {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.6rem;
  /* Füllt die Zeilenhöhe des <summary> aus, damit der Inhalt mittig steht,
     auch wenn er nur eine Zeile braucht. */
  min-height: 1.8rem;
}

/* Der Kreis um den Pfeil. Er macht aus der Überschrift sichtbar einen
   Schalter - ein Pfeil allein am Rand liest sich wie Verzierung. */
.section > summary::before {
  content: '';
  position: absolute;
  top: 50%;
  right: 1rem;
  width: 2rem;
  height: 2rem;
  margin-top: -1rem;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 50%;
  transition:
    background 0.15s ease,
    border-color 0.15s ease;
}

.section > summary::after {
  /* Herausgenommen aus dem Fluss, sonst rutschte der Pfeil in eine eigene
     Zeile, sobald Überschrift und Kennzeichen zusammen umbrechen - am Handy
     also fast immer. So steht er am rechten Rand auf halber Höhe, egal wie
     viele Zeilen die Kopfzeile braucht. */
  content: '';
  position: absolute;
  top: 50%;
  right: 1.65rem;
  width: 0.62rem;
  height: 0.62rem;
  margin-top: -0.5rem;
  border-right: 2px solid var(--accent);
  border-bottom: 2px solid var(--accent);
  border-radius: 1px;
  transform: rotate(45deg);
  transition: transform 0.18s ease;
}

.section[open] > summary::after {
  margin-top: -0.16rem;
  transform: rotate(225deg);
}

.section > summary:hover {
  border-color: var(--accent);
}

.section > summary:hover::before {
  background: var(--ok-bg);
  border-color: var(--accent);
}

.section > summary:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* Offen: die Kopfzeile bekommt Farbe und wächst mit der Karte darunter
   zusammen. Zwei getrennte Kästchen liessen offen, was zu wem gehört. */
.section[open] > summary {
  background: var(--ok-bg);
  border-color: var(--border);
  border-bottom-color: transparent;
  border-radius: var(--radius) var(--radius) 0 0;
  box-shadow: none;
}

.section[open] > summary::before {
  background: var(--surface);
}

.section-title {
  font-size: var(--fs-lg);
  font-weight: 600;
  line-height: 1.3;
}

/* Abstand zwischen mehreren Karten in einem Abschnitt, etwa den einzelnen
   Arzneimitteln. */
.section > *:not(summary) {
  margin-top: 0.75rem;
}

/* Die erste Karte hängt direkt an der Kopfzeile. */
.section[open] > summary + .card {
  margin-top: 0;
  border-top-left-radius: 0;
  border-top-right-radius: 0;
}

/* Untergruppen - derzeit die einzelnen Arzneimittel.

   Sie müssen auf einen Blick als *untergeordnet* lesbar sein, sonst sieht
   ein Präparat aus wie ein Hauptabschnitt und die Gliederung geht verloren.
   Drei Mittel zusammen, weil eines allein zu schwach war:

     1. Einzug von links - der Rand des Abschnitts bleibt sichtbar daneben,
     2. eine durchgehende Linie an diesem Rand, die alle Präparate eines
        Abschnitts zu einer Gruppe bindet,
     3. eine Stufe leiser: kleinere Überschrift, flachere Kopfzeile, kein
        Schlagschatten. */
.section-sub {
  position: relative;
  margin-left: 1.1rem;
  padding-left: 0.9rem;
  border-left: 3px solid var(--border);
}

/* Der kurze Querstrich zur Kopfzeile: Er macht aus dem Einzug sichtbar eine
   Verzweigung und nicht nur einen Abstand. */
.section-sub::before {
  content: '';
  position: absolute;
  top: 1.7rem;
  left: 0;
  width: 0.9rem;
  height: 3px;
  background: var(--border);
}

.section-sub[open] {
  border-left-color: var(--accent);
}

.section-sub[open]::before {
  background: var(--accent-solid);
}

.section-sub > summary {
  min-height: 3rem;
  padding-top: 0.65rem;
  padding-bottom: 0.65rem;
  box-shadow: none;
  background: var(--bg);
}

.section-sub .section-title {
  font-size: var(--fs-base);
  font-weight: 600;
}

/* Offen bleibt die Kopfzeile ruhiger als beim Hauptabschnitt: Der Rahmen
   führt zur Karte, die Farbe braucht es dafür nicht. */
.section-sub[open] > summary {
  background: var(--surface);
}

/* Der eigene Pfeil darf kleiner sein als beim Hauptabschnitt - er gehört zu
   einer Zeile, nicht zu einem Block. */
.section-sub > summary::before {
  width: 1.6rem;
  height: 1.6rem;
  margin-top: -0.8rem;
  right: 0.8rem;
}

.section-sub > summary::after {
  right: 1.35rem;
}

@media (max-width: 560px) {
  /* Am Handy ist die Breite knapp: Einzug ja, aber sparsam. */
  .section-sub {
    margin-left: 0.5rem;
    padding-left: 0.5rem;
  }

  .section-sub::before {
    width: 0.5rem;
  }
}

@media (max-width: 560px) {
  .section > summary {
    /* Rechts bleibt Platz für den Pfeil - sonst schöbe sich ein langes
       Kennzeichen darunter. */
    padding: 0.8rem 3.4rem 0.8rem 0.85rem;
  }

  .section > summary::before {
    right: 0.7rem;
    width: 1.85rem;
    height: 1.85rem;
    margin-top: -0.925rem;
  }

  .section > summary::after {
    right: 1.28rem;
  }

  .section-title {
    font-size: var(--fs-md);
  }
}

@media (prefers-reduced-motion: reduce) {
  .section > summary,
  .section > summary::before,
  .section > summary::after {
    transition: none;
  }
}

/* Kennzeichen für "hier fehlt noch etwas". Dieselbe Farbe wie beim
   Hinweisfeld, damit ein fehlender Wert überall gleich aussieht. */
.badge-warn {
  background: var(--warn-bg);
  border-color: transparent;
  color: var(--warn);
}

/* Der Absende-Knopf neben einem Kamera-Feld ist der Weg für Browser ohne
   htmx. Ist htmx da, schickt sich das Formular beim Auswählen des Fotos von
   selbst ab - dann ist der Knopf nur noch ein Rätsel neben dem echten. */
.htmx-da .ohne-htmx {
  display: none;
}

/* ------------------------------------------------ Tiere einer Gruppe sammeln */

/* Der Bestand als Ankreuzliste.

   Mehrspaltig, weil ein Stall dreissig Tiere hat und eine einspaltige Liste
   davon drei auf den Bildschirm brächte. Mit eigener Höhenbegrenzung: Was
   darunter steht - Übernehmen-Knopf und der Weg zurück zur Behandlung - soll
   erreichbar bleiben, ohne an hundert Ohrmarken vorbeizuscrollen. */
.picklist-check {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr));
  gap: 0.25rem 1rem;
  max-height: 22rem;
  overflow-y: auto;
  margin: 0.75rem 0;
  padding: 0.5rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}

/* Grosse Trefferfläche: angehakt wird mit Handschuhen. */
.picklist-check label {
  align-items: center;
  gap: 0.6rem;
  padding: 0.5rem 0.4rem;
  border-radius: 6px;
  cursor: pointer;
}

.picklist-check label:hover {
  background: var(--bg);
}

.picklist-check input[type='checkbox'] {
  width: 1.15rem;
  height: 1.15rem;
  flex-shrink: 0;
}

/* Das gerade zugeordnete Tier hebt sich kurz ab - im Stall schaut man nach
   dem Scan einmal hin und will ohne Suchen sehen, welches es war. */
.chip-neu {
  background: var(--ok-bg);
  border-color: var(--ok);
}

/* Die Liste der zugeordneten Tiere ist eine Liste - ohne Aufzählungspunkte. */
ul.chips {
  list-style: none;
  margin: 0.5rem 0 0;
  padding: 0;
}

/* Schon zugeordnet: in der Bestandsliste angehakt und leicht abgesetzt. */
.picklist-check label.ist-dabei {
  background: var(--ok-bg);
}

/* ------------------------------------------------------------- Zahlenrad --- */

/*
 * Behandlungstage und Wartezeiten am Finger: ein Rad, an dem hoch- und
 * runtergewischt wird. Aufgebaut wird es von zahlenrad.js und nur dort, wo
 * mit dem Finger bedient wird (`pointer: coarse`) - am Schreibtisch bleibt
 * das gewöhnliche Eingabefeld stehen. Die Regeln hier gelten deshalb erst,
 * wenn das Rad tatsächlich in der Seite steht.
 *
 * Das Rasten macht der Browser (`scroll-snap`), nicht das Skript: Schwung,
 * Trägheit und das Einrasten fühlen sich damit an wie überall sonst auf dem
 * Gerät - nachgebaut wäre beides schlechter und mehr Code.
 */
.rad {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin-top: 0.35rem;
}

/* Ein Feld mit Rad braucht mehr Platz als eines mit Zahlenfeld. */
.row-fields > label.narrow.hat-rad {
  flex: 1 1 11rem;
}

.rad-fenster {
  position: relative;
  flex: 0 1 5.5rem;
  min-width: 4rem;
}

.rad-bahn {
  height: 8.4rem;
  overflow-y: auto;
  scroll-snap-type: y mandatory;
  /* Am Ende des Rades soll nicht die Seite darunter weiterrutschen. */
  overscroll-behavior: contain;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  /* Die Leiste würde neben dreistelligen Zahlen kaum Platz lassen - und was
     zu sehen ist, sagt ohnehin die Marke in der Mitte. */
  scrollbar-width: none;
  /* Oben und unten ausblenden: Der Rand des Rades soll nicht wie ein
     abgeschnittener Text aussehen. */
  -webkit-mask-image: linear-gradient(
    to bottom,
    transparent 0,
    #000 2.2rem,
    #000 6.2rem,
    transparent 100%
  );
  mask-image: linear-gradient(
    to bottom,
    transparent 0,
    #000 2.2rem,
    #000 6.2rem,
    transparent 100%
  );
}

.rad-bahn::-webkit-scrollbar {
  display: none;
}

.rad-bahn:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.rad-liste {
  list-style: none;
  margin: 0;
  /* Genau eine Zeile Luft oben und unten, damit auch die erste und die
     letzte Zahl in der Mitte stehen können. */
  padding: 2.8rem 0;
}

.rad-wert {
  height: 2.8rem;
  display: flex;
  align-items: center;
  justify-content: center;
  scroll-snap-align: center;
  font-size: var(--fs-lg);
  font-variant-numeric: tabular-nums;
  color: var(--muted);
}

/* Der Balken, in dem der geltende Wert steht. Er liegt über der Bahn und
   nimmt keine Berührung an - gewischt wird auf dem Rad darunter. */
.rad-marke {
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  height: 2.8rem;
  transform: translateY(-50%);
  border-radius: var(--radius-sm);
  border: 2px solid var(--accent);
  /* Nur eine leichte Tönung über der Zahl - durchscheinend statt
     multipliziert, damit sie hell wie dunkel lesbar bleibt. */
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  pointer-events: none;
}

.rad-knopf {
  flex: 0 0 auto;
  width: 2.6rem;
  height: 2.6rem;
  font: inherit;
  font-size: 1.3rem;
  line-height: 1;
  color: var(--text);
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  cursor: pointer;
}

.rad-knopf:active {
  background: var(--ok-bg);
  border-color: var(--accent);
}

/* Der Ausweg zur Tastatur: Was auf dem Rad zu weit weg liegt, tippt man
   schneller. Bewusst leise - der Regelfall ist das Rad. */
.rad-tippen {
  width: 2.4rem;
  height: 2.4rem;
  font-size: var(--fs-xs);
  letter-spacing: 0.02em;
  color: var(--muted);
  background: none;
}

/* -------------------------------------------------------- Heutige Einsätze --- */

/* Am Schreibtisch nur zwei Kleinigkeiten: Die Zusatzwörter für die schmale
   Ansicht bleiben weg, und der Knopf braucht keinen Umbruch. */
.nur-schmal {
  display: none;
}

.einsaetze .btn {
  white-space: nowrap;
}

/*
 * Am Handy wird aus jeder Zeile ein Block.
 *
 * Sieben Spalten passen auf kein Telefon; bisher musste man zur Seite
 * scrollen, um zur Uhrzeit den Betrieb zu finden. Jetzt stehen sie
 * untereinander:
 *
 *     09:15        Milchviehstall Nord         offen
 *     Fam. Bauer   Ammerbuch                12 Tiere
 *     [        Öffnen über die volle Breite        ]
 *
 * Gemacht wird das mit einem Raster aus drei Spalten, in dem jede Zelle
 * ihren Platz bekommt. Die Tabelle bleibt eine Tabelle - für die Ansicht am
 * Schreibtisch und für Vorleseprogramme.
 *
 * Die Grenze liegt bei 820px und damit über dem Hochformat eines Tablets:
 * Dort ist die Tabelle mit sieben Spalten schon zu breit, sobald ein
 * Betreiber einmal ausgeschrieben "Landwirtschaftliche Betriebsgemeinschaft
 * ... GbR" heisst.
 */
@media (max-width: 820px) {
  .wrap-einsaetze {
    /* Der Rahmen sitzt jetzt an den einzelnen Blöcken. */
    background: none;
    border: 0;
    border-radius: 0;
    overflow-x: visible;
  }

  .einsaetze,
  .einsaetze tbody,
  .einsaetze tr,
  .einsaetze td {
    display: block;
  }

  /* Die Kopfzeile trägt in dieser Ansicht nichts mehr: Was die Angaben
     bedeuten, sagen sie selbst. Sie bleibt aber im Dokument stehen. */
  .einsaetze thead {
    display: none;
  }

  .einsaetze tr {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    gap: 0.2rem 0.7rem;
    align-items: baseline;
    margin-bottom: 0.75rem;
    padding: 0.85rem;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
  }

  .einsaetze td {
    padding: 0;
    border: 0;
    /* Ohne das weigert sich eine Rasterzelle zu schrumpfen. */
    min-width: 0;
    overflow-wrap: break-word;
  }

  /* Zeile 1: Uhrzeit, Betrieb, Stand. */
  .einsaetze td:nth-child(1) { grid-area: 1 / 1; }
  .einsaetze td:nth-child(2) { grid-area: 1 / 2; }
  .einsaetze td:nth-child(6) { grid-area: 1 / 3; justify-self: end; }

  /* Zeile 2: der Betreiber über die volle Breite. Er steht nicht in einer
     eigenen Spalte, weil ein ausgeschriebener Name ("Landwirtschaftliche
     Betriebsgemeinschaft … GbR") die Spalte sonst entweder über den
     Bildschirmrand schiebt oder in eine Buchstabensäule presst. Über die
     ganze Breite bricht er einfach um. */
  .einsaetze td:nth-child(3) { grid-area: 2 / 1 / auto / -1; }

  /* Zeile 3: Ort links, Anzahl rechts. */
  .einsaetze td:nth-child(4) { grid-area: 3 / 1 / auto / 3; }
  .einsaetze td:nth-child(5) { grid-area: 3 / 3; justify-self: end; }

  .einsaetze td:nth-child(7) { grid-area: 4 / 1 / auto / -1; }

  /* Betreiber, Ort und Anzahl sind die Beiwerk-Zeile - leiser als der
     Betrieb darüber, damit der Blick zuerst dorthin fällt. */
  .einsaetze td:nth-child(3),
  .einsaetze td:nth-child(4),
  .einsaetze td:nth-child(5) {
    color: var(--muted);
    font-size: var(--fs-sm);
  }

  .einsaetze td:nth-child(2) a {
    font-weight: 600;
  }

  .nur-schmal {
    display: inline;
  }

  /* Der Knopf ist am Handy die eigentliche Handlung der Zeile: volle Breite,
     Daumengrösse. Als leiser Verweis am Rand war er kaum als Knopf zu
     erkennen und schon gar nicht bequem zu treffen. */
  .einsaetze td:nth-child(7) {
    margin-top: 0.6rem;
  }

  .einsaetze td:nth-child(7) .btn {
    display: block;
    width: 100%;
    /* Auf einem Tablet im Hochformat wäre die volle Breite für ein Wort zu
       viel des Guten. */
    max-width: 26rem;
    padding: 0.7rem 1rem;
    font-weight: 500;
  }
}

/* ===========================================================================
   Behandlung per Auswahl: Erfassungsart, Altersklasse, Körperbereiche

   Alles hier ist auf den Daumen ausgelegt, nicht auf die Maus. Im Stall wird
   das Handy mit einer Hand gehalten, oft in Handschuhen - deshalb grosse
   Flächen, viel Abstand und keine Ziele, die kleiner sind als eine
   Fingerkuppe.
   ========================================================================= */

/* --------------------------------------------- Sprechen oder klicken --- */
.modus-frage h2 {
  margin-top: 0;
}

.modus-knoepfe {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  gap: 0.9rem;
}

.modus-knopf {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.35rem;
  min-height: 8.5rem;
  padding: 1.2rem 1rem;
  background: var(--surface);
  border: 2px solid var(--border);
  border-radius: var(--radius);
  font: inherit;
  color: inherit;
  text-align: center;
  cursor: pointer;
  transition:
    border-color 0.15s ease,
    background 0.15s ease;
}

.modus-knopf:hover,
.modus-knopf:focus-visible {
  background: var(--ok-bg);
  border-color: var(--accent);
}

.modus-zeichen {
  font-size: 2.4rem;
  line-height: 1;
}

.modus-titel {
  font-size: var(--fs-lg);
  font-weight: 600;
}

.modus-erklaerung {
  font-size: var(--fs-sm);
  color: var(--muted);
}

/* ------------------------------------------------ Kalb oder Alttier --- */
/* Zwei Knöpfe, und der Unterschied zwischen ihnen ist genau das, worum es
   geht: das eine Tier klein, das andere gross. Deshalb steht die Grösse im
   Bild und nicht nur im Wort. */
.alter-wahl {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
  gap: 0.9rem;
  margin: 1rem 0;
}

.alter-knopf {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  gap: 0.5rem;
  min-height: 10rem;
  padding: 1rem;
  background: var(--surface);
  border: 2px solid var(--border);
  border-radius: var(--radius);
  color: inherit;
  text-decoration: none;
  transition:
    border-color 0.15s ease,
    background 0.15s ease;
}

.alter-knopf:hover,
.alter-knopf:focus-visible {
  background: var(--ok-bg);
  border-color: var(--accent);
}

.alter-bild {
  line-height: 1;
}

.alter-klein {
  font-size: 2.2rem;
}

.alter-gross {
  font-size: 4rem;
}

.alter-titel {
  font-size: var(--fs-md);
  font-weight: 600;
}

/* --------------------------------------------------- Umriss des Rinds --- */
.kuh-rahmen {
  padding: 0.5rem;
  margin: 0.75rem 0;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}

.kuh {
  display: block;
  width: 100%;
  height: auto;
}

.kuh-koerper {
  fill: var(--kuh);
}

/* Die Felder: getönt genug, um als Fläche zu lesen, durchsichtig genug, um
   den Umriss darunter nicht zu verdecken. */
.kuh-feld {
  cursor: pointer;
}

.kuh-feld ellipse,
.kuh-feld rect,
.kuh-feld path {
  fill: var(--accent);
  fill-opacity: 0.16;
  stroke: var(--accent);
  stroke-width: 2;
  transition: fill-opacity 0.15s ease;
}

.kuh-feld:hover ellipse,
.kuh-feld:hover rect,
.kuh-feld:hover path,
.kuh-feld:focus-visible ellipse,
.kuh-feld:focus-visible rect,
.kuh-feld:focus-visible path {
  fill-opacity: 0.42;
}

.kuh-feld text {
  fill: var(--accent-dark);
  font-size: 13px;
  font-weight: 600;
  text-anchor: middle;
  /* Sonst fängt die Schrift den Zeiger ab und der Tipp geht ins Leere. */
  pointer-events: none;
}

.kuh-feld:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* Bereiche ohne Ort am Tier - Stoffwechsel, Haut. */
.bereich-knoepfe {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
  gap: 0.6rem;
  margin: 0.75rem 0;
}

/* Ein Knopf, den man im Stall mit dem Daumen trifft. */
.btn-gross {
  display: inline-block;
  padding: 0.85rem 1.4rem;
  font-size: var(--fs-md);
}

@media (prefers-reduced-motion: reduce) {
  .modus-knopf,
  .alter-knopf,
  .kuh-feld ellipse,
  .kuh-feld rect,
  .kuh-feld path {
    transition: none;
  }
}

/* Das jeweils fernere Bein eines Paares: etwas dunkler, damit der Umriss
   Tiefe bekommt und nicht als flache Fläche liest. */
.kuh-fern {
  fill: var(--kuh-fern);
}

/* ===========================================================================
   Fehlende Pflichtangaben am Feld markieren

   Die Aufzählung im Abschluss sagt, was fehlt - aber nicht, wo. Bei drei
   Präparaten mit je einem Dutzend Feldern ist das eine Suche. Deshalb wird
   das Feld selbst gekennzeichnet.

   Nicht allein über Farbe: Neben der Beschriftung steht „fehlt". Ein
   farbiger Rahmen hilft niemandem, der Farben schlecht unterscheidet - und
   bei Sonne auf dem Display im Stall auch sonst kaum.
   ========================================================================= */
.feld-kopf {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.4rem;
}

.fehlt-marke {
  padding: 0.05rem 0.4rem;
  background: var(--warn-bg);
  border-radius: var(--radius-pill);
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--warn);
  text-transform: uppercase;
}

.fehlt > input,
.fehlt > textarea,
.fehlt > select {
  border-color: var(--warn-line);
  background: var(--warn-bg-leicht);
  /* Der Streifen am linken Rand bleibt sichtbar, auch wenn das Feld selbst
     bei schmalen Spalten kaum Rahmen zeigt. */
  box-shadow: inset 3px 0 0 var(--warn-line);
}

.fehlt > input:focus-visible,
.fehlt > textarea:focus-visible,
.fehlt > select:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* Die offenen Punkte im Abschluss sind Sprungziele auf das jeweilige Feld. */
.fehlt-liste a {
  color: inherit;
}

.fehlt-liste a:hover,
.fehlt-liste a:focus-visible {
  text-decoration: none;
}

/* ===========================================================================
   Autospeicherung, Gewicht, errechnete Menge, Abbruch
   ========================================================================= */

/* Der Speicherstand neben dem Knopf.
   Er muss sichtbar sein, sonst verlässt man sich auf ein Speichern, das
   gelegentlich nicht klappt - und das wäre schlechter als gar keines. */
.speicherstand {
  font-size: var(--fs-sm);
  color: var(--muted);
  align-self: center;
}

.speicherstand.ist-gespeichert {
  color: var(--ok);
}

.speicherstand.ist-fehler {
  color: var(--danger);
  font-weight: 600;
}

/* ------------------------------------------------------------ Gewicht --- */
.gewicht-karte {
  margin: 1rem 0;
}

.gewicht-karte .row-fields {
  align-items: flex-end;
}

.gewicht-hinweis {
  flex: 1 1 14rem;
  margin: 0 0 0.5rem;
}

/* ---------------------------------------------------- Errechnete Menge --- */
/* Steht neben dem Mengenfeld und ist als Rechnung erkennbar, nicht als
   Eingabe: heller Grund, kein Rahmen wie bei einem Feld. Wer sie mit einem
   ausgefüllten Feld verwechselte, trüge sie nicht ein. */
.menge-rechnung {
  flex: 1 1 16rem;
  padding: 0.6rem 0.8rem;
  background: var(--ok-bg);
  border-radius: var(--radius);
}

.menge-werte {
  margin: 0.15rem 0 0;
  font-size: var(--fs-base);
}

.menge-trenner {
  margin: 0 0.25rem;
  color: var(--muted);
}

.menge-grundlage {
  margin: 0.15rem 0 0;
}

.menge-uebernehmen {
  margin-top: 0.5rem;
}

/* ---------------------------------------------------------- Abbrechen --- */
.abbruch {
  margin-top: 1rem;
}

.abbruch-schalter {
  font-weight: 600;
  color: var(--danger);
}

/* Rot, weil dabei kein Beleg entsteht - das ist der Punkt, an dem man kurz
   nachdenken soll. Nicht rot als Warnung vor einem Fehler: Abbrechen ist ein
   ordentlicher Ausgang, nur eben ein endgültiger. */
.btn-abbruch {
  background: var(--danger-solid);
  border-color: var(--danger-solid);
  color: var(--on-solid);
}

.btn-abbruch:hover,
.btn-abbruch:focus-visible {
  background: var(--danger-solid-hover);
  border-color: var(--danger-solid-hover);
  color: var(--on-solid);
}

/* Der Grund eines Abbruchs in der Übersicht. */
.abbruch-grund {
  display: block;
  font-size: var(--fs-sm);
  color: var(--muted);
}

/* Das Gewichtsfeld am einzelnen Tier: klein, damit die Kachel eine Kachel
   bleibt und nicht zur Zeile wird. */
.tier-gewicht {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  margin: 0;
}

.tier-gewicht input {
  width: 4.5rem;
  padding: 0.25rem 0.4rem;
}

/* Der Schalter für die Autospeicherung. Steht oben, weil er für alles
   darunter gilt - und ruhig, weil er im Regelfall angehakt bleibt. */
.autospeichern-schalter {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.4rem 0.9rem;
  margin: 1rem 0;
  padding: 0.7rem 0.9rem;
}

.autospeichern-schalter label {
  font-weight: 500;
}

/* Ein Knopf, für den es gerade nichts zu tun gibt. Sichtbar bleibt er
   trotzdem: Er sagt, dass alles gespeichert ist. */
.btn:disabled,
.btn[disabled] {
  opacity: 0.45;
  cursor: default;
  box-shadow: none;
}

.btn:disabled:hover,
.btn[disabled]:hover {
  background: inherit;
  border-color: inherit;
}

/* ------------------------------------------------------- Textbausteine --- */
/* Vorschläge über dem Feld. Klein und leise: Sie sollen das Feld anbieten,
   nicht überdecken - und im Stall trotzdem mit dem Daumen zu treffen sein. */
.bausteine {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  margin: 0.15rem 0 0.1rem;
}

.baustein {
  padding: 0.35rem 0.7rem;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  font: inherit;
  font-size: var(--fs-sm);
  font-weight: 500;
  color: var(--text);
  cursor: pointer;
  transition:
    background 0.15s ease,
    border-color 0.15s ease;
}

.baustein:hover,
.baustein:focus-visible {
  background: var(--ok-bg);
  border-color: var(--accent);
  color: var(--accent-dark);
}

/* Was nicht zum Fall passt, klappt weg statt zu verschwinden. Bewusst leise:
   Wer den passenden Knopf oben findet, soll hier gar nicht hinsehen. Kein
   `display` auf dem <summary> - WebKit macht daraus sonst ein Element ohne
   Aufklapp-Dreieck. */
.weitere-bausteine {
  margin: 0.1rem 0 0.25rem;
}

.weitere-bausteine > summary {
  color: var(--muted);
  font-size: var(--fs-sm);
  cursor: pointer;
  /* Genug Fläche für den Daumen, ohne dass es nach Knopf aussieht. */
  padding: 0.25rem 0;
}

.weitere-bausteine > summary:hover,
.weitere-bausteine > summary:focus-visible {
  color: var(--text);
}

/* -------------------------------------------------------- Leistungen --- */
.leistungsliste {
  list-style: none;
  margin: 0;
  padding: 0;
}

.leistungsliste li {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem 0.9rem;
  padding: 0.6rem 0;
}

.leistungsliste li + li {
  border-top: 1px solid var(--border);
}

.leistung-name {
  flex: 1 1 12rem;
  font-weight: 500;
}

.leistung-anzahl {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  margin: 0;
}

.leistung-anzahl input {
  width: 4.5rem;
  padding: 0.25rem 0.4rem;
}

@media (prefers-reduced-motion: reduce) {
  .baustein {
    transition: none;
  }
}

/* ===========================================================================
   Dokumentierte Behandlungen: am Handy Blöcke statt Tabelle

   Sieben Spalten passen auf kein Telefon. Bisher musste man dafür nach
   rechts scrollen - und ausgerechnet die Diagnose, wegen der man die Liste
   liest, stand ausserhalb des Bildes.

   Dieselbe Machart wie bei "Heutige Einsätze": Das Markup bleibt eine
   Tabelle, nur die Darstellung wird ein Raster.
   ========================================================================= */
@media (max-width: 820px) {
  .wrap-behandlungen {
    /* Der Rahmen sitzt jetzt an den einzelnen Blöcken. */
    background: none;
    border: 0;
    border-radius: 0;
    overflow-x: visible;
  }

  .behandlungen,
  .behandlungen tbody,
  .behandlungen tr,
  .behandlungen td {
    display: block;
  }

  /* Die Kopfzeile trägt hier nichts mehr: Was die Angaben bedeuten, sagen
     sie selbst. Im Dokument bleibt sie stehen. */
  .behandlungen thead {
    display: none;
  }

  .behandlungen tr {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 0.25rem 0.7rem;
    align-items: baseline;
    margin-bottom: 0.75rem;
    padding: 0.85rem;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
  }

  .behandlungen td {
    padding: 0;
    border: 0;
    /* Ohne das weigert sich eine Rasterzelle zu schrumpfen. */
    min-width: 0;
    overflow-wrap: break-word;
  }

  /* Zeile 1: Zeitpunkt links, Stand rechts. */
  .behandlungen td:nth-child(1) { grid-area: 1 / 1; }
  .behandlungen td:nth-child(6) { grid-area: 1 / 2; justify-self: end; }

  /* Zeile 2: der Stall über die ganze Breite - ein ausgeschriebener Name
     presste sich in einer schmalen Spalte zur Buchstabensäule. */
  .behandlungen td:nth-child(2) { grid-area: 2 / 1 / auto / -1; }

  /* Zeile 3: die Diagnose, ebenfalls über die ganze Breite. Sie ist der
     Grund, warum man diese Liste überhaupt liest. */
  .behandlungen td:nth-child(4) { grid-area: 3 / 1 / auto / -1; }

  /* Zeile 4: die Ohrmarken. */
  .behandlungen td:nth-child(3) { grid-area: 4 / 1 / auto / -1; }

  /* Zeile 5: Anzahl Arzneimittel links, Belegnummer rechts. */
  .behandlungen td:nth-child(5) { grid-area: 5 / 1; }
  .behandlungen td:nth-child(7) { grid-area: 5 / 2; justify-self: end; }

  .behandlungen td:nth-child(1) a {
    font-weight: 600;
  }

  .behandlungen td:nth-child(2) {
    font-weight: 600;
  }

  /* Beiwerk-Zeile: leiser als Stall und Diagnose darüber. */
  .behandlungen td:nth-child(5),
  .behandlungen td:nth-child(7) {
    color: var(--muted);
    font-size: var(--fs-sm);
  }

  /* `num` richtet am Schreibtisch rechtsbündig aus - hier steht die Zahl
     am Anfang ihrer Zeile. Und "Arzneimittel" bleibt ein Wort: Das
     `break-word` weiter oben braucht es für lange Betriebsnamen, hier
     zerlegte es die Einheit in "Arzneimitte" und "l". */
  .behandlungen td.num {
    text-align: left;
    overflow-wrap: normal;
  }

  /* Der Stand steht rechts. Ein langer Abbruchgrund darunter darf die
     Spalte aber nicht beliebig breit ziehen - sonst bliebe für den
     Zeitpunkt daneben kein Platz mehr. */
  .behandlungen td:nth-child(6) {
    max-width: 14rem;
    text-align: right;
  }

  .behandlungen .abbruch-grund {
    /* Der Grund gehört unter das Kennzeichen, nicht daneben. */
    display: block;
    margin-top: 0.15rem;
    text-align: right;
  }
}

/* ===========================================================================
   Knopfreihen

   Bisher stand jede Schaltfläche in einer eigenen `.row`, und die Reihen
   liefen unterschiedlich weit auseinander. Das las sich unfertig: Man sah
   Knöpfe, aber nicht, welche zusammengehören und welche der Hauptweg ist.

   `.aktionen` ist die eine Form dafür: links, was man tut; rechts, was man
   selten tut oder rückgängig macht. Am Handy nimmt die Haupthandlung die
   ganze Breite - dort ist sie der Daumen-Weg -, und die leisen Knöpfe
   rutschen unter eine Trennlinie, damit man nicht danebengreift.
   ========================================================================= */
.aktionen {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem;
  margin-top: 0.9rem;
}

/* Was rechts steht: Zuordnung lösen, Entfernen, Verwerfen. */
.aktionen-rechts {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem;
  margin-left: auto;
}

.aktionen-rechts form {
  margin: 0;
}

@media (max-width: 560px) {
  .aktionen > .btn-primary,
  .aktionen > form > .btn-primary {
    /* Die Haupthandlung über die ganze Breite: Sie ist am Handy das Ziel
       des Daumens, und ein halbbreiter Knopf neben einem Statustext ist
       schwerer zu treffen als er sein müsste. */
    flex: 1 1 100%;
  }

  .aktionen-rechts {
    width: 100%;
    margin-left: 0;
    justify-content: flex-end;
    padding-top: 0.5rem;
    border-top: 1px solid var(--border);
  }
}

/* ---------------------------------------------------------------- Wege --- */
/* Mehrere gleichwertige Einstiege nebeneinander - beim Arzneimittel sind es
   drei: auswählen, fotografieren, ansagen. Gleich gross und gleich schwer,
   weil keiner davon der richtigere ist. Untereinander gestapelt sahen sie
   aus wie eine Rangfolge, die es nicht gibt.

   Gleich gross hiess bis jetzt: ein Raster aus drei gleich breiten Feldern.
   Am Handy war das dann doch ein Stapel - drei volle Balken übereinander,
   über 200 Pixel hoch, bevor überhaupt ein Präparat dastand. Jetzt ist es
   eine Reihe, in der jeder Knopf so breit ist wie seine Beschriftung und
   umbricht, wenn es eng wird. Hervorgehoben ist weiterhin keiner. */
.wege {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  align-items: center;
}

/* Die Ansage bringt zwei Knöpfe mit (starten, fertig) und ihre Rückmeldung.
   `contents` stellt die Knöpfe in dieselbe Reihe wie die anderen beiden -
   als eigener Kasten hätte die Ansage eine dritte Spalte belegt und ihren
   Ladebalken auf Streichholzbreite gequetscht. Der Balken bringt seine
   eigene volle Breite mit und landet dadurch in der Zeile darunter, quer
   unter den Knöpfen: genau dort, wo der Blick nach dem Auslösen ohnehin
   ist. */
.weg-diktat {
  display: contents;
}

/* --------------------------------------------------- Ausweichwege --- */
/* Zugeklappte Nebenwege (Datei hochladen, ohne Artikelstamm erfassen). Sie
   sollen erreichbar sein, aber nicht wie eine Hauptsache aussehen. */
.ausweich {
  margin-top: 0.9rem;
  padding: 0 0.75rem;
  background: var(--bg);
  border: 1px dashed var(--border);
  border-radius: var(--radius);
  box-shadow: none;
}

/* Die ganze Zeile ist der Schalter und daumenhoch - nicht nur die Schrift. */
.ausweich > summary {
  padding: 0.7rem 0;
  min-height: var(--tap);
  font-size: var(--fs-sm);
  color: var(--muted);
}

.ausweich[open] {
  padding-bottom: 0.75rem;
}

/* =========================================================================
   Technisches Protokoll

   Zwei Angaben stehen hier nebeneinander, die man vergleichen soll:
   angefragt und geantwortet. Alles andere ordnet sich dem unter.
   ========================================================================= */
.kennwerte {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.35rem 1rem;
  margin: 0 0 0.6rem;
}

.kennwerte dt {
  color: var(--muted);
}

.kennwerte dd {
  margin: 0;
}

/* Ein fehlgeschlagener Aufruf ist kein Nebenbefund - dafür liest man das
   Protokoll. Er wird deshalb ruhig, aber sichtbar abgesetzt. */
.protokoll .zeile-fehler > td:first-child {
  border-left: 3px solid var(--danger);
  padding-left: 0.5rem;
}

.protokoll-fehler {
  display: block;
  margin-top: 0.2rem;
  color: var(--muted);
  font-size: 0.85em;
}

.protokoll-fehler {
  /* Erbt sonst die Auszeichnung der Schritt-Spalte. */
  font-weight: 400;
}

/* Modellnamen sind zum Vergleichen da. Mitten im Wort umgebrochen -
   "claude-haiku-4-" / "5" - kann man sie nicht mit einem Blick gegeneinander
   halten, also lieber die Spalte breiter. */
.protokoll code {
  white-space: nowrap;
  font-size: 0.82em;
}

/* Sieben Spalten, davon zwei mit Modellnamen, die nicht umbrechen dürfen -
   das wird schnell breiter als der Inhaltsbereich. Etwas enger gesetzt
   passt es, ohne dass die Dauer nach rechts aus dem Bild rutscht. */
.protokoll th,
.protokoll td {
  padding-left: 0.5rem;
  padding-right: 0.5rem;
}

@media (max-width: 820px) {
  .wrap-protokoll {
    background: none;
    border: 0;
    border-radius: 0;
    overflow-x: visible;
  }

  .protokoll,
  .protokoll tbody,
  .protokoll tr,
  .protokoll td {
    display: block;
  }

  .protokoll thead {
    display: none;
  }

  .protokoll tr {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 0.25rem 0.7rem;
    align-items: baseline;
    margin-bottom: 0.75rem;
    padding: 0.85rem;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
  }

  .protokoll td {
    padding: 0;
    border: 0;
    min-width: 0;
    overflow-wrap: break-word;
  }

  /* Zeile 1: Schritt links, Zeitpunkt rechts. */
  .protokoll td:nth-child(2) { grid-area: 1 / 1; font-weight: 600; }
  .protokoll td:nth-child(1) { grid-area: 1 / 2; justify-self: end; color: var(--muted); }
  /* Zeile 2: Zweck. */
  .protokoll td:nth-child(3) { grid-area: 2 / 1 / auto / -1; color: var(--muted); }
  /* Zeile 3 und 4: die beiden Modelle - untereinander, damit der
     Vergleich am Telefon nicht am Rand abreisst. */
  .protokoll td:nth-child(4) { grid-area: 3 / 1 / auto / -1; }
  .protokoll td:nth-child(5) { grid-area: 4 / 1 / auto / -1; }
  /* Zeile 5: Verbrauch links, Dauer rechts. */
  .protokoll td:nth-child(6) { grid-area: 5 / 1; }
  .protokoll td:nth-child(7) { grid-area: 5 / 2; justify-self: end; }

  /* Am Telefon ist der Platz knapper als der längste Modellname; hier darf
     er umbrechen, dafür stehen die beiden Namen untereinander. */
  .protokoll code {
    white-space: normal;
    overflow-wrap: anywhere;
  }

  .protokoll td:nth-child(4)::before { content: "angefragt "; color: var(--muted); }
  .protokoll td:nth-child(5)::before { content: "geantwortet "; color: var(--muted); }

  .protokoll td.num {
    text-align: left;
    color: var(--muted);
    font-size: 0.9em;
  }

  .protokoll td:nth-child(7) { text-align: right; }

  .protokoll .zeile-fehler {
    border-color: var(--danger);
  }

  .protokoll .zeile-fehler > td:first-child {
    border-left: 0;
    padding-left: 0;
  }
}

/* ------------------------------------------------- Wartezeiten je Tierart --- */
/* Ein Präparat, das für Rind und Schwein zugelassen ist, hat zwei
   verschiedene Wartezeiten - deshalb eine Tabelle und kein Feld. Sie ist die
   Auskunft; entschieden wird darunter, je Tierart einzeln. */
.wartezeiten {
  margin-top: 1.25rem;
}

.wartezeiten h2 {
  margin-top: 0;
}

/* Fünf Spalten passen am Telefon nicht nebeneinander. Scrollen darf dieser
   Kasten, die Seite nicht: Eine Seite, die sich waagerecht schieben lässt,
   verliert man beim Blättern. */
.wrap-wartezeiten {
  overflow-x: auto;
  margin-bottom: 1rem;
}

.wartezeiten-liste {
  width: 100%;
  border-collapse: collapse;
  /* Ohne das schrumpfen die Spalten, statt den Kasten scrollen zu lassen -
     und "Vorschlag" bricht mitten im Wort um. Knapp bemessen: Mit vier
     Spalten passt die Tabelle am Telefon ganz ins Bild, und die Spalte, die
     sagt ob die Angabe überhaupt gilt, steht dann auch da. Der Kasten
     scrollt erst, wenn die Eier-Spalte dazukommt. */
  min-width: 19rem;
}

.wartezeiten-liste th,
.wartezeiten-liste td {
  padding: 0.5rem 0.45rem;
  text-align: left;
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}

.wartezeiten-liste .num {
  text-align: right;
}

/* Die Fundstelle steht bewusst vollständig da, mit Adresse: Wer die Zahl
   gegenliest, soll sie nachschlagen können, ohne zu suchen. Eine Adresse ist
   aber länger als ein Telefon breit - hier darf sie umbrechen, wo es sein
   muss. */
.wartezeiten .quelle {
  margin: 0.75rem 0;
  overflow-wrap: anywhere;
}

.freigabe-vermerk {
  margin: 0.75rem 0 0.25rem;
  font-size: var(--fs-sm);
}

/* ------------------------------------------------------------- Befunde --- */
/* Was an einem Arzneimittel auffällt, ohne einen Abschluss zu verhindern:
   ein verbotener Stoff am lebensmittelliefernden Tier, eine Umwidmung, die
   Mindestwartezeiten dazu.

   Bewusst nicht als `alert`: Die Meldungen dort sind Rückmeldungen auf eine
   Handlung und verschwinden wieder. Ein Befund gehört zum Vorgang und steht
   auch an der abgeschlossenen Behandlung noch da. */
.befund {
  margin: 0 0 0.75rem;
  padding: 0.75rem 0.85rem;
  border-radius: var(--radius-sm);
  border-left: 4px solid var(--border);
  background: var(--surface);
}

.befund p {
  margin: 0;
}

.befund p + p {
  margin-top: 0.3rem;
}

/* Zwei Gewichte. Die Umwidmung ist eine Auflage: Sie ist zu begründen und
   verlängert die Wartezeit. Der verbotene Stoff ist etwas anderes - dafür
   gibt es keine Wartezeit, nach der es ginge.

   Dieselben Farben wie bei `alert-warn` und `alert-danger`: Es gibt in dieser
   Anwendung genau zwei Sorten "aufpassen", und sie sollen überall gleich
   aussehen. Eine dritte Warnfarbe einzuführen hiesse, dem Auge eine
   Unterscheidung beizubringen, die es nicht gibt. */
.befund-umwidmung {
  border-left-color: var(--warn);
  background: var(--warn-bg);
  color: var(--warn);
}

.befund-verboten {
  border-left-color: var(--danger);
  background: var(--danger-bg);
  color: var(--danger);
}

.befund-verboten p:first-child {
  font-weight: 600;
}

/* Die Erinnerung an das Antibiogramm ist die leiseste der drei: Sie kann
   zutreffen und trotzdem erledigt sein, denn beim Einzeltier entfällt die
   Pflicht bei ausreichenden Kenntnissen zur Resistenzlage. Sie soll auffallen
   und nicht anklagen. */
.befund-antibiogramm {
  border-left-color: var(--accent);
  background: var(--bg);
}

/* --------------------------------------------------------- Durchsicht --- */
/* Die Liste der offenen Punkte aus der fachlichen Durchsicht. Bewusst eine
   Liste und keine Tabelle: Zu jedem Punkt gehören ein Hinweis und eine
   Fundstelle, und die passen in keine Spalte. */
.durchsicht-liste {
  list-style: none;
  margin: 0;
  padding: 0;
}

.durchsicht-liste > li {
  padding: 0.85rem 0;
  border-top: 1px solid var(--border);
}

.durchsicht-liste > li:first-child {
  border-top: 0;
}

.durchsicht-liste p {
  margin: 0 0 0.25rem;
}

.durchsicht-liste p:last-child {
  margin-bottom: 0;
}

.durchsicht-kopf {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.5rem;
  font-weight: 600;
}

.durchsicht-werte {
  font-size: var(--fs-base);
}

/* ================================================== Einsatzplanung === */
/* Der Tag zum Abarbeiten. Bewusst eine Liste und keine Tabelle: Zu jedem
   Einsatz gehören Anlass, Bemerkung, Zuteilung und bis zu vier Knöpfe - das
   passt in keine Spalte, und am Handy wäre aus jeder Zeile ohnehin wieder ein
   Block geworden. */

/* Gegenstück zu `.nur-schmal`: Wörter, die nur am Schreibtisch Platz haben.
   Am Handy heisst der Knopf „←", am grossen Bildschirm „← Vortag". */
.nur-breit {
  display: inline;
}

.tagwechsel {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0.75rem 0 0.25rem;
}

/* Die Mitte nimmt den Platz, die Pfeile bleiben so breit wie ihr Inhalt -
   sonst wandern sie je nach Datumslänge hin und her. */
.tagwechsel-mitte {
  flex: 1 1 auto;
  min-width: 0;
}

.tagwechsel-mitte input[type='date'] {
  width: 100%;
}

.tagzeile {
  margin: 0 0 1rem;
}

.einsatzliste {
  list-style: none;
  margin: 0 0 1.5rem;
  padding: 0;
}

.einsatz {
  padding: 0.9rem 1rem;
  margin-bottom: 0.75rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 4px solid var(--accent);
  border-radius: var(--radius);
}

/* Erledigt und abgesagt treten zurück, ohne zu verschwinden: Der Tag soll
   sich hinterher noch erklären lassen, auch der Teil, der nicht stattfand. */
.einsatz-done {
  border-left-color: var(--ok);
  background: var(--bg);
}

/* Zurücktreten über die Farbe, nicht über Transparenz: `opacity` machte das
   ohnehin graue Kleingedruckte zu blass zum Lesen (3,2:1). */
.einsatz-cancelled {
  border-left-color: var(--border);
  background: var(--bg);
}

.einsatz-cancelled .einsatz-ort strong {
  color: var(--muted);
}

.einsatz-kopf {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.4rem 0.9rem;
}

/* Die Uhrzeit bekommt eine feste Breite, damit die Stallnamen untereinander
   stehen - eine Liste, in der die zweite Spalte wandert, liest sich nicht. */
.einsatz-zeit {
  flex: 0 0 auto;
  min-width: 5.5rem;
}

.einsatz-ort {
  display: flex;
  flex-wrap: wrap;
  gap: 0.15rem 0.5rem;
  flex: 1 1 12rem;
  min-width: 0;
}

.einsatz-marken {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem;
  margin-left: auto;
}

.einsatz-anlass {
  margin: 0.4rem 0 0;
}

.einsatz-behandlungen {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem;
  margin: 0.5rem 0 0;
}

.einsatz-aktionen {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  margin-top: 0.75rem;
}

.einsatz-aktionen > form {
  margin: 0;
}

.einsatz-reihenfolge {
  display: flex;
  gap: 0.25rem;
}

/* Die beiden Pfeile sind klein, müssen aber mit dem Daumen zu treffen sein. */
.einsatz-reihenfolge .btn {
  min-width: 2.75rem;
  padding-left: 0.5rem;
  padding-right: 0.5rem;
}

.einsatz-reihenfolge .btn[disabled] {
  opacity: 0.35;
  cursor: default;
}

/* Verschieben und Absagen sind seltener als „erledigt" und stehen deshalb
   hinter einem Aufklapper - sichtbar, aber nicht im Weg. */
.einsatz-mehr {
  flex: 1 1 100%;
  margin-top: 0.25rem;
}

.einsatz-mehr form {
  margin-top: 0.6rem;
}

@media (max-width: 560px) {
  .nur-breit {
    display: none;
  }

  /* Am Handy steht jede Angabe auf ihrer eigenen Zeile. Die Marken rutschen
     dabei nach links - `margin-left: auto` schöbe sie sonst allein in eine
     Zeile, in der sonst nichts steht. */
  .einsatz-marken {
    margin-left: 0;
  }

  .einsatz-zeit {
    min-width: 0;
  }

  /* Der laute Knopf ist am Handy die eigentliche Handlung: volle Breite,
     Daumengrösse. */
  .einsatz-aktionen > form:first-child,
  .einsatz-aktionen > form:first-child .btn-primary {
    width: 100%;
  }
}

/* ===================================================== Planung: Karte === */

/*
 * Die Karte. Feste Höhe in Bildschirmanteilen, damit sie am Handy weder
 * winzig ist noch den ganzen Bildschirm schluckt - darunter stehen die
 * Knöpfe, die man nach dem Setzen des Pins braucht.
 */
.karte {
  position: relative;
  height: min(60vh, 520px);
  min-height: 300px;
  margin: 0.75rem 0;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--karte-bg);
}

.karte-fehler {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1rem;
  color: var(--muted);
  text-align: center;
}

/* Die Bedienknöpfe der Karte groß genug für den Daumen. */
.karte .maplibregl-ctrl-group button {
  width: 40px;
  height: 40px;
}

/* Ein Stall auf der Übersichtskarte - als Knopf, damit er per Tastatur
   erreichbar ist und sein Name vorgelesen wird. */
.karte-punkt {
  display: block;
  width: 18px;
  height: 18px;
  padding: 0;
  border: 2px solid var(--marker-ring);
  border-radius: 50%;
  box-shadow: 0 1px 4px rgb(var(--schatten-rgb) / 0.45);
  cursor: pointer;
  touch-action: manipulation;
}

.karte-punkt:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 2px;
}

/* Zonen nach Fahrzeit ab Praxis: von nah (grün) bis fern (rot). Gelb und
   Orange sind dunkel genug, um auf der hellen Karte zu stehen. */
.zone-nah { background: var(--zone-nah); }
.zone-mittel { background: var(--zone-mittel); }
.zone-weit { background: var(--zone-weit); }
.zone-fern { background: var(--zone-fern); }
.zone-unbekannt { background: var(--grau-marke); }

.karte-praxis {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border: 2px solid var(--marker-ring);
  border-radius: var(--radius-sm);
  background: var(--accent-solid-hover);
  color: var(--on-solid);
  font-weight: 700;
  font-size: var(--fs-sm);
  box-shadow: 0 1px 5px rgb(var(--schatten-rgb) / 0.5);
}

.karte-praxis-klein {
  display: inline-flex;
  width: 18px;
  height: 18px;
  border-radius: 5px;
  font-size: 0.65rem;
  vertical-align: -3px;
  box-shadow: none;
}

.karte-blase {
  font-size: var(--fs-sm);
  line-height: 1.4;
}

.karte-blase a {
  display: inline-block;
  margin-top: 0.3rem;
}

.zonen-legende {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1rem;
  margin: 0 0 0.5rem;
  padding: 0;
  list-style: none;
  font-size: var(--fs-sm);
}

.zonen-punkt {
  display: inline-block;
  width: 12px;
  height: 12px;
  margin-right: 0.3rem;
  border-radius: 50%;
  vertical-align: -1px;
}

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

.kurzliste li {
  display: flex;
  flex-wrap: wrap;
  gap: 0.2rem 0.6rem;
  padding: 0.55rem 0;
  border-bottom: 1px solid var(--border);
}

.lage-status,
.lage-fahrzeit {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem 0.6rem;
}

.lage-fahrzeit strong {
  font-size: var(--fs-md);
}

.pin-form .row,
.ohne-standort {
  margin-top: 0.5rem;
}

.ohne-standort {
  padding-top: 0.75rem;
  border-top: 1px solid var(--border);
}

/* Kopf einer Seite mit Knopf rechts daneben. */
.seitenkopf {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem 1rem;
}

.seitenkopf h1 {
  margin-bottom: 0.5rem;
}

/* Nur für Vorleseprogramme. */
.nur-leser {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* =========================================== Planung: Einsatzarten === */

/*
 * Feste Palette statt freier Farben: Inline-Styles verbietet die
 * Content-Security-Policy, und jede Farbe hier ist auf Weiß lesbar.
 * Hell als Fläche, kräftig als Rand - so bleibt der Text dunkel.
 */
.art-farbe-gruen { --art: #2e7d32; --art-hell: #e6f2e6; }
.art-farbe-blau { --art: #1d5fa8; --art-hell: #e6eef8; }
.art-farbe-tuerkis { --art: #0e7c86; --art-hell: #e1f3f4; }
.art-farbe-gelb { --art: #a07800; --art-hell: #fbf3d6; }
.art-farbe-orange { --art: #c25400; --art-hell: #fdebdc; }
.art-farbe-rot { --art: #b3261e; --art-hell: #fdecea; }
.art-farbe-lila { --art: #6a3fa0; --art-hell: #efe8f7; }
.art-farbe-grau { --art: #5b6672; --art-hell: #eef0f3; }

/* Im Dunkeln wäre die helle Fläche ein greller Fleck mit heller Schrift
   darauf. Sie wird aus der Farbe der Art und dem Kartengrund gemischt - so
   bleibt jede Art an ihrem Ton erkennbar. */
@media (prefers-color-scheme: dark) {
  [class*='art-farbe-'] {
    --art-hell: color-mix(in srgb, var(--art) 28%, var(--surface));
  }
}

/* Die Farbe der Art als Punkt vor dem Namen. Ein farbiger Rand links an einer
   Pille rundete sich mit und sah aus wie eine Klammer: „(Bestandsbetreuung". */
.art-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  background: var(--art-hell);
  border-color: transparent;
  color: var(--text);
}

.art-badge::before {
  content: '';
  flex-shrink: 0;
  width: 0.55rem;
  height: 0.55rem;
  border-radius: 50%;
  background: var(--art);
}

.art-marke {
  display: inline-block;
  flex-shrink: 0;
  width: 12px;
  height: 12px;
  border-radius: 3px;
  background: var(--art);
}

/* Dringlichkeit: nur, was nicht Routine ist, bekommt überhaupt eine Marke. */
.dringlichkeit-soon {
  background: var(--soon-bg);
  border-color: transparent;
  color: var(--soon);
}

.dringlichkeit-urgent {
  background: var(--warn-bg);
  border-color: transparent;
  color: var(--warn);
  font-weight: 600;
}

.dringlichkeit-emergency {
  background: var(--danger-solid);
  border-color: transparent;
  color: var(--on-solid);
  font-weight: 600;
}

/* Auswahl als Chips: ein Tipp statt einer Liste zum Aufklappen. */
.chips-feld {
  margin: 0 0 0.75rem;
  padding: 0;
  border: 0;
}

.chips-feld legend {
  margin-bottom: 0.35rem;
  font-size: var(--fs-sm);
}

.chip-radio {
  position: relative;
  padding: 0;
  font-size: var(--fs-base);
  cursor: pointer;
  touch-action: manipulation;
}

.chip-radio input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

.chip-radio span {
  display: flex;
  align-items: center;
  min-height: var(--tap);
  padding: 0 1rem;
  border-radius: var(--radius-pill);
}

.chip-radio input:checked + span {
  background: var(--accent-solid);
  color: var(--on-solid);
}

.chip-radio input:focus-visible + span {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

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

.einsatzart {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 0.75rem;
  padding: 0.75rem 0;
  border-bottom: 1px solid var(--border);
}

/* Abgeschaltet tritt die Art zurück - aber nur ihr Formular. Der Knopf
   „Wieder aktivieren" muss lesbar bleiben; mit dem ganzen Eintrag verblasst
   lag er bei 2,6:1. */
.einsatzart.ist-aus > .einsatzart-form {
  opacity: 0.65;
}

.einsatzart-form {
  display: flex;
  flex: 1 1 32rem;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 0.5rem 0.75rem;
  min-width: 0;
}

.einsatzart-form .art-marke {
  align-self: center;
}

.einsatzart-form .grow {
  flex: 1 1 12rem;
  min-width: 0;
}

.einsatzart-form .klein {
  flex: 0 1 6.5rem;
  min-width: 0;
}

.einsatzart-form .klein input,
.einsatzart-form .klein select {
  width: 100%;
}

@media (max-width: 560px) {
  .karte {
    height: 55vh;
    min-height: 260px;
    margin-left: -0.25rem;
    margin-right: -0.25rem;
  }

  .einsatzart-form .klein {
    flex: 1 1 30%;
  }
}

/* Einplanen: der frei benannte Ort als eigener Block. */
.ort-frei {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.ort-frei .hint {
  margin: 0;
}

/* ===================================================== Planung: Tour === */

/* Wessen Tour: eine Reihe Chips, am Handy waagrecht scrollbar statt
   umbrechend - die Seite selbst scrollt nie seitwärts. */
.personen {
  display: flex;
  gap: 0.4rem;
  margin: 0 0 1rem;
  padding-bottom: 0.25rem;
  overflow-x: auto;
  scrollbar-width: thin;
  -webkit-overflow-scrolling: touch;
}

.person-chip {
  display: inline-flex;
  flex: 0 0 auto;
  align-items: center;
  gap: 0.4rem;
  min-height: 2.75rem;
  padding: 0.3rem 0.75rem 0.3rem 0.35rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  background: var(--surface);
  color: var(--text);
  text-decoration: none;
  white-space: nowrap;
}

.person-chip.person-offen {
  padding-left: 0.75rem;
}

.person-chip.is-active {
  border-color: var(--accent);
  background: var(--accent-solid);
  color: var(--on-solid);
}

.person-kurz {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  border-radius: 50%;
  background: var(--bg);
  color: var(--accent-dark);
  font-size: var(--fs-sm);
  font-weight: 700;
}

/* Das Kürzel im gewählten Chip: helle Scheibe, grüne Schrift. Weiss auf
   durchscheinendem Weiss über Grün reichte nicht für den Kontrast (3,7:1). */
.person-chip.is-active .person-kurz {
  background: var(--surface);
  color: var(--accent-dark);
}

.person-zahl {
  min-width: 1.4rem;
  padding: 0 0.35rem;
  border-radius: var(--radius-pill);
  background: var(--bg);
  color: var(--muted);
  font-size: var(--fs-sm);
  text-align: center;
}

.person-chip.is-active .person-zahl {
  background: color-mix(in srgb, var(--on-solid) 22%, transparent);
  color: var(--on-solid);
}

.tourkopf .hint {
  margin: 0.5rem 0 0;
}

.tourkopf-zeile {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.2rem 0.75rem;
}

/* Auslastung: drei Abschnitte nebeneinander, der Rest bleibt hell - das ist
   die Zeit, die noch frei ist. */
.auslastung {
  display: flex;
  height: 0.8rem;
  margin: 0.6rem 0 0.35rem;
  overflow: hidden;
  border-radius: var(--radius-pill);
  background: var(--bg);
  box-shadow: inset 0 0 0 1px var(--border);
}

.auslastung.ist-voll {
  box-shadow: inset 0 0 0 2px var(--danger);
}

.seg {
  display: block;
  height: 100%;
}

.seg-arbeit { background: var(--accent-solid); }
.seg-fahrt { background: var(--seg-fahrt); }
.seg-puffer { background: var(--seg-puffer); }

.auslastung-legende {
  display: flex;
  flex-wrap: wrap;
  gap: 0.2rem 0.9rem;
  margin: 0;
  color: var(--muted);
}

.auslastung-legende .punkt {
  display: inline-block;
  width: 0.65rem;
  height: 0.65rem;
  margin-right: 0.3rem;
  border-radius: 50%;
  vertical-align: -1px;
}

.text-gefahr {
  color: var(--danger);
}

.konfliktliste {
  margin: 0.6rem 0 0;
  padding-left: 1.75rem;
}

.konfliktliste li + li {
  margin-top: 0.2rem;
}

.tour-aktionen {
  margin-top: 0.6rem;
}

.tour-aktionen:empty {
  display: none;
}

.karte-aufklapper .karte {
  margin-top: 0.6rem;
}

/* Die Zeitachse: links die Uhrzeit, rechts was passiert. Fahrten sind
   schmale Zeilen zwischen den Einsätzen. */
.zeitachse {
  list-style: none;
  margin: 0 0 1.5rem;
  padding: 0;
}

.za-punkt,
.za-fahrt {
  display: flex;
  gap: 0.75rem;
  align-items: baseline;
  padding: 0.35rem 0.25rem;
}

.za-punkt {
  font-weight: 600;
}

.za-punkt.ist-spaet .za-uhr {
  color: var(--danger);
}

.za-fahrt {
  margin: -0.25rem 0 0.5rem;
  color: var(--muted);
  font-size: var(--fs-sm);
}

.za-fahrt::before {
  content: "";
  order: -1;
  flex: 0 0 auto;
  align-self: stretch;
  width: 0;
  margin-left: 1.6rem;
  border-left: 2px dashed var(--border);
}

.za-fahrt .za-uhr {
  display: none;
}

.za-uhr {
  flex: 0 0 3.2rem;
  font-variant-numeric: tabular-nums;
}

.puffer {
  color: var(--puffer);
}

.za-einsatz {
  position: relative;
  touch-action: pan-y;
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}

.za-einsatz .einsatz-zeit {
  font-variant-numeric: tabular-nums;
}

.za-einsatz.hat-konflikt {
  border-left-color: var(--konflikt);
}

.einsatz-dauer {
  margin: 0.35rem 0 0;
  color: var(--muted);
}

/* Der Griff zum Umsortieren: gross genug für den Daumen, ohne die Zeile
   breiter zu machen. */
.za-griff {
  flex: 0 0 auto;
  width: 2.25rem;
  height: 2.25rem;
  margin: -0.3rem 0 -0.3rem -0.4rem;
  padding: 0;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--muted);
  font-size: var(--fs-base);
  letter-spacing: -0.2em;
  cursor: grab;
  touch-action: none;
}

.za-griff:hover,
.za-griff:focus-visible {
  background: var(--bg);
}

.wird-sortiert .za-fahrt {
  display: none;
}

.wird-gezogen {
  box-shadow: 0 6px 18px rgb(var(--schatten-rgb) / 0.2);
  cursor: grabbing;
}

.wird-gespeichert {
  opacity: 0.6;
}

/* Wischen: Die Karte folgt dem Finger, die Farbe sagt, was beim Loslassen
   passiert. */
.wisch-rechts {
  box-shadow: inset 6px 0 0 var(--ok);
  background: var(--ok-bg);
}

.wisch-links {
  box-shadow: inset -6px 0 0 var(--muted);
}

.wisch-erledigt {
  opacity: 0.6;
}

/* Der Backlog: Offenes, noch niemandem zugeteilt. */
.backlog h2 .badge {
  vertical-align: 0.15em;
}

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

.backlog-einsatz {
  border-left-color: var(--muted);
  touch-action: pan-y;
}

.backlog-einsatz:last-child {
  margin-bottom: 0;
}

/* Team in den Einstellungen. */
.teamliste {
  list-style: none;
  margin: 0;
  padding: 0;
}

.teamliste > li + li {
  margin-top: 0.5rem;
}

.ohne-rand {
  min-width: 0;
  margin: 0;
  padding: 0;
  border: 0;
}


@media (max-width: 560px) {
  .za-uhr {
    flex-basis: 2.9rem;
  }

  .einsatz-aktionen > [data-wisch-rechts],
  .einsatz-aktionen > [data-wisch-rechts] form,
  .einsatz-aktionen > [data-wisch-rechts] .btn {
    width: 100%;
  }

  .einsatz-aktionen > [data-navi] {
    flex: 1 1 auto;
    text-align: center;
  }

  .tour-aktionen .btn {
    flex: 1 1 100%;
    text-align: center;
  }
}

/* ================================================ Planung: Etappe 3 === */

.alert-info {
  background: var(--info-bg);
  border-color: var(--info-line);
  color: var(--info);
}

/* Hinweis auf eine bessere Reihenfolge: Text und Knopf nebeneinander, am
   Handy untereinander. */
.optimier-hinweis {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem 1rem;
  margin: 0.6rem 0 0;
}

.einplanen-knoepfe {
  flex-wrap: wrap;
}

/* Vorschläge: der beste hervorgehoben, die Alternativen ruhiger. */
.vorschlag-einsatz {
  margin-bottom: 1rem;
}

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

.vorschlag {
  margin-bottom: 0.75rem;
}

.vorschlag.ist-bester {
  border-left: 4px solid var(--accent);
}

.vorschlag p {
  margin: 0 0 0.35rem;
}

.vorschlag-wer {
  font-size: var(--fs-md);
}

.vorschlag-wer .badge {
  margin-right: 0.4rem;
  vertical-align: 0.1em;
}

.vorschlag .konfliktliste {
  margin: 0.4rem 0 0.6rem;
}

.vorschlag form {
  margin-top: 0.6rem;
}

/* Verteilen: eine Zeile je Einsatz, der Haken ist die ganze Zeile. */
.verteilliste {
  list-style: none;
  margin: 0 0 1rem;
  padding: 0;
}

.verteilzeile {
  margin-bottom: 0.6rem;
  padding: 0.75rem 1rem;
}

.verteilzeile.ohne-platz {
  background: var(--bg);
  box-shadow: none;
}

.verteil-wahl {
  display: flex;
  gap: 0.75rem;
  align-items: flex-start;
  cursor: pointer;
}

.verteil-wahl input {
  flex: 0 0 auto;
  width: 1.4rem;
  height: 1.4rem;
  margin-top: 0.15rem;
}

/* Optimieren: Zahlen vorher → nachher, dann die beiden Folgen. */
.vergleich {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 0.35rem 1rem;
  margin: 0;
}

.vergleich dt {
  color: var(--muted);
}

.vergleich dd {
  margin: 0;
}

.optimier-spalten {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
  gap: 0 1.5rem;
  margin: 1rem 0;
}

.optimier-liste {
  margin: 0;
  padding-left: 1.5rem;
}

.optimier-liste li {
  padding: 0.2rem 0;
}

.optimier-liste .za-uhr {
  display: inline-block;
  min-width: 3.2rem;
}

.optimier-liste .ist-fest {
  color: var(--muted);
}

/* Woche: je Tag eine Karte, je Person eine Zeile. */
.wochentitel {
  text-align: center;
  font-weight: 600;
}

.woche {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(17rem, 1fr));
  gap: 0.75rem;
  margin: 0.75rem 0 1rem;
}

.wochentag {
  padding: 0.9rem 1rem;
}

.wochentag h2 {
  margin: 0 0 0.5rem;
  font-size: var(--fs-md);
}

.wochentag h2 a {
  color: inherit;
}

.wochentag.ist-heute {
  border-color: var(--accent);
  box-shadow: inset 0 3px 0 var(--accent), var(--shadow);
}

.wochentag.kein-arbeitstag {
  background: var(--bg);
}

.wochen-touren {
  list-style: none;
  margin: 0;
  padding: 0;
}

.wochen-tour {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 1.6rem 4rem 4.6rem;
  align-items: center;
  gap: 0.5rem;
  min-height: 2.5rem;
  color: inherit;
  text-decoration: none;
}

.wochen-tour .auslastung {
  margin: 0;
}

.wochen-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

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

.wochen-ende {
  font-size: var(--fs-sm);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.wochen-tour .badge {
  grid-column: 1 / -1;
  justify-self: start;
}

/* Breiten für die Abschnitte der Auslastung in 5-%-Schritten - die
   Content-Security-Policy erlaubt keine Inline-Styles. */
.w-0 { width: 0%; }
.w-5 { width: 5%; }
.w-10 { width: 10%; }
.w-15 { width: 15%; }
.w-20 { width: 20%; }
.w-25 { width: 25%; }
.w-30 { width: 30%; }
.w-35 { width: 35%; }
.w-40 { width: 40%; }
.w-45 { width: 45%; }
.w-50 { width: 50%; }
.w-55 { width: 55%; }
.w-60 { width: 60%; }
.w-65 { width: 65%; }
.w-70 { width: 70%; }
.w-75 { width: 75%; }
.w-80 { width: 80%; }
.w-85 { width: 85%; }
.w-90 { width: 90%; }
.w-95 { width: 95%; }
.w-100 { width: 100%; }

/* Auf der Tourkarte: nummerierte Halte und grau die offenen Einsätze. */
.karte-halt {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  padding: 0;
  border: 2px solid var(--marker-ring);
  border-radius: 50%;
  background: var(--accent-solid);
  color: var(--on-solid);
  font: 700 0.8rem/1 system-ui, sans-serif;
  box-shadow: 0 1px 4px rgb(var(--schatten-rgb) / 0.45);
  cursor: pointer;
}

.karte-halt:focus-visible {
  outline: 3px solid var(--accent-dark);
  outline-offset: 2px;
}

.karte-offen {
  background: var(--grau-marke);
  width: 14px;
  height: 14px;
}

.karte-hinweis {
  position: absolute;
  left: 0.5rem;
  bottom: 0.5rem;
  margin: 0;
  padding: 0.3rem 0.6rem;
  border-radius: 6px;
  background: var(--surface);
  font-size: var(--fs-sm);
}

.optimier-uebernehmen {
  margin: 1rem 0 0;
}

/* ================================================ Planung: Etappe 4 === */

/* Wo ein Einsatz gerade steht: unterwegs, vor Ort. */
.ist-zustand {
  display: inline-block;
  margin: 0.4rem 0 0;
  padding: 0.2rem 0.6rem;
  border-radius: var(--radius-pill);
}

.ist-unterwegs {
  background: var(--info-bg);
  color: var(--info);
}

.ist-vor-ort {
  background: var(--ok-bg);
  color: var(--ok);
}

.abweichung {
  margin: 0.5rem 0 0;
}

.entlastung {
  margin: 0.6rem 0 0;
}

.entlastung p,
.entlastung ul {
  margin: 0 0 0.4rem;
}

.standortabgleich {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.25rem 0.75rem;
  margin-top: 0.6rem;
}

.standortabgleich form {
  margin: 0;
}

.standortabgleich-aus {
  margin-top: 0.6rem;
}

.ist-form {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  margin-top: 0.75rem;
  padding-top: 0.6rem;
  border-top: 1px dashed var(--border);
}

.ist-form .btn {
  align-self: flex-start;
}

.ist-titel {
  font-weight: 600;
  font-size: var(--fs-sm);
}

/* ================================================ Planung: Etappe 5 === */

/* Die Glocke im Kopf - immer sichtbar, auch am Handy. */
.glocke {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.5rem;
  height: 2.5rem;
  margin-left: auto;
  border-radius: 50%;
  color: var(--text);
}

.glocke:hover,
.glocke.is-active {
  background: var(--bg);
}

.topbar .glocke .icon {
  display: block;
  width: 1.4rem;
  height: 1.4rem;
}

.glocke-zahl {
  position: absolute;
  top: 0.1rem;
  right: 0.05rem;
  min-width: 1.15rem;
  height: 1.15rem;
  padding: 0 0.25rem;
  border-radius: var(--radius-pill);
  background: var(--danger-solid);
  color: var(--on-solid);
  font-size: 0.7rem;
  font-weight: 700;
  line-height: 1.15rem;
  text-align: center;
}

/* Nach der eigenen Änderung: zurücknehmen. */
.rueckgaengig-leiste {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.4rem 1rem;
  margin: 0 0 1rem;
  padding: 0.5rem 0.75rem;
  border-radius: var(--radius);
  background: var(--inverse-bg);
  color: var(--on-inverse);
}

.rueckgaengig-leiste form {
  margin: 0;
}

.rueckgaengig-leiste .btn {
  background: transparent;
  border-color: color-mix(in srgb, var(--on-inverse) 50%, transparent);
  color: var(--on-inverse);
}

/* Protokoll: wer hat wann was geändert. */
.protokoll {
  margin-top: 0.6rem;
}

.protokoll-liste {
  list-style: none;
  margin: 0.5rem 0;
  padding: 0;
}

.protokoll-liste.card {
  padding: 0.25rem 1rem;
}

.protokoll-liste li {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.2rem 0.75rem;
  padding: 0.45rem 0;
  border-bottom: 1px solid var(--border);
}

.protokoll-liste li:last-child {
  border-bottom: 0;
}

.protokoll-liste form {
  margin: 0 0 0 auto;
}

.protokoll-zeit {
  flex: 0 0 auto;
  min-width: 3rem;
  color: var(--muted);
  font-size: var(--fs-sm);
  font-variant-numeric: tabular-nums;
}

.protokoll-text {
  flex: 1 1 12rem;
  min-width: 0;
}

.protokoll-liste .ist-zurueck .protokoll-text {
  text-decoration: line-through;
  color: var(--muted);
}

/* Benachrichtigungen. */
.nachrichten {
  list-style: none;
  margin: 0 0 1.5rem;
  padding: 0;
}

.nachrichten li a {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  padding: 0.75rem 1rem;
  margin-bottom: 0.5rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--text);
  text-decoration: none;
}

.nachrichten li.ist-neu a {
  border-left: 4px solid var(--accent);
  font-weight: 600;
}

.push-bereich h2 {
  margin-top: 0;
}

/* Mit Glocke: Sie schiebt sich nach rechts, der Menüknopf folgt direkt
   daneben statt einen zweiten Abstand aufzumachen. Am Schreibtisch, wo die
   Leiste daneben steht, bleibt sie beim Logo. */
.glocke ~ .menu-button {
  margin-left: 0.25rem;
}

@media (min-width: 1200px) {
  .glocke {
    margin-left: -0.75rem;
  }
}

/* ================================================ Planung: Etappe 6 === */

/* Notfall: rot, aber nicht schreiend - der Knopf muss sofort zu finden sein. */
.btn-notfall {
  background: var(--danger-solid);
  border-color: var(--danger-solid);
  color: var(--on-solid);
  font-weight: 600;
}

.btn-notfall:hover,
.btn-notfall:focus-visible {
  background: var(--danger-solid-hover);
  border-color: var(--danger-solid-hover);
  color: var(--on-solid);
}

.notfall-titel {
  color: var(--danger);
}

.notfall-form .btn-notfall {
  width: 100%;
  min-height: 3rem;
}

.notfall-einsatz {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.3rem 0.6rem;
  margin-bottom: 1rem;
  border-left: 4px solid var(--danger);
}

.notfall-einsatz .hint {
  flex-basis: 100%;
  margin: 0.3rem 0 0;
}

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

.notfall-kandidat {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  margin-bottom: 0.5rem;
  padding: 0.75rem 1rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--text);
  text-decoration: none;
}

.notfall-kandidat.is-active {
  border-color: var(--danger);
  box-shadow: inset 4px 0 0 var(--danger);
}

.kandidat-kopf {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem;
}

.notfall-vorschau h2 {
  margin-top: 0;
}

.notfall-vorschau .btn-notfall {
  width: 100%;
  min-height: 3rem;
  margin-top: 0.5rem;
}

.notfall-tour .ist-notfall {
  font-weight: 600;
  color: var(--danger);
}

.za-einsatz.einsatz-notfall {
  border-left-color: var(--danger);
}

/* Lange Hofnamen in der Auswahl dürfen die Karte nicht sprengen. */
.notfall-vorschau form.row label {
  flex: 1 1 100%;
  min-width: 0;
}

.notfall-vorschau select {
  width: 100%;
  min-width: 0;
  max-width: 100%;
  text-overflow: ellipsis;
}

/* ---------- Ansage (KI-Spracheingabe) ---------- */

.ansage .aufnahme {
  margin: 0.75rem 0;
}

.ansage textarea {
  width: 100%;
}

.ansage-wortlaut {
  font-style: italic;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.ansage-eintrag {
  scroll-margin-top: 4.5rem;
}

.ansage-eintrag h2 {
  overflow-wrap: anywhere;
}

.ansage-eintrag select {
  width: 100%;
  min-width: 0;
  max-width: 100%;
}

.ansage-eintrag.ist-erledigt {
  opacity: 0.75;
}

/* ---------- Karte im Dunkelmodus ---------- */

/* Die Karte selbst bleibt hell - Strassen und Orte sind auf hellem Grund
   gezeichnet. Was auf ihr liegt (Blase, Bedienknöpfe, Hinweis), bekommt
   deshalb die hellen Bausteine zurück, sonst stünde helle Schrift auf
   weissem Grund. */
.maplibregl-popup,
.maplibregl-ctrl,
.karte-hinweis {
  color-scheme: light;
  --surface: #ffffff;
  --text: #1c2430;
  --muted: #63707f;
  --accent: #14746f;
  --border: #dfe3e8;
  color: var(--text);
}

/* ===================================================== Heute (Startseite) === */

/*
 * Das grüne Band oben mit Gruss und drei Zahlen, darauf die Karte „Jetzt".
 * Am Handy reicht das Band bis an die Ränder und läuft unter der Kopfzeile
 * weiter - die Kopfzeile nimmt auf dieser Seite seine Farbe an. Am grossen
 * Bildschirm ist es eine runde Fläche über dem Inhalt.
 */
.heute-band {
  display: flex;
  flex-direction: column;
  gap: 1.1rem;
  padding: 1.4rem 1.4rem 4.5rem;
  border-radius: var(--radius-lg);
  background: var(--band);
  color: var(--on-band);
}

.heute-kopf {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.heute-kopf-text {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.heute-kopf h1 {
  margin: 0;
  font-size: var(--fs-lg);
  color: var(--on-band);
}

.heute-datum {
  font-size: var(--fs-sm);
  color: var(--on-band-leise);
  font-variant-numeric: tabular-nums;
}

.heute-avatar {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.6rem;
  height: 2.6rem;
  border-radius: 50%;
  background: var(--gold);
  color: var(--on-gold);
  font-weight: 800;
  font-size: var(--fs-sm);
}

/* Drei Zahlen nebeneinander: gross die Zahl, klein darunter, was sie ist. */
.heute-zahlen {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0.5rem;
  margin: 0;
}

.heute-zahlen > div {
  display: flex;
  flex-direction: column-reverse;
  gap: 0.15rem;
  min-width: 0;
}

.heute-zahlen dt {
  font-size: var(--fs-xs);
  color: var(--on-band-leise);
}

.heute-zahlen dd {
  margin: 0;
  font-size: 1.65rem;
  font-weight: 800;
  line-height: 1;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}

.heute-zahlen small {
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--on-band-leise);
}

/* Inhalt unter dem Band: die erste Karte schiebt sich auf das Band. */
.heute-raster {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 1rem;
  margin-top: -3.6rem;
  padding: 0 0.6rem;
}

.heute-spalte {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  min-width: 0;
}

/* Am Handy eine Spalte in der Reihenfolge des Entwurfs: erst „Jetzt", dann
   die Schnellwege, dann der Rest der Tour. Die beiden Spalten des grossen
   Bildschirms lösen sich dafür auf (`contents`), `order` sortiert. */
@media (max-width: 899px) {
  .heute-spalte {
    display: contents;
  }

  .heute-jetzt { order: 1; }
  .heute-kacheln { order: 2; }
  .heute-weiter { order: 3; }
  .heute-team { order: 4; }
  .heute-nachricht { order: 5; }
  .heute-behandlungen { order: 6; }
}

@media (min-width: 900px) {
  .heute-raster {
    grid-template-columns: minmax(0, 3fr) minmax(0, 2fr);
    align-items: start;
    padding: 0 1.25rem;
  }
}

/* ------------------------------------------------------- Karte „Jetzt" --- */
.heute-jetzt {
  display: flex;
  flex-direction: column;
  gap: 0.85rem;
  padding: 1.1rem;
  box-shadow: 0 12px 32px var(--accent-schatten), var(--shadow);
}

.heute-jetzt h2 {
  margin: 0;
  font-size: var(--fs-lg);
  font-weight: 800;
}

.heute-jetzt-kopf {
  display: flex;
  align-items: flex-start;
  gap: 0.8rem;
}

.heute-jetzt-text {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-width: 0;
}

.heute-symbol {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 3rem;
  height: 3rem;
  border-radius: 14px;
  background: var(--ok-bg);
  color: var(--accent);
}

.heute-symbol .icon {
  width: 1.5rem;
  height: 1.5rem;
}

.heute-symbol-blau {
  background: var(--soon-bg);
  color: var(--soon);
}

.heute-marke {
  font-size: var(--fs-xs);
  font-weight: 800;
  color: var(--accent);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.heute-leise {
  color: var(--muted);
  font-size: var(--fs-sm);
}

.heute-klein {
  font-size: var(--fs-xs);
}

.heute-anlass {
  margin: 0;
}

.heute-fortschritt {
  display: flex;
  height: 0.5rem;
  overflow: hidden;
  border-radius: var(--radius-pill);
  background: var(--bg);
}

.heute-fortschritt > span {
  display: block;
  background: var(--accent-solid);
  border-radius: var(--radius-pill);
}

.heute-fortschritt > span.ist-drueber {
  background: var(--warn-mark);
}

.heute-aktionen {
  display: flex;
  gap: 0.6rem;
}

.heute-form {
  margin: 0;
  flex: 1;
  display: flex;
}

.heute-aktionen .btn-primary {
  flex: 1;
  min-height: 3.25rem;
  font-size: var(--fs-base);
  border-radius: 14px;
}

.heute-navi {
  flex: 0 0 3.25rem;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 3.25rem;
  padding: 0;
  border-radius: 14px;
}

.heute-navi .icon {
  width: 1.4rem;
  height: 1.4rem;
}

.heute-nebenaktion {
  display: flex;
  justify-content: center;
  margin-top: -0.4rem;
}

.heute-nebenaktion .heute-form {
  flex: 0 0 auto;
}

.heute-ruhe {
  flex-direction: row;
  align-items: center;
}

.heute-ruhe h2 {
  font-size: var(--fs-md);
}

.heute-ruhe p {
  margin: 0.15rem 0 0;
}

/* ---------------------------------------------------------- Kacheln --- */
.heute-kacheln {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.65rem;
}

.heute-kachel {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 0.75rem;
  min-height: 6rem;
  padding: 0.95rem;
  border-radius: var(--radius-lg);
  background: var(--surface);
  border: 1px solid var(--card-rand);
  box-shadow: var(--shadow);
  color: var(--text);
  font-weight: 700;
  text-decoration: none;
  touch-action: manipulation;
}

.heute-kachel:visited {
  color: var(--text);
}

.heute-kachel .icon {
  width: 1.65rem;
  height: 1.65rem;
  color: var(--accent);
}

.heute-kachel:hover {
  border-color: var(--accent);
}

.heute-kachel-notfall,
.heute-kachel-notfall:visited {
  background: var(--danger-solid);
  border-color: var(--danger-solid);
  color: var(--on-solid);
}

.heute-kachel-notfall .icon {
  color: var(--on-solid);
}

.heute-kachel-notfall:hover {
  background: var(--danger-solid-hover);
  border-color: var(--danger-solid-hover);
}

.heute-kachel-kopf {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.4rem;
}

.heute-zaehler {
  padding: 0.15rem 0.5rem;
  border-radius: var(--radius-pill);
  background: var(--bg);
  color: var(--muted);
  font-size: var(--fs-xs);
  font-weight: 800;
  white-space: nowrap;
}

.heute-zaehler.ist-dringend {
  background: var(--warn-bg);
  color: var(--warn);
}

/* ------------------------------------------------------- Listen --- */
.heute-titel {
  margin: 0.25rem 0.25rem 0.6rem;
  font-size: var(--fs-md);
}

.heute-liste {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.heute-zeile {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 0.75rem;
  min-height: 3.5rem;
  padding: 0.7rem 0.9rem;
  border-radius: var(--radius);
  background: var(--surface);
  border: 1px solid var(--card-rand);
  color: var(--text);
  text-decoration: none;
}

.heute-zeile:visited {
  color: var(--text);
}

.heute-zeile:hover {
  border-color: var(--accent);
}

.heute-zeit {
  display: flex;
  flex-direction: column;
  min-width: 3.1rem;
  font-variant-numeric: tabular-nums;
}

.heute-zeit span,
.heute-zeile-text > span {
  color: var(--muted);
  font-size: var(--fs-xs);
}

.heute-zeile-text {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.heute-zeile-text > strong {
  font-weight: 700;
}

.heute-zeile-text > span {
  font-size: var(--fs-sm);
  overflow-wrap: anywhere;
}

.heute-punkt {
  width: 0.65rem;
  height: 0.65rem;
  border-radius: 50%;
  background: var(--art);
}

.heute-mehr {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  min-height: var(--tap);
  margin: 0.25rem 0.25rem 0;
  font-weight: 600;
  text-decoration: none;
}

.heute-mehr .icon {
  width: 1rem;
  height: 1rem;
}

/* Team: Kürzel mit Ring - grün, wer im Plan ist, gelb, wer spät dran ist. */
.heute-person-kurz {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 50%;
  background: var(--soon-bg);
  color: var(--soon);
  font-weight: 800;
  font-size: var(--fs-sm);
}

.heute-status {
  width: 0.65rem;
  height: 0.65rem;
  border-radius: 50%;
  background: var(--ok);
}

.heute-status.ist-spaet {
  background: var(--warn-mark);
}

.heute-nachricht {
  display: flex;
  align-items: center;
  gap: 0.8rem;
  padding: 0.9rem;
  color: var(--text);
  text-decoration: none;
}

.heute-nachricht:visited {
  color: var(--text);
}

.heute-behandlungen {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  padding: 0.5rem;
}

.heute-behandlungen .heute-zeile {
  border: 0;
  background: transparent;
  padding: 0.4rem;
}

.heute-behandlungen .heute-symbol {
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 12px;
}

.heute-massen {
  margin: 0 0.4rem 0.4rem;
}

/* Am Handy: das Band über die volle Breite, die Kopfzeile in seiner Farbe. */
@media (max-width: 760px) {
  .seite-heute .page {
    padding-top: 0;
  }

  .heute-band {
    margin: 0 -1rem;
    padding: 0.4rem 1.25rem 4.6rem;
    border-radius: 0;
  }

  .heute-raster {
    padding: 0;
  }

  .seite-heute .topbar {
    background: var(--band);
    border-bottom-color: var(--band);
    color: var(--on-band);
  }

  .seite-heute .topbar .brand,
  .seite-heute .topbar .glocke {
    color: var(--on-band);
  }

  .seite-heute .topbar .brand-mark {
    filter: invert(1);
  }

  .seite-heute .glocke:hover,
  .seite-heute .glocke.is-active {
    background: rgb(255 255 255 / 0.12);
  }

  .seite-heute .glocke-zahl {
    box-shadow: 0 0 0 2px var(--band);
  }
}

/* Eine Marke rechts in der Zeile („Termin 10:00 verpasst") darf umbrechen,
   statt dem Hofnamen daneben den Platz zu nehmen. */
.heute-zeile > .badge {
  max-width: 6.5rem;
  white-space: normal;
  text-align: center;
  line-height: 1.25;
}

/* ====================================================== Planung kompakt === */

/*
 * Der Kopf in einer Zeile: Überschrift links, rechts Notfall und drei
 * Zeichen. Wird es zu eng (sehr schmale Handys), rutschen die Knöpfe unter
 * die Überschrift statt die Seite zu verbreitern.
 */
.planung-kopf {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem 0.75rem;
}

.planung-kopf h1 {
  margin: 0;
}

.planung-knoepfe {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem;
}

.planung-knoepfe .btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  min-height: var(--tap);
}

.planung-knoepfe .icon {
  width: 1.25rem;
  height: 1.25rem;
}

.knopf-zeichen {
  width: var(--tap);
  padding: 0;
}

/* „Neuer Einsatz" steht am grossen Bildschirm im Kopf; am Handy übernimmt
   das schwebende „+". */
.knopf-neu {
  display: none !important;
}

@media (min-width: 761px) {
  .knopf-neu {
    display: inline-flex !important;
  }
}

@media (max-width: 760px) {
  .planung-kopf h1 {
    font-size: var(--fs-lg);
  }

  /* Am Handy reicht das Wort: Das Zeichen davor kostet die Breite, die der
     Kopf für eine Zeile braucht. */
  .planung-knoepfe .btn-notfall .icon {
    display: none;
  }
}

.tagzeile {
  margin: 0 0 0.75rem;
}

/* --------------------------------------------------------- Tourkopf --- */
.tourkopf {
  padding: 1rem 1.1rem;
}

.tourkopf .auslastung-legende {
  font-size: var(--fs-xs);
}

.tour-werkzeuge > summary .muted {
  display: none;
}

@media (min-width: 561px) {
  .tour-werkzeuge > summary .muted {
    display: inline;
  }
}

.tour-werkzeuge[open] {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}

.tour-werkzeuge .tour-aktionen {
  margin-top: 0;
}

.tour-werkzeuge .ausweich {
  background: var(--surface);
}

/* -------------------------------------------------- Einsatz als Zeile --- */
.za-einsatz,
.backlog-einsatz {
  margin-bottom: 0.5rem;
  padding: 0;
  background: var(--surface);
  border: 1px solid var(--card-rand);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}

.za-einsatz.mit-griff {
  display: grid;
  grid-template-columns: 2rem minmax(0, 1fr);
  align-items: start;
}

.za-einsatz .za-griff {
  margin: 0.6rem 0 0 0.25rem;
}

.einsatz-zeile {
  min-width: 0;
}

/* Die Zeile selbst ist der Schalter. Das <summary> bleibt ein Block (siehe
   „Abschnitte"); angeordnet wird im Behälter darin. */
.einsatz-zeile > summary {
  position: relative;
  display: block;
  min-height: 3.5rem;
  padding: 0.65rem 2.4rem 0.65rem 0.8rem;
  list-style: none;
  cursor: pointer;
}

.mit-griff .einsatz-zeile > summary {
  padding-left: 0.2rem;
}

.einsatz-zeile > summary::-webkit-details-marker {
  display: none;
}

/* Der Pfeil rechts: zu nach unten, offen nach oben. */
.einsatz-zeile > summary::after {
  content: '';
  position: absolute;
  top: 1.35rem;
  right: 1rem;
  width: 0.5rem;
  height: 0.5rem;
  border-right: 2px solid var(--muted);
  border-bottom: 2px solid var(--muted);
  transform: rotate(45deg);
  transition: transform 0.15s ease;
}

.einsatz-zeile[open] > summary::after {
  top: 1.55rem;
  transform: rotate(225deg);
}

.einsatz-zeile > summary:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
  border-radius: var(--radius);
}

.einsatz-zeile .einsatz-kopf {
  display: grid;
  grid-template-columns: 3.1rem minmax(0, 1fr);
  gap: 0.15rem 0.7rem;
  align-items: start;
}

.einsatz-zeile .einsatz-zeit {
  display: flex;
  flex-direction: column;
  min-width: 0;
  line-height: 1.25;
  font-variant-numeric: tabular-nums;
}

.einsatz-zeile .einsatz-ort {
  display: flex;
  flex-direction: column;
  flex-wrap: nowrap;
  min-width: 0;
  line-height: 1.3;
}

/* Betreiber, Ort und Anlass in einer Zeile - was nicht passt, steht beim
   Aufklappen ohnehin darunter. */
.einsatz-zeile .einsatz-ort > .muted {
  /* Als Flex-Kind wäre die Mindestbreite sonst die ganze Textlänge - und
     die Zeile liefe über den Rand, statt mit „…" zu enden. */
  min-width: 0;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: var(--fs-sm);
}

.einsatz-zeile .einsatz-kopf > .einsatz-marken {
  grid-column: 2;
  margin: 0.2rem 0 0;
  align-items: center;
}

.einsatz-zeile .einsatz-kopf > .einsatz-marken:empty {
  display: none;
}

.einsatz-zeile .einsatz-kopf .badge {
  font-size: var(--fs-xs);
  padding: 0.05rem 0.5rem;
}

/* Die Einsatzart als Farbpunkt in der Zeile; der Name steht im Inhalt. */
.einsatz-art {
  display: inline-block;
  width: 0.65rem;
  height: 0.65rem;
  border-radius: 50%;
  background: var(--art);
}

.einsatz-haken {
  display: inline-flex;
  color: var(--ok);
}

.einsatz-haken .icon {
  width: 1.3rem;
  height: 1.3rem;
}

.einsatz-inhalt {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  padding: 0 0.8rem 0.85rem;
}

.mit-griff .einsatz-inhalt {
  padding-left: 0.2rem;
}

.einsatz-inhalt > p,
.einsatz-inhalt > form,
.einsatz-inhalt > .einsatz-marken {
  margin: 0;
}

.einsatz-inhalt .einsatz-aktionen {
  margin-top: 0.4rem;
}

/* Zustände: der aktuelle Einsatz mit grünem Rahmen, erledigte treten
   zurück, Notfall und Konflikt mit einem Streifen links. */
.za-einsatz.ist-aktuell {
  border: 2px solid var(--accent);
  box-shadow: 0 8px 24px var(--accent-schatten);
}

.za-einsatz.einsatz-done,
.za-einsatz.einsatz-cancelled {
  background: transparent;
  box-shadow: none;
  border-color: var(--border);
}

.einsatz-done .einsatz-zeile > summary .einsatz-ort strong,
.einsatz-cancelled .einsatz-zeile > summary .einsatz-ort strong {
  color: var(--muted);
  font-weight: 600;
}

.za-einsatz.hat-konflikt {
  box-shadow: inset 4px 0 0 var(--konflikt), var(--shadow);
}

.za-einsatz.einsatz-notfall {
  box-shadow: inset 4px 0 0 var(--danger-solid), var(--shadow);
}

/* Fahrten zwischen den Zeilen: klein, damit die Einsätze zusammenstehen. */
.zeitachse .za-fahrt {
  margin: -0.15rem 0 0.35rem;
  padding: 0.05rem 0.25rem;
  font-size: var(--fs-xs);
}

.zeitachse .za-punkt {
  font-size: var(--fs-sm);
}

.backlog .backlogliste {
  margin-top: 0.5rem;
}

.backlog-einsatz .einsatz-zeit strong {
  font-size: var(--fs-sm);
}

/* ---------------------------------------------------- „+" am Handy --- */
.plus-knopf {
  display: none;
}

@media (max-width: 760px) {
  .plus-knopf {
    position: fixed;
    right: max(1rem, env(safe-area-inset-right));
    bottom: calc(6.25rem + env(safe-area-inset-bottom));
    z-index: 34;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 3.5rem;
    height: 3.5rem;
    border-radius: 18px;
    background: var(--accent-solid);
    color: var(--on-solid);
    box-shadow: 0 10px 24px rgb(0 0 0 / 0.25);
  }

  .plus-knopf .icon {
    width: 1.75rem;
    height: 1.75rem;
  }

  body.tastatur .plus-knopf {
    display: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .einsatz-zeile > summary::after {
    transition: none;
  }
}

/* Konflikte der Tour: zugeklappt eine Zeile, aufgeklappt die Liste. */
.konflikt-aufklapper > summary {
  cursor: pointer;
  min-height: 1.5rem;
}

.konflikt-aufklapper .konfliktliste {
  margin: 0.5rem 0 0;
  padding-left: 1.25rem;
}

/* Navigation und Hauptknopf nebeneinander - wie auf „Heute". Die übrigen
   Knöpfe brechen darunter um. */
@media (max-width: 560px) {
  .einsatz-inhalt .einsatz-aktionen > [data-navi] {
    flex: 0 0 auto;
  }

  .einsatz-inhalt .einsatz-aktionen > [data-wisch-rechts] {
    flex: 1 1 0;
    width: auto;
    min-width: 9rem;
  }

  .einsatz-inhalt .einsatz-aktionen > [data-wisch-rechts] form,
  .einsatz-inhalt .einsatz-aktionen > [data-wisch-rechts] .btn {
    width: 100%;
  }
}

.backlog .seitenkopf h2 {
  margin: 0;
}

.backlog > .muted {
  margin: 0.25rem 0 0;
}

/* In der Zeile ist der Anlass Teil der grauen zweiten Zeile. */
.einsatz-zeile > summary .einsatz-anlass {
  margin: 0;
}

/* ======================================================= Neuer Einsatz === */

/*
 * Eine schmale Spalte, auch am grossen Bildschirm: Das Formular liest sich
 * von oben nach unten, breiter würde es nur leerer. Wo, was, wann als
 * eigene Karten - so sieht man, was schon erledigt ist.
 */
.neu-seite {
  max-width: 40rem;
  margin: 0 auto;
}

.neu-form {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  margin-top: 0.75rem;
}

.neu-teil {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.neu-teil h2 {
  margin: 0;
  font-size: var(--fs-lg);
}

.neu-teil .chips-feld,
.neu-teil .chips {
  margin: 0;
}

.neu-teil .ort-frei {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

/* Die Dauer der Einsatzart klein hinter dem Namen, der Farbpunkt davor.
   `.chip-radio span` macht aus jedem inneren span eine Pille - der Punkt
   bekommt seine Masse deshalb hier zurück. */
.chip-radio span.einsatz-art {
  display: inline-block;
  flex: none;
  width: 0.65rem;
  height: 0.65rem;
  min-height: 0;
  margin-right: 0.45rem;
  padding: 0;
  border-radius: 50%;
}

.chip-zusatz {
  margin-left: 0.4rem;
  font-size: var(--fs-xs);
  white-space: nowrap;
  opacity: 0.75;
}

/* Die vier Dringlichkeiten nebeneinander wie ein Schalter - am Handy in
   einer Zeile statt zwei. */
.neu-teil .chips.dringlichkeit {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(4.6rem, 1fr));
  gap: 0.35rem;
}

.chips.dringlichkeit .chip {
  justify-content: stretch;
}

.chips.dringlichkeit .chip-radio span {
  justify-content: center;
  width: 100%;
  padding: 0 0.4rem;
}

/* ---- Stall wählen: Suche und Liste zum Antippen ---- */

.stall-feld {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.stall-suche {
  width: 100%;
}

/* Die Liste scrollt in sich - die Knöpfe unten bleiben erreichbar, auch
   bei zweihundert Ställen. */
.stall-liste {
  max-height: 18rem;
  overflow-y: auto;
  overscroll-behavior: contain;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--field);
}

.stall-gruppe {
  margin: 0;
  padding: 0.5rem 0.85rem 0.25rem;
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--muted);
}

.stall-wahl {
  flex-direction: row;
  align-items: center;
  gap: 0.6rem;
  min-height: var(--tap);
  padding: 0.35rem 0.85rem;
  border-top: 1px solid var(--border);
  font-size: var(--fs-base);
  font-weight: 400;
  cursor: pointer;
}

.stall-gruppe + .stall-wahl,
.stall-liste > .stall-wahl:first-child {
  border-top: 0;
}

.stall-wahl input {
  flex: none;
  width: 1.15rem;
  height: 1.15rem;
  margin: 0;
  accent-color: var(--accent-solid);
}

.stall-wahl > span {
  min-width: 0;
  overflow-wrap: anywhere;
}

.stall-wahl b {
  font-weight: 600;
}

.stall-wahl:has(input:checked) {
  background: var(--ok-bg);
}

.stall-leer {
  margin: 0;
  padding: 0.75rem 0.85rem;
}

/* ---- Tag: heute, morgen, übermorgen ---- */

.tag-knoepfe {
  margin: 0;
}

.tag-knopf {
  min-height: var(--tap);
  padding: 0 1rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  background: var(--bg);
  color: var(--text);
  font: inherit;
  cursor: pointer;
  touch-action: manipulation;
}

.tag-knopf[aria-pressed='true'] {
  border-color: var(--accent-solid);
  background: var(--accent-solid);
  color: var(--on-solid);
}

.tag-knopf:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* ---- Weitere Angaben und Knöpfe ---- */

.neu-mehr > summary {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.25rem 0.6rem;
  min-height: var(--tap);
  align-content: center;
  cursor: pointer;
}

.neu-mehr > summary .muted {
  font-size: var(--fs-sm);
}

.neu-mehr-inhalt {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  margin-top: 0.75rem;
}

.neu-knoepfe {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.neu-knoepfe .btn {
  flex: 1 1 12rem;
  min-height: 3rem;
  justify-content: center;
}

.neu-form > .hint {
  margin: 0;
}

/* ======================================================== Disposition === */

/* Breite Seiten (Disposition, Woche) dürfen den grossen Bildschirm nutzen. */
.seite-breit .page {
  max-width: 1600px;
}

.text-warn {
  color: var(--warn);
}

/* Tour · Alle · Woche: drei Verweise wie ein Schalter. */
.ansicht-schalter {
  display: inline-flex;
  padding: 0.2rem;
  border-radius: var(--radius-pill);
  background: var(--surface);
  box-shadow: inset 0 0 0 1px var(--border);
}

.ansicht-schalter a {
  display: inline-flex;
  align-items: center;
  min-height: calc(var(--tap) - 0.4rem);
  padding: 0 0.9rem;
  border-radius: var(--radius-pill);
  color: var(--text);
  font-size: var(--fs-sm);
  font-weight: 500;
  text-decoration: none;
}

.ansicht-schalter a[aria-current='page'] {
  background: var(--accent-solid);
  color: var(--on-solid);
}

.ansicht-schalter a:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* Auf der Tour einer Person nur am grossen Bildschirm: Am Handy ist die
   eine Tour die Ansicht, und der Kopf hat keinen Platz für mehr. */
.ansicht-schalter.nur-gross {
  display: none;
}

@media (min-width: 761px) {
  .ansicht-schalter.nur-gross {
    display: inline-flex;
  }
}

.dispo-summe {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem 1.1rem;
  margin: 0 0 0.9rem;
  color: var(--muted);
  font-size: var(--fs-sm);
}

.dispo-summe strong {
  color: var(--text);
}

.dispo-summe .text-warn strong,
.dispo-summe .text-gefahr strong {
  color: inherit;
}

/*
 * Die Spalten: so viele, wie Touren fahren, plus „Offen". Passen sie nicht
 * nebeneinander, scrollt der Bereich seitlich in sich - die Seite selbst
 * nie. Am Handy stehen die Spalten untereinander.
 */
.dispo {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(15.5rem, 1fr);
  gap: 0.75rem;
  align-items: start;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  padding-bottom: 0.5rem;
}

@media (max-width: 760px) {
  .dispo {
    grid-auto-flow: row;
    grid-auto-columns: auto;
  }
}

.dispo-spalte {
  min-width: 0;
  padding: 0.9rem;
}

.dispo-spalte.ist-voll {
  box-shadow: var(--shadow), inset 0 3px 0 var(--danger);
}

.dispo-offen {
  background: var(--bg);
  border: 1px dashed var(--border);
  box-shadow: none;
}

.dispo-kopf {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: baseline;
  gap: 0 0.5rem;
  margin-bottom: 0.6rem;
}

.dispo-kopf h2 {
  margin: 0;
  font-size: var(--fs-lg);
}

.dispo-kopf h2 a {
  color: inherit;
  text-decoration: none;
}

.dispo-kopf h2 a:hover {
  text-decoration: underline;
}

.dispo-zahl {
  color: var(--muted);
  font-size: var(--fs-sm);
}

.dispo-kopf .auslastung {
  grid-column: 1 / -1;
  margin: 0.5rem 0 0.3rem;
}

.dispo-werte {
  grid-column: 1 / -1;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.2rem 0.75rem;
  margin: 0;
  font-size: var(--fs-sm);
}

.dispo-werte .badge {
  display: inline-flex;
  align-items: center;
  gap: 0.2rem;
}

.dispo-werte .icon,
.dispo-marken .icon {
  width: 0.9rem;
  height: 0.9rem;
}

.dispo-hinweis {
  grid-column: 1 / -1;
  margin: 0.25rem 0 0;
  font-size: var(--fs-xs);
}

.dispo-liste {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}

.dispo-einsatz {
  border-radius: var(--radius-sm);
  background: var(--bg);
  box-shadow: inset 3px 0 0 var(--accent-solid);
}

.dispo-offen .dispo-einsatz {
  background: var(--surface);
  box-shadow: inset 0 0 0 1px var(--border);
}

.dispo-einsatz.einsatz-done {
  box-shadow: inset 3px 0 0 var(--ok);
}

.dispo-einsatz.einsatz-cancelled {
  box-shadow: inset 3px 0 0 var(--border);
}

.dispo-einsatz.hat-konflikt {
  box-shadow: inset 3px 0 0 var(--konflikt);
}

.dispo-einsatz.einsatz-notfall {
  box-shadow: inset 3px 0 0 var(--danger);
}

.dispo-link {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: start;
  gap: 0.1rem 0.6rem;
  padding: 0.5rem 0.6rem 0.5rem 0.75rem;
  color: inherit;
  text-decoration: none;
  border-radius: var(--radius-sm);
}

a.dispo-link:hover {
  background: var(--accent-schatten);
}

a.dispo-link:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

/* In „Offen" gibt es keine Zeit - der Ort nimmt die ganze Breite. */
.dispo-offen .dispo-link {
  grid-template-columns: 1fr;
}

.dispo-zeit {
  min-width: 2.9rem;
  font-variant-numeric: tabular-nums;
}

.dispo-zeit .einsatz-haken .icon {
  width: 1.1rem;
  height: 1.1rem;
}

.dispo-ort {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.dispo-ort strong,
.dispo-ort .muted {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.dispo-ort .muted {
  font-size: var(--fs-sm);
}

.dispo-einsatz.einsatz-cancelled .dispo-ort strong {
  color: var(--muted);
}

.dispo-marken {
  grid-column: 2;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.3rem;
}

.dispo-offen .dispo-marken {
  grid-column: 1;
}

.dispo-marken:empty {
  display: none;
}

.dispo-marken .badge {
  display: inline-flex;
  align-items: center;
  gap: 0.2rem;
  font-size: var(--fs-xs);
  padding: 0.05rem 0.45rem;
}

.dispo-einplanen {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  padding: 0 0.6rem 0.6rem 0.75rem;
}

.dispo-einplanen select {
  flex: 1 1 8rem;
  min-width: 0;
  padding-block: 0.4rem;
}

.dispo-einplanen .btn {
  min-height: 2.4rem;
}

.dispo-leer {
  margin: 0.25rem 0 0;
}

/* Am grossen Bildschirm übernimmt der Umschalter, was hier ein Zeichen ist. */
@media (min-width: 761px) {
  .nur-klein {
    display: none !important;
  }
}

/* ======================================================= Woche als Raster === */

.nur-gross-block {
  display: none;
}

@media (min-width: 761px) {
  .nur-gross-block {
    display: block;
  }
}

/* Viele Personen oder ein schmales Tablet: Die Tabelle scrollt in sich. */
.wochen-raster-rahmen {
  overflow-x: auto;
  border-radius: var(--radius-lg);
  background: var(--surface);
  box-shadow: var(--shadow);
  border: 1px solid var(--card-rand);
}

.wochen-raster {
  width: 100%;
  border-collapse: collapse;
  table-layout: fixed;
  min-width: 46rem;
}

.wochen-raster th,
.wochen-raster td {
  padding: 0.4rem;
  border-bottom: 1px solid var(--border);
  vertical-align: middle;
  text-align: left;
}

.wochen-raster thead th {
  padding: 0.7rem 0.5rem;
  font-size: var(--fs-sm);
  font-weight: 600;
}

.wochen-raster thead th a {
  color: inherit;
  text-decoration: none;
}

.wochen-raster thead th a:hover {
  text-decoration: underline;
}

.wochen-raster thead th:first-child,
.wochen-raster tbody th {
  width: 9rem;
  padding-left: 1rem;
}

.wochen-raster tbody th {
  font-weight: 600;
}

.raster-name {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.wochen-raster tbody th .small {
  font-weight: 400;
}

.wochen-raster .ist-heute {
  background: var(--ok-bg);
}

.wochen-raster .kein-arbeitstag {
  background: var(--bg);
}

.wochen-raster tr:last-child > * {
  border-bottom: 0;
}

.raster-zelle {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  min-height: 3.2rem;
  justify-content: center;
  padding: 0.35rem 0.5rem;
  border-radius: var(--radius-sm);
  color: inherit;
  text-decoration: none;
}

.raster-zelle:hover {
  background: var(--accent-schatten);
}

.raster-zelle:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

.raster-oben {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.15rem 0.45rem;
  font-size: var(--fs-sm);
  font-variant-numeric: tabular-nums;
}

.raster-oben strong {
  font-size: var(--fs-base);
}

.raster-oben .badge {
  display: inline-flex;
  align-items: center;
  gap: 0.15rem;
  padding: 0 0.35rem;
}

.raster-oben .icon,
.wochen-tour .badge .icon {
  width: 0.85rem;
  height: 0.85rem;
}

.raster-zelle .auslastung {
  height: 0.55rem;
  margin: 0;
}

.raster-zelle.ist-frei .auslastung {
  opacity: 0.6;
}

.raster-leer {
  display: block;
  padding-left: 0.5rem;
  color: var(--muted);
}

.raster-offen th {
  color: var(--muted);
  font-weight: 500;
}

.raster-offen .badge {
  text-decoration: none;
}

.wochen-tour .badge {
  display: inline-flex;
  align-items: center;
  gap: 0.15rem;
}

/* Die Tabelle der Woche liest sich wie ein Plan, nicht wie eine Liste:
   Namen und Tage in normaler Schrift. */
.wochen-raster th {
  text-transform: none;
  letter-spacing: normal;
  color: var(--text);
}

.wochen-raster thead th {
  color: var(--muted);
}

.wochen-raster thead th.ist-heute {
  color: var(--text);
}

/* Ohne Einsätze kein leerer Balken - „frei" sagt es schon. */
.raster-zelle.ist-frei .auslastung {
  display: none;
}

.wochen-raster-rahmen + .woche + .row,
.wochen-raster-rahmen + .row {
  margin-top: 1rem;
}

/* ================================================ Hinweise unten (Toast) === */

/*
 * Meldungen nach einer Aktion: unten, über der Leiste und dem „+", damit
 * sie dort erscheinen, wo der Daumen gerade ist. Ohne JavaScript bleiben
 * sie oben in der Seite stehen (ohne-neuladen.js holt sie hierher).
 */
.meldungen {
  position: fixed;
  left: 50%;
  bottom: calc(1.25rem + env(safe-area-inset-bottom));
  z-index: 40;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  width: min(32rem, calc(100% - 2rem));
  transform: translateX(-50%);
  pointer-events: none;
}

@media (max-width: 760px) {
  .mit-tableiste .meldungen {
    bottom: calc(10.5rem + env(safe-area-inset-bottom));
  }
}

.meldung {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem 0.9rem;
  margin: 0;
  padding: 0.75rem 3rem 0.75rem 1rem;
  border-radius: var(--radius);
  box-shadow: 0 10px 30px rgb(0 0 0 / 0.22);
  font-size: var(--fs-sm);
  pointer-events: auto;
  animation: meldung-rein 180ms ease-out;
}

/* Ein Hinweis unten soll sich vom Seitengrund abheben - in der Gegenfarbe
   (hell: dunkel, dunkel: hell). Die Art steht als farbiger Rand links. */
.meldung.alert-ok,
.meldung.alert-warn,
.meldung.alert-error,
.meldung.rueckgaengig-leiste {
  background: var(--inverse-bg);
  color: var(--on-inverse);
  border: 0;
}

.meldung.alert-ok { box-shadow: 0 10px 30px rgb(0 0 0 / 0.22), inset 4px 0 0 var(--zone-nah); }
.meldung.alert-warn { box-shadow: 0 10px 30px rgb(0 0 0 / 0.22), inset 4px 0 0 var(--warn-mark); }
.meldung.alert-error { box-shadow: 0 10px 30px rgb(0 0 0 / 0.22), inset 4px 0 0 var(--danger-solid); }

.meldung.rueckgaengig-leiste {
  justify-content: space-between;
}

.meldung-zu {
  position: absolute;
  top: 50%;
  right: 0.4rem;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  transform: translateY(-50%);
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: inherit;
  font: inherit;
  font-size: 1.3rem;
  line-height: 1;
  cursor: pointer;
}

.meldung-zu:hover {
  background: rgb(255 255 255 / 0.12);
}

.meldung-zu:focus-visible {
  outline: 2px solid var(--on-inverse);
  outline-offset: 1px;
}

.meldung-weg {
  opacity: 0;
  transform: translateY(0.5rem);
  transition: opacity 200ms, transform 200ms;
}

@keyframes meldung-rein {
  from { opacity: 0; transform: translateY(0.75rem); }
  to { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  .meldung { animation: none; }
  .meldung-weg { transition: none; }
}

/* Während eine Aktion unterwegs ist: der Knopf zeigt es, der Rest bleibt
   bedienbar lesbar. */
form.wird-gesendet button[type='submit'],
form.wird-gesendet button:not([type]) {
  opacity: 0.6;
  cursor: progress;
}

.planung-bereich[aria-busy='true'] {
  cursor: progress;
}

.meldung .btn {
  background: transparent;
  border-color: color-mix(in srgb, var(--on-inverse) 50%, transparent);
  color: var(--on-inverse);
}

/* ============================================ Betreiber & Ställe (UI-7) === */

/* Suche über der Liste: Feld, Schalter, Knopf in einer Zeile. */
.such-zeile {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  margin: 0.75rem 0 1rem;
}

.such-zeile input[type='search'] {
  flex: 1 1 14rem;
  min-width: 0;
}

.such-zeile .chip-schalter span {
  min-height: calc(var(--tap) - 0.25rem);
  font-size: var(--fs-sm);
}

/* Eine Liste aus Karten-Zeilen: ein Tipp öffnet den Eintrag. */
.karten-liste {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.karten-zeile {
  display: flex;
  align-items: stretch;
  background: var(--surface);
  border: 1px solid var(--card-rand);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}

.karten-zeile.ist-aus {
  background: var(--bg);
  box-shadow: none;
}

.karten-link {
  display: flex;
  flex: 1 1 auto;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.35rem 0.75rem;
  min-width: 0;
  min-height: 3.5rem;
  padding: 0.6rem 0.9rem;
  color: inherit;
  text-decoration: none;
  border-radius: var(--radius);
}

.karten-link:hover {
  background: var(--accent-schatten);
}

.karten-link:focus-visible,
.karten-anruf:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.karten-link > .icon {
  flex: none;
  width: 1.1rem;
  height: 1.1rem;
  margin-left: auto;
  color: var(--muted);
}

.karten-haupt {
  display: flex;
  flex-direction: column;
  flex: 1 1 12rem;
  min-width: 0;
}

.karten-haupt strong,
.karten-haupt .muted {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.karten-haupt .muted {
  font-size: var(--fs-sm);
}

.karten-zeile.ist-aus .karten-haupt strong {
  color: var(--muted);
}

.karten-marken {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem;
}

.karten-marken .badge {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
}

.karten-marken .icon {
  width: 0.9rem;
  height: 0.9rem;
}

/* Anrufen direkt aus der Liste - am Hof das Häufigste. */
.karten-anruf {
  display: flex;
  flex: none;
  align-items: center;
  justify-content: center;
  width: 3.25rem;
  border-left: 1px solid var(--border);
  color: var(--accent);
  border-radius: 0 var(--radius) var(--radius) 0;
}

.karten-anruf:hover {
  background: var(--accent-schatten);
}

.karten-anruf .icon {
  width: 1.3rem;
  height: 1.3rem;
}

/* ---- Neue Seiten: Unterteile, Häkchen-Zeile, Namensprüfung ---- */

.neu-unterteil {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.schalter-zeile {
  min-height: var(--tap);
  font-size: var(--fs-base);
}

.schalter-zeile input {
  width: 1.2rem;
  height: 1.2rem;
  accent-color: var(--accent-solid);
}

.name-treffer {
  margin: -0.35rem 0 0;
  padding: 0.5rem 0.75rem;
  border-radius: var(--radius-sm);
  background: var(--warn-bg);
  color: var(--warn);
  font-size: var(--fs-sm);
}

.name-treffer a {
  color: inherit;
  font-weight: 600;
}

.stall-wahl-neu b {
  color: var(--accent);
}

/* ---- Anschrift mit Ortsvorschlag ---- */

.anschrift {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.anschrift .row-fields > label.narrow {
  flex: 0 1 7.5rem;
}

.anschrift-quelle {
  margin: -0.25rem 0 0;
  font-size: var(--fs-xs);
}

.ort-feld {
  position: relative;
  display: flex;
  flex-direction: column;
}

.ort-liste {
  position: absolute;
  top: calc(100% + 0.25rem);
  left: 0;
  right: 0;
  z-index: 30;
  min-width: 15rem;
  max-height: 16rem;
  margin: 0;
  padding: 0.25rem;
  overflow-y: auto;
  list-style: none;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  box-shadow: 0 10px 30px rgb(0 0 0 / 0.18);
}

.ort-liste li {
  display: flex;
  flex-direction: column;
  padding: 0.5rem 0.65rem;
  border-radius: calc(var(--radius-sm) - 0.25rem);
  font-size: var(--fs-base);
  font-weight: 400;
  cursor: pointer;
}

.ort-liste li span {
  color: var(--muted);
  font-size: var(--fs-sm);
}

.ort-liste li[aria-selected='true'],
.ort-liste li:hover {
  background: var(--ok-bg);
}

.footer-quelle {
  display: block;
  margin-top: 0.25rem;
  font-size: var(--fs-xs);
}

.kontakt-zeile {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: 0 0 1rem;
}

.kontakt-zeile .btn,
.section .row .btn {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
}

.kontakt-zeile .icon,
.section .row .btn .icon {
  width: 1.1rem;
  height: 1.1rem;
}

.section .karten-liste {
  margin-bottom: 0.75rem;
}

/* ======================================== Vorerst gesperrte Bereiche === */

/* Grau und ohne Ziel: Man sieht, dass es kommt, kann es aber nicht öffnen. */
.nav-gesperrt {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.55rem 0.8rem;
  color: var(--muted);
  opacity: 0.75;
  cursor: not-allowed;
}

.nav-gesperrt small {
  margin-left: auto;
  padding: 0.05rem 0.45rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  font-size: var(--fs-xs);
  white-space: nowrap;
}

.tab.ist-gesperrt {
  opacity: 0.45;
  cursor: not-allowed;
}

.heute-kachel.ist-gesperrt,
.heute-behandlungen.ist-gesperrt {
  opacity: 0.55;
  cursor: not-allowed;
}

.heute-kachel.ist-gesperrt small {
  display: block;
  font-size: var(--fs-xs);
  font-weight: 400;
}

/* In der Leiste oben am grossen Bildschirm passt die Marke nicht in die
   Zeile - dort genügt das Grau, der Hinweis steht im Tooltip. In Schublade
   und Blatt bleibt sie stehen. */
@media (min-width: 1200px) {
  .nav-list > li > .nav-gesperrt {
    padding: 0.4rem 0.55rem;
    border-bottom: 2px solid transparent;
  }

  .nav-list > li > .nav-gesperrt small {
    display: none;
  }
}

/* ---------------------------------------------------------- Einsatzzeiten */

.zeiten-hinweis {
  margin: 0.25rem 0 0.75rem;
}

.zeiten-wer {
  margin: 1rem 0 0.5rem;
  font-size: var(--fs-lg);
}

.zeiten-liste {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.zeit-tag {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  padding: 0.6rem 1rem 0.35rem;
}

.zeit-tag.ist-frei {
  background: var(--bg);
}

.zeit-kopf {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem 0.6rem;
}

.zeit-tagname {
  flex: 1 1 10rem;
}

.zeit-anzahl {
  font-size: var(--fs-sm);
}

.zeit-warnung {
  margin: 0;
}

.badge-bereitschaft {
  background: var(--info-bg);
  border-color: transparent;
  color: var(--info);
}

.zeit-aendern > summary {
  min-height: var(--tap);
  display: flex;
  align-items: center;
  cursor: pointer;
  color: var(--accent);
  font-weight: 600;
}

.zeit-form {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  padding-top: 0.25rem;
}

.zeit-form .chips-feld,
.zeit-form .chips {
  margin: 0;
}

.zeit-knoepfe {
  display: flex;
  justify-content: flex-end;
}

.dienst-zeile {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem 0.6rem;
  margin: 0.25rem 0 0;
}

/* Nicht im Dienst: in Disposition und Woche zurückgenommen. */
.dispo-spalte.ist-frei,
.raster-zelle.ist-dienstfrei,
.wochen-tour.ist-dienstfrei {
  background: var(--bg);
}

.dispo-spalte.ist-frei .dispo-kopf h2 a,
.wochen-tour.ist-dienstfrei .wochen-name {
  color: var(--muted);
}

.heute-dienst,
.heute-dienst:visited {
  display: inline-block;
  margin-top: 0.2rem;
  font-size: var(--fs-sm);
  color: var(--on-band-leise);
  text-decoration: none;
}

.heute-dienst-link {
  color: var(--on-band);
  text-decoration: underline;
}

.notfall-kandidat.ist-ausserhalb {
  background: var(--bg);
}

.notfall-frage p {
  margin: 0 0 0.4rem;
}

.notfall-frage .schalter-zeile {
  margin-top: 0.25rem;
}

.tagzeile-link {
  white-space: nowrap;
}

.tagzeile-link .icon {
  width: 1em;
  height: 1em;
  margin-right: 0.2em;
  vertical-align: -0.15em;
}

/* Uhrzeit-Rad (uhrrad.js): Stunde und Minute nebeneinander, nur am Finger. */
.uhrrad {
  gap: 0.25rem;
}

.uhrrad .rad-fenster {
  flex: 0 0 3.4rem;
  min-width: 3.4rem;
}

.uhrrad-trenner {
  font-size: var(--fs-lg);
  font-weight: 600;
}

.row-fields > label.narrow.hat-uhrrad {
  flex: 1 1 7.5rem;
}

.uhrrad.ist-leer .rad-fenster:last-child {
  opacity: 0.4;
}

.zeit-hinweis {
  margin: -0.4rem 0 0;
}

.zeit-start {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}

.zeit-start .anschrift {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}
