/* ===========================================================================
   Krisennetz - gemeinsames Designsystem
   ===========================================================================

   Warum diese Datei existiert
   ---------------------------
   Das Aussehen des Portals steckte bisher an drei Stellen: ein <style>-Block
   in base.html (Kopfleiste), ein deutlich größerer in base_fleet.html (alle
   Verwaltungsansichten) und ein weiterer in simulation_list.html. Dieselbe
   Tabelle sah dadurch je nach Seite unterschiedlich aus, und jede Änderung
   musste mehrfach gepflegt werden.

   Hier stehen jetzt die Grundwerte (Farben, Abstände, Radien, Typografie) und
   alle wiederverwendbaren Bausteine an genau einer Stelle.

   Bewusste Entscheidungen
   -----------------------
   * Kein Build-Schritt, kein Framework, keine externen Schriften oder CDNs.
     Der Core-Server läuft in Umgebungen ohne Internetzugang; alles muss aus
     dem eigenen Static-Verzeichnis kommen. Das entspricht dem Bestand.
   * SÄMTLICHE bisherigen Klassennamen bleiben gültig (.fl, .badge, .card,
     .btn, .note, .msg, .fl-form, .keybox, .muted, .small, .nowrap …). Die
     Vorlagen mussten dafür nicht umgeschrieben werden - sie sehen nur besser
     aus. Neue Klassen kommen additiv dazu.
   * Farben über CSS-Variablen. Wer die Hausfarbe einer Kommune abbilden will,
     ändert genau eine Zeile.

   Gestaltungsprinzipien dieser Fassung
   ------------------------------------
   * Eine Akzentachse Blau→Türkis, sparsam eingesetzt (Kopfleiste, aktive
     Zustände, Abschnittslinien). Sie gibt dem Portal eine erkennbare
     Handschrift, ohne die Verwaltungsinhalte zu übertönen.
   * Flächen statt Rahmen: Karten und Tabellen heben sich über sehr flache,
     mehrstufige Schatten und Hairline-Ränder ab.
   * Zahlen immer in Tabellenziffern (font-variant-numeric), Beschriftungen
     als ruhige Kapitälchen - die Hierarchie entsteht über Größe und Farbe,
     nicht über Dekoration.

   Aufbau
   ------
     1. Grundwerte (Design-Tokens)
     2. Basis: Seite, Typografie, Fokus
     3. Kopfbereich und Navigation
     4. Seitenlayout und Überschriften
     5. Kennzahlenkarten
     6. Tabellen
     7. Statusabzeichen (Badges)
     8. Schaltflächen
     9. Hinweise und Meldungen
    10. Formulare, Such- und Filterbereiche
    11. Sonstiges (Schlüsselbox, Hilfsklassen)
    12. Responsive Darstellung
   =========================================================================== */

/* ── 1. Grundwerte ────────────────────────────────────────────────────────── */
:root {
  /* Neutrale Flächen - hell, aber nicht reinweiß: Tabellen und Karten heben
     sich dadurch ab, ohne dass Rahmen laut werden müssen. */
  --k-bg:            #f3f5fa;
  --k-surface:       #ffffff;
  --k-surface-muted: #f8fafc;
  --k-surface-sunk:  #f1f4f9;

  --k-border:        #e4e9f1;
  --k-border-strong: #cbd5e1;

  --k-text:          #0f172a;
  --k-text-soft:     #334155;
  --k-text-muted:    #64748b;

  /* Ein einziger Akzent, kräftig genug für Aktionen, zurückhaltend genug für
     eine Verwaltungsoberfläche. Die zweite Akzentfarbe (Türkis) taucht nur in
     der Verlaufsachse auf - nie als Fläche. */
  --k-primary:       #2563eb;
  --k-primary-dark:  #1d4ed8;
  --k-primary-darker:#1e40af;
  --k-primary-soft:  #eef4ff;
  --k-primary-line:  #c7dbfc;
  --k-accent-2:      #0ea5b7;

  /* Die Markenachse: ein Verlauf von Aktionsblau nach Türkis. */
  --k-brand-axis: linear-gradient(90deg, #2563eb, #06b6d4);

  /* Statusfarben - portalweit dieselben, egal ob Badge, Hinweis oder Meldung. */
  --k-ok:        #15803d;
  --k-ok-soft:   #e7f8ee;
  --k-ok-line:   #a7e8bf;
  --k-warn:      #b45309;
  --k-warn-soft: #fff8e6;
  --k-warn-line: #f5d98a;
  --k-bad:       #b91c1c;
  --k-bad-soft:  #fdf1f1;
  --k-bad-line:  #f3c5c5;
  --k-info:      #1d4ed8;
  --k-info-soft: #e8f0fe;
  --k-info-line: #c7dbfc;

  /* Kopfleiste */
  --k-nav-bg:      #0d1526;
  --k-nav-bg-soft: #1c2941;
  --k-nav-text:    #b6c2d6;
  --k-nav-text-on: #ffffff;

  /* Abstände - eine 4er-Skala, damit Abstände im ganzen Portal gleich sind. */
  --k-1:  4px;
  --k-2:  8px;
  --k-3: 12px;
  --k-4: 16px;
  --k-5: 24px;
  --k-6: 32px;
  --k-7: 48px;

  /* Radien */
  --k-r-sm:   7px;
  --k-r-md:  10px;
  --k-r-lg:  14px;
  --k-r-pill: 999px;

  /* Schatten - sehr flach und mehrstufig. Eine Verwaltungssoftware darf
     nicht schweben; sie darf aber Tiefe andeuten. */
  --k-shadow-sm: 0 1px 2px rgba(15, 23, 42, .05), 0 1px 1px rgba(15, 23, 42, .03);
  --k-shadow-md: 0 2px 4px rgba(15, 23, 42, .05), 0 14px 28px -18px rgba(15, 23, 42, .28);

  /* Fokusring - überall derselbe. */
  --k-ring: 0 0 0 3px rgba(37, 99, 235, .18);

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

  /* Höhe der Kopfleiste. Der Planer rechnet damit seine Kartenhöhe aus
     (calc(100vh - var(--k-topbar-h))) - deshalb steht der Wert hier zentral
     und nicht doppelt in planner.css. */
  --k-topbar-h: 60px;
}

/* ── 2. Basis ─────────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }

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

/* Das hidden-Attribut muss stärker sein als jede display-Regel einer
   Komponente. Ohne diese Zeile blieb z.B. die Gebietsanzeige im Planer
   (#area-chosen, display:flex) sichtbar, obwohl planner.js sie über
   element.hidden = true ausgeblendet hatte - ein leerer Kasten, den niemand
   erklären konnte. */
[hidden] { display: none !important; }

body {
  margin: 0;
  background: var(--k-bg);
  color: var(--k-text);
  font-family: var(--k-font);
  font-size: 14px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

h1, h2, h3, h4 { color: var(--k-text); font-weight: 700; line-height: 1.25; }

a { color: var(--k-primary-dark); }

code, pre, .mono { font-family: var(--k-font-mono); }

::selection { background: #cfe0fc; color: var(--k-text); }

/* Sichtbarer Fokus - für Tastaturbedienung unverzichtbar, für die Maus
   unsichtbar. :focus-visible statt :focus, damit Klicks keinen Rahmen setzen. */
:where(a, button, input, select, textarea, summary, label.k-nav-burger):focus-visible {
  outline: 2px solid var(--k-primary);
  outline-offset: 2px;
  border-radius: var(--k-r-sm);
}

/* Für Screenreader sichtbar, optisch nicht. */
.k-sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ── 3. Kopfbereich und Navigation ────────────────────────────────────────
   Die Klasse .topbar bleibt erhalten (Bestand), bekommt aber eine echte
   Struktur: Produktmarke links, Hauptnavigation daneben, Benutzerbereich
   rechts. Auf schmalen Geräten klappt die Navigation ein - ohne JavaScript,
   über eine versteckte Checkbox, damit die Seite auch ohne Skripte bedienbar
   bleibt. */
.topbar {
  position: sticky;
  top: 0;
  z-index: 900;
  display: flex;
  align-items: center;
  gap: var(--k-2);
  min-height: var(--k-topbar-h);
  padding: 0 var(--k-5);
  background:
    radial-gradient(120% 180% at 0% 0%, rgba(37, 99, 235, .16), transparent 45%),
    linear-gradient(180deg, #121d33 0%, var(--k-nav-bg) 100%);
  color: var(--k-nav-text-on);
  font-weight: 600;
  box-shadow: 0 2px 14px rgba(8, 14, 28, .28);
}

/* Die Markenachse als schmale Lichtkante unter der Leiste - das eine
   wiederkehrende Gestaltungselement des Portals. */
.topbar::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 2px;
  background: linear-gradient(90deg, #2563eb, #06b6d4 42%, rgba(6, 182, 212, 0) 78%);
  opacity: .85;
  pointer-events: none;
}

/* Produktmarke: Wortmarke plus Signet auf einer Akzentkachel. Klickbar zur
   Startseite. */
.k-brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  color: var(--k-nav-text-on);
  text-decoration: none;
  font-size: 16px;
  font-weight: 750;
  letter-spacing: -.01em;
  white-space: nowrap;
}
.k-brand:hover { color: var(--k-nav-text-on); }
.k-brand svg {
  flex: none;
  box-sizing: content-box;
  padding: 5px;
  border-radius: 9px;
  color: #fff;
  background: linear-gradient(135deg, #3b82f6, #1d4ed8 60%, #1e40af);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 2px 6px rgba(8, 14, 28, .45);
}
.k-brand-sub {
  display: none;
  font-size: 10.5px;
  font-weight: 600;
  color: #7d8db0;
  letter-spacing: .14em;
  text-transform: uppercase;
  margin-top: 2px;
}
@media (min-width: 1100px) { .k-brand-sub { display: inline; } }

.k-nav {
  display: flex;
  align-items: center;
  gap: var(--k-1);
  margin-left: var(--k-4);
  min-width: 0;
}

/* Bestandsselektor .topbar a bleibt gültig, damit nichts ungestylt bleibt,
   falls irgendwo noch ein direkter Link in der Leiste steht. */
.topbar a { color: var(--k-nav-text); text-decoration: none; font-weight: 500; }
.topbar a:hover { color: var(--k-nav-text-on); }

.k-nav a {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 7px 12px;
  border-radius: var(--k-r-pill);
  color: var(--k-nav-text);
  font-size: 13.5px;
  font-weight: 550;
  letter-spacing: .002em;
  white-space: nowrap;
  transition: background-color .14s ease, color .14s ease, box-shadow .14s ease;
}
.k-nav a svg { flex: none; opacity: .8; transition: opacity .14s ease; }
.k-nav a:hover { background: rgba(255, 255, 255, .08); color: var(--k-nav-text-on); }
.k-nav a:hover svg { opacity: 1; }

/* Aktiver Menüpunkt: gefüllt statt nur heller. „Wo bin ich?" muss aus zwei
   Metern Abstand erkennbar sein, nicht nur an einem Farbton. Die
   Bestandsklasse .active steuert das weiterhin. */
.k-nav a.active,
.topbar a.active {
  background: linear-gradient(180deg, rgba(59, 130, 246, .32), rgba(37, 99, 235, .22));
  color: var(--k-nav-text-on);
  font-weight: 650;
  box-shadow: inset 0 0 0 1px rgba(147, 197, 253, .38), 0 1px 4px rgba(8, 14, 28, .3);
}
.k-nav a.active svg { opacity: 1; }

.topbar .spacer, .k-nav-spacer { flex: 1 1 auto; }

/* Benutzerbereich rechts */
.k-user {
  display: flex;
  align-items: center;
  gap: var(--k-2);
  white-space: nowrap;
}
.topbar .who, .k-user .who {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 4px 12px 4px 4px;
  border-radius: var(--k-r-pill);
  background: rgba(255, 255, 255, .07);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .07);
  font-size: 13px;
  font-weight: 550;
  color: #dbe4f0;
}
.k-avatar {
  display: inline-flex; align-items: center; justify-content: center;
  width: 24px; height: 24px; border-radius: 50%;
  background: linear-gradient(135deg, #3b82f6, #1d4ed8);
  color: #fff;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .28);
  font-size: 11px; font-weight: 750; text-transform: uppercase;
}
.k-user a.k-nav-action {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 13px;
  border-radius: var(--k-r-pill);
  border: 1px solid rgba(255, 255, 255, .16);
  color: #dbe4f0; font-size: 13px; font-weight: 550;
  transition: background-color .14s ease, border-color .14s ease, color .14s ease;
}
.k-user a.k-nav-action:hover {
  background: rgba(255, 255, 255, .1);
  border-color: rgba(255, 255, 255, .3);
  color: #fff;
}

/* Einklapp-Schalter für schmale Geräte (reines CSS) */
.k-nav-toggle { position: absolute; opacity: 0; pointer-events: none; }
.k-nav-burger {
  display: none;
  align-items: center; justify-content: center;
  width: 38px; height: 38px; margin-left: auto;
  border-radius: var(--k-r-sm);
  color: var(--k-nav-text);
  cursor: pointer;
}
.k-nav-burger:hover { background: rgba(255, 255, 255, .1); color: #fff; }

/* ── 4. Seitenlayout ──────────────────────────────────────────────────────
   .fl-wrap ist die Bestandsklasse für den Inhaltsbereich der
   Verwaltungsansichten. Sie bekommt mehr Luft und eine feste Maximalbreite,
   damit Zeilen lesbar lang bleiben. .k-wrap ist derselbe Baustein für Seiten
   außerhalb von fleet (z.B. die Simulationsliste). */
.fl-wrap, .k-wrap {
  max-width: 1280px;
  margin: 0 auto;
  padding: var(--k-6) var(--k-5) var(--k-7);
}

/* Brotkrumenpfad - zeigt, wo man ist, und führt zurück. */
.fl-crumb {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin-bottom: var(--k-3);
  font-size: 12.5px;
  font-weight: 500;
  letter-spacing: .01em;
  color: var(--k-text-muted);
}
.fl-crumb a {
  color: var(--k-text-muted);
  text-decoration: none;
  padding: 1px 5px;
  border-radius: 5px;
  transition: color .12s ease, background-color .12s ease;
}
.fl-crumb a:hover { color: var(--k-primary-dark); background: var(--k-primary-soft); }

/* Seitentitel - mit kurzem Stück der Markenachse als Auftakt. */
.fl-wrap h1, .k-wrap h1 {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--k-3);
  font-size: 27px;
  font-weight: 750;
  letter-spacing: -.022em;
  margin: 0 0 var(--k-1);
}
.fl-wrap h1::before, .k-wrap h1::before {
  content: "";
  flex: none;
  width: 5px;
  height: 24px;
  border-radius: 3px;
  background: linear-gradient(180deg, #2563eb, #06b6d4);
}

/* Abschnittsüberschrift: wirkt als Trenner zwischen den Blöcken einer
   Detailseite. Bewusst mit Abstand darüber, damit lange Detailseiten in
   erkennbare Abschnitte zerfallen. Unter der Trennlinie liegt links ein
   kurzes Stück der Markenachse. */
.fl-wrap h2, .k-wrap h2 {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--k-2);
  font-size: 16.5px;
  font-weight: 700;
  margin: var(--k-6) 0 var(--k-3);
  padding-bottom: var(--k-2);
  border-bottom: 1px solid var(--k-border);
  background: linear-gradient(90deg, #2563eb, #06b6d4) left bottom / 44px 2px no-repeat;
  letter-spacing: -.008em;
}
.fl-wrap h3, .k-wrap h3 { font-size: 15px; margin: var(--k-5) 0 var(--k-2); }

/* Kurzbeschreibung unter dem Titel - sekundär, also ruhig. */
.fl-sub {
  color: var(--k-text-muted);
  font-size: 14px;
  max-width: 78ch;
  margin: 0 0 var(--k-5);
}

/* Optionaler Kopfbaustein für Seiten, die Titel und Aktionen nebeneinander
   zeigen wollen. Additiv - bestehende Seiten funktionieren ohne. */
.k-page-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--k-4);
}

/* ── 5. Kennzahlenkarten ──────────────────────────────────────────────────
   Die wichtigsten Zahlen einer Seite auf einen Blick. */
.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: var(--k-3);
  margin: var(--k-4) 0 var(--k-5);
}
.card {
  background: var(--k-surface);
  border: 1px solid var(--k-border);
  border-radius: var(--k-r-md);
  padding: 14px var(--k-4) var(--k-3);
  box-shadow: var(--k-shadow-sm);
  transition: box-shadow .16s ease, border-color .16s ease, transform .16s ease;
}
.card:hover {
  border-color: var(--k-primary-line);
  box-shadow: var(--k-shadow-md);
  transform: translateY(-1px);
}
.card .value {
  font-size: 27px;
  font-weight: 750;
  line-height: 1.12;
  letter-spacing: -.02em;
  color: var(--k-text);
  font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere;
}
.card .label {
  margin-top: 3px;
  font-size: 10.5px;
  font-weight: 650;
  color: var(--k-text-muted);
  text-transform: uppercase;
  letter-spacing: .09em;
}

/* ── 6. Tabellen ──────────────────────────────────────────────────────────
   Klasse .fl bleibt. Neu ist der optionale Rahmen .table-card: Er gibt der
   Tabelle eine Kartenfläche und - wichtig für Mobilgeräte - erlaubt
   waagerechtes Scrollen, ohne dass die ganze Seite verrutscht. */
.table-card {
  background: var(--k-surface);
  border: 1px solid var(--k-border);
  border-radius: var(--k-r-md);
  box-shadow: var(--k-shadow-sm);
  overflow-x: auto;
  overscroll-behavior-x: contain;
  -webkit-overflow-scrolling: touch;
}
.table-card > table.fl,
.table-card > table { margin: 0; }

/* Hinweis, dass seitlich noch Spalten liegen: eine schmale Schattenkante, die
   verschwindet, sobald man an diesem Rand angekommen ist. Umgesetzt mit der
   bekannten Vier-Ebenen-Technik - zwei „Abdeckungen" scrollen mit dem Inhalt
   (background-attachment: local) und schieben sich über die beiden festen
   Schattenebenen. Kein JavaScript nötig.
   Wichtig bei den breiten Geräte- und Satellitentabellen, wo sonst Spalten
   unbemerkt außerhalb des sichtbaren Bereichs liegen. */
.table-card {
  background-color: var(--k-surface);
  background-image:
    linear-gradient(to right, var(--k-surface), rgba(255, 255, 255, 0)),
    linear-gradient(to left,  var(--k-surface), rgba(255, 255, 255, 0)),
    linear-gradient(to right, rgba(15, 23, 42, .13), rgba(15, 23, 42, 0)),
    linear-gradient(to left,  rgba(15, 23, 42, .13), rgba(15, 23, 42, 0));
  background-position: left center, right center, left center, right center;
  background-repeat: no-repeat;
  background-size: 26px 100%, 26px 100%, 13px 100%, 13px 100%;
  background-attachment: local, local, scroll, scroll;
}
/* Damit die Kante sichtbar bleibt, darf die Tabelle selbst keine eigene
   Füllfarbe über den Verlauf legen. */
.table-card > table.fl { background: transparent; }

table.fl, .k-wrap table.fl {
  width: 100%;
  border-collapse: collapse;
  font-size: 13.5px;
  background: var(--k-surface);
}
table.fl th {
  position: sticky;
  top: 0;
  z-index: 1;
  text-align: left;
  padding: 10px 14px;
  background: var(--k-surface-muted);
  box-shadow: inset 0 -1px 0 var(--k-border-strong);
  border-bottom: 1px solid var(--k-border-strong);
  font-size: 11px;
  font-weight: 700;
  color: var(--k-text-muted);
  text-transform: uppercase;
  letter-spacing: .07em;
  white-space: nowrap;
}
table.fl td {
  padding: 11px 14px;
  border-bottom: 1px solid #edf1f7;
  vertical-align: top;
  transition: background-color .1s ease;
}
table.fl tbody tr:last-child td { border-bottom: none; }
table.fl tbody tr:hover td { background: #f4f8ff; }
table.fl a { color: var(--k-primary-dark); text-decoration: none; font-weight: 550; }
table.fl a:hover { text-decoration: underline; }
table.fl .num { text-align: right; font-variant-numeric: tabular-nums; }
table.fl th.num { text-align: right; }

/* Schlüssel-/Wert-Tabellen (Detailseiten) benutzen <th> in der ersten Spalte
   bzw. td.k - beides bekommt dieselbe ruhige Beschriftungsoptik. */
table.fl tbody th,
table.fl td.k {
  position: static;
  box-shadow: none;
  text-transform: none;
  letter-spacing: 0;
  font-size: 13px;
  font-weight: 600;
  color: var(--k-text-soft);
  background: var(--k-surface-muted);
  border-bottom: 1px solid #edf1f7;
  border-right: 1px solid var(--k-border);
  white-space: normal;
  width: 240px;
}

/* Aktionsspalte einer Tabelle. Die Schaltflächen stehen dort in eigenen
   <form>-Elementen (CSRF-Schutz), die sonst untereinander brechen würden -
   vorher über wiederholtes style="display:inline" gelöst. */
td.k-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  white-space: nowrap;
}
td.k-actions form { display: inline-flex; margin: 0; }

/* Leerzustand einer Tabelle: nicht als normale Zeile, sondern erkennbar als
   Hinweis. Greift automatisch bei den {% empty %}-Zeilen. */
table.fl tbody tr td[colspan] {
  color: var(--k-text-muted);
  padding: var(--k-6) var(--k-4);
  text-align: center;
}
table.fl tbody tr td[colspan] a { font-weight: 600; }

/* ── 7. Statusabzeichen ───────────────────────────────────────────────────
   Farbe UND Rahmen: Die Zustände müssen sich auch bei Rot-Grün-Schwäche und
   im Schwarzweißausdruck unterscheiden. */
.badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2.5px 10px;
  border: 1px solid transparent;
  border-radius: var(--k-r-pill);
  font-size: 11.5px;
  font-weight: 650;
  letter-spacing: .01em;
  line-height: 1.5;
  white-space: nowrap;
  vertical-align: baseline;
  box-shadow: 0 1px 1px rgba(15, 23, 42, .04);
}
.badge-online   { background: var(--k-ok-soft);   color: var(--k-ok);   border-color: var(--k-ok-line); }
.badge-degraded { background: #fdf6d8;            color: #a16207;       border-color: var(--k-warn-line); }
.badge-offline  { background: #fdeaea;            color: var(--k-bad);  border-color: var(--k-bad-line); }
.badge-neutral  { background: var(--k-surface-sunk); color: #475569;    border-color: var(--k-border-strong); }
.badge-info     { background: var(--k-info-soft); color: var(--k-info); border-color: var(--k-info-line); }

/* ── 8. Schaltflächen ─────────────────────────────────────────────────────
   Drei Stufen, portalweit gleich: primär (die eine erwartete Aktion),
   sekundär (alles Weitere), gefährlich (löscht oder sperrt etwas aus). */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 8px 16px;
  border: 1px solid var(--k-primary-dark);
  border-radius: var(--k-r-sm);
  background: linear-gradient(180deg, #3f7ef7, var(--k-primary));
  color: #fff;
  font-family: inherit;
  font-size: 13.5px;
  font-weight: 620;
  letter-spacing: .004em;
  line-height: 1.4;
  text-decoration: none;
  cursor: pointer;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .18), 0 1px 2px rgba(29, 78, 216, .28);
  transition: background-color .12s ease, border-color .12s ease,
              box-shadow .12s ease, filter .12s ease, transform .12s ease;
}
.btn:hover {
  background: linear-gradient(180deg, #3372ec, var(--k-primary-dark));
  color: #fff;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 2px 6px rgba(29, 78, 216, .32);
}
.btn:active {
  background: var(--k-primary-darker);
  box-shadow: none;
  transform: translateY(1px);
}

.btn-sec {
  background: var(--k-surface);
  color: var(--k-text-soft);
  border-color: var(--k-border-strong);
  box-shadow: var(--k-shadow-sm);
}
.btn-sec:hover  { background: var(--k-surface-muted); color: var(--k-text); border-color: #94a3b8; box-shadow: var(--k-shadow-sm); }
.btn-sec:active { background: #e2e8f0; transform: translateY(1px); }

/* Destruktiv: nicht nur rot, sondern deutlich als Ausnahme gezeichnet. */
.btn-danger {
  background: var(--k-surface);
  color: var(--k-bad);
  border-color: var(--k-bad-line);
  box-shadow: var(--k-shadow-sm);
}
.btn-danger:hover  { background: #dc2626; color: #fff; border-color: #dc2626; box-shadow: 0 2px 6px rgba(185, 28, 28, .3); }
.btn-danger:active { background: #991b1b; border-color: #991b1b; transform: translateY(1px); }

.btn.small, .btn-sec.small, .btn-danger.small { padding: 5px 11px; font-size: 12.5px; }

.btn:disabled, .btn[disabled] { opacity: .55; cursor: not-allowed; box-shadow: none; transform: none; }

/* Aktionsleiste. Formulare darin sind nur Träger einzelner Knöpfe und dürfen
   die Zeile nicht umbrechen. */
.btn-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--k-2);
  margin: var(--k-3) 0 var(--k-5);
}
.btn-row form { display: inline-flex; margin: 0; }

/* ── 9. Hinweise und Meldungen ────────────────────────────────────────────
   .note = dauerhafter Erklärtext auf der Seite.
   .msg  = Rückmeldung auf eine gerade ausgeführte Aktion. */
.note {
  border: 1px solid var(--k-primary-line);
  border-left: 4px solid var(--k-primary);
  background: linear-gradient(180deg, #f4f8ff, var(--k-primary-soft));
  color: #1e3a5f;
  padding: var(--k-3) var(--k-4);
  margin: var(--k-4) 0;
  border-radius: var(--k-r-sm) var(--k-r-md) var(--k-r-md) var(--k-r-sm);
  font-size: 13.5px;
  box-shadow: var(--k-shadow-sm);
}
.note > :first-child { margin-top: 0; }
.note > :last-child  { margin-bottom: 0; }
.note-warn   { border-color: var(--k-warn-line); border-left-color: #d97706; background: linear-gradient(180deg, #fffdf4, var(--k-warn-soft)); color: #713f12; }
.note-danger { border-color: var(--k-bad-line);  border-left-color: #dc2626; background: linear-gradient(180deg, #fef6f6, var(--k-bad-soft));  color: #7f1d1d; }

/* Inline-Code in Hinweisen: dunkel, damit Befehle klar als solche lesbar
   sind und beim Kopieren nichts übersehen wird. */
.note code, code.inline {
  background: var(--k-nav-bg-soft);
  color: #e2e8f0;
  padding: 1.5px 6px;
  border-radius: var(--k-r-sm);
  font-family: var(--k-font-mono);
  font-size: 12.5px;
  overflow-wrap: anywhere;
}

.msg {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 11px var(--k-4);
  margin-bottom: var(--k-3);
  border: 1px solid transparent;
  border-radius: var(--k-r-md);
  font-size: 13.5px;
  font-weight: 500;
  box-shadow: var(--k-shadow-sm);
}
/* Das Zeichen sitzt in einem kleinen gefüllten Kreis - schneller erfassbar
   als ein loses Sonderzeichen, und farbfehlsichtig weiterhin unterscheidbar,
   weil jede Meldungsart ihr eigenes Zeichen behält. */
.msg::before {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 19px;
  height: 19px;
  margin-top: 1px;
  border-radius: 50%;
  color: #fff;
  font-size: 11px;
  font-weight: 750;
  line-height: 1;
}
.msg-success { background: var(--k-ok-soft);   color: #14532d; border-color: var(--k-ok-line); }
.msg-success::before { content: "✓"; background: var(--k-ok); }
.msg-warning { background: #fdf6d8;            color: #713f12; border-color: var(--k-warn-line); }
.msg-warning::before { content: "!"; background: #d97706; }
.msg-error   { background: #fdeaea;            color: #7f1d1d; border-color: var(--k-bad-line); }
.msg-error::before { content: "✕"; background: #dc2626; }
.msg-info    { background: var(--k-info-soft); color: #1e3a8a; border-color: var(--k-info-line); }
.msg-info::before { content: "i"; background: var(--k-info); font-family: Georgia, serif; font-style: italic; }

/* ── 10. Formulare ────────────────────────────────────────────────────────
   Klasse .fl-form bleibt. Felder sind jetzt einheitlich hoch, haben einen
   erkennbaren Fokuszustand und Fehler werden nicht mehr nur rot, sondern
   auch am Feld selbst sichtbar. */
form.fl-form { max-width: 640px; }
form.fl-form label {
  display: block;
  margin: var(--k-4) 0 5px;
  font-weight: 620;
  font-size: 13px;
  letter-spacing: .004em;
  color: var(--k-text-soft);
}
form.fl-form input[type=text], form.fl-form input[type=email],
form.fl-form input[type=number], form.fl-form input[type=password],
form.fl-form input[type=url], form.fl-form input[type=search],
form.fl-form textarea, form.fl-form select {
  width: 100%;
  max-width: 520px;
  padding: 8px 12px;
  border: 1px solid var(--k-border-strong);
  border-radius: var(--k-r-sm);
  background: var(--k-surface);
  color: var(--k-text);
  font-size: 14px;
  font-family: inherit;
  box-shadow: inset 0 1px 2px rgba(15, 23, 42, .04);
  transition: border-color .12s ease, box-shadow .12s ease;
}
form.fl-form input:hover, form.fl-form textarea:hover, form.fl-form select:hover {
  border-color: #94a3b8;
}
form.fl-form input:focus, form.fl-form textarea:focus, form.fl-form select:focus {
  outline: none;
  border-color: var(--k-primary);
  box-shadow: var(--k-ring);
}
form.fl-form textarea { min-height: 96px; resize: vertical; }
form.fl-form .helptext, .helptext {
  display: block;
  color: var(--k-text-muted);
  font-size: 12px;
  line-height: 1.5;
  margin-top: var(--k-1);
  max-width: 520px;
}
form.fl-form ul.errorlist, ul.errorlist {
  list-style: none;
  color: var(--k-bad);
  font-size: 12.5px;
  font-weight: 600;
  padding: 0;
  margin: var(--k-1) 0 0;
}
form.fl-form ul.errorlist li::before { content: "✕ "; }

/* Das fehlerhafte Feld selbst markieren, nicht nur den Text darunter - sonst
   muss man bei langen Formularen suchen, wo das Problem sitzt. Django stellt
   die Fehlerliste direkt hinter das Feld, deshalb genügt der
   Geschwister-Selektor. Wo :has() fehlt, bleibt es bei der Fehlermeldung -
   die Information geht also nirgends verloren. */
form.fl-form input:has(+ ul.errorlist),
form.fl-form select:has(+ ul.errorlist),
form.fl-form textarea:has(+ ul.errorlist) {
  border-color: var(--k-bad);
  background: var(--k-bad-soft);
}

/* Formulare, die Django mit as_p rendert (Befehls- und Aufgabenformulare),
   bekommen dieselbe Optik wie handgebaute Felder. */
form.fl-form p { margin: var(--k-4) 0 0; }
form.fl-form p label { margin-top: 0; }

.checkline {
  display: flex;
  align-items: center;
  gap: var(--k-2);
  margin-top: var(--k-3);
  padding: 9px 12px;
  background: var(--k-surface-muted);
  border: 1px solid var(--k-border);
  border-radius: var(--k-r-sm);
  max-width: 520px;
}
.checkline input { width: auto; accent-color: var(--k-primary); }
.checkline label { margin: 0; }

/* Such- und Filterbereiche: die kleinen Filterformulare in den Übersichten
   (Kunde auswählen) bekommen ein erkennbares Feld statt eines nackten
   Select. .k-filter ist additiv - der Bestand nutzt inline-Styles, die
   weiterhin greifen. */
.k-filter {
  display: flex;
  align-items: center;
  gap: var(--k-2);
  padding: 5px 6px 5px 13px;
  background: var(--k-surface);
  border: 1px solid var(--k-border);
  border-radius: var(--k-r-pill);
  box-shadow: var(--k-shadow-sm);
}
.k-filter-label {
  font-size: 11px;
  font-weight: 650;
  color: var(--k-text-muted);
  text-transform: uppercase;
  letter-spacing: .07em;
  white-space: nowrap;
}
.k-filter select {
  padding: 6px 10px;
  border: 1px solid var(--k-border-strong);
  border-radius: var(--k-r-pill);
  background: var(--k-surface);
  font-family: inherit;
  font-size: 13.5px;
  color: var(--k-text);
}
.k-filter select:focus {
  outline: none;
  border-color: var(--k-primary);
  box-shadow: var(--k-ring);
}

/* ── 11. Sonstiges ────────────────────────────────────────────────────────*/

/* Schlüssel/Befehle zum Abschreiben oder Kopieren. */
.keybox {
  background: linear-gradient(180deg, #101a2e, var(--k-nav-bg));
  color: #4ade80;
  padding: var(--k-4);
  border: 1px solid #223252;
  border-radius: var(--k-r-md);
  font-family: var(--k-font-mono);
  font-size: 13.5px;
  line-height: 1.6;
  word-break: break-all;
  white-space: pre-wrap;
  margin: var(--k-3) 0;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .05), var(--k-shadow-sm);
}

/* Meldungsbereich oben auf der Seite. */
.k-messages { margin-bottom: var(--k-4); }

/* Sekundärangabe in der Simulationsliste (Gebietsart, Einheit). */
.sim-kind { font-size: 11.5px; color: var(--k-text-muted); }

/* Variante für Befehle: neutrales Hell statt Schlüsselgrün. Vorher stand das
   als wiederholtes style="color:#e2e8f0" in den Vorlagen. */
.keybox-cmd { color: #e2e8f0; }

/* Fehlertexte in Tabellen - einheitliche Farbe statt wiederholter
   Inline-Angaben. */
.k-err { color: var(--k-bad); }

/* Fortschrittsbalken über die volle Breite - Web-Flasher, Ausrollungen. */
.k-progress { width: 100%; }

/* Mitlaufendes Protokoll: fester Ausschnitt, der Rest wird gescrollt. Ohne
   Deckel wächst die Seite beim Flashen mit jeder Zeile weiter, und der Knopf,
   den man als Nächstes braucht, wandert aus dem Bild. word-break bleibt
   normal - .keybox bricht mitten im Wort, was bei Schlüsseln richtig ist und
   bei Fließtextmeldungen unlesbar. */
.keybox-log {
  max-height: 20em;
  overflow: auto;
  word-break: normal;
  overflow-wrap: anywhere;
}

.muted  { color: var(--k-text-muted); }
.small  { font-size: 12.5px; }
.nowrap { white-space: nowrap; }

/* ── Lagekarte ────────────────────────────────────────────────────────────
   Reales Funknetz auf der Karte (fleet/situation_map.html + lagekarte.js).
   Die Karte liegt in einer Kartenfläche des Designsystems; die Legende
   schwebt unten links über der Karte, damit sie beim Ablesen im Blick ist,
   ohne eigene Bildschirmfläche zu kosten. */
.sitmap-frame {
  position: relative;
  border: 1px solid var(--k-border);
  border-radius: var(--k-r-md);
  overflow: hidden;
  box-shadow: var(--k-shadow-sm);
  background: var(--k-surface-sunk);
}
.sitmap-map { height: 62vh; min-height: 380px; }
.sitmap-legend {
  position: absolute;
  left: 10px;
  bottom: 10px;
  z-index: 800; /* über den Leaflet-Kacheln (400), unter Popups (700+) nicht nötig */
  display: flex;
  flex-wrap: wrap;
  gap: 4px 12px;
  padding: 6px 12px;
  background: rgba(255, 255, 255, .92);
  border: 1px solid var(--k-border);
  border-radius: var(--k-r-pill);
  box-shadow: var(--k-shadow-sm);
  font-size: 11.5px;
  color: var(--k-text-soft);
  pointer-events: none;
}
.sitmap-legend-item { display: inline-flex; align-items: center; gap: 5px; white-space: nowrap; }
.sitmap-dot {
  display: inline-block;
  width: 9px; height: 9px;
  border-radius: 50%;
  box-shadow: inset 0 0 0 1px rgba(15, 23, 42, .15);
}
.sitmap-dot-online  { background: var(--k-ok); }
.sitmap-dot-stale   { background: #d97706; }
.sitmap-dot-offline { background: #dc2626; }
.sitmap-dot-unknown { background: var(--k-text-muted); }
.sitmap-dot-manual  { background: #fff; border: 2px dashed var(--k-text-muted); box-shadow: none; }
.sitmap-stand { align-self: center; }

/* Ampelfarbige Kennzahlenkarten der Lagekarte: derselbe .card-Baustein,
   nur der Wert trägt die Statusfarbe. */
.sitmap-card-online  .value { color: var(--k-ok); }
.sitmap-card-stale   .value { color: var(--k-warn); }
.sitmap-card-offline .value { color: var(--k-bad); }

/* Popup-Inhalt der Gerätemarker. Leaflet bringt den Rahmen mit; hier nur
   die Typografie, damit sie zum Portal passt. */
.sitmap-popup { font-family: var(--k-font); font-size: 12.5px; line-height: 1.5; }
.sitmap-popup-status { font-weight: 650; }
.sitmap-popup-online  { color: var(--k-ok); }
.sitmap-popup-stale   { color: var(--k-warn); }
.sitmap-popup-offline { color: var(--k-bad); }
.sitmap-popup-unknown { color: var(--k-text-muted); }
.sitmap-popup-facts { color: var(--k-text-soft); font-size: 12px; }

/* Kleine Karte zur Standortwahl auf der Gerätedetailseite. */
.standort-map {
  height: 320px;
  border: 1px solid var(--k-border);
  border-radius: var(--k-r-md);
  overflow: hidden;
  box-shadow: var(--k-shadow-sm);
  background: var(--k-surface-sunk);
  margin-bottom: var(--k-3);
}

/* Dezente Bildlaufleisten in scrollenden Flächen (Tabellenkarten,
   Planer-Seitenspalte). Nur WebKit/Blink; Firefox über scrollbar-width. */
.table-card::-webkit-scrollbar { height: 8px; width: 8px; }
.table-card::-webkit-scrollbar-thumb {
  background: var(--k-border-strong);
  border-radius: 99px;
}
.table-card::-webkit-scrollbar-thumb:hover { background: #94a3b8; }
.table-card { scrollbar-width: thin; scrollbar-color: var(--k-border-strong) transparent; }

/* ── Anmeldung, zweiter Faktor, Passwort ──────────────────────────────────
   Die Anmeldeseiten haben bewusst KEINE Kopfleiste (dort führte jeder
   Menüpunkt nur hierher zurück) und stattdessen eine ruhige, mittige Karte.
   Dieselben Tokens, dieselben Formularfelder wie im Portal - eine
   Anmeldeseite, die anders aussieht als die Anwendung dahinter, ist genau
   der Eindruck, den Phishing-Seiten erzeugen. */
.k-auth-body {
  min-height: 100vh;
  margin: 0;
  display: flex;
  background:
    radial-gradient(1200px 520px at 50% -10%, rgba(37, 99, 235, .10), transparent 70%),
    var(--k-bg);
}
.k-auth {
  margin: auto;
  width: 100%;
  max-width: 440px;
  padding: var(--k-6) var(--k-4);
}
.k-auth-card {
  background: var(--k-surface);
  border: 1px solid var(--k-border);
  border-radius: var(--k-r-lg);
  box-shadow: var(--k-shadow-md);
  padding: var(--k-6) var(--k-5) var(--k-5);
  position: relative;
  overflow: hidden;
}
/* Dieselbe Markenachse wie unter der Kopfleiste des Portals. */
.k-auth-card::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 3px;
  background: linear-gradient(90deg, #2563eb, #06b6d4);
}
.k-auth-brand {
  display: flex;
  align-items: center;
  gap: 9px;
  color: var(--k-primary-dark);
  margin-bottom: var(--k-5);
}
.k-auth-name { font-weight: 700; font-size: 17px; letter-spacing: -.01em; color: var(--k-text); }
.k-auth-sub {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .09em;
  color: var(--k-text-muted);
  padding-left: 9px;
  border-left: 1px solid var(--k-border-strong);
}
.k-auth-title { font-size: 20px; margin: 0 0 var(--k-2); letter-spacing: -.015em; }
.k-auth-lead { color: var(--k-text-soft); font-size: 13.5px; line-height: 1.6; margin: 0 0 var(--k-4); }
.k-auth-form { max-width: none; }
.k-auth-form input { max-width: none !important; }
.k-auth-form label:first-of-type { margin-top: 0; }
.k-auth-actions { margin-top: var(--k-5); }
.k-auth-actions > .btn { flex: 1; justify-content: center; }
.k-auth-links { margin: var(--k-4) 0 0; font-size: 13px; text-align: center; }
.k-auth-links a { color: var(--k-primary-dark); }
.k-auth-foot { text-align: center; color: var(--k-text-muted); font-size: 12px; margin-top: var(--k-4); }

/* Eingabefeld für Einmalkennwörter: groß, mit Ziffernabstand - sechs Stellen
   werden abgelesen und abgetippt, oft unter Zeitdruck. */
.k-code-input {
  font-family: var(--k-font-mono);
  font-size: 22px !important;
  letter-spacing: .22em;
  text-align: center;
  max-width: 260px !important;
}

/* Einrichtungsseite: QR-Code links, Schlüssel zum Abtippen rechts. */
.k-2fa-setup {
  display: flex;
  flex-wrap: wrap;
  gap: var(--k-5);
  align-items: flex-start;
  margin-bottom: var(--k-2);
}
.k-2fa-qr {
  flex: none;
  background: #fff;
  border: 1px solid var(--k-border);
  border-radius: var(--k-r-md);
  padding: var(--k-3);
  box-shadow: var(--k-shadow-sm);
  line-height: 0;
}
.k-2fa-qr svg { width: 190px; height: 190px; }
.k-2fa-key { flex: 1 1 260px; min-width: 240px; }
.k-2fa-key p { margin: 0 0 var(--k-2); font-size: 13.5px; color: var(--k-text-soft); line-height: 1.6; }
/* Der Schlüssel steht in einem <p class="keybox"> - die Absatzregel darüber
   ist spezifischer als .keybox und würde ihm sonst Schriftfarbe und
   -größe der Fließtexte aufzwingen (grau auf dunkelblau, kaum lesbar). */
.k-2fa-key p.keybox {
  color: #4ade80;
  font-family: var(--k-font-mono);
  font-size: 15px;
  letter-spacing: .12em;
  margin: var(--k-3) 0;
}

/* Wiederherstellungscodes: zum Ausdrucken gedacht, deshalb großzügig und
   im Druck ohne Farbfläche. */
.k-codes {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: var(--k-2);
  margin: var(--k-4) 0;
  max-width: 640px;
}
.k-code {
  font-family: var(--k-font-mono);
  font-size: 15px;
  letter-spacing: .06em;
  padding: 9px 12px;
  text-align: center;
  background: var(--k-surface-sunk);
  border: 1px solid var(--k-border);
  border-radius: var(--k-r-sm);
  color: var(--k-text);
}

/* ── 12. Responsive ──────────────────────────────────────────────────────── */

/* Tablet: Beschriftungen bleiben stehen, nur die Abstände werden knapper.
   Die Menüpunkte sollen lesbar bleiben - ein reines Symbol beantwortet die
   Frage „wo bin ich?" nicht zuverlässig. */
@media (max-width: 1024px) {
  .fl-wrap, .k-wrap { padding: var(--k-4) var(--k-4) var(--k-6); }
  .topbar { padding: 0 var(--k-4); }
  .k-nav { margin-left: var(--k-3); }
  .k-nav a { padding: 7px 9px; font-size: 13.5px; }
}

/* Mit sieben Menüpunkten wird es unter ~1500 px eng: Abstände und Schrift
   der Leiste treten einen Schritt zurück, bevor Beschriftungen fallen. */
@media (max-width: 1500px) and (min-width: 951px) {
  .k-nav { margin-left: var(--k-2); gap: 2px; }
  .k-nav a { padding: 6px 8px; font-size: 12.5px; gap: 5px; }
  .k-user a.k-nav-action { padding: 6px 10px; font-size: 12.5px; }
  .topbar .who, .k-user .who { font-size: 12.5px; padding-right: 9px; }
  .k-brand { font-size: 15px; }
}
/* Noch schmaler: zuerst verliert der lange Menüpunkt seine Beschriftung.
   Die Grenze liegt bei 1440 px, weil rechts inzwischen drei Elemente stehen
   (Name, Admin, Abmelden) - bei 1280 px lief die Leiste sonst ineinander,
   und zwar überlappend statt umbrechend: Die Menüpunkte dürfen nicht
   umbrechen (white-space: nowrap), also schieben sie sich übereinander.
   Deshalb müssen die Beschriftungen früh genug weichen. */
@media (max-width: 1439px) and (min-width: 1280px) {
  .k-nav a[title="Gespeicherte Simulationen"] { gap: 0; }
  .k-nav a[title="Gespeicherte Simulationen"] span { display: none; }
}

/* Darunter tragen alle Menüpunkte nur noch ihr Symbol. Sie behalten ihr
   title-Attribut, der Name bleibt also als Kurzinfo erreichbar - und der
   aktive Punkt bleibt farbig gefüllt, damit „wo bin ich?" beantwortet
   bleibt. */
@media (max-width: 1279px) and (min-width: 801px) {
  .k-nav a { gap: 0; padding: 7px 10px; }
  .k-nav a span { display: none; }
}

/* Noch enger: der Benutzername weicht dem Namenskürzel im Kreis. */
@media (max-width: 1050px) and (min-width: 801px) {
  .k-user .who { padding: 5px; font-size: 0; }
  .k-avatar { font-size: 11px; }
}

/* Smartphone: Navigation klappt ein */
@media (max-width: 800px) {
  .topbar {
    flex-wrap: wrap;
    padding: 0 var(--k-4);
    row-gap: 0;
  }
  .k-nav-burger { display: inline-flex; }
  .k-nav, .k-user {
    display: none;
    width: 100%;
    flex-direction: column;
    align-items: stretch;
    gap: var(--k-1);
    margin: 0;
    padding: var(--k-2) 0;
  }
  .k-nav-toggle:checked ~ .k-nav,
  .k-nav-toggle:checked ~ .k-user { display: flex; }
  .k-nav-toggle:checked ~ .k-user {
    border-top: 1px solid rgba(255, 255, 255, .1);
    padding-bottom: var(--k-3);
  }
  .k-nav a { padding: 10px 12px; gap: 10px; font-size: 15px; border-radius: var(--k-r-sm); }
  .k-nav a span { display: inline; }
  .k-nav-spacer, .topbar .spacer { display: none; }
  .k-user .who { justify-content: flex-start; }
  .k-user a.k-nav-action { justify-content: center; border-radius: var(--k-r-sm); }

  .fl-wrap, .k-wrap { padding: var(--k-4) var(--k-3) var(--k-6); }
  .fl-wrap h1, .k-wrap h1 { font-size: 21px; }
  .fl-wrap h1::before, .k-wrap h1::before { height: 18px; width: 4px; }
  .fl-wrap h2, .k-wrap h2 { font-size: 16px; margin-top: var(--k-5); }
  .cards { grid-template-columns: repeat(auto-fit, minmax(132px, 1fr)); gap: var(--k-2); }
  .card { padding: 10px 12px; }
  .card .value { font-size: 21px; }

  /* Tabellen bleiben Tabellen, scrollen aber innerhalb ihrer Karte statt die
     Seite zu verbreitern. Kopfzeilen kleben nicht mehr, weil das auf kleinen
     Displays mehr stört als hilft. */
  table.fl th { position: static; }
  table.fl th, table.fl td { padding: 8px 10px; }
  table.fl tbody th, table.fl td.k { width: auto; min-width: 130px; }

  /* Lagekarte: auf dem Telefon etwas flacher, damit Kennzahlen und Liste
     ohne langes Scrollen erreichbar bleiben. */
  .sitmap-map { height: 52vh; min-height: 300px; }
  .standort-map { height: 260px; }

  /* Aktionen füllen die Breite - auf dem Telefon leichter zu treffen. */
  .btn-row { gap: var(--k-2); }
  .btn-row > .btn, .btn-row > form, .btn-row > form > .btn { width: 100%; }

  form.fl-form input[type=text], form.fl-form input[type=email],
  form.fl-form input[type=number], form.fl-form input[type=password],
  form.fl-form textarea, form.fl-form select { max-width: none; }
  .checkline, .helptext { max-width: none; }
  .k-filter { width: 100%; }
  .k-filter select { flex: 1; }
}

/* Tabellen ohne .table-card-Rahmen (falls irgendwo einer fehlt) sollen die
   Seite trotzdem nicht sprengen. */
@media (max-width: 800px) {
  .fl-wrap > table.fl, .k-wrap > table.fl { display: block; overflow-x: auto; }
}

/* Wer Bewegung reduziert hat, bekommt keine Hover-Verschiebungen. */
@media (prefers-reduced-motion: reduce) {
  .card, .card:hover { transform: none; transition: none; }
  .btn, .btn:active, .btn-sec:active, .btn-danger:active { transform: none; }
}

/* Druck: Farbflächen sparen, Inhalt behalten. */
@media print {
  .topbar, .btn-row, .k-nav-burger { display: none !important; }
  body { background: #fff; }
  .table-card, .card { box-shadow: none; }
}
