/*
 * Gestaltung des AStA-Verleihsystems.
 *
 * Aufbau: erst die Design-Tokens (Farben, Abstände, Radien) als
 * CSS-Variablen, dann Grundlagen, Layout und zuletzt die Komponenten.
 * Der Dunkelmodus tauscht nur die Tokens aus – kein zweiter Regelsatz.
 *
 * Bewusst ohne Frameworks, Build-Schritt und externe Ressourcen: Das passt
 * zum selbst gehosteten Betrieb und funktioniert auch offline.
 */

/* ---------------------------------------------------------------- Tokens */

:root {
  color-scheme: light dark;

  /* Flächen und Text */
  --bg: #f4f6f8;
  --surface: #ffffff;
  --surface-sunken: #f8fafb;
  --text: #14181d;
  --text-muted: #5c6673;
  --border: #e2e7ec;
  --border-strong: #cbd3dc;

  /* Marke: ein ruhiges Petrol – institutionell, aber nicht steril */
  --brand: #0d6f6b;
  --brand-hover: #0a5b58;
  --brand-contrast: #ffffff;
  --brand-tint: #e6f2f1;
  --brand-ring: rgba(13, 111, 107, 0.28);

  /* Semantik für Status und Rückmeldungen */
  --ok: #12704a;
  --ok-tint: #e6f4ed;
  --warn: #8a5206;
  --warn-tint: #fdf2e0;
  --danger: #b02b23;
  --danger-tint: #fdebe9;
  --info: #1a5cb0;
  --info-tint: #e9f0fc;

  /* Form */
  --radius-sm: 6px;
  --radius: 10px;
  --radius-lg: 14px;
  --radius-pill: 999px;

  --shadow-sm: 0 1px 2px rgba(16, 24, 40, 0.05);
  --shadow: 0 1px 3px rgba(16, 24, 40, 0.08), 0 1px 2px rgba(16, 24, 40, 0.04);
  --shadow-lg: 0 8px 24px rgba(16, 24, 40, 0.09);

  --container: 74rem;
  --container-narrow: 42rem;

  --font: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue",
    Arial, sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas,
    monospace;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #111418;
    --surface: #181c22;
    --surface-sunken: #1e232a;
    --text: #e7ebf0;
    --text-muted: #9aa5b1;
    --border: #2a3038;
    --border-strong: #3a424c;

    --brand: #3fbdb4;
    --brand-hover: #5cd0c7;
    --brand-contrast: #06231f;
    --brand-tint: rgba(63, 189, 180, 0.14);
    --brand-ring: rgba(63, 189, 180, 0.32);

    --ok: #57c795;
    --ok-tint: rgba(87, 199, 149, 0.14);
    --warn: #e0a95c;
    --warn-tint: rgba(224, 169, 92, 0.14);
    --danger: #f0837a;
    --danger-tint: rgba(240, 131, 122, 0.14);
    --info: #79aaf0;
    --info-tint: rgba(121, 170, 240, 0.14);

    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
    --shadow: 0 1px 3px rgba(0, 0, 0, 0.45);
    --shadow-lg: 0 10px 30px rgba(0, 0, 0, 0.5);
  }
}

/* ------------------------------------------------------------ Grundlagen */

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

html {
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  font-family: var(--font);
  font-size: 1rem;
  line-height: 1.55;
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
}

h1,
h2,
h3 {
  margin: 0 0 0.5rem;
  line-height: 1.25;
  letter-spacing: -0.015em;
  font-weight: 700;
}

h1 {
  font-size: 1.6rem;
}

h2 {
  font-size: 1.2rem;
  margin-top: 2rem;
}

h3 {
  font-size: 1rem;
}

p {
  margin: 0 0 1rem;
}

a {
  color: var(--brand);
  text-decoration-color: color-mix(in srgb, var(--brand) 35%, transparent);
  text-underline-offset: 2px;
}

a:hover {
  text-decoration-color: currentColor;
}

code {
  font-family: var(--font-mono);
  font-size: 0.875em;
  background: var(--surface-sunken);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 0.1em 0.35em;
}

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

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

.site-header {
  position: sticky;
  top: 0;
  z-index: 20;
  background: color-mix(in srgb, var(--surface) 88%, transparent);
  backdrop-filter: saturate(180%) blur(12px);
  border-bottom: 1px solid var(--border);
}

.site-header__inner {
  max-width: var(--container);
  margin: 0 auto;
  padding: 0.65rem 1.25rem;
  display: flex;
  align-items: center;
  gap: 1.25rem;
  flex-wrap: wrap;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--text);
  text-decoration: none;
  white-space: nowrap;
}

.brand__mark {
  display: grid;
  place-items: center;
  width: 2rem;
  height: 2rem;
  border-radius: var(--radius-sm);
  background: var(--brand);
  color: var(--brand-contrast);
  flex: none;
}

.brand__mark svg {
  width: 1.15rem;
  height: 1.15rem;
}

.brand__text small {
  display: block;
  font-size: 0.7rem;
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
  line-height: 1;
}

.nav {
  display: flex;
  align-items: center;
  gap: 0.25rem;
  flex-wrap: wrap;
}

.nav a {
  padding: 0.4rem 0.7rem;
  border-radius: var(--radius-sm);
  color: var(--text-muted);
  text-decoration: none;
  font-size: 0.925rem;
  font-weight: 500;
  white-space: nowrap;
}

.nav a:hover {
  background: var(--surface-sunken);
  color: var(--text);
}

.nav a[aria-current="page"] {
  background: var(--brand-tint);
  color: var(--brand);
}

.site-header__spacer {
  flex: 1 1 auto;
}

.user-menu > * {
  display: inline-block;
  vertical-align: middle;
  margin-left: 0.6rem;
}

/* Der eigene Name führt zu „Mein Konto“. Er bleibt gedämpft wie zuvor – in
   Markenfarbe zöge er den Blick auf sich, obwohl er nur ein Nebenweg ist. Die
   Unterstreichung erscheint erst beim Darüberfahren, damit er trotzdem als
   anklickbar zu erkennen ist. */
.user-menu__name {
  font-size: 0.875rem;
  color: var(--text-muted);
  max-width: 16rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  text-decoration: none;
}

a.user-menu__name:hover {
  color: var(--text);
  text-decoration: underline;
}

.user-menu form {
  margin: 0;
}

.main {
  flex: 1 0 auto;
  width: 100%;
  max-width: var(--container);
  margin: 0 auto;
  padding: 2rem 1.25rem 3.5rem;
}

.main--narrow {
  max-width: var(--container-narrow);
}

.site-footer {
  border-top: 1px solid var(--border);
  background: var(--surface);
}

.site-footer__inner {
  max-width: var(--container);
  margin: 0 auto;
  padding: 1.25rem;
  font-size: 0.8125rem;
  color: var(--text-muted);
  display: flex;
  gap: 1rem;
  flex-wrap: wrap;
  justify-content: space-between;
}

/* Kopfzeile einer Seite: Titel links, Aktionen rechts. */
.page-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  margin-bottom: 1.5rem;
}

/* Der Titelblock darf nicht unter seine Inhaltsbreite schrumpfen – sonst
   bricht schon „Antrag #16" um, nur weil rechts Aktionen stehen. */
.page-head > :first-child {
  flex: 1 1 22rem;
  min-width: 0;
}

.page-head h1 {
  margin-bottom: 0.25rem;
}

.page-head__lead {
  margin: 0;
  color: var(--text-muted);
  max-width: 52ch;
}

.page-head__actions {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.stack > * + * {
  margin-top: 1.25rem;
}

/* ------------------------------------------------------------- Buttons */

.btn,
button,
input[type="submit"] {
  /* inline-block statt inline-flex: Ein Button soll sich nie über die volle
     Breite seiner Zelle ziehen, auch nicht in Tabellen. */
  display: inline-block;
  width: auto;
  text-align: center;
  padding: 0.5rem 0.95rem;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text);
  font: inherit;
  font-size: 0.925rem;
  font-weight: 600;
  line-height: 1.4;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 0.12s ease, border-color 0.12s ease,
    transform 0.06s ease;
}

.btn:hover,
button:hover,
input[type="submit"]:hover {
  background: var(--surface-sunken);
  border-color: var(--text-muted);
}

.btn:active,
button:active {
  transform: translateY(1px);
}

.btn--primary,
button.btn--primary {
  background: var(--brand);
  border-color: var(--brand);
  color: var(--brand-contrast);
}

.btn--primary:hover,
button.btn--primary:hover {
  background: var(--brand-hover);
  border-color: var(--brand-hover);
}

.btn--danger,
button.btn--danger {
  background: var(--danger);
  border-color: var(--danger);
  color: #fff;
}

.btn--danger:hover,
button.btn--danger:hover {
  filter: brightness(1.08);
}

.btn--ghost,
button.btn--ghost {
  background: transparent;
  border-color: transparent;
  color: var(--brand);
}

.btn--ghost:hover,
button.btn--ghost:hover {
  background: var(--brand-tint);
  border-color: transparent;
}

.btn--sm,
button.btn--sm {
  padding: 0.3rem 0.6rem;
  font-size: 0.825rem;
}

.btn--icon,
button.btn--icon {
  padding: 0.35rem 0.55rem;
  color: var(--text-muted);
  border-color: transparent;
  background: transparent;
}

.btn--icon:hover,
button.btn--icon:hover {
  color: var(--danger);
  background: var(--danger-tint);
  border-color: transparent;
}

/* Bewusst kein Flex-Container: Buttons und die kleinen Formulare darin sind
   ohnehin inline-block, und so bleibt die Reihe überall gleich – auch dort,
   wo Flexbox mit Formularelementen zickt. */
.btn-row > * {
  display: inline-block;
  vertical-align: middle;
  margin: 0 0.6rem 0.6rem 0;
}

.btn-row {
  margin-bottom: -0.6rem;
}

/* Sortierbare Spaltenüberschrift. Sie sieht aus wie die anderen Überschriften
   und nicht wie ein Link – auffällig wäre sie hier Lärm, acht davon
   nebeneinander. Das Zeichen dahinter zeigt, dass es etwas zu klicken gibt,
   und in welche Richtung gerade sortiert ist. */
th .sortable {
  color: inherit;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
}

th .sortable:hover {
  color: var(--brand);
}

.sortable__mark {
  font-size: 0.7em;
  opacity: 0.55;
}

th[aria-sort] .sortable__mark {
  opacity: 1;
  color: var(--brand);
}

/* Aktionsspalte einer Liste: Die Knöpfe gehören nebeneinander. Umgebrochen
   machen sie ihre Zeile doppelt so hoch wie alle anderen, und die Liste
   franst aus. Breiter werden darf die Tabelle dafür – sie steht ohnehin in
   einem Bereich, der waagerecht scrollt. */
.row-actions {
  white-space: nowrap;
}

/* -------------------------------------------------------------- Flächen */

.card {
  /* Wichtig: Karten sind auch als <a> im Einsatz – ohne display:block bliebe
     der Link inline und das Kastenlayout bräche auseinander. */
  display: block;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  padding: 1.25rem 1.35rem;
}

a.card {
  color: inherit;
  text-decoration: none;
  transition: border-color 0.12s ease, box-shadow 0.12s ease;
}

a.card h3 {
  color: var(--brand);
}

a.card:hover {
  border-color: var(--brand);
  box-shadow: var(--shadow);
}

.card > :first-child {
  margin-top: 0;
}

.card > :last-child {
  margin-bottom: 0;
}

.card--accent {
  border-left: 3px solid var(--brand);
}

/* Bewusst Flexbox statt Grid: gleiches Ergebnis, aber überall verlässlich –
   auch dort, wo CSS Grid nur teilweise unterstützt wird. */
.card-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
}

.card-grid > * {
  flex: 1 1 18rem;
  min-width: 0;
}

/* Kennzahl-Kachel, z. B. „3 überfällig". */
.stat {
  display: block;
  padding: 1rem 1.15rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  text-decoration: none;
  color: inherit;
}

.stat:hover {
  border-color: var(--border-strong);
}

.stat__value {
  display: block;
  font-size: 1.75rem;
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: -0.02em;
}

.stat__label {
  display: block;
  font-size: 0.825rem;
  color: var(--text-muted);
}

/* Kennzahlenreihe: schmaler als .card-grid, damit vier Zahlen nebeneinander
   passen und nicht die letzte allein über die volle Breite steht. */
.stat-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
}

.stat-grid > * {
  flex: 1 1 11rem;
  min-width: 0;
}

.stat--danger .stat__value {
  color: var(--danger);
}

.stat--ok .stat__value {
  color: var(--ok);
}

/* Eigene Zuständigkeiten: hervorgehoben, aber nicht als Alarm – „drei Vorgänge
   liegen bei dir" ist kein Problem, sondern eine Zuständigkeit. */
.stat--accent .stat__value {
  color: var(--brand);
}

/* Fassungen des Verleihvertrags: Nummer, Datum, Kennzeichnung. */
.versions {
  list-style: none;
  margin: 0.5rem 0 0.75rem;
  padding: 0;
}

.versions li {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0.5rem;
  padding: 0.35rem 0;
  border-bottom: 1px solid var(--border);
}

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

/* Fließtext aus einer Markdown-Datei (content/). Die Regeln greifen bewusst
   über den Nachfahren-Selektor: Was in der Datei steht, entscheidet der
   Redakteur, und der soll keine CSS-Klassen setzen müssen. */
.prose {
  max-width: 60ch;
}

.prose h1 {
  margin-top: 0;
}

.prose h2 {
  margin-top: 2rem;
}

.prose li + li {
  margin-top: 0.35rem;
}

.prose ol,
.prose ul {
  padding-left: 1.25rem;
}

/* Aufklapper für die überholten Fassungen. Sie sind Beleg, nicht Alltag –
   offen verdeckte eine lange Liste das, was fast immer gesucht wird. Der
   Zusammenklapp-Pfeil des Browsers bleibt, nur die Beschriftung bekommt die
   Anmutung der übrigen Bedienelemente. */
.fold > summary {
  cursor: pointer;
  color: var(--muted);
  font-size: 0.9rem;
  padding: 0.35rem 0;
}

.fold > summary:hover {
  color: var(--text);
}

/* Der Rahmen bündelt das Aufgeklappte sichtbar unter seiner Beschriftung –
   sonst schwimmen die alten Fassungen zwischen den Abschnitten daneben. */
.fold[open] > summary {
  color: var(--text);
  margin-bottom: 0.25rem;
}

.fold[open] {
  border-left: 2px solid var(--border);
  padding-left: 0.75rem;
}

/* Bestenliste der Statistik: Platz, Name, Anzahl. */
.ranking {
  margin: 0.5rem 0 0;
  padding-left: 1.5rem;
}

.ranking li {
  margin-bottom: 0.35rem;
}

/* Balkenverlauf – bewusst aus reinem CSS statt aus einer Diagrammbibliothek:
   Zwölf Zahlen brauchen kein JavaScript, und die Seite bleibt ohne es lesbar. */
.bars {
  list-style: none;
  margin: 0.5rem 0 0;
  padding: 0;
}

.bars li {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin-bottom: 0.35rem;
}

.bars__label {
  flex: 0 0 4.5rem;
  font-variant-numeric: tabular-nums;
  color: var(--text-muted);
  font-size: 0.875rem;
}

.bars__track {
  flex: 1 1 auto;
  height: 0.75rem;
  border-radius: var(--radius-sm);
  background: var(--surface-sunken);
  border: 1px solid var(--border);
  overflow: hidden;
}

.bars__fill {
  display: block;
  height: 100%;
  background: var(--brand);
  /* Auch ein einzelner Vorgang soll sichtbar sein, nicht nur ein Haarstrich. */
  min-width: 2px;
}

.bars__value {
  flex: 0 0 2.5rem;
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* Abschnittsüberschrift der Vorgangsliste: Titel, Anzahl und die Erklärung,
   warum dieser Abschnitt an dieser Stelle steht – alles auf einer Zeile. */
.section-head {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-top: 2rem;
}

.section-head .hint {
  font-weight: 400;
}

.section-head--overdue {
  color: var(--danger);
}

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

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

table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.9375rem;
}

thead th {
  position: sticky;
  top: 0;
  text-align: left;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-muted);
  background: var(--surface-sunken);
  border-bottom: 1px solid var(--border);
  padding: 0.6rem 0.9rem;
  white-space: nowrap;
}

tbody td {
  padding: 0.7rem 0.9rem;
  border-bottom: 1px solid var(--border);
  vertical-align: top;
}

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

tbody tr:hover td {
  background: color-mix(in srgb, var(--brand-tint) 45%, transparent);
}

/* Kautionsspalte im Erfassungsformular: Die Zahlen sollen untereinander
   stehen, nicht mit den Auswahllisten daneben umbrechen. */
.deposit-cell {
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

/* Zeitstempelspalte im Protokoll: Ein Datum, das nach dem Punkt umbricht, ist
   in einer chronologischen Liste kaum noch zu überfliegen. Gleiche
   Ziffernbreite, damit die Uhrzeiten untereinander stehen. */
.log-time {
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

/* Summenzeile: Ohne eigene Linie verschmilzt sie mit der letzten Position und
   liest sich wie ein weiterer Posten. */
tfoot td {
  padding: 0.7rem 0.9rem;
  border-top: 2px solid var(--border-strong);
  vertical-align: top;
}

td .muted,
.muted {
  color: var(--text-muted);
}

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

/* ------------------------------------------------------------- Kalender */

/* Bewusst eine <table>: Ein Monat ist tabellarisch (Wochen mal Wochentage).
   Das trägt die Bedeutung mit, liest sich mit Screenreader vernünftig und
   braucht kein eigenes Rasterlayout. Die Regeln für Listentabellen weiter
   oben passen hier allerdings nicht – deshalb werden sie zurückgenommen. */
.cal-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 1.25rem 1.75rem;
}

/* Ein Monat: außen das Flex-Element, innen die Tabelle. Beides in einem zu
   erledigen ginge schief – eine Tabelle mit width:100% als Flex-Element zieht
   sich über die ganze Zeile, und die Monate stapeln sich untereinander. */
.cal {
  flex: 1 1 15rem;
  max-width: 21rem;
}

.cal table {
  width: 100%;
  /* Feste Spaltenbreiten: Sonst richtet sich jede Spalte nach ihrem breitesten
     Datum und das Raster verzieht sich. */
  table-layout: fixed;
  /* Getrennte Rahmen: Bei collapse verschluckt der durchgehende Rahmen den
     farbigen Rand der heutigen Zelle. */
  border-collapse: separate;
  border-spacing: 1px;
  font-size: 0.875rem;
}

.cal caption {
  padding-bottom: 0.5rem;
  font-weight: 600;
  text-align: left;
}

.cal thead th {
  position: static; /* nur lange Listen brauchen eine klebende Kopfzeile */
  padding: 0.2rem 0;
  text-align: center;
  background: none;
  border: none;
  font-size: 0.6875rem;
}

.cal tbody td {
  padding: 0.3rem 0.15rem;
  text-align: center;
  vertical-align: middle;
  border: 1px solid transparent; /* Rahmen wird erst bei „heute“ sichtbar */
  border-radius: var(--radius-sm);
  font-variant-numeric: tabular-nums;
}

/* Der Zeilen-Hover der Listentabellen würde eine ganze Woche einfärben. */
.cal tbody tr:hover td {
  background: none;
}

.cal__day--outside {
  color: var(--text-muted);
  opacity: 0.4;
}

.cal__day--past {
  opacity: 0.55;
}

/* Reihenfolge = Rangfolge: Ist ein Tag beides, gewinnt die Belegung. */
.cal__day--sperrzeit {
  /* Zwei Ebenen mit Absicht: Die Fläche trägt die Information überall, die
     Schraffur darüber macht sie zusätzlich ohne Farbwahrnehmung erkennbar.
     Fällt der Verlauf beim Rendern durch – ältere Engines und WeasyPrint tun
     das –, bleibt der Farbton stehen und nichts geht verloren. */
  background-color: var(--info-tint);
  background-image: repeating-linear-gradient(
    -45deg,
    transparent 0,
    transparent 3px,
    var(--border-strong) 3px,
    var(--border-strong) 5px
  );
  color: var(--info);
}

.cal__day--teilweise {
  background: var(--warn-tint);
  color: var(--warn);
  font-weight: 600;
}

.cal__day--belegt {
  background: var(--danger-tint);
  color: var(--danger);
  font-weight: 600;
}

.cal tbody td.cal__day--today {
  border-color: var(--brand);
  font-weight: 700;
}

/* Restbestand eines Mengenartikels an belegten Tagen. */
.cal__free {
  display: block;
  font-size: 0.625rem;
  font-weight: 400;
  line-height: 1;
}

.cal-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem 1.25rem;
  margin-top: 1rem;
  font-size: 0.8125rem;
  color: var(--text-muted);
}

.cal-legend__swatch {
  display: inline-block;
  width: 0.85em;
  height: 0.85em;
  margin-right: 0.15em;
  border: 1px solid transparent;
  border-radius: 3px;
  vertical-align: -0.1em;
}

/* Die beiden Zustände zeigen sich im Kalender über den Rahmen der Zelle –
   den muss die Legende eigens setzen, sie ist keine Tabellenzelle. */
.cal-legend__swatch.cal__day--sperrzeit {
  border-color: var(--border-strong);
}

.cal-legend__swatch.cal__day--today {
  border-color: var(--brand);
}

/* --------------------------------------------------------------- Badges */

.badge {
  display: inline-block;
  padding: 0.15em 0.6em;
  border-radius: var(--radius-pill);
  font-size: 0.8125rem;
  font-weight: 600;
  line-height: 1.5;
  white-space: nowrap;
  background: var(--surface-sunken);
  color: var(--text-muted);
  border: 1px solid transparent;
}

.badge::before {
  content: "";
  display: inline-block;
  width: 0.45em;
  height: 0.45em;
  margin-right: 0.4em;
  border-radius: 50%;
  background: currentColor;
  vertical-align: 0.08em;
}

.badge--plain::before {
  display: none;
}

/* Buchungsstatus – die Klassen entsprechen den Statuswerten im Modell. */
.badge--unbestaetigt {
  background: var(--surface-sunken);
  color: var(--text-muted);
}

.badge--angefragt {
  background: var(--info-tint);
  color: var(--info);
}

.badge--bestaetigt {
  background: var(--ok-tint);
  color: var(--ok);
}

.badge--ausgeliehen {
  background: var(--brand-tint);
  color: var(--brand);
}

.badge--zurueckgegeben {
  background: var(--surface-sunken);
  color: var(--text-muted);
}

.badge--abgelehnt,
.badge--storniert {
  background: var(--surface-sunken);
  color: var(--text-muted);
}

.badge--overdue,
.badge--danger {
  background: var(--danger-tint);
  color: var(--danger);
}

.badge--ok {
  background: var(--ok-tint);
  color: var(--ok);
}

.badge--warn {
  background: var(--warn-tint);
  color: var(--warn);
}

/* Zustand eines Gegenstands – ebenfalls die Werte aus dem Modell. */
.badge--verfuegbar {
  background: var(--ok-tint);
  color: var(--ok);
}

.badge--reparatur {
  background: var(--warn-tint);
  color: var(--warn);
}

.badge--defekt,
.badge--verloren {
  background: var(--danger-tint);
  color: var(--danger);
}

/* --------------------------------------------------------------- Chips */

.chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  align-items: center;
  margin: 0 0 1rem;
  padding: 0;
  list-style: none;
}

.chip {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.25rem 0.7rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  background: var(--surface);
  color: var(--text-muted);
  font-size: 0.875rem;
  text-decoration: none;
}

.chip:hover {
  border-color: var(--border-strong);
  color: var(--text);
}

.chip[aria-current="true"] {
  background: var(--brand);
  border-color: var(--brand);
  color: var(--brand-contrast);
}

.chip__count {
  font-size: 0.8em;
  opacity: 0.75;
}

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

/* Nicht auf die Standardregeln des Browsers verlassen: CSRF-Token und die
   Verwaltungsfelder von Formsets dürfen nirgends sichtbar werden. */
input[type="hidden"] {
  display: none;
}

label {
  display: block;
  font-size: 0.875rem;
  font-weight: 600;
  margin-bottom: 0.25rem;
}

input[type="text"],
input[type="email"],
input[type="password"],
input[type="tel"],
input[type="url"],
input[type="number"],
input[type="search"],
input[type="date"],
input[type="datetime-local"],
input[type="file"],
select,
textarea {
  width: 100%;
  max-width: 26rem;
  padding: 0.45rem 0.65rem;
  font: inherit;
  font-size: 0.9375rem;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  transition: border-color 0.12s ease, box-shadow 0.12s ease;
}

textarea {
  max-width: 40rem;
  resize: vertical;
}

input:focus,
select:focus,
textarea:focus {
  outline: none;
  border-color: var(--brand);
  box-shadow: 0 0 0 3px var(--brand-ring);
}

input[type="checkbox"],
input[type="radio"] {
  width: auto;
  accent-color: var(--brand);
}

form p {
  margin: 0 0 1rem;
}

.helptext {
  display: block;
  margin-top: 0.25rem;
  font-size: 0.8125rem;
  color: var(--text-muted);
}

.errorlist {
  list-style: none;
  margin: 0 0 0.4rem;
  padding: 0.4rem 0.7rem;
  border-radius: var(--radius-sm);
  background: var(--danger-tint);
  color: var(--danger);
  font-size: 0.875rem;
}

/* Einzelfeld eines Pflege-Formulars (die Filterleiste unten hat eigene Regeln). */
.form-field + .form-field {
  margin-top: 1rem;
}

/* Nicht auf die Standardregeln des Browsers verlassen: Das Pflege-Formular
   blendet die Felder aus, die zum gewählten Typ nicht gehören. */
[hidden] {
  display: none !important;
}

/* Mehrfachauswahl, etwa die Kategorien: Die Beschriftungen im Widget gehören
   zu den einzelnen Optionen – sie dürfen nicht wie eine Feldbeschriftung
   aussehen und stehen neben statt über ihrer Checkbox. */
.form-field--checkboxselectmultiple > div label {
  display: flex;
  gap: 0.45rem;
  align-items: center;
  margin: 0 0 0.2rem;
  font-weight: 400;
}

/* Filterleiste über Listen. */
.filters {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  align-items: flex-end;
  margin-bottom: 1.25rem;
  padding: 0.9rem 1rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
}

.filters .field {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
}

.filters .field--grow {
  flex: 1 1 12rem;
}

.filters input,
.filters select {
  max-width: none;
}

.filters label {
  margin: 0;
  font-size: 0.75rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-muted);
}

/* Ein Ankreuzfeld in der Filterleiste trägt keinen Feldnamen, sondern einen
   Satz. In Versalien sähe er aus wie eine Überschrift über einem leeren Feld. */
.filters .field--check label {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.875rem;
  letter-spacing: 0;
  text-transform: none;
  color: var(--text);
}

/* ------------------------------------------------------- Meldungen, Hinweise */

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

.messages li + li {
  margin-top: 0.6rem;
}

.messages li {
  padding: 0.75rem 1rem;
  border-radius: var(--radius);
  border: 1px solid transparent;
  border-left-width: 3px;
  font-size: 0.9375rem;
  background: var(--surface-sunken);
  color: var(--text);
}

.messages li.success {
  background: var(--ok-tint);
  border-left-color: var(--ok);
}

.messages li.info,
.messages li.debug {
  background: var(--info-tint);
  border-left-color: var(--info);
}

.messages li.warning {
  background: var(--warn-tint);
  border-left-color: var(--warn);
}

.messages li.error {
  background: var(--danger-tint);
  border-left-color: var(--danger);
}

.hint {
  color: var(--text-muted);
  font-size: 0.875rem;
}

.notice {
  padding: 0.85rem 1.1rem;
  border-radius: var(--radius);
  border: 1px solid var(--border);
  border-left: 3px solid var(--info);
  background: var(--info-tint);
  font-size: 0.9375rem;
}

.notice--warn {
  border-left-color: var(--warn);
  background: var(--warn-tint);
}

.notice--danger {
  border-left-color: var(--danger);
  background: var(--danger-tint);
}

.notice--ok {
  border-left-color: var(--ok);
  background: var(--ok-tint);
}

/* Konkurrierende Anträge auf der Entscheidungsseite: außen der umkämpfte
   Gegenstand, darunter eingerückt die anderen Anträge. Ohne Aufzählungszeichen –
   die Verschachtelung trägt die Gliederung schon. */
.contested {
  margin: 0.6rem 0 0;
  padding-left: 0;
  list-style: none;
}

.contested > li + li {
  margin-top: 0.6rem;
}

.contested ul {
  margin: 0.25rem 0 0;
  padding-left: 1.1rem;
  list-style: none;
  font-size: 0.9375rem;
}

.contested ul li::before {
  content: "↳";
  margin-right: 0.4rem;
  color: var(--text-muted);
}

.devbox {
  padding: 0.9rem 1.1rem;
  margin-top: 2rem;
  border: 1px dashed var(--warn);
  border-radius: var(--radius);
  background: var(--warn-tint);
  font-size: 0.9375rem;
}

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

.empty {
  padding: 2.5rem 1.5rem;
  text-align: center;
  color: var(--text-muted);
  background: var(--surface);
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius-lg);
}

/* ------------------------------------------------------- Beschreibungslisten */

.details {
  display: grid;
  grid-template-columns: minmax(9rem, max-content) 1fr;
  gap: 0.5rem 1.5rem;
  margin: 0;
}

.details dt {
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--text-muted);
}

.details dd {
  margin: 0;
}

@media (max-width: 32rem) {
  .details {
    grid-template-columns: 1fr;
    gap: 0.1rem 0;
  }

  .details dd {
    margin-bottom: 0.75rem;
  }
}

/* ------------------------------------------------------------ Paginierung */

.pagination {
  display: flex;
  gap: 0.75rem;
  align-items: center;
  justify-content: center;
  margin-top: 1.25rem;
  font-size: 0.9375rem;
  color: var(--text-muted);
}

/* ------------------------------------------------------------------ Sonstiges */

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

.timeline li + li {
  margin-top: 0.75rem;
}

.timeline li {
  position: relative;
  padding-left: 1.5rem;
  font-size: 0.9375rem;
}

.timeline li::before {
  content: "";
  position: absolute;
  left: 0.3rem;
  top: 0.55em;
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background: var(--brand);
}

.timeline time {
  display: block;
  font-size: 0.8125rem;
  color: var(--text-muted);
}

@media print {
  .site-header,
  .site-footer,
  .btn-row,
  .filters {
    display: none;
  }

  body {
    background: #fff;
  }
}
