/* customerdb/assets/style.css
 *
 * Farbschema und Schriftgroesse kommen als data-Attribut am <html>-Element
 * vom Server (siehe include/Appearance.php). Kein JavaScript, dadurch steht
 * das Theme schon beim ersten Byte fest.
 *
 * Die Rohwerte der Paletten stehen einmal unter :root als --p-*. Die Themes
 * darunter weisen sie nur noch zu - so gibt es pro Farbe genau eine Quelle,
 * auch fuer das Dunkel-Schema, das zweimal gebraucht wird (fest gewaehlt und
 * ueber die Systemeinstellung).
 */

:root {
  /* ---- Markenfarben, gemessen am Original-Logo ---- */
  --p-brand-blue:      #143370;
  --p-brand-blue-dark: #0d2350;
  --p-brand-blue-lite: #4a6bb0;
  --p-brand-red:       #9d2c1f;
  --p-brand-red-lite:  #c95a4a;

  /* ---- Palette hell ---- */
  --p-l-bg: #f4f6f9;      --p-l-surface: #ffffff;  --p-l-border: #e2e6ec;
  --p-l-text: #1b2430;    --p-l-muted: #5c6b7f;
  --p-l-accent: #1b5fa8;  --p-l-accent-dark: #16497f; --p-l-accent-soft: #e8f1fb;
  --p-l-danger: #b42318;  --p-l-danger-soft: #fef3f2;
  --p-l-success: #067647; --p-l-success-soft: #ecfdf3;
  --p-l-warn: #7a4b03;    --p-l-warn-soft: #fff7e0;  --p-l-warn-line: #e0a422;

  /* ---- Palette dunkel ---- */
  --p-d-bg: #12161c;      --p-d-surface: #1a2029;  --p-d-border: #2b333f;
  --p-d-text: #e6eaf0;    --p-d-muted: #9aa5b4;
  --p-d-accent: #6ba6de;  --p-d-accent-dark: #8cbce8; --p-d-accent-soft: #1d2b3a;
  --p-d-danger: #f27166;  --p-d-danger-soft: #2c1c1c;
  --p-d-success: #5bc98f; --p-d-success-soft: #16281f;
  --p-d-warn: #f5c451;    --p-d-warn-soft: #2e2612;  --p-d-warn-line: #8a6a16;

  /* ---- Zuweisung: Standard ist hell ---- */
  --bg: var(--p-l-bg);
  --surface: var(--p-l-surface);
  --border: var(--p-l-border);
  --text: var(--p-l-text);
  --text-muted: var(--p-l-muted);
  --accent: var(--p-l-accent);
  --accent-dark: var(--p-l-accent-dark);
  --accent-soft: var(--p-l-accent-soft);
  --danger: var(--p-l-danger);
  --danger-soft: var(--p-l-danger-soft);
  --success: var(--p-l-success);
  --success-soft: var(--p-l-success-soft);
  --warn: var(--p-l-warn);
  --warn-soft: var(--p-l-warn-soft);
  --warn-line: var(--p-l-warn-line);

  --header-bg: var(--surface);
  --header-text: var(--text);
  --header-muted: var(--text-muted);
  --header-border: var(--border);
  --nav-active: var(--accent);

  --radius: 10px;
  --radius-sm: 6px;
  --border-w: 1px;
  --shadow: 0 1px 2px rgba(16, 24, 40, .06), 0 1px 3px rgba(16, 24, 40, .10);
  --focus: var(--accent);
  --link-decoration: none;

  --font-scale: 1;
  font-size: calc(100% * var(--font-scale));
}

/* ---- Schriftgroessen ---- */
:root[data-size="klein"]      { --font-scale: .9; }
:root[data-size="normal"]     { --font-scale: 1; }
:root[data-size="gross"]      { --font-scale: 1.15; }
:root[data-size="sehr-gross"] { --font-scale: 1.32; }

/* ---- Dunkel: fest gewaehlt ---- */
:root[data-theme="dunkel"] {
  --bg: var(--p-d-bg);              --surface: var(--p-d-surface);
  --border: var(--p-d-border);      --text: var(--p-d-text);
  --text-muted: var(--p-d-muted);   --accent: var(--p-d-accent);
  --accent-dark: var(--p-d-accent-dark); --accent-soft: var(--p-d-accent-soft);
  --danger: var(--p-d-danger);      --danger-soft: var(--p-d-danger-soft);
  --success: var(--p-d-success);    --success-soft: var(--p-d-success-soft);
  --warn: var(--p-d-warn);          --warn-soft: var(--p-d-warn-soft);
  --warn-line: var(--p-d-warn-line);
  --shadow: 0 1px 2px rgba(0, 0, 0, .4);
}

/* ---- Dunkel: der Systemeinstellung folgend ---- */
@media (prefers-color-scheme: dark) {
  :root[data-theme="auto"] {
    --bg: var(--p-d-bg);              --surface: var(--p-d-surface);
    --border: var(--p-d-border);      --text: var(--p-d-text);
    --text-muted: var(--p-d-muted);   --accent: var(--p-d-accent);
    --accent-dark: var(--p-d-accent-dark); --accent-soft: var(--p-d-accent-soft);
    --danger: var(--p-d-danger);      --danger-soft: var(--p-d-danger-soft);
    --success: var(--p-d-success);    --success-soft: var(--p-d-success-soft);
  --warn: var(--p-d-warn);          --warn-soft: var(--p-d-warn-soft);
  --warn-line: var(--p-d-warn-line);
    --shadow: 0 1px 2px rgba(0, 0, 0, .4);
  }
}

/* ---- Lokstoredigital: Wortmarken-Blau als Leitfarbe, Rot als Akzent ---- */
:root[data-theme="marke"] {
  --bg: #f1f4f9;
  --surface: #ffffff;
  --border: #dbe2ed;
  --text: #16202e;
  --text-muted: #56637a;
  --accent: var(--p-brand-blue);
  --accent-dark: var(--p-brand-blue-dark);
  --accent-soft: #e7ecf6;
  --danger: var(--p-brand-red);
  --danger-soft: #fbeae7;
  --success: #0a6b45;
  --success-soft: #e9f7f0;
  --warn: #6f4502;
  --warn-soft: #fff6dd;
  --warn-line: #d59a1c;

  --header-bg: var(--p-brand-blue);
  --header-text: #ffffff;
  --header-muted: rgba(255, 255, 255, .78);
  --header-border: var(--p-brand-blue-dark);
  --nav-active: var(--p-brand-red-lite);
}

/* ---- Hoher Kontrast ---- */
:root[data-theme="kontrast"] {
  --bg: #ffffff;
  --surface: #ffffff;
  --border: #000000;
  --text: #000000;
  --text-muted: #000000;
  --accent: #00339e;
  --accent-dark: #001f66;
  --accent-soft: #ffffff;
  --danger: #a00000;
  --danger-soft: #ffffff;
  --success: #00522a;
  --success-soft: #ffffff;
  --warn: #000000;
  --warn-soft: #ffff00;
  --warn-line: #000000;

  --header-bg: #ffffff;
  --header-text: #000000;
  --header-muted: #000000;
  --header-border: #000000;
  --nav-active: #00339e;

  --border-w: 2px;
  --shadow: none;
  --radius: 4px;
  --radius-sm: 3px;
  --link-decoration: underline;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 1rem/1.55 system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  -webkit-text-size-adjust: 100%;
}

a { color: var(--accent); text-decoration: var(--link-decoration); }
a:hover { text-decoration: underline; }

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

h2 { font-size: 1.4rem; margin: 0 0 1rem; letter-spacing: -.01em; }
h3 { font-size: 1.05rem; margin: 0 0 .6rem; }
h4 { font-size: .95rem; margin: 1.1rem 0 .4rem; }

/* Laengere Fliesstexte wie die Nutzungsregeln: Abschnitte voneinander
   absetzen und die Zeilen nicht ueber die ganze Breite laufen lassen. */
.card h3 { margin-top: 1.8rem; }
.card h3:first-of-type { margin-top: .5rem; }
.card ul { margin: .4rem 0 .8rem; padding-left: 1.3rem; }
.card ul li { margin-bottom: .35rem; }
.card > p, .card > ul { max-width: 62ch; }

code {
  background: var(--accent-soft);
  border: var(--border-w) solid var(--border);
  padding: .1em .4em;
  border-radius: 4px;
  font-size: .9em;
}

/* ---------- Kopfbereich ---------- */

.site-header {
  background: var(--header-bg);
  color: var(--header-text);
  border-bottom: var(--border-w) solid var(--header-border);
  position: sticky;
  top: 0;
  z-index: 10;
}

.site-header__inner {
  display: flex;
  align-items: center;
  gap: 1.25rem;
  max-width: 1280px;
  margin: 0 auto;
  padding: .75rem 1.25rem;
}

/* Zwei freigestellte Logo-Fassungen. Die Original-Wortmarke ist so dunkelblau
   wie die Kopfleiste des Marken-Themes und dort praktisch unsichtbar, die
   schwarze Unterzeile geht auf dunklem Grund unter - deshalb gibt es eine
   aufgehellte Variante fuer dunkle und farbige Kopfleisten. */
.brand { display: flex; align-items: center; flex: 0 0 auto; }
/* Hier bewusst KEIN display: ".brand img" hat mit 0-1-1 eine hoehere
   Spezifitaet als ".brand__inv" mit 0-1-0 und setzte damit beide Fassungen
   auf display:block - in "hell", "kontrast" und "auto" im hellen Systemmodus
   standen beide Logos nebeneinander. In "dunkel" und "marke" fiel es nicht
   auf, weil dort die Themenregel mit 0-2-0 dazwischengeht. */
.brand img { height: 42px; width: auto; }
.brand__std { display: block; }
.brand__inv { display: none; }

:root[data-theme="dunkel"] .brand__std,
:root[data-theme="marke"]  .brand__std { display: none; }
:root[data-theme="dunkel"] .brand__inv,
:root[data-theme="marke"]  .brand__inv { display: block; }

@media (prefers-color-scheme: dark) {
  :root[data-theme="auto"] .brand__std { display: none; }
  :root[data-theme="auto"] .brand__inv { display: block; }
}

.site-title {
  font-size: 1.25rem;
  font-weight: 600;
  margin: 0;
  padding-left: 1.25rem;
  border-left: var(--border-w) solid var(--header-border);
  letter-spacing: -.01em;
}

.account {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: .75rem;
}

.account__info { display: flex; align-items: center; gap: .5rem; font-size: .9rem; }
.account__name { font-weight: 600; }
/* Im abgemeldeten Zustand stehen hier zwei Knoepfe statt Name und Abmelden.
   Alle Bedienelemente der Kopfzeile sind btn--small, damit sie dieselbe Hoehe
   haben wie die Darstellungssteuerung daneben. */
.account .btn { white-space: nowrap; }
.account__form { margin: 0; }

.badge {
  font-size: .7rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .04em;
  padding: .15rem .45rem;
  border-radius: 999px;
  background: rgba(127, 127, 127, .22);
  color: inherit;
  border: var(--border-w) solid transparent;
}
:root[data-theme="kontrast"] .badge { border-color: currentColor; }

.badge--own     { background: var(--accent-soft);  color: var(--accent); }
.badge--public  { background: var(--success-soft); color: var(--success); }
.badge--private { background: var(--danger-soft);  color: var(--danger); }
/* Hinweis, kein Fehler - etwa ein Gesellschaftsname, der mehrfach vorkommt.
   Das ist erlaubt und oft historisch korrekt, deshalb nicht in Rot. */
.badge--warn    { background: var(--warn-soft);    color: var(--warn); }
/* Zustaende, die nichts mit Sichtbarkeit zu tun haben - etwa der einer
   Schluesselgeneration. Farblich wie public/private, aber eigener Name:
   "oeffentlich" und "gueltig" sind zwei verschiedene Aussagen. */
/* Ein Hinweis direkt unter einer Tabelle stiess sonst an deren Unterkante -
   .field-hint hat bewusst keinen oberen Abstand, weil es sonst unter jedem
   Eingabefeld zu luftig waere. Deshalb hier gezielt statt global. */
/* Geraeteliste im Konto: Bezeichnung links, Knopf rechts, bricht auf schmalen
   Schirmen um. Bewusst eine Liste statt einer Tabelle - es sind zwei bis drei
   Zeilen mit je einer Angabe, dafuer waeren Spaltenkoepfe mehr Aufwand als
   Nutzen. */
.geraeteliste { list-style: none; margin: 0; padding: 0; }
/* Die Lesebreite aus ".card > ul" gilt hier nicht: das ist kein Fliesstext,
   sondern eine Zeile je Geraet mit einer Aktion rechts. Mit 62ch endete die
   Liste bei halber Kartenbreite, und der Knopf stand mitten im Nichts.
   Spezifitaet: zwei Klassen (0-2-0) schlagen Klasse+Element (0-1-1). */
.card > .geraeteliste { max-width: none; }
.geraeteliste li {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem 1rem;
  align-items: center;
  justify-content: space-between;
  padding: .7rem 0;
  border-top: var(--border-w) solid var(--border);
}
.geraeteliste li:first-child { border-top: 0; }
/* Der Textblock darf schrumpfen, damit der Knopf rechts stehen bleibt. Ohne
   flex-basis und min-width:0 schob ein langer Hinweis ihn in die naechste
   Zeile - und das sah bei jeder Zeile anders aus, je nach Textlaenge. */
.geraeteliste li > div { flex: 1 1 20rem; min-width: 0; }
.geraeteliste .field-hint { margin: .15rem 0 0; max-width: none; }
.geraeteliste__frage { display: flex; gap: .5rem; align-items: center; flex-wrap: wrap; }
.geraeteliste__frage span { font-size: .9rem; }

.table-wrap + .field-hint { margin-top: .6rem; }

.badge--ok      { background: var(--success-soft); color: var(--success); }
.badge--err     { background: var(--danger-soft);  color: var(--danger); }
/* Ohne eigene Farbe: im Verlauf stehen Fahrzeug, Tasten und CVs
   nebeneinander, und eine dritte Signalfarbe waere Laerm ohne Aussage. */
.badge--neutral { background: rgba(127, 127, 127, .22); color: var(--text-muted); }

.detail__meta dd .badge { vertical-align: middle; }
.detail__meta dd .muted { font-size: .85rem; }

/* Der Kopfbereich kann farbig sein - Knoepfe darin erben seine Textfarbe. */
.site-header .btn {
  color: var(--header-text);
  border-color: var(--header-muted);
  background: transparent;
}
.site-header .btn:hover {
  color: var(--header-text);
  background: rgba(127, 127, 127, .18);
  border-color: var(--header-text);
}

/* ---------- Darstellungs-Umschalter ---------- */

.appearance { position: relative; }
.appearance > summary { list-style: none; cursor: pointer; user-select: none; }
.appearance > summary::-webkit-details-marker { display: none; }
.appearance > summary::after { content: " ▾"; }
.appearance[open] > summary::after { content: " ▴"; }

.appearance__panel {
  position: absolute;
  right: 0;
  top: calc(100% + .5rem);
  z-index: 20;
  min-width: 250px;
  padding: 1rem;
  background: var(--surface);
  color: var(--text);
  border: var(--border-w) solid var(--border);
  border-radius: var(--radius);
  box-shadow: 0 8px 24px rgba(16, 24, 40, .18);
}
.appearance__panel label {
  display: block;
  font-size: .85rem;
  font-weight: 600;
  margin: .7rem 0 .25rem;
}
.appearance__panel label:first-of-type { margin-top: 0; }
.appearance__panel .btn { margin-top: 1rem; width: 100%; }

/* ---------- Hauptmenü ---------- */

.mainnav {
  border-top: var(--border-w) solid var(--header-border);
  overflow-x: auto;
}

.mainnav ul {
  display: flex;
  gap: .25rem;
  list-style: none;
  margin: 0 auto;
  padding: 0 1.25rem;
  max-width: 1280px;
}

.mainnav a {
  display: block;
  padding: .8rem .95rem;
  color: var(--header-muted);
  text-decoration: none;
  font-weight: 500;
  font-size: .95rem;
  white-space: nowrap;
  border-bottom: 3px solid transparent;
  transition: color .15s, border-color .15s;
}

.mainnav a:hover { color: var(--header-text); text-decoration: none; }
.mainnav a.is-active {
  color: var(--header-text);
  border-bottom-color: var(--nav-active);
  font-weight: 600;
}

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

.layout {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1.5rem;
  max-width: 1280px;
  margin: 0 auto;
  padding: 1.5rem 1.25rem 3rem;
}

.layout--with-aside { grid-template-columns: 210px minmax(0, 1fr); }

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

.submenu a {
  display: block;
  padding: .55rem .75rem;
  margin-bottom: .15rem;
  border: var(--border-w) solid transparent;
  border-radius: var(--radius-sm);
  color: var(--text-muted);
  text-decoration: none;
  font-size: .93rem;
}

.submenu a:hover { background: var(--surface); color: var(--text); }
.submenu a.is-active {
  background: var(--accent-soft);
  border-color: var(--accent);
  color: var(--accent);
  font-weight: 600;
}

.content { min-width: 0; }

/* ---------- Bausteine ---------- */

.card {
  background: var(--surface);
  border: var(--border-w) solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 1.25rem;
  margin-bottom: 1.25rem;
}

.card--narrow { max-width: 460px; }
.card--welcome p:last-child { margin-bottom: 0; }

.card--link {
  display: block;
  text-decoration: none;
  color: inherit;
  transition: border-color .15s, transform .15s;
}
.card--link:hover { border-color: var(--accent); transform: translateY(-2px); text-decoration: none; }

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

.notice {
  padding: .8rem 1rem;
  border-radius: var(--radius-sm);
  border: var(--border-w) solid var(--border);
  background: var(--surface);
  margin: 0 0 1rem;
  font-size: .93rem;
}
.notice-error   { border-color: var(--danger);  background: var(--danger-soft);  color: var(--danger); }
.notice-success { border-color: var(--success); background: var(--success-soft); color: var(--success); }
.notice-info    { border-color: var(--accent);  background: var(--accent-soft);  color: var(--text); }
/* Die Warnfarben gab es als Variablen und als .badge--warn, aber nicht als
   Hinweiskasten - eine Meldung mit .notice-warn fiel deshalb stumm auf das
   neutrale Kaestchen zurueck und sah aus wie eine Beilaeufigkeit. Genau das
   soll eine ablaufende Lizenz nicht. */
.notice-warn    { border-color: var(--warn-line); background: var(--warn-soft); color: var(--warn); }

.list { margin: 0; padding-left: 1.1rem; color: var(--text-muted); font-size: .93rem; }

.grid-3 {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 1rem;
}

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

.form { display: flex; flex-direction: column; gap: .3rem; }
.form label { font-size: .88rem; font-weight: 600; margin-top: .6rem; }

.form--grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: .75rem 1rem;
  /*
   * start, nicht end.
   *
   * Mit "end" richtet das Raster die UNTERKANTEN aus. Sobald ein Feld einen
   * Hinweis darunter hat und das Nachbarfeld nicht - oder der eine Hinweis
   * zwei Zeilen braucht und der andere eine -, stehen die Eingabefelder auf
   * verschiedenen Hoehen. Genau so sah das Formular der Bahngesellschaften
   * aus: Kuerzel und Name unten, Von und Bis zwei Zeilen hoeher, das
   * Auswahlfeld dazwischen.
   *
   * Mit "start" fluchten die Beschriftungen oben, damit auch die
   * Eingabefelder, und die Hinweise haengen unterschiedlich weit nach unten -
   * was niemanden stoert.
   */
  align-items: start;
}
.form--grid label { display: block; margin: 0 0 .25rem; }
.form--grid > div { min-width: 0; }
.form__actions { grid-column: 1 / -1; display: flex; gap: .6rem; }

/* Stillgelegte Zeile: zurueckgenommen, aber lesbar - sie wird nie geloescht
   und muss dauerhaft gut zu erfassen bleiben. Nur ausgrauen reichte nicht,
   der Kontrast fiel unter das, was man im Register noch bequem liest. */
/* Eine technische Kennung mitten im Fliesstext soll nicht umbrechen - sonst
   steht die Haelfte von "lodi-con" in der naechsten Zeile und sieht aus wie
   zwei verschiedene Namen. */
.field-hint code { white-space: nowrap; }

/* Ein vollstaendiger Schluessel in einer Tabellenzelle. Die Breite haelt ihn
   auf zwei Zeilen zu vier Achtergruppen - genau die Einteilung des
   Seed-Papiers, sonst zaehlt man beim Vergleichen die Stellen ab. */
code.schluessel {
  display: inline-block;
  max-width: 19rem;
  line-height: 1.5;
}

.zeile--still td { opacity: .72; }
.zeile--still .cell--strong { font-weight: 500; }

/* Feld ueber die volle Breite des Rasters */
.span-2 { grid-column: 1 / -1; }

/* Formular links in fester Breite, daneben Platz fuer Erlaeuterungen.
   Untereinander stehende Felder lesen sich besser als ein Raster, und der
   freiwerdende Raum wird sinnvoll genutzt statt leer zu bleiben. */
.form-layout {
  display: grid;
  grid-template-columns: minmax(0, 460px) minmax(0, 1fr);
  gap: 2rem;
  align-items: start;
}

.form--stack { display: block; }
.form--stack .field { margin-bottom: 1.1rem; }
.form--stack .field:last-of-type { margin-bottom: 0; }
.form--stack label {
  display: block;
  margin: 0 0 .3rem;
  font-size: .88rem;
  font-weight: 600;
}
.form--stack .form__actions { margin-top: 1.5rem; }

.form-aside > * { margin-top: 0; }
.form-aside p { font-size: .92rem; }
.form-aside .card { margin-bottom: 1rem; }
.form-aside .card:last-child { margin-bottom: 0; }

/* ---------- Schiebeschalter privat / oeffentlich ----------
   Ohne JavaScript: das Kaestchen bleibt ein echtes <input type=checkbox> und
   wird nur unsichtbar gemacht (nicht display:none, sonst waere es nicht mehr
   mit der Tastatur erreichbar). Aussehen und der eingeblendete Hinweis haengen
   an :checked und Geschwister-Selektoren - dadurch stimmt die Anzeige auch bei
   abgeschaltetem Skript, und der Formularwert bleibt derselbe wie vorher. */

.field-label {
  display: block;
  margin: 0 0 .4rem;
  font-size: .88rem;
  font-weight: 600;
}

.toggle__input {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: 0;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}

/* Drei feste Spalten: Beschriftung - Spur - Beschriftung. Im Fluss konnte die
   Spur in den Text laufen; als Raster hat jedes Teil seinen eigenen Platz.
   Masse in em, damit der Schalter bei allen vier Schriftgroessen mitwaechst. */
.toggle {
  display: inline-grid;
  grid-template-columns: auto auto auto;
  align-items: center;
  gap: .7em;
  cursor: pointer;
  user-select: none;
  font-size: .95rem;
  line-height: 1.2;
}

/* Muss die allgemeine Label-Regel des gestapelten Formulars ueberstimmen:
   ".form--stack label" setzt display:block und zerlegt den Schalter sonst. */
.form--stack label.toggle {
  display: inline-grid;
  font-weight: 400;
  margin: 0;
}

.toggle__track {
  position: relative;
  width: 3.25em;
  height: 1.75em;
  border-radius: 999px;
  background: var(--border);
  border: var(--border-w) solid var(--border);
  transition: background .18s, border-color .18s;
}

.toggle__thumb {
  position: absolute;
  top: 50%;
  left: .25em;
  width: 1.25em;
  height: 1.25em;
  border-radius: 50%;
  background: var(--surface);
  box-shadow: 0 1px 2px rgba(0, 0, 0, .35);
  transform: translateY(-50%);
  transition: transform .18s;
}

.toggle__side { color: var(--text-muted); transition: color .18s; white-space: nowrap; }

/* aus = privat */
.toggle__input:not(:checked) ~ .toggle .toggle__side--off {
  color: var(--text);
  font-weight: 600;
}

/* an = oeffentlich */
.toggle__input:checked ~ .toggle .toggle__track {
  background: var(--success);
  border-color: var(--success);
}
/* Weg = Spurbreite minus Daumen minus beide Abstaende: 3.25 - 1.25 - .5 */
.toggle__input:checked ~ .toggle .toggle__thumb {
  transform: translateY(-50%) translateX(1.5em);
}
.toggle__input:checked ~ .toggle .toggle__side--on {
  color: var(--success);
  font-weight: 600;
}

.toggle__input:focus-visible ~ .toggle .toggle__track {
  outline: 3px solid var(--focus);
  outline-offset: 2px;
}

/* Im Kontrastmodus darf Farbe kein alleiniges Unterscheidungsmerkmal sein.
   Das leisten hier die Position des Daumens und die fette aktive Beschriftung,
   die zusaetzlich unterstrichen wird - kein Farbwert noetig. */
:root[data-theme="kontrast"] .toggle__input:not(:checked) ~ .toggle .toggle__side--off,
:root[data-theme="kontrast"] .toggle__input:checked ~ .toggle .toggle__side--on {
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* ---------- Urheberrechts-Hinweis ----------
   Nur sichtbar, wenn der Schalter auf oeffentlich steht. */

.copyright-note {
  display: none;
  margin: .9rem 0 0;
  padding: .7rem .9rem;
  font-size: .9rem;
  color: var(--warn);
  background: var(--warn-soft);
  border: var(--border-w) solid var(--warn-line);
  border-left-width: 4px;
  border-radius: var(--radius-sm);
}
.toggle__input:checked ~ .copyright-note { display: block; }
.copyright-note strong { font-weight: 700; }
/* Derselbe Kasten ohne Schalter davor - fuer Warnungen, die immer stehen. */
.copyright-note--static { display: block; }

/* Nur fuer Screenreader: eine Spaltenueberschrift, die optisch leer bleiben
   soll, darf im Markup nicht leer sein. */
.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

@media (max-width: 900px) {
  .form-layout { grid-template-columns: 1fr; gap: 1.25rem; }
}

.field-hint {
  margin: .3rem 0 0;
  font-size: .8rem;
  color: var(--text-muted);
}


input[type=file] {
  width: 100%;
  padding: .5rem;
  border: var(--border-w) dashed var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg);
  color: var(--text);
  font: inherit;
  font-size: .9rem;
}
input[type=file]:focus { border-color: var(--accent); border-style: solid; }

.edit-preview {
  margin-bottom: 1.25rem;
  padding-bottom: 1.25rem;
  border-bottom: var(--border-w) solid var(--border);
}
.edit-preview img {
  max-width: 100%;
  height: auto;
  border-radius: var(--radius-sm);
  display: block;
}
.edit-preview p { margin: .5rem 0 0; font-size: .85rem; }

.detail__actions { margin: 1.25rem 0 0; }

/* textarea gehoert in dieselbe Liste. Fehlte sie, blieb in Firefox die
   Vorgabefarbe stehen - also weisser Hintergrund mit dunkler Schrift, auch im
   dunklen Farbschema. */
input[type=text], input[type=email], input[type=password],
input[type=search], input[type=number], select, textarea {
  width: 100%;
  padding: .55rem .7rem;
  border: var(--border-w) solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text);
  font: inherit;
  font-size: .95rem;
}

textarea {
  /* Nur senkrecht: waagerechtes Ziehen sprengt das Raster des Formulars. */
  resize: vertical;
  min-height: 5.5rem;
  line-height: 1.5;
}

input:focus, select:focus, textarea:focus { border-color: var(--accent); }

.btn {
  display: inline-block;
  padding: .55rem 1rem;
  border: var(--border-w) solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text);
  font: inherit;
  font-size: .93rem;
  font-weight: 500;
  text-decoration: none;
  cursor: pointer;
  white-space: nowrap;
  transition: background .15s, border-color .15s;
}
.btn:hover { border-color: var(--accent); color: var(--accent); text-decoration: none; }

.btn--primary {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}

/* Der Abstand ueber dem Absende-Knopf gehoert an die Stelle, wo er gebraucht
   wird: als letztes Element eines gestapelten Formulars. Frueher stand er an
   .btn--primary selbst - dadurch bekam JEDE Knopfleiste mit einem primaeren
   Knopf einen Versatz nach unten, und weil diese Leisten Flex-Container mit
   dem Vorgabewert "stretch" sind, wurde der Knopf zugleich niedriger als
   seine Nachbarn. Gegengesteuert wurde mit einer Liste von Ausnahmen, die bei
   jeder neuen Leiste erweitert werden musste - vergessen wurde sie zuletzt in
   der Kopfzeile.
   Der Kindselektor trifft nur direkte Kinder: in .form__actions,
   .filterbar__actions und dergleichen steckt der Knopf eine Ebene tiefer und
   bleibt damit von selbst aussen vor. */
form > .btn--primary { margin-top: 1rem; }
.btn--primary:hover { background: var(--accent-dark); border-color: var(--accent-dark); color: #fff; }
.site-header .btn--primary { background: var(--accent); border-color: var(--accent); color: #fff; }

.btn--ghost { background: transparent; }

/* Gemischte Leisten aus <button> und <a class="btn">: mittig statt gestreckt,
   damit eine kuenftige Abweichung in der Hoehe nicht wieder als Versatz
   auffaellt. Nur .form__actions - die anderen Leisten sind entweder schon
   flex mit eigener Ausrichtung oder enthalten nur einen Knopf. */
.form__actions { align-items: center; }

/* Fuer Aktionen, die sich nicht rueckgaengig machen lassen. */
.btn--danger {
  background: var(--danger);
  border-color: var(--danger);
  color: #fff;
}
.btn--danger:hover { background: var(--danger); border-color: var(--danger); color: #fff; filter: brightness(.9); }
:root[data-theme="kontrast"] .btn--danger { color: #fff; }
.btn--small { padding: .3rem .6rem; font-size: .85rem; }

.filterbar { display: flex; gap: .6rem; margin-bottom: 1.25rem; flex-wrap: wrap; }
.filterbar input[type=search] { max-width: 320px; }
/* Auswahlfelder erben sonst die 100% aus der Formularregel weiter unten. Die
   Angabe muss spezifischer sein als "select" allein - bei gleicher
   Spezifitaet gewaenne die spaetere Regel, und das waere die andere. */
.filterbar select { width: auto; min-width: 10rem; }

/* Mehrspaltige Filterleiste: wächst mit dem Platz, bricht auf schmalen
   Bildschirmen von selbst um. */
.filterbar--grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
  gap: .75rem 1rem;
  align-items: end;
  padding: 1rem;
  background: var(--surface);
  border: var(--border-w) solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}
.filterbar--grid label {
  display: block;
  font-size: .82rem;
  font-weight: 600;
  color: var(--text-muted);
  margin-bottom: .25rem;
}
.filterbar--grid input[type=search] { max-width: none; }
.filterbar__actions { display: flex; gap: .5rem; align-items: end; }

/* ---------- Seitennavigation ---------- */

.pager {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: .75rem;
  margin-top: 1.25rem;
}
.pager__info { color: var(--text-muted); font-size: .9rem; }
.pager__nav { display: flex; align-items: center; gap: .4rem; }
.pager__page { font-size: .9rem; padding: 0 .5rem; white-space: nowrap; }

.btn.is-disabled {
  opacity: .45;
  cursor: default;
  pointer-events: none;
}

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

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

table.data { width: 100%; border-collapse: collapse; font-size: .93rem; }

table.data th {
  text-align: left;
  font-size: .78rem;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--text-muted);
  padding: .7rem .9rem;
  border-bottom: var(--border-w) solid var(--border);
  white-space: nowrap;
}

table.data td { padding: .7rem .9rem; border-bottom: var(--border-w) solid var(--border); }
table.data tbody tr:last-child td { border-bottom: none; }
table.data tbody tr:hover { background: var(--accent-soft); }
.cell--strong { font-weight: 600; }

/* Fahrzeug-Detailansicht: Bild oben ueber die ganze Breite, darunter die vier
   Rubriken als Spalten. Lokbilder sind breit und niedrig - neben den Angaben
   blieben sie winzig. */
.lok-detail__image {
  display: flex;
  justify-content: center;
  margin: .8rem 0 1.4rem;
}
.lok-detail__image img {
  max-width: 100%;
  height: auto;
  border-radius: var(--radius-sm);
}

.lok-detail__cols {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 1.2rem 1.6rem;
}
.lok-detail__cols > section { min-width: 0; }
.lok-detail__cols h3 { margin: 0 0 .6rem; }
/* In einer Viertelspalte ist kein Platz fuer Bezeichnung und Wert
   nebeneinander - deshalb hier untereinander statt im zweispaltigen
   Raster aus .detail__meta.
   Der Doppelselektor ist noetig: ".detail__meta dl" steht weiter unten in
   dieser Datei und hat dieselbe Spezifikitaet, waere also stärker. Beide
   Klassen haengen am selben Element. */
.detail__meta.lok-detail__cols dl { grid-template-columns: 1fr; gap: 0; }
.detail__meta.lok-detail__cols dt { margin-top: .55rem; }
.detail__meta.lok-detail__cols dt:first-child { margin-top: 0; }
.detail__meta.lok-detail__cols dd { overflow-wrap: anywhere; }
.detail__meta.lok-detail__cols dd .muted { display: block; font-size: .8rem; }

.lok-detail__actions { margin: 0 0 .4rem; }
.lok-detail__text { margin-top: 1.6rem; max-width: 70ch; }
.lok-detail__stamps { margin-top: 1.6rem; font-size: .85rem; }

@media (max-width: 1100px) {
  .lok-detail__cols { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 620px) {
  .lok-detail__cols { grid-template-columns: 1fr; }
}

/* Fahrzeug-Formular: dieselben vier Rubriken wie in der Detailansicht, jede
   in einer eigenen Karte. Die Felder darin nebeneinander, solange Platz ist. */
.lok-form__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: .5rem 1.2rem;
}
.lok-form__field { min-width: 0; }
.lok-form__field label {
  display: block;
  font-size: .88rem;
  font-weight: 600;
  margin: .6rem 0 .25rem;
}
/* Das von der API beanstandete Feld hervorheben - die Meldung darunter allein
   wuerde man in einem Formular mit zwanzig Feldern uebersehen. */
.lok-form__field--error input,
.lok-form__field--error select,
.lok-form__field--error textarea { border-color: var(--danger); }
.field-error {
  margin: .3rem 0 0;
  font-size: .8rem;
  font-weight: 600;
  color: var(--danger);
}
.lok-form__suche {
  display: flex;
  flex-wrap: wrap;
  align-items: end;
  gap: .5rem;
  margin-bottom: .4rem;
}
.lok-form__suche label {
  flex: 0 0 100%;
  font-size: .88rem;
  font-weight: 600;
}
.lok-form__suche input { flex: 1 1 220px; min-width: 0; }

#bildwahl-treffer:empty { margin: 0; }

/* Bildauswahl als Kachelraster. Radio-Felder in <label>n - damit funktioniert
   die Auswahl auch ohne JavaScript, und die Bilder sind sichtbar, was ein
   <select> nicht kann. */
.bildwahl {
  border: var(--border-w) solid var(--border);
  border-radius: var(--radius-sm);
  padding: .3rem .8rem .8rem;
  margin: .6rem 0 0;
  min-width: 0;
}
.bildwahl--error { border-color: var(--danger); }
.bildwahl legend { font-size: .88rem; font-weight: 600; padding: 0 .3rem; }

/* Eingeklappte Bildauswahl. Die Zusammenfassung zeigt zugeklappt, was
   gewaehlt ist - mit Vorschaubild, damit man es nicht aufklappen muss. */
.bildwahl__klapp > summary {
  display: flex;
  align-items: center;
  gap: .6rem;
  cursor: pointer;
  padding: .35rem .2rem;
  border-radius: var(--radius-sm);
  font-size: .93rem;
}
.bildwahl__klapp > summary:hover { color: var(--accent); }
.bildwahl__klapp > summary:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.bildwahl__vorschau { display: flex; flex: 0 0 auto; }
.bildwahl__vorschau img {
  max-width: 110px;
  max-height: 44px;
  border-radius: var(--radius-sm);
  display: block;
}
/* Ohne Bild soll die Zusammenfassung nicht auseinanderfallen. */
.bildwahl__vorschau:empty { display: none; }
.bildwahl__gewaehlt { min-width: 0; overflow-wrap: anywhere; }
.bildwahl__klapp[open] > summary { margin-bottom: .4rem; }

.bildwahl__gruppe { margin-top: .9rem; }
.bildwahl__titel {
  margin: 0 0 .4rem;
  font-size: .82rem;
  font-weight: 600;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: .04em;
}
.bildwahl__raster {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: .5rem;
}
.bildwahl__raster--leer { grid-template-columns: minmax(150px, 200px); }

.bildkachel {
  /* position: relative, weil das Radio-Feld darin absolut liegt - sonst
     bezieht es sich auf einen weiter aussen liegenden Vorfahren. */
  position: relative;
  display: block;
  cursor: pointer;
  border: var(--border-w) solid var(--border);
  border-radius: var(--radius-sm);
  padding: .3rem;
  background: var(--surface);
  /* Die Vorgabe .form label { margin-top: .6rem } wuerde die Kacheln einer
     Reihe gegeneinander verschieben. */
  margin: 0;
  font-weight: 400;
  min-width: 0;
}
.bildkachel:hover { border-color: var(--accent); }
/* Das Radio-Feld selbst braucht niemand zu sehen - die Kachel ist der
   Schalter. Nicht display:none und nicht visibility:hidden: dann waere es per
   Tastatur nicht mehr erreichbar. */
.bildkachel input {
  position: absolute;
  top: 0; left: 0;
  width: 1px; height: 1px;
  opacity: 0;
}
.bildkachel__bild {
  display: flex;
  aspect-ratio: 5 / 2;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  background: var(--bg);
  border-radius: var(--radius-sm);
}
.bildkachel__bild img { max-width: 100%; max-height: 100%; display: block; }
.bildkachel__name {
  display: block;
  margin-top: .3rem;
  font-size: .8rem;
  line-height: 1.3;
  overflow-wrap: anywhere;
}
.bildkachel--leer { display: flex; align-items: center; justify-content: center; }
.bildkachel--leer .bildkachel__name { margin: 0; font-size: .88rem; }

/* Gewaehlte Kachel hervorheben. Der Rahmen haengt am Geschwisterselektor
   (das Radio-Feld steht vor den Spans) und greift damit in jedem Browser;
   :has() legt darueber nur noch den Rahmen um die ganze Kachel. */
.bildkachel input:checked ~ .bildkachel__bild {
  box-shadow: inset 0 0 0 2px var(--accent);
}
.bildkachel input:checked ~ .bildkachel__name {
  color: var(--accent);
  font-weight: 600;
}
.bildkachel:has(input:checked) { border-color: var(--accent); }
/* Sichtbarer Fokus fuer die Tastaturbedienung - ohne ihn waere beim
   Durchtabben nicht zu erkennen, wo man steht. */
.bildkachel:has(input:focus-visible) { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Wird von bildwahl.js beim Filtern gesetzt. */
.bildkachel.is-hidden,
.bildwahl__gruppe.is-hidden { display: none; }

/* --- Funktionstasten ----------------------------------------------------- */

/* Die Symbole aus dem LoDi-Con sind reine schwarze Silhouetten auf
   transparentem Grund (32x32, RGBA). Als <img> waeren sie im dunklen Thema
   praktisch unsichtbar. Deshalb als Maske: die Flaeche bekommt currentColor,
   das Bild bestimmt nur die Form. So sind sie im hellen Thema dunkel, im
   dunklen hell - und im kontrastreichen Modus so kraeftig wie der Text.
   Die Datei-URL kommt je Element ueber --fkey-icon. */
.fkey-icon {
  display: inline-block;
  width: 28px;
  height: 28px;
  flex: 0 0 auto;
  background-color: currentColor;
  -webkit-mask: var(--fkey-icon) center / contain no-repeat;
  mask: var(--fkey-icon) center / contain no-repeat;
}
.fkey-icon--klein { width: 22px; height: 22px; }
/* Platzhalter fuer eine Taste ohne Symbol - haelt die Spalte in der Flucht. */
.fkey-icon--leer { background-color: transparent; }

/* --- Aenderungsverlauf --------------------------------------------------- */

.verlauf { list-style: none; margin: 0; padding: 0; }
.verlauf__eintrag {
  border-left: 3px solid var(--border);
  padding: .5rem 0 .8rem .9rem;
  margin-left: .3rem;
}
.verlauf__eintrag:hover { border-left-color: var(--accent); }
.verlauf__kopf {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: .5rem;
  font-size: .9rem;
}
.verlauf__tat { font-weight: 600; }
.verlauf__zeit, .verlauf__wer { font-size: .85rem; }
.verlauf__felder {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: .1rem .9rem;
  margin: .35rem 0 0;
  font-size: .88rem;
}
.verlauf__felder dt { color: var(--text-muted); }
.verlauf__felder dd { margin: 0; overflow-wrap: anywhere; }
/* Der alte Wert durchgestrichen - so ist die Richtung auch ohne den Pfeil
   erkennbar, etwa im Screenreader. */
.verlauf__alt { text-decoration: line-through; color: var(--text-muted); }
.verlauf__neu { font-weight: 600; }

@media (max-width: 620px) {
  .verlauf__felder { grid-template-columns: 1fr; }
  .verlauf__felder dt { margin-top: .4rem; }
}

/* Belegte Funktionstasten in der Fahrzeug-Detailansicht. */
.lok-detail__fkeys { margin-top: 1.6rem; }
.fkeyliste {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: .3rem .9rem;
  margin: 0;
  padding: 0;
  list-style: none;
}
.fkeyliste__eintrag {
  display: flex;
  align-items: center;
  gap: .5rem;
  min-width: 0;
  font-size: .9rem;
}
.fkeyliste__nr {
  flex: 0 0 2.6rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.fkeyliste__name { min-width: 0; overflow-wrap: anywhere; }

/* Kleinere, neutrale Fassung des Schiebeschalters fuer die Tastenliste.
   Nicht gruen wie beim Sichtbarkeitsschalter: Dauer und Puls sind zwei
   gleichwertige Betriebsarten, keine davon ist "gut" oder "eingeschaltet". */
.toggle--klein { font-size: .82rem; gap: .45em; }
.toggle--klein .toggle__track { width: 2.6em; height: 1.4em; }
.toggle--klein .toggle__thumb { width: 1em; height: 1em; left: .2em; }
.toggle__input:checked ~ .toggle--klein .toggle__thumb {
  transform: translateY(-50%) translateX(1.2em);
}
.toggle__input:checked ~ .toggle--neutral .toggle__track {
  background: var(--accent);
  border-color: var(--accent);
}
.toggle__input:checked ~ .toggle--neutral .toggle__side--on { color: var(--accent); }

table.data.fkeys td { padding: .3rem .9rem; }
.fkeys__bild {
  width: 56px;
  height: 32px;
}
/* Tasten jenseits dessen, was mfx kann - sichtbar, aber zurueckgenommen. */
.fkeys__jenseits { opacity: .6; }

/* Anker fuer die aufgeklappte Liste - das Skript haengt sie an die Zelle des
   Eingabefeldes. Bewusst ueber eine eigene Klasse statt ueber td:last-child:
   mit der Spalte "Betriebsart" war die letzte Zelle nicht mehr die richtige,
   und die Liste fiel mangels positioniertem Vorfahren an den Bildschirmrand. */
table.data.fkeys td.fkeys__zelle { position: relative; }
.fkeys__wahl { max-width: 26rem; }
.fkeys__wahl--error { border-color: var(--danger); }

.fkeys__panel {
  position: absolute;
  z-index: 20;
  left: .9rem;
  right: .9rem;
  max-width: 26rem;
  max-height: 19rem;
  overflow-y: auto;
  margin-top: .15rem;
  padding: .25rem;
  background: var(--surface);
  border: var(--border-w) solid var(--accent);
  border-radius: var(--radius-sm);
  box-shadow: 0 6px 20px rgba(0, 0, 0, .25);
}
.fkeys__treffer {
  display: flex;
  align-items: center;
  gap: .6rem;
  width: 100%;
  padding: .3rem .4rem;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text);
  font: inherit;
  font-size: .9rem;
  text-align: left;
  cursor: pointer;
}
.fkeys__treffer:hover,
.fkeys__treffer:focus-visible { background: var(--accent-soft); color: var(--accent); }
.fkeys__treffer-bild {
  flex: 0 0 30px;
  height: 26px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.fkeys__treffer-name { min-width: 0; overflow-wrap: anywhere; }
.fkeys__leer {
  margin: 0;
  padding: .4rem;
  font-size: .85rem;
  color: var(--text-muted);
}

/* Kundenauswahl beim Ausstellen einer Lizenz (assets/kundenwahl.js).

   Gleiches Erscheinungsbild wie die Symbolauswahl darueber, aber eigene
   Geometrie statt gemeinsamer Regeln: dort sitzt das Feld in einer
   Tabellenzeile und die Liste braucht feste Raender, hier sitzt es in einem
   Formularraster und soll genau so breit sein wie das Feld. Ein gemeinsames
   Regelwerk muesste beides koennen und waere an beiden Stellen ein Kompromiss.

   Ohne JavaScript entsteht nichts davon - dann steht dort ein schlichtes
   Eingabefeld. */
.kundenwahl { position: relative; }
.kundenwahl__panel {
  position: absolute;
  z-index: 20;
  left: 0;
  right: 0;
  max-height: 19rem;
  overflow-y: auto;
  margin-top: .15rem;
  padding: .25rem;
  background: var(--surface);
  border: var(--border-w) solid var(--accent);
  border-radius: var(--radius-sm);
  box-shadow: 0 6px 20px rgba(0, 0, 0, .25);
}
.kundenwahl__treffer {
  display: block;
  width: 100%;
  padding: .35rem .45rem;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text);
  font: inherit;
  font-size: .9rem;
  text-align: left;
  cursor: pointer;
}
.kundenwahl__treffer:hover,
.kundenwahl__treffer:focus-visible,
.kundenwahl__treffer[aria-selected="true"] {
  background: var(--accent-soft);
  color: var(--accent);
}
.kundenwahl__name { display: block; overflow-wrap: anywhere; }
.kundenwahl__mail {
  display: block;
  font-size: .8rem;
  color: var(--text-muted);
  overflow-wrap: anywhere;
}
/* Beim Ueberfahren traegt die ganze Zeile die Akzentfarbe - die gedaempfte
   Adresse darunter wuerde sonst stehenbleiben und fremd wirken. */
.kundenwahl__treffer:hover .kundenwahl__mail,
.kundenwahl__treffer[aria-selected="true"] .kundenwahl__mail { color: inherit; }
.kundenwahl__ruht {
  margin-left: .4rem;
  font-size: .75rem;
  font-style: italic;
  color: var(--text-muted);
}
.kundenwahl__treffer:hover .kundenwahl__ruht,
.kundenwahl__treffer[aria-selected="true"] .kundenwahl__ruht { color: inherit; }
.kundenwahl__leer {
  margin: 0;
  padding: .4rem;
  font-size: .85rem;
  color: var(--text-muted);
}

/* Vorschaubild in der Fahrzeugliste. Feste Zellenbreite, damit die
   Bezeichnung daneben nicht bei jeder Zeile springt. */
.cell--thumb { width: 130px; padding: .35rem .9rem; }
.cell--thumb img {
  display: block;
  max-width: 120px;
  height: auto;
  border-radius: var(--radius-sm);
}

/* ---------- Bildergalerie ---------- */

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

.tile {
  display: flex;
  flex-direction: column;
  gap: .5rem;
  padding: .75rem;
  background: var(--surface);
  border: var(--border-w) solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  text-decoration: none;
  color: inherit;
  transition: border-color .15s, transform .15s;
}
.tile:hover { border-color: var(--accent); transform: translateY(-2px); text-decoration: none; }

.tile__frame {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 110px;
  background: var(--bg);
  border-radius: var(--radius-sm);
  overflow: hidden;
}
.tile__frame img { max-width: 100%; height: auto; display: block; }
.tile__label { font-size: .9rem; font-weight: 500; overflow-wrap: anywhere; }

.detail { display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); gap: 1.5rem; }
.detail__image { display: flex; align-items: flex-start; justify-content: center; }
.detail__image img { max-width: 100%; height: auto; border-radius: var(--radius-sm); }
.detail__meta dl { display: grid; grid-template-columns: auto 1fr; gap: .4rem .9rem; margin: 0; }
.detail__meta dt { color: var(--text-muted); font-size: .85rem; }
.detail__meta dd { margin: 0; font-size: .93rem; }

/* ---------- Fußbereich ---------- */

.site-footer {
  border-top: var(--border-w) solid var(--border);
  padding: 1.25rem;
  display: flex;
  gap: 1rem;
  justify-content: center;
  color: var(--text-muted);
  font-size: .87rem;
}

/* ---------- Bewegung reduzieren ---------- */

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
  .card--link:hover, .tile:hover { transform: none; }
}

/* ---------- Schmale Bildschirme ---------- */

@media (max-width: 860px) {
  .layout--with-aside { grid-template-columns: 1fr; }
  .submenu ul { display: flex; flex-wrap: wrap; gap: .3rem; }
  .site-title { font-size: 1.05rem; padding-left: .9rem; }
  .brand img { height: 34px; }
  .detail { grid-template-columns: 1fr; }
}

@media (max-width: 560px) {
  .site-header__inner { flex-wrap: wrap; gap: .75rem; }
  .account { width: 100%; margin-left: 0; justify-content: space-between; }
  .site-title { border-left: none; padding-left: 0; }
  .appearance__panel { right: auto; left: 0; }
}

/* --- CV-Werte ------------------------------------------------------------ */

/* Anzeige in der Fahrzeug-Detailansicht, gleiche Bauart wie .fkeyliste. */
.lok-detail__cvs { margin-top: 1.4rem; }
.cvliste {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
  gap: .25rem .9rem;
  margin: 0;
  padding: 0;
  list-style: none;
}
.cvliste__eintrag {
  display: flex;
  align-items: baseline;
  gap: .5rem;
  min-width: 0;
  font-size: .9rem;
}
.cvliste__nr {
  flex: 0 0 4.2rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
/* Rechtsbuendig und mit gleich breiten Ziffern: so stehen die Werte
   untereinander und lassen sich spaltenweise ueberfliegen. */
.cvliste__wert {
  flex: 0 0 2.6rem;
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.cvliste__name { min-width: 0; overflow-wrap: anywhere; font-size: .82rem; }

table.data.cvs td { padding: .35rem .9rem; vertical-align: top; }
/* Das Wertfeld nur so breit wie noetig - 255 sind drei Stellen, und ein
   Feld ueber die halbe Spalte sieht nach mehr Eingabe aus als gemeint. */
.cvs__wert { width: 6.5rem; font-variant-numeric: tabular-nums; }
/* Die Nummer ist eine Kombobox: "29 – Konfiguration" muss hineinpassen,
   sonst sieht der Vorschlag abgeschnitten aus. */
.cvs__nr { width: 100%; max-width: 18rem; }
.cvs__wert--error { border-color: var(--danger); }
.cvs__bedeutung { font-size: .88rem; max-width: 46rem; }
/* Der Beschreibungstext in eine eigene Zeile unter den Namen. */
.cvs__desc { display: block; margin-top: .15rem; }
.cvs__bits {
  margin: .3rem 0 0;
  padding-left: 1.1rem;
  font-size: .82rem;
}
/* Leerzeilen zum Anlegen - abgesetzt, damit der Bestand erkennbar bleibt. */
.cvs__neu td { background: rgba(127, 127, 127, .06); }

/* --- Geschwindigkeitskennlinie ------------------------------------------- */

.lok-detail__speed { margin-top: 1.4rem; }

/* Das SVG bringt sein Seitenverhaeltnis ueber die viewBox mit und skaliert
   mit der Breite. max-width, damit die Kurve auf einem breiten Bildschirm
   nicht ins Absurde waechst. */
.speedchart {
  max-width: 46rem;
  margin: .6rem 0;
}
.speedchart__svg {
  display: block;
  width: 100%;
  height: auto;
}

/* Farben aus den Themenvariablen - die Grafik muss hell wie dunkel lesbar
   sein, und ein fest eingetragenes Schwarz waere im dunklen Thema unsichtbar. */
.speedchart__grid line {
  stroke: var(--border);
  stroke-width: 1;
}
.speedchart__achsen line {
  stroke: var(--text-muted);
  stroke-width: 1.5;
}
.speedchart__labels text,
.speedchart__achsname {
  fill: var(--text-muted);
  font-size: 12px;
}
.speedchart__achsname { font-size: 11px; }

.speedchart__linie {
  fill: none;
  stroke: var(--accent);
  stroke-width: 2.5;
  stroke-linejoin: round;
  stroke-linecap: round;
}
/* Nur angedeutet: die Flaeche soll die Kurve heben, nicht das Gitter
   zudecken. */
.speedchart__flaeche {
  fill: var(--accent);
  fill-opacity: .12;
  stroke: none;
}
.speedchart__punkte circle {
  fill: var(--accent);
  stroke: var(--surface);
  stroke-width: 1.5;
}

/* Zwei Richtungen: vorwaerts gruen, rueckwaerts rot. Nur gesetzt, wenn
   beide vorliegen - bei einer einzelnen Kurve bleibt es bei der Akzentfarbe,
   weil die Farbe dann nichts unterscheidet. */
.speedchart__linie--vor    { stroke: var(--success); }
.speedchart__linie--rueck  { stroke: var(--danger); }
.speedchart__punkte.speedchart__linie--vor circle   { fill: var(--success); }
.speedchart__punkte.speedchart__linie--rueck circle { fill: var(--danger); }

/* Farbe allein traegt die Unterscheidung nicht - fuer Rot-Gruen-Blindheit
   und in Schwarzweiss steht die Richtung als Text in der Legende. */
.speedchart__legende text {
  fill: var(--text-muted);
  font-size: 12px;
}
.speedchart__legende line { stroke-width: 3; }

/* Im Kontrastthema traegt die Farbe allein nicht - dann kraeftiger. */
:root[data-theme="kontrast"] .speedchart__linie { stroke-width: 3.5; }
/* Zusaetzlich zur Farbe eine Strichelung: im Kontrastthema und im Ausdruck
   ist Rot gegen Gruen sonst kaum zu unterscheiden. */
:root[data-theme="kontrast"] .speedchart__linie--rueck { stroke-dasharray: 8 4; }
:root[data-theme="kontrast"] .speedchart__flaeche { fill-opacity: 0; }

.speedchart__werte { margin-top: .6rem; }
.speedchart__werte summary { cursor: pointer; color: var(--text-muted); }
.speedchart__werte .table-wrap { margin-top: .5rem; max-height: 22rem; overflow-y: auto; }

/* --- Nutzerliste im Adminbereich ----------------------------------------- */

/* Zahlen rechtsbuendig und mit gleich breiten Ziffern: so stehen sie
   untereinander und lassen sich spaltenweise ueberfliegen. */
table.data.nutzer .zahl {
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
table.data.nutzer tfoot td {
  border-top: var(--border-w) solid var(--border);
  font-weight: 600;
}
table.data.nutzer tfoot td.muted { font-weight: 400; }
/* Adressen sind lang und duerfen umbrechen, statt die Tabelle zu sprengen. */
.nutzer__mail { overflow-wrap: anywhere; }
.nutzer__frist { font-size: .8rem; white-space: nowrap; }
.nutzer__loeschen { display: inline-flex; gap: .35rem; margin: 0; }

/* --- Tag-Auswahl im Fahrzeugformular ------------------------------------- */

.lok-form__tags { margin-top: 1.2rem; }
/* Fliessende Kaestchen statt einer langen Spalte - zwanzig Tags untereinander
   waeren eine halbe Bildschirmseite. */
.tagwahl {
  display: flex;
  flex-wrap: wrap;
  gap: .4rem .9rem;
}
.tagwahl__eintrag {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  padding: .2rem .5rem .2rem .3rem;
  border: var(--border-w) solid var(--border);
  border-radius: 999px;
  cursor: pointer;
  font-size: .9rem;
}
.tagwahl__eintrag:hover { border-color: var(--accent); }
/* Das gewaehlte Tag deutlich absetzen - bei einem Dutzend Kaestchen ist der
   Haken allein zu leicht zu uebersehen. */
.tagwahl__eintrag:has(input:checked) {
  border-color: var(--accent);
  background: var(--accent-soft);
}
.tagwahl__eintrag input { margin: 0; }

/* Tags in der Fahrzeugliste: mehrere Abzeichen duerfen umbrechen. */
.lokliste__tags { max-width: 22rem; }
.lokliste__tags .badge { display: inline-block; margin: .1rem .15rem .1rem 0; }

/* Eigene Bezeichnung und Symbolname nebeneinander: der Name ist die Hauptsache,
   das Symbol die Nebenangabe. Umbricht auf schmalen Anzeigen unter den Namen. */
.fkeyliste__symbol {
  font-size: .85em;
  margin-left: .4rem;
}
.fkeyliste__symbol::before { content: '· '; }

/* --- Sprachumschalter ----------------------------------------------------- */

/* Zwei Kuerzel im Kopfbereich, das aktive als Text statt als Knopf: man kann
   nicht dorthin wechseln, wo man schon ist. Ein Auswahlfeld mit
   "Uebernehmen" waere bei zwei Sprachen ein Schritt zuviel. */
.langswitch {
  display: inline-flex;
  align-items: center;
  gap: .15rem;
  margin: 0;
}
.langswitch__knopf,
.langswitch__aktiv {
  font: inherit;
  font-size: .8rem;
  font-weight: 600;
  letter-spacing: .03em;
  padding: .25rem .4rem;
  border-radius: var(--radius, 4px);
  line-height: 1;
}
/* Farben aus den KOPF-Variablen, nicht aus den Seitenvariablen.
   Die erste Fassung nahm var(--text) und ein erfundenes var(--surface-2, #eef).
   --surface-2 gibt es nicht, also galt immer der Notwert #eef - fast weiss.
   Im dunklen Thema ist --text hell, und die aktive Sprache stand damit als
   helle Schrift auf hellem Grund: unlesbar. Erfundene Variablennamen fallen
   nicht auf, weil der Notwert im hellen Thema zufaellig passt. */
.langswitch__knopf {
  background: none;
  border: 1px solid transparent;
  color: var(--header-muted);
  cursor: pointer;
}
.langswitch__knopf:hover,
.langswitch__knopf:focus-visible {
  color: var(--header-text);
  border-color: var(--header-border);
}
/* Die aktive Sprache ist Zustand, kein Bedienelement - kein Zeigerwechsel.
   Umgekehrte Kopffarben: --header-text auf --header-bg ist in jedem der fuenf
   Themen ein Kontrastpaar, sonst waere die Kopfzeile selbst unlesbar. Damit
   stimmt es auch im blauen Markenthema, ohne fuer jedes Thema eine eigene
   Regel zu schreiben. */
.langswitch__aktiv {
  color: var(--header-bg);
  background: var(--header-text);
  border: 1px solid var(--header-text);
  cursor: default;
}

/* Vorbehalt ueber den Rechtstexten.
   Ein <div> und kein <p>: ein <form> darf nicht in einem Absatz stehen, der
   Browser schliesst den Absatz sonst davor - der Knopf rutschte dann aus dem
   Kasten heraus. Genau so sah es aus, bis es jemandem auffiel. */
.notice--rechtsvorbehalt { display: block; }
.rechtsvorbehalt__form { display: inline; margin-left: .4rem; }
.rechtsvorbehalt__form .btn { vertical-align: baseline; }

/* --- Seitenkopf und Aktionsspalte ---------------------------------------- */

/* Ueberschrift links, die Aktionen rechts. Zusammen in einer Zeile, damit
   der Knopf zur Ueberschrift gehoert und nicht zum ersten Absatz darunter. */
.seitenkopf {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  margin-bottom: 1rem;
}
.seitenkopf h2 { margin: 0; }

/* Mehr als eine Aktion. Der eigene Flexkasten ist noetig: als zwei einzelne
   Kinder wuerde space-between sie auf beide Enden verteilen und die
   Ueberschrift landete zwischen ihnen. */
.seitenkopf__aktionen {
  display: flex;
  align-items: center;
  gap: .5rem;
  flex-wrap: wrap;
}

/* Knopfleiste in einer Tabellenzeile. Rechtsbuendig und ohne Umbruch: die
   Knoepfe gehoeren zusammen, und einer allein in der naechsten Zeile sieht
   aus, als betraefe er etwas anderes. */
.tabelle__aktionen {
  white-space: nowrap;
  text-align: right;
}
.tabelle__aktionen .btn { margin-left: .3rem; }
.tabelle__aktionen .btn:first-child { margin-left: 0; }
/* Ein <form> um einen einzelnen Knopf soll die Zeile nicht umbrechen. */
.tabelle__aktionen form { display: inline-block; margin: 0; }

/* --- Mehrfachauswahl in der Fahrzeugliste -------------------------------- */

.lokliste__form { margin: 0; }
/* Die Auswahlspalte so schmal wie das Kaestchen. */
.lokliste__wahl { width: 1%; white-space: nowrap; }

/* Die Leiste unter der Tabelle gehoert sichtbar zu ihr - abgesetzt, aber
   ohne Abstand dazwischen, sonst wirkt sie wie ein eigener Block. */
.lokliste__massen {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: .6rem;
  padding: .7rem .9rem;
  margin-top: -1px;
  border: var(--border-w) solid var(--border);
  border-radius: 0 0 var(--radius) var(--radius);
  background: var(--surface);
}
.lokliste__massen label { font-weight: 600; font-size: .9rem; }
/* Ohne diese Breite erbt das Auswahlfeld die 100% der Formularfelder und
   sprengt die Zeile - Beschriftung, Feld und Knoepfe standen untereinander. */
.lokliste__massen select { width: auto; min-width: 12rem; max-width: 20rem; }
