/* ═══════════════════════════════════════════════════════════════════════════════
   team.junaspin — App-Shell

   Die Tokens stammen aus dem junaspin-PIM und sind bewusst unverändert übernommen,
   damit beide Anwendungen als eine Familie lesbar sind. Herleitung und Messwerte:
   docs/PIM-ANALYSE.md §3.

   ⛔ DIE FARBWERTE HIER SIND NUR DIE VORBELEGUNG. Die gültigen Werte stehen in
   app_settings.design und werden von views/layout.html als :root-Block DAHINTER
   ausgegeben. Wer eine Farbe ändern will, tut das im Admin-UI, nicht hier.

   Die Regeln, gegen die jede Zeile prüfbar ist:
    1 Höchstens eine Primäraktion pro Seite.
    2 Farbe ist Bedeutung, nie Dekoration.
    3 Ziffern tabellarisch, rechtsbündig, Einheiten grau.
    4 Schriftgrößen nur über Tokens — keine Pixelzahl in einer font-size.
    5 Schatten nur für z > 0. Was liegen bleibt, wirft keinen.
   ═══════════════════════════════════════════════════════════════════════════════ */

:root {
  --rail-w: 236px;
  --h-topbar: 48px;
  --h-pagehead: 56px;

  --f-ui: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --f-mono: ui-monospace, "SF Mono", "Cascadia Mono", Consolas, "Liberation Mono", monospace;

  /* Typo-Skala. `--fs-terminal` ist die einzige Erweiterung gegenüber dem PIM: eine
     Lagerhalle liest keine 28 px aus zwei Metern Entfernung. */
  --fs-micro: 11px; --fs-dense: 13px; --fs-ui: 14px;
  --fs-body: 15px;  --fs-sect: 17px;  --fs-title: 22px; --fs-kpi: 28px;
  --fs-icon: 10px;  --fs-terminal: 64px;

  /* Ein Zeilenmaß für Fließtext, überall. 780 px sind bei 15 px rund 95 Zeichen.
     ⛔ Gilt NUR für Fließtext — Tabellen und Raster haben es absichtlich nicht. */
  --measure: 780px;

  --sp-1: 4px; --sp-2: 8px; --sp-3: 12px; --sp-4: 16px;
  --sp-5: 20px; --sp-6: 24px; --sp-8: 32px;

  --r-1: 3px; --r-2: 6px; --r-3: 10px; --r-full: 999px;
  --sh-pop:   0 4px 12px rgba(16,22,30,.13), 0 0 0 1px rgba(16,22,30,.06);
  --sh-modal: 0 16px 48px rgba(16,22,30,.26);

  /* Neutrale mit WARMEM Bias. Ziehen Neutrale und Markenblau beide ins Kühle, hebt
     sich nichts ab. Auf warmem Grund bekommt das gedeckte Stahlblau Präsenz. */
  --canvas: #FFFFFF;
  --sunken: #F7F6F4;
  --table-head: #EFECE6;
  --hover: #F5F2ED;
  --selected: #E8EFF5;
  --border: #E5E2DC;
  --border-strong: #CFCAC1;
  --row-line: #EDEAE4;

  --text: #23201C;        /* 16,2:1 */
  --text-muted: #6B655D;  /*  5,8:1 — Labels, Sekundärwerte */
  --text-faint: #9A938A;  /*  3,0:1 — NUR Platzhalter/Einheiten/disabled. Nie auf einem Wert. */

  /* Marke: das junaspin-Logo ist gedecktes Stahlblau #5B7F9E. --primary ist daraus auf
     Kontrast gezogen (Weiß darauf 6,9:1). */
  --primary: #2C5F85;
  --primary-hover: #234E6E;
  --focus: #2C5F85;

  /* Ampel — nachgemessen auf warmem Grund: good 6,2:1 · warn 5,0:1 · bad 6,1:1.
     Sie gehört dem Tagesstatus und dem Urlaubskonto. Kein Button trägt sie. */
  --good: #12693F;
  --warn: #B54708;
  --bad:  #B32318;

  --badge-ok-bg: #E9F4EE;   --badge-ok-bd: #C4E2D2;   --badge-ok-fg: #12693F;
  --badge-warn-bg: #FCF5E9; --badge-warn-bd: #EFDDBE; --badge-warn-fg: #8A4B0A;
  --badge-err-bg: #FCF0EE;  --badge-err-bd: #F2D1CC;  --badge-err-fg: #92221A;
  --badge-neu-bg: #F0F3F5;  --badge-neu-bd: #DEE3E8;  --badge-neu-fg: #4A545F;

  --rail: #EDE8DF;
  --rail-hover: #E5DFD3;
  --rail-active: #FFFFFF;
  --rail-border: #D9D2C6;
  --rail-text: #55504A;
  --rail-text-active: #1C4E75;
  --rail-section: #756D63;

  --toast-bg: #12161B;
  --toast-fg: #E4E8ED;

  color-scheme: light;
}

/* Dark: EIN Block, EIN Selektor. Kein zusätzlicher `prefers-color-scheme`-Block —
   im PIM war das toter Code und eine Falle: 24 Token-Zeilen, die jemand von Hand
   synchron halten musste, und beim Palettenwechsel liefen sie auseinander.
   `data-theme` wird vor dem ersten Paint gesetzt (layout.html). */
:root[data-theme="dark"] {
  --canvas: #22201E; --sunken: #1A1917; --table-head: #2B2926;
  --hover: #2E2B27; --selected: #24384A;
  --border: #3A3733; --border-strong: #4B4741; --row-line: #302D29;
  --text: #EBE7E1; --text-muted: #A8A199; --text-faint: #7A736B;
  --primary: #6BA3D0; --primary-hover: #82B5DD; --focus: #8CBEE2;
  --good: #45C08A; --warn: #E5A34C; --bad: #F0655A;
  --badge-ok-bg: #14301F; --badge-ok-bd: #1F5637; --badge-ok-fg: #6EDCA6;
  --badge-warn-bg: #2E2415; --badge-warn-bd: #5A4520; --badge-warn-fg: #F0BE6B;
  --badge-err-bg: #331A18; --badge-err-bd: #63302B; --badge-err-fg: #F58B80;
  --badge-neu-bg: #232A33; --badge-neu-bd: #363F4A; --badge-neu-fg: #A7B1BD;
  --rail: #12161B; --rail-hover: #1C222B; --rail-active: #23303D;
  --rail-border: #232B35; --rail-text: #A7B1BD; --rail-text-active: #FFFFFF;
  --rail-section: #626D7A;
  --sh-pop: 0 4px 12px rgba(0,0,0,.5), 0 0 0 1px rgba(255,255,255,.07);
  --sh-modal: 0 16px 48px rgba(0,0,0,.62);
  color-scheme: dark;
}

*, *::before, *::after { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--canvas);
  color: var(--text);
  font: 400 var(--fs-body)/1.5 var(--f-ui);
  -webkit-text-size-adjust: 100%;
}

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

:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; border-radius: var(--r-1); }

/* ── SHELL ─────────────────────────────────────────────────────────────────── */
.app { display: grid; grid-template-columns: var(--rail-w) 1fr; min-height: 100vh; }

.rail {
  background: var(--rail);
  border-right: 1px solid var(--rail-border);
  padding: var(--sp-4) 0;
  display: flex; flex-direction: column; gap: var(--sp-1);
}
.rail-brand {
  display: flex; align-items: center; gap: var(--sp-2);
  padding: 0 var(--sp-4) var(--sp-5);
  font: 600 var(--fs-sect)/1.2 var(--f-ui); color: var(--text);
}
.rail-brand small { color: var(--rail-section); font-weight: 500; font-size: var(--fs-dense); }
.rail-section {
  padding: var(--sp-4) var(--sp-4) var(--sp-1);
  font: 600 var(--fs-micro)/1.4 var(--f-ui);
  letter-spacing: .04em; text-transform: uppercase; color: var(--rail-section);
}
.rail a {
  display: block; padding: var(--sp-2) var(--sp-4);
  color: var(--rail-text); font-size: var(--fs-ui); text-decoration: none;
  border-left: 3px solid transparent;
}
.rail a:hover { background: var(--rail-hover); color: var(--text); }
.rail a[aria-current="page"] {
  background: var(--rail-active); color: var(--rail-text-active);
  border-left-color: var(--primary); font-weight: 600;
}
.rail-fuss { margin-top: auto; padding: var(--sp-4); }

.main { display: flex; flex-direction: column; min-width: 0; }

.topbar {
  height: var(--h-topbar); flex: none;
  display: flex; align-items: center; gap: var(--sp-4);
  padding: 0 var(--sp-6);
  border-bottom: 1px solid var(--border);
  background: var(--canvas);
}
.topbar .rechts { margin-left: auto; display: flex; align-items: center; gap: var(--sp-3); }
.topbar .uhr { font: 500 var(--fs-dense)/1 var(--f-mono); color: var(--text-muted); }

.inhalt { padding: var(--sp-6); flex: 1; min-width: 0; }
.seitenkopf { margin-bottom: var(--sp-5); }
.seitenkopf h1 { margin: 0 0 var(--sp-1); font: 600 var(--fs-title)/1.25 var(--f-ui); }
.seitenkopf p { margin: 0; color: var(--text-muted); max-width: var(--measure); }

/* ── BAUSTEINE ─────────────────────────────────────────────────────────────── */
.karte {
  background: var(--canvas);
  border: 1px solid var(--border);
  border-radius: var(--r-3);
  padding: var(--sp-5);
  margin-bottom: var(--sp-4);
}
.karte > h2 { margin: 0 0 var(--sp-3); font: 600 var(--fs-sect)/1.3 var(--f-ui); }
.karte > p { max-width: var(--measure); }
.karte-hinweis { color: var(--text-muted); font-size: var(--fs-ui); }

.raster { display: grid; gap: var(--sp-4); grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }

.kennzahl { display: flex; flex-direction: column; gap: var(--sp-1); }
.kennzahl .wert {
  font: 600 var(--fs-kpi)/1.1 var(--f-ui);
  font-variant-numeric: tabular-nums;
}
.kennzahl .beschriftung { font-size: var(--fs-dense); color: var(--text-muted); }
.kennzahl .einheit { color: var(--text-faint); font-size: var(--fs-ui); font-weight: 400; }

.knopf {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2);
  min-height: 38px; padding: 0 var(--sp-4);
  border: 1px solid var(--border-strong); border-radius: var(--r-2);
  background: var(--canvas); color: var(--text);
  font: 500 var(--fs-ui)/1 var(--f-ui); cursor: pointer;
}
.knopf:hover { background: var(--hover); }
.knopf-primaer {
  background: var(--primary); border-color: var(--primary); color: #fff;
}
.knopf-primaer:hover { background: var(--primary-hover); border-color: var(--primary-hover); }
.knopf[disabled] { opacity: .5; cursor: not-allowed; }

.feld { display: block; margin-bottom: var(--sp-4); }
.feld > span { display: block; margin-bottom: var(--sp-1); font-size: var(--fs-dense); color: var(--text-muted); }
.feld input[type="text"], .feld input[type="password"], .feld input[type="number"], .feld select {
  width: 100%; min-height: 38px; padding: 0 var(--sp-3);
  border: 1px solid var(--border-strong); border-radius: var(--r-2);
  background: var(--canvas); color: var(--text);
  font: 400 var(--fs-ui)/1 var(--f-ui);
}
.feld input:focus-visible, .feld select:focus-visible { border-color: var(--focus); }

/* Farbwähler: der native Picker daneben, der Hexwert daneben lesbar — man muss den
   Wert abtippen können, ohne ihn aus dem Picker zu erraten. */
.farbfeld { display: flex; align-items: center; gap: var(--sp-3); }
.farbfeld input[type="color"] {
  width: 44px; height: 38px; padding: 2px;
  border: 1px solid var(--border-strong); border-radius: var(--r-2);
  background: var(--canvas); cursor: pointer;
}
.farbfeld input[type="text"] { width: 10ch; font-family: var(--f-mono); }
.farbfeld .probe {
  width: 24px; height: 24px; border-radius: var(--r-1);
  border: 1px solid var(--border-strong);
}

.hinweis {
  border: 1px solid var(--border); border-left-width: 3px;
  border-radius: var(--r-2); padding: var(--sp-3) var(--sp-4);
  margin-bottom: var(--sp-4); max-width: var(--measure);
  font-size: var(--fs-ui);
}
.hinweis-ok   { background: var(--badge-ok-bg);   border-color: var(--badge-ok-bd);   border-left-color: var(--good); }
.hinweis-warn { background: var(--badge-warn-bg); border-color: var(--badge-warn-bd); border-left-color: var(--warn); }
.hinweis-bad  { background: var(--badge-err-bg);  border-color: var(--badge-err-bd);  border-left-color: var(--bad); }
.hinweis-neu  { background: var(--badge-neu-bg);  border-color: var(--badge-neu-bd);  border-left-color: var(--text-faint); }

.gitter { width: 100%; border-collapse: collapse; font-size: var(--fs-ui); }
.gitter th {
  background: var(--table-head); text-align: left;
  font: 600 var(--fs-dense)/16px var(--f-ui);
  padding: var(--sp-2) var(--sp-3); border-bottom: 1px solid var(--border);
}
.gitter td { padding: var(--sp-2) var(--sp-3); border-bottom: 1px solid var(--row-line); }
.gitter tr:hover td { background: var(--hover); }
/* Regel 3: Ziffern tabellarisch und rechtsbündig — sonst tanzen die Kommastellen. */
.gitter .zahl { text-align: right; font-variant-numeric: tabular-nums; }

.schritte { counter-reset: schritt; list-style: none; padding: 0; margin: 0; }
.schritte > li {
  counter-increment: schritt;
  position: relative; padding: 0 0 var(--sp-5) var(--sp-8);
  border-left: 1px solid var(--border); margin-left: 13px;
}
.schritte > li:last-child { border-left-color: transparent; padding-bottom: 0; }
.schritte > li::before {
  content: counter(schritt);
  position: absolute; left: -14px; top: 0;
  width: 26px; height: 26px; border-radius: var(--r-full);
  display: grid; place-items: center;
  background: var(--primary); color: #fff;
  font: 600 var(--fs-dense)/1 var(--f-ui);
}
.schritte h3 { margin: 2px 0 var(--sp-1); font: 600 var(--fs-ui)/1.35 var(--f-ui); }
.schritte p { margin: 0 0 var(--sp-2); max-width: var(--measure); }
.schritte .merke {
  font-size: var(--fs-dense); color: var(--text-muted);
  border-left: 2px solid var(--border-strong); padding-left: var(--sp-3);
}

/* ── ANMELDESEITE ──────────────────────────────────────────────────────────── */
.anmelden {
  min-height: 100vh; display: grid; place-items: center;
  background: var(--sunken); padding: var(--sp-4);
}
.anmelden-karte {
  width: 100%; max-width: 380px;
  background: var(--canvas); border: 1px solid var(--border);
  border-radius: var(--r-3); box-shadow: var(--sh-pop);
  padding: var(--sp-8);
}
.anmelden-karte h1 { margin: 0 0 var(--sp-5); font: 600 var(--fs-title)/1.2 var(--f-ui); }
.anmelden-karte .knopf { width: 100%; }

/* ── STEMPELUHR ─────────────────────────────────────────────────────────────
   Die einzige Fläche, die jeder Mitarbeiter täglich benutzt. Drei Regeln:

   1 Der Zustand steht VOR den Knöpfen. Wer nicht weiß, ob er eingestempelt ist,
     drückt aufs Geratewohl — und das erzeugt genau die Doppelbuchungen, gegen
     die die Datenbank sich dann wehren muss.
   2 Nur mögliche Knöpfe werden gezeigt. Kein ausgegrautes „Pause beenden", das
     erst beim Drücken erklärt, warum es nicht geht.
   3 Genau eine Primäraktion: der nächste Schritt im Tagesablauf. „Gehen" steht
     immer daneben, aber nie als der auffälligere von beiden — sonst endet der
     Tag beim Griff nach der Pause.

   Die Zielgrößen sind fürs Lager gerechnet: 56 px hohe Knöpfe lassen sich mit
   Arbeitshandschuhen auf einem Tablet treffen. */
.stempeluhr { display: grid; gap: var(--sp-5); }

.stempel-lage { display: flex; align-items: center; gap: var(--sp-3); flex-wrap: wrap; }
/* Die Ampel gehört dem Tagesstatus — hier, nicht an einem Knopf. */
.stempel-lage .ampel {
  flex: none; width: 12px; height: 12px; border-radius: var(--r-full);
  background: var(--text-faint);
}
.stempel-lage[data-lage="arbeit"] .ampel { background: var(--good); }
.stempel-lage[data-lage="pause"]  .ampel { background: var(--warn); }
.stempel-lage .text { font: 600 var(--fs-sect)/1.3 var(--f-ui); }
.stempel-lage .seit { color: var(--text-muted); font-size: var(--fs-ui); }

.laufzeit {
  font: 600 var(--fs-kpi)/1 var(--f-mono);
  font-variant-numeric: tabular-nums; letter-spacing: -.01em;
}
.laufzeit .einheit { color: var(--text-faint); font-size: var(--fs-ui); font-weight: 400; }

.stempel-knoepfe { display: flex; gap: var(--sp-3); flex-wrap: wrap; }
.stempel-knoepfe form { margin: 0; }
.knopf-gross {
  min-height: 56px; padding: 0 var(--sp-8);
  font: 600 var(--fs-sect)/1 var(--f-ui); border-radius: var(--r-3);
}

/* Ein laufendes Segment hat kein Ende — der Gedankenstrich in der Endespalte sähe
   aus wie ein fehlender Wert. Stattdessen steht dort, was tatsächlich der Fall ist. */
.gitter .laeuft { color: var(--good); font-weight: 600; }
.gitter .geschaetzt { color: var(--warn); }

/* ── FORMULARE UND LISTEN ───────────────────────────────────────────────────
   Ein Muster für alle Antrags- und Stammdatenformulare. Drei Regeln:
   Zeitraum zuerst, Besonderheiten in ein <details>, genau eine Primäraktion. */
.antrag { max-width: var(--measure); }
.antrag .knopf + .knopf, .antrag .knopf + a.knopf { margin-left: var(--sp-3); }

/* Zwei Felder nebeneinander, solange Platz ist. Auf dem Handy untereinander — nicht
   zwei je 160 px, in denen kein Datum mehr lesbar steht. */
.feldpaar { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 0 var(--sp-4); }

.feld input[type="date"], .feld input[type="email"], .feld textarea {
  width: 100%; min-height: 38px; padding: 0 var(--sp-3);
  border: 1px solid var(--border-strong); border-radius: var(--r-2);
  background: var(--canvas); color: var(--text); font: 400 var(--fs-ui)/1 var(--f-ui);
}
.feld textarea { min-height: 72px; padding: var(--sp-2) var(--sp-3); line-height: 1.45; resize: vertical; }
.feld-hinweis { display: block; margin-top: var(--sp-1); color: var(--text-muted); font-size: var(--fs-dense); }
.feld-schalter { display: grid; grid-template-columns: auto 1fr; gap: 0 var(--sp-2); align-items: baseline; }
.feld-schalter .feld-hinweis { grid-column: 2; }
.feld-schalter > span { margin: 0; font-size: var(--fs-ui); color: var(--text); }

/* Eingabe und Knopf in einer Zeile — für Kleinigkeiten wie „PIN setzen", die kein
   eigenes Formularfeld mit Beschriftung rechtfertigen. */
.reihenform { display: flex; gap: var(--sp-2); align-items: center; }
.reihenform input[type="text"] {
  min-height: 38px; padding: 0 var(--sp-3); min-width: 12ch;
  border: 1px solid var(--border-strong); border-radius: var(--r-2);
  background: var(--canvas); color: var(--text); font: 400 var(--fs-ui)/1 var(--f-ui);
}
.aktionsreihe { display: flex; flex-wrap: wrap; gap: var(--sp-3); margin-top: var(--sp-4); }
.aktionsreihe form { margin: 0; }

.karte-kopf { display: flex; align-items: baseline; gap: var(--sp-4); margin-bottom: var(--sp-4); }
.karte-kopf > h2 { margin: 0; font: 600 var(--fs-sect)/1.3 var(--f-ui); }
.karte-kopf > .knopf, .karte-kopf > a.knopf { margin-left: auto; }

/* ⛔ EINE TABELLE ROLLT IN IHREM EIGENEN KASTEN, NICHT IM BODY. Fünf Spalten auf 360 px
   schieben sonst die ganze Seite waagerecht — und mit ihr den Stempelknopf aus dem Bild. */
.gitter-rolle { overflow-x: auto; }
.gitter td > a { font-weight: 500; }
.zeile-zusatz { display: block; color: var(--text-muted); font-size: var(--fs-dense); }
/* Farbe ist Bedeutung: rot steht hier für „hier fehlt etwas, das gebraucht wird". */
.fehlt { color: var(--bad); font-weight: 500; }

.fehlerliste { margin: var(--sp-2) 0 0; padding-left: var(--sp-5); }
.fehlerliste li + li { margin-top: var(--sp-1); }

/* ⛔ DER ZUGANGSCODE ERSCHEINT GENAU EINMAL. Er darf deshalb nicht aussehen wie ein Hinweis,
   den man wegliest — groß, einzeilig, in Monospace, damit er sich abtippen und vorlesen lässt. */
.code-karte { border-left: 3px solid var(--primary); }
.code-karte .code {
  font: 600 var(--fs-kpi)/1.2 var(--f-mono);
  letter-spacing: .08em; margin: var(--sp-3) 0;
  -webkit-user-select: all; user-select: all;   /* Safari braucht den Praefix — und iOS ist Zielgeraet. */
}

/* ── SCHMALE FENSTER ───────────────────────────────────────────────────────── */
/* Die Schiene wird zur waagerechten Leiste. Kein Overlay mit Umschalter: für M0 ist
   das eine Abhängigkeit von JavaScript, die die Stempeluhr sich nicht leisten soll. */
@media (max-width: 780px) {
  .app { grid-template-columns: 1fr; }
  .rail {
    flex-direction: row; overflow-x: auto; gap: 0;
    padding: 0; border-right: none; border-bottom: 1px solid var(--rail-border);
  }
  .rail-brand, .rail-section { display: none; }
  .rail a { border-left: none; border-bottom: 3px solid transparent; white-space: nowrap; }
  .rail a[aria-current="page"] { border-left: none; border-bottom-color: var(--primary); }
  .inhalt { padding: var(--sp-4); }
  .topbar { padding: 0 var(--sp-4); }

  /* 38 px liegen unter dem Fingermaß. 44 px sind das Minimum, das sich auf einem
     Telefon zuverlässig treffen lässt — und im Lager oft mit Handschuh. */
  .knopf { min-height: 44px; }

  /* Auf dem Telefon steht jeder Stempelknopf über die ganze Breite. Zwei Knöpfe
     nebeneinander sind auf 360 px so schmal, dass der Daumen zwischen sie gerät —
     und ein Fehlgriff kostet hier eine Korrektur mit Begründungspflicht. */
  .stempel-knoepfe { flex-direction: column; align-items: stretch; }
  .stempel-knoepfe .knopf-gross { width: 100%; padding: 0 var(--sp-4); min-height: 64px; }
}

/* Was auf dem Bildschirm Orientierung gibt, ist auf Papier Ballast. */
@media print {
  /* ⛔ DIE TOKENS MÜSSEN ZURÜCKGESETZT WERDEN. Ohne diesen Block druckt die Seite im
     Dunkel-Theme hellgrauen Text auf weißem Papier — unlesbar, und es fällt erst am
     Drucker auf. Ein Stundenzettel wird unterschrieben; er muss immer gleich aussehen. */
  :root, :root[data-theme="dark"] {
    --canvas: #fff; --sunken: #fff; --table-head: #f0f0f0; --hover: #fff;
    --border: #999; --border-strong: #666; --row-line: #ccc;
    --text: #000; --text-muted: #333; --text-faint: #666;
    --primary: #000; --good: #000; --warn: #000; --bad: #000;
    color-scheme: light;
  }
  @page { size: A4 portrait; margin: 16mm 14mm; }
  .rail, .topbar, .stempel-knoepfe, .aktionsreihe, .knopf, .hinweis { display: none; }
  .app { display: block; }
  .inhalt { padding: 0; }
  .karte { border: none; padding: 0; margin: 0 0 var(--sp-4); }
  .gitter-rolle { overflow: visible; }
  /* Über einen Seitenumbruch hinweg wiederholt sich der Tabellenkopf — sonst steht auf
     Seite zwei eine Zahlenkolonne ohne Beschriftung. */
  .gitter thead { display: table-header-group; }
  .gitter tr { break-inside: avoid; }
  .gitter tr:hover td { background: none; }
  a[href]::after { content: none; }
}

/* Die Zahl an einem Schienen-Eintrag. Rechtsbündig und nur dann farbig, wenn sie
   etwas bedeutet — ein Badge, das immer leuchtet, wird nach einer Woche nicht mehr
   gesehen, und dann leuchtet es auch nicht mehr, wenn es zählt. */
.rail a { display: flex; justify-content: space-between; align-items: baseline; gap: var(--sp-2); }
.rail-zahl {
  font-variant-numeric: tabular-nums; font-size: var(--fs-dense);
  color: var(--rail-section); font-weight: 600;
}

/* Die Rechnung unter einem Antragsformular: was kostet dieser Zeitraum? */
.antrag-rechnung {
  border-top: 1px solid var(--row-line); padding-top: var(--sp-3); margin: var(--sp-4) 0;
  font-size: var(--fs-ui); font-variant-numeric: tabular-nums; color: var(--text-muted);
}
.feinheit > summary {
  cursor: pointer; padding: var(--sp-2) 0;
  font-size: var(--fs-dense); color: var(--text-muted);
}

/* ── TEAM-RADAR ─────────────────────────────────────────────────────────────
   ⛔ FORM STATT FARBE. Die Ampel gehört dem eigenen Tagesstatus und dem
   Urlaubskonto; Anwesenheit ist kein Zustand von gut nach schlecht, und ein
   rotes Zeichen an einem Kollegen liest sich wie ein Vorwurf. Unterschieden
   wird über gefüllt / halb / offen — und die Gruppenüberschrift sagt dasselbe
   noch einmal in Worten, für alle, die die Form nicht unterscheiden. */
.radar-summe { font-size: var(--fs-dense); color: var(--text-muted); margin: 0 0 var(--sp-4); }
.radar-gruppe { margin-bottom: var(--sp-4); }
.radar-gruppe > h3 {
  margin: 0 0 var(--sp-2); font: 600 var(--fs-micro)/1.4 var(--f-ui);
  letter-spacing: .04em; text-transform: uppercase; color: var(--text-muted);
}
.radar-liste { display: flex; flex-wrap: wrap; gap: var(--sp-2); list-style: none; padding: 0; margin: 0; }
.person {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  padding: var(--sp-1) var(--sp-3); min-height: 32px;
  border: 1px solid var(--border); border-radius: var(--r-full);
  font-size: var(--fs-dense);
}
.person small { color: var(--text-muted); }
.person-mal { flex: none; width: 10px; height: 10px; border: 1.5px solid var(--text-muted); }
.person[data-lage="arbeit"] .person-mal { background: var(--text); border-color: var(--text); }
.person[data-lage="abwesend"] { color: var(--text-muted); border-style: dashed; }
.person[data-lage="abwesend"] .person-mal {
  background: linear-gradient(135deg, var(--text-muted) 50%, transparent 50%);
}

/* ── TEAM-KALENDER ──────────────────────────────────────────────────────────
   Zeilen sind Menschen, Spalten sind Tage. Kein 7×5-Raster: ein Balken liegt in
   einer Tabellenzeile und bricht nie um — im Wochenraster müsste jede mehrtägige
   Abwesenheit an jeder Wochengrenze zerlegt werden, und genau das ist ohne
   JavaScript die eigentliche Schwierigkeit. */
.kalender-breit { overflow-x: auto; }
.kalender { border-collapse: collapse; font-size: var(--fs-micro); }
.kalender th, .kalender td { border: 1px solid var(--row-line); padding: 0; }
.kalender thead th { padding: var(--sp-1) 0; width: 22px; text-align: center; background: var(--table-head); }
.kalender-kurz { display: block; color: var(--text-muted); }
.kalender-zahl { display: block; font-variant-numeric: tabular-nums; }
.kalender-name {
  padding: var(--sp-1) var(--sp-3) !important; text-align: left; white-space: nowrap;
  font: 500 var(--fs-dense)/1.4 var(--f-ui); background: var(--canvas); position: sticky; left: 0;
}
.kalender-zelle { height: 26px; }
.kalender .wochenende { background: var(--sunken); }
.kalender .feiertag { background: var(--hover); }
.kalender .heute { outline: 2px solid var(--primary); outline-offset: -2px; }

.balken { display: block; height: 16px; margin: 5px 0; background: var(--selected); border: 1px solid var(--border-strong); }
.balken.rand-start { border-radius: var(--r-full) 0 0 var(--r-full); border-right: none; margin-left: 3px; }
.balken.rand-ende { border-radius: 0 var(--r-full) var(--r-full) 0; border-left: none; margin-right: 3px; }
.balken.rand-mitte { border-radius: 0; border-left: none; border-right: none; }
.balken.rand-einzeln { border-radius: var(--r-full); margin: 5px 3px; }
/* Beantragt wird schraffiert, nicht eingefärbt — Farbe ist Bedeutung, und „noch nicht
   entschieden" ist keine Ampelstufe. */
.balken.beantragt {
  background: repeating-linear-gradient(45deg,
    var(--selected) 0 4px, var(--canvas) 4px 8px);
  border-style: dashed;
}

.kalender-schmal { display: none; }
.kalender-person { padding: var(--sp-3) 0; border-bottom: 1px solid var(--row-line); }
.kalender-person ul { margin: var(--sp-2) 0 0; padding-left: var(--sp-5); font-size: var(--fs-ui); }
.kalender-person li.beantragt { color: var(--text-muted); font-style: italic; }

@media (max-width: 780px) {
  /* Ein Raster mit 31 Spalten ist auf 360 px unlesbar. Umgeschaltet wird über CSS
     und nicht über JavaScript: beide Ansichten stehen im selben DOM, damit es keine
     zweite Wahrheit gibt. */
  .kalender-breit { display: none; }
  .kalender-schmal { display: block; }
}

/* ── ÄNDERUNGSPROTOKOLL ─────────────────────────────────────────────────────
   Ein Eintrag je Änderung, nicht eine Tabellenzeile: Vorher und Nachher stehen
   nebeneinander, und der Grund gehört sichtbar dazu — ohne ihn ist ein
   Protokolleintrag im Streitfall nur die Feststellung, DASS etwas geschah. */
.protokoll-eintrag { padding: var(--sp-4) 0; border-bottom: 1px solid var(--row-line); }
.protokoll-eintrag:last-child { border-bottom: none; }
.protokoll-kopf { display: flex; flex-wrap: wrap; gap: var(--sp-2); align-items: baseline; font-size: var(--fs-ui); }
.protokoll-wann { margin-left: auto; color: var(--text-muted); font-size: var(--fs-dense); }
.protokoll-grund {
  margin: var(--sp-2) 0; padding-left: var(--sp-3);
  border-left: 3px solid var(--border-strong);
  color: var(--text-muted); font-size: var(--fs-ui);
}
.protokoll-diff { margin-top: var(--sp-2); font-size: var(--fs-dense); }
/* Farbe ist auch hier Bedeutung: der alte Wert ist durchgestrichen, weil er nicht
   mehr gilt — nicht rot, weil er falsch gewesen wäre. */
.protokoll-vorher { color: var(--text-muted); text-decoration: line-through; }
.protokoll-nachher { font-weight: 500; }

/* ── NACHWEISE (ATTESTE) ────────────────────────────────────────────────────
   Die Löschfrist steht neben dem Link und nicht in einer Fußnote: sie ist der
   Grund, warum der Nachweis überhaupt befristet hier liegt. */
.nachweis-zeile {
  display: flex; flex-wrap: wrap; gap: var(--sp-2); align-items: center;
  padding: var(--sp-1) 0; font-size: var(--fs-dense);
}
.nachweis-frist { color: var(--text-muted); }
