/* =====================================================================
   SHL Hafenlogistik - Stylesheet

   Mobil zuerst. Der entscheidende Unterschied zum Altsystem: die
   Datentabellen brechen auf schmalen Geraeten in Kartenform um, statt
   seitlich aus dem Bild zu laufen. Dafuer traegt jede Zelle im Markup
   ein data-label mit ihrer Spaltenueberschrift.
   ===================================================================== */

:root {
  --paper:     #eef0f1;
  --surface:   #ffffff;
  --surface-2: #f5f7f8;
  /* Hintergrund der Eingabefelder - getrennt von den Karten, damit sich
     ein zarter Ton (z. B. seichtes Gelb) nur auf Felder legt. Wählbar
     unter Einstellungen › Design; siehe App\Support\UiTheme. */
  --input-bg:  var(--surface);
  --ink:       #17202a;
  --ink-2:     #56636c;
  --ink-3:     #8b959c;
  --rule:      #d5dadd;
  --rule-soft: #e6eaec;
  --accent:    #9c3d19;
  --accent-2:  #f5e9e3;
  --ok:        #2c6349;
  --ok-bg:     #e6f0ea;
  --warn:      #8a5a12;
  --warn-bg:   #f7efe1;
  --info:      #24556e;
  --info-bg:   #e4eef4;

  --shell: 74rem;
  --radius: 3px;

  --font: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --mono: ui-monospace, "SFMono-Regular", Menlo, Consolas, "Liberation Mono", monospace;
}

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font);
  font-size: 1rem;
  line-height: 1.6;
}

img { max-width: 100%; height: auto; }

a { color: var(--accent); text-underline-offset: 2px; }
a:focus-visible,
button:focus-visible,
input:focus-visible,
summary:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.visually-hidden {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.skip {
  position: absolute; left: -9999px;
  background: var(--ink); color: #fff; padding: .6rem 1rem; z-index: 10;
}
.skip:focus { left: .5rem; top: .5rem; }

.shell { max-width: var(--shell); margin: 0 auto; padding: 0 1.25rem; }
.block { padding: 2.5rem 1.25rem; }
.muted { color: var(--ink-2); }
.mono  { font-family: var(--mono); font-size: .9375em; }

/* ---------------- Kopfbereich ---------------- */

.site-head {
  background: var(--surface);
  border-bottom: 1px solid var(--rule);
}

.head-inner {
  display: flex;
  align-items: center;
  gap: 1rem;
  min-height: 4.5rem;
  flex-wrap: wrap;
}

.brand { display: inline-flex; margin-right: auto; }
/* Logo-Slot: breit/flach, ~4:1. Mobil etwas kleiner (48px), damit es neben
   dem Menüknopf nicht drückt; am Desktop prominenter (56px, siehe 56rem). */
.brand img { display: block; width: auto; max-height: 3rem; }

/* Farbe fuer jeden Zustand ausdruecklich gesetzt. Mit "background: none"
   malten manche Android-Browser nach dem Antippen ihr eigenes Schwarz in
   die Schaltflaeche, und das blieb stehen, bis man woanders hintippte -
   der Fokus bleibt nach einem Tipp ja auf dem Knopf. Hover nur dort, wo
   es eine Maus gibt: auf dem Telefon klebt er sonst genauso fest. */
.nav-toggle {
  margin-left: auto;
  width: 2.75rem; height: 2.75rem;
  -webkit-appearance: none;
  appearance: none;
  -webkit-tap-highlight-color: transparent;
  background: var(--surface);
  color: var(--ink);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  cursor: pointer;
  display: grid;
  place-items: center;
}
.nav-toggle:focus,
.nav-toggle:active { background: var(--surface); }
.nav-toggle:focus:not(:focus-visible) { outline: none; }
.nav-toggle[aria-expanded="true"] { background: var(--surface-2); border-color: var(--ink-3); }
@media (hover: hover) {
  .nav-toggle:hover { background: var(--surface-2); }
}
.nav-toggle-bar,
.nav-toggle-bar::before,
.nav-toggle-bar::after {
  display: block; width: 1.15rem; height: 2px;
  background: var(--ink); content: "";
}
.nav-toggle-bar { position: relative; }
.nav-toggle-bar::before { position: absolute; top: -6px; }
.nav-toggle-bar::after  { position: absolute; top: 6px; }

.site-nav {
  display: none;
  flex-basis: 100%;
  flex-direction: column;
  padding-bottom: 1rem;
}
.site-nav.is-open { display: flex; }

.site-nav a {
  padding: .65rem 0;
  color: var(--ink);
  text-decoration: none;
  border-bottom: 1px solid var(--rule-soft);
}
.site-nav a:hover { color: var(--accent); }
.site-nav .lang { font-weight: 600; letter-spacing: .06em; }

@media (min-width: 56rem) {
  .nav-toggle { display: none; }
  /* Am Desktop den Anker prominenter zeigen. */
  .brand img { max-height: 3.5rem; }
  .site-nav {
    display: flex;
    flex-direction: row;
    flex-basis: auto;
    align-items: center;
    gap: 1.5rem;
    padding-bottom: 0;
  }
  .site-nav a { padding: 0; border-bottom: 0; }
}

/* ---------------- Hero ---------------- */

.hero {
  background: var(--surface);
  border-bottom: 1px solid var(--rule);
  padding: 2.75rem 0 3rem;
}
.eyebrow {
  margin: 0 0 .5rem;
  font-size: .75rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.hero h1 {
  margin: 0 0 .75rem;
  font-size: clamp(1.9rem, 5vw, 2.9rem);
  line-height: 1.1;
  letter-spacing: -.02em;
  text-wrap: balance;
}
.hero-text { margin: 0 0 2rem; max-width: 46rem; font-size: 1.125rem; color: var(--ink-2); }

.track label {
  display: block;
  font-size: .8125rem;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--ink-2);
  margin-bottom: .4rem;
}
.track-row { display: flex; flex-wrap: wrap; gap: .5rem; max-width: 44rem; }
.track-row input { flex: 1 1 16rem; }

/* ---------------- Formularelemente ---------------- */

input, button, select {
  font: inherit;
  border-radius: var(--radius);
}

input[type="search"],
input[type="text"],
input[type="email"],
input[type="password"],
input[type="date"],
input[type="time"],
input[type="number"],
textarea {
  width: 100%;
  padding: .65rem .8rem;
  border: 1px solid var(--rule);
  background: var(--input-bg);
  color: var(--ink);
}

button, .button {
  display: inline-block;
  padding: .65rem 1.25rem;
  background: var(--ink);
  color: #fff;
  border: 1px solid var(--ink);
  text-decoration: none;
  cursor: pointer;
}
button:hover, .button:hover { background: #000; }

.filters {
  display: grid;
  gap: 1rem;
  grid-template-columns: 1fr;
  background: var(--surface);
  border: 1px solid var(--rule);
  padding: 1.25rem;
  margin-bottom: 1.5rem;
}
@media (min-width: 48rem) {
  .filters { grid-template-columns: 2fr 1fr 1fr auto; align-items: end; }
}
/* Mit der Auswahl der Zeilenzahl sind es fuenf Felder - sonst rutscht das
   letzte allein in eine zweite Reihe. */
@media (min-width: 62rem) {
  .filters { grid-template-columns: 2fr 1fr 1fr 1fr auto; }
}
.filters select {
  width: 100%; padding: .65rem .8rem;
  border: 1px solid var(--rule); background: var(--surface); color: var(--ink);
}
.field label {
  display: block;
  font-size: .8125rem;
  color: var(--ink-2);
  margin-bottom: .3rem;
}
.field-action { display: flex; align-items: center; gap: .75rem; }
.reset { font-size: .875rem; }
.form-error {
  background: var(--accent-2);
  color: var(--accent);
  border: 1px solid var(--rule);
  padding: .6rem .8rem;
  margin: 0 0 1rem;
  font-size: .9375rem;
}

.flash {
  margin: 1rem 0 0;
  padding: .65rem .9rem;
  border: 1px solid var(--rule);
  font-size: .9375rem;
}
.flash-info    { background: var(--info-bg); color: var(--info); }
.flash-success { background: var(--ok-bg);   color: var(--ok); }
.flash-error   { background: var(--accent-2); color: var(--accent); }
.flash-warning { background: var(--warn-bg); color: var(--warn); }
/* Echter Bearbeitungs-Konflikt: auffaelliger als die Sammelwarnung -
   leichtes Rot mit rotem Balken, damit er nicht uebersehen wird. */
.flash-conflict { background: #fdecea; color: #9f1f14; border: 1px solid #f3bab3; border-left: 4px solid #d3382b; }
.flash-lead { text-decoration: underline; }

/* ---------------- Tabellen ---------------- */

.table-scroll { overflow-x: auto; }

/* Breite Arbeitslisten.
 *
 * Ohne Hoehenbegrenzung sitzt der waagerechte Rollbalken am unteren Rand
 * der gesamten Tabelle: bei 25 Zeilen muss man erst ganz nach unten und
 * dann zur Seite rollen. Der Rahmen bekommt deshalb eine an die
 * Fensterhoehe gebundene Hoehe - damit liegt der Balken immer im Blick.
 * Spaltenkopf und erste Spalte bleiben beim Rollen stehen, sonst weiss
 * man nach drei Spalten nicht mehr, welche Zeile man liest.
 */
@media (min-width: 48rem) {
  .table-viewport {
    overflow: auto;
    max-height: calc(100vh - 8rem);
    border: 1px solid var(--rule);
    background: var(--surface);
    overscroll-behavior: contain;
  }
  .table-viewport table.data { border: 0; }

  .table-viewport thead th {
    position: sticky;
    top: 0;
    z-index: 3;
    /* Bei border-collapse rollt eine echte Rahmenlinie mit weg, der
       Schatten bleibt am Kopf haften. */
    border-bottom: 0;
    box-shadow: inset 0 -1px 0 var(--rule);
  }

  .table-viewport tbody td:first-child,
  .table-viewport thead th:first-child {
    position: sticky;
    left: 0;
    background: var(--surface);
    box-shadow: 1px 0 0 var(--rule);
  }
  .table-viewport thead th:first-child {
    z-index: 4;
    background: var(--surface-2);
    box-shadow: 1px 0 0 var(--rule), inset 0 -1px 0 var(--rule);
  }
  .table-viewport tbody td:first-child { z-index: 2; }

  /* Die Sonderfarben der Zeile muss die festgestellte Spalte
     mittragen, sonst steht dort ein weisser Streifen. */
  .table-viewport tr.is-deleted td:first-child    { background: var(--accent-2); }
  .table-viewport tr.is-hidden-row td:first-child { background: var(--surface-2); }

  /* Die Aktionsspalte klebt am rechten Rand - Gegenstueck zur ersten
     Spalte. So bleiben Bearbeiten/PDF/Loeschen immer erreichbar, ohne
     erst ganz nach rechts (und dafuer nach unten zum Rollbalken) zu
     rollen. Sie traegt eine linke Trennlinie und die Zeilenfarben mit. */
  .table-viewport tbody td.row-actions,
  .table-viewport thead th:last-child {
    position: sticky;
    right: 0;
    background: var(--surface);
    box-shadow: -1px 0 0 var(--rule);
  }
  .table-viewport thead th:last-child {
    z-index: 4;
    background: var(--surface-2);
    box-shadow: -1px 0 0 var(--rule), inset 0 -1px 0 var(--rule);
  }
  .table-viewport tbody td.row-actions { z-index: 2; }

  /* Die Aktionszelle darf im Tabellen-Kontext KEIN Flex-Container sein:
     eine Flex-<td> laesst sich in verschachtelten Scroll-Containern (Liste
     im fensterhohen Modus) nicht festkleben - das Sticky oben griffe sonst
     ins Leere und die Schaltflaechen wanderten aus dem Bild. Sie bleibt
     darum eine echte Tabellenzelle; die Schaltflaechen reihen sich inline
     auf und behalten ihren Abstand ueber margin statt flex-gap. */
  .table-viewport tbody td.row-actions {
    display: table-cell;
    white-space: nowrap;
    vertical-align: middle;
  }
  .table-viewport tbody td.row-actions > * {
    display: inline-flex;
    vertical-align: middle;
  }
  .table-viewport tbody td.row-actions > * + * {
    margin-left: .4rem;
  }

  .table-viewport tr.is-deleted td.row-actions    { background: var(--accent-2); }
  .table-viewport tr.is-hidden-row td.row-actions { background: var(--surface-2); }
}

/* Listenseiten fuellen das Fenster genau aus.
 *
 * Sonst reicht der Tabellenrahmen ueber den unteren Fensterrand hinaus und
 * der waagerechte Rollbalken liegt wieder ausserhalb des Blickfelds - nur
 * eben etwas weniger weit unten als vorher. Hier rollt stattdessen nur noch
 * die Tabelle selbst, die Seite gar nicht mehr.
 *
 * :has() kennen alle aktuellen Browser. Wo nicht, faellt die Regel weg und
 * es bleibt bei der Hoehenbegrenzung oben - unschoener, aber nicht kaputt.
 * Die Mindesthoehe schuetzt kleine Fenster davor, dass Filter und Tabelle
 * sich gegenseitig auf null druecken.
 */
/* Wer die Tabelle lieber auslaufen laesst, bekommt die gewohnte Seite:
   dann rollt das Fenster und nicht der Rahmen. Der Rollbalken sitzt dafuer
   wieder am Ende der Tabelle - eine Abwaegung, die jeder selbst trifft. */
@media (min-width: 48rem) {
  .table-viewport.height-lang {
    max-height: none;
    overflow: visible;
    overflow-x: auto;
  }
  .table-viewport.height-lang thead th { position: static; box-shadow: none; }
  .table-viewport.height-lang thead th { border-bottom: 1px solid var(--rule); }
}

@media (min-width: 48rem) and (min-height: 34rem) {
  body.admin-body:has(.table-viewport) {
    height: 100vh;
    overflow: hidden;
    display: flex;
    flex-direction: column;
  }
  .admin-main:has(.table-viewport) {
    flex: 1;
    min-height: 0;
    display: flex;
    flex-direction: column;
    overflow-y: auto;
    padding-bottom: 1.25rem;
  }
  .admin-main:has(.table-viewport) .table-viewport {
    flex: 1 1 auto;
    max-height: none;
    min-height: 14rem;
  }

  /* Ausnahme: bei "lang" bleibt alles beim gewohnten Seitenlauf. */
  body.admin-body:has(.table-viewport.height-lang) {
    height: auto;
    overflow: visible;
    display: block;
  }
  .admin-main:has(.table-viewport.height-lang) {
    display: block;
    overflow: visible;
  }
}

/* ---------------- Spaltenliste mit Reihenfolge ---------------- */

.columns-list { list-style: none; padding: 0; }
.column-item {
  display: flex; align-items: center; gap: .4rem;
  padding: .15rem .35rem; border: 1px solid transparent;
}
.column-item:hover { border-color: var(--rule); background: var(--surface-2); }
.column-item label { display: flex; align-items: center; gap: .45rem; margin: 0; flex: 1; }
.column-item.is-locked .column-label { color: var(--ink-3); }
.column-move { display: flex; gap: .15rem; }
.column-move button {
  padding: 0 .3rem; line-height: 1.4;
  background: none; color: var(--ink-2);
  border: 1px solid var(--rule); border-radius: 2px;
  font-size: .8125rem; cursor: pointer;
}
.column-move button:hover { background: var(--rule-soft); color: var(--ink); }

/* ---------------- Filterkasten einklappen ---------------- */

.filter-toggle {
  display: inline-flex; align-items: center; gap: .35rem;
  font-size: .875rem; color: var(--ink-2);
  text-decoration: none; margin: 0 0 .75rem;
}
.filter-toggle:hover { color: var(--accent); }
.filter-summary {
  margin: 0 0 1.25rem; padding: .5rem .8rem;
  background: var(--surface); border: 1px solid var(--rule);
  font-size: .875rem; color: var(--ink-2);
  display: flex; flex-wrap: wrap; gap: .5rem 1rem; align-items: center;
}

/* ---------------- Zeilen je Seite an der Blätterleiste ---------------- */

.pager-size { display: flex; align-items: center; gap: .4rem; font-size: .875rem; color: var(--ink-2); }
.pager-size select { width: auto; padding: .3rem .45rem; }

table.data {
  width: 100%;
  border-collapse: collapse;
  background: var(--surface);
  border: 1px solid var(--rule);
  font-variant-numeric: tabular-nums;
}
table.data th {
  text-align: left;
  font-size: .75rem;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--ink-2);
  background: var(--surface-2);
  padding: .7rem .85rem;
  border-bottom: 1px solid var(--rule);
  white-space: nowrap;
}
table.data td {
  padding: .65rem .85rem;
  border-bottom: 1px solid var(--rule-soft);
  vertical-align: top;
}
table.data tbody tr:last-child td { border-bottom: 0; }

/* Kartenform auf schmalen Geraeten - der Punkt, an dem das Altsystem
   unbedienbar wurde. */
@media (max-width: 47.99rem) {
  table.data, table.data tbody, table.data tr, table.data td { display: block; width: 100%; }
  table.data thead { display: none; }

  /* Jede Zeile eine eigene Karte mit Rahmen, dazwischen echter Abstand.
     Frueher trennte ein Streifen in der Farbe --paper - das trug auf der
     oeffentlichen Seite, im internen Bereich aber nicht: dort ist der
     Seitengrund selbst hellgrau, nicht oeffentliche Eintraege sind es auch,
     und Grau auf fast demselben Grau liess die Karten ineinanderlaufen.
     Der Abstand zeigt jetzt einfach, was darunter liegt. */
  table.data { background: none; border: 0; }
  table.data tr {
    padding: .7rem 0;
    background: var(--surface);
    border: 1px solid var(--rule);
  }
  table.data tr + tr { margin-top: .75rem; }

  /* Zeilenfarben auf die ganze Karte - nur auf den Zellen blieb oben und
     unten ein weisser Rand stehen. */
  table.data tr.is-hidden-row,
  table.data tr.is-hidden-row td { background: var(--surface-2); }
  table.data tr.is-deleted,
  table.data tr.is-deleted td { background: var(--accent-2); }

  /* Die Schaltflaechen einer Karte: eigene Reihe ueber die volle Breite,
     ohne Beschriftung davor. Im Raster landeten sie sonst zur Haelfte in
     der Beschriftungsspalte. */
  table.data td.row-actions {
    display: flex;
    flex-wrap: wrap;
    gap: .45rem;
    margin-top: .4rem;
    padding-top: .7rem;
    border-top: 1px solid var(--rule-soft);
  }
  table.data td.row-actions::before { content: none; }

  /* Im Raster wird jedes Kind so breit wie die Spalte - eine Statuspille
     soll aber so breit bleiben wie ihr Wort. */
  table.data td > .pill { justify-self: start; }

  /* Auswahlfelder in der Karte (Status direkt in der Zeile) duerfen nicht
     breiter werden als die Wertespalte - bei 360 Pixeln ragte die
     Statusauswahl sonst rechts ueber den Kartenrand. */
  table.data td > form { min-width: 0; }
  table.data td select { max-width: 100%; }

  table.data td {
    display: grid;
    /* minmax(0, 1fr) statt 1fr: sonst wird die Wertespalte nie schmaler
       als ihr laengstes Wort, und eine ATLAS-Nummer schiebt die ganze
       Karte ueber den Bildschirmrand. */
    grid-template-columns: 9.5rem minmax(0, 1fr);
    gap: .75rem;
    border-bottom: 0;
    padding: .3rem .85rem;
    overflow-wrap: anywhere;
  }
  table.data td::before {
    content: attr(data-label);
    font-size: .75rem;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--ink-3);
    padding-top: .15rem;
  }
}

.pill {
  display: inline-block;
  padding: .12rem .5rem;
  border-radius: 999px;
  font-size: .8125rem;
  white-space: nowrap;
  background: var(--surface-2);
  color: var(--ink-2);
}
/* Die Farbe eines Statuswerts steht seit 021 an den Daten und wird
   frei gewaehlt - sie kommt deshalb als style-Angabe an der Marke und
   nicht als Klasse von hier. Siehe App\Support\StatusColor: aus der
   gewaehlten Farbe entstehen Flaeche und Schrift, mit eingehaltenem
   Kontrast.

   Was hier bleibt, sind die Marken, die *kein* Containerstatus sind. */
.pill-ok    { background: var(--ok-bg); color: var(--ok); }
.pill-quiet { background: var(--surface-2); color: var(--ink-2); }

/* Die Statustabelle in den Einstellungen.

   Feste Breiten, sonst teilt der Browser den Platz nach Textlaenge zu:
   die laengste Ueberschrift gewinnt dann gegen das wichtigste Feld, und
   jede Zelle bricht um. Eine Zeile war dadurch so hoch wie drei. */
.status-table { table-layout: fixed; }
.status-table th, .status-table td { padding: .35rem .4rem; vertical-align: middle; }
.status-table input[type="text"] { width: 100%; }
/* Alles in Prozent, zusammen genau hundert: Prozente und feste
   Breiten nebeneinander addieren sich, und die Tabelle lief rechts
   ueber. */
.status-table .col-label { width: 21%; }
.status-table .col-tone  { width: 15%; }
.status-table .col-sort  { width: 9%; }
.status-table .col-flag  { width: 7%; text-align: center; }
.status-table .col-usage { width: 21%; white-space: nowrap; }
.status-table .col-del   { width: 6%; text-align: center; }

/* Das Zahlenfeld traegt hoechstens drei Ziffern - mit der ueblichen
   Polsterung blieb von "10" nur "1" sichtbar. */
.status-table .col-sort input { padding-left: .3rem; padding-right: .3rem; text-align: center; }
.status-table .status-new-hint { white-space: normal; font-size: .8rem; line-height: 1.35; }

/* Die Erklaerung der Spalten - drei kurze Zeilen statt eines Absatzes,
   damit sich jede einzeln lesen laesst. */
.status-legend { list-style: none; margin: .6rem 0 0; padding: 0; }
.status-legend li { margin: .15rem 0; }
.status-legend .icon { vertical-align: -.15em; margin-right: .25rem; }

/* In der Kartenform greifen die Spaltenbreiten nicht mehr - dort steht
   die Beschriftung links und das Feld rechts. Ohne diese Regel blieb
   das Auswahlfeld der Farbe so schmal wie in der Tabellenspalte. */
@media (max-width: 47.99rem) {
  .status-table { table-layout: auto; }

  /* Die Spaltenbreiten muessen hier ausdruecklich weichen: sie tragen
     zwei Klassen und schlagen damit die Regel, die aus jeder Zelle eine
     Zeile macht. Die Farbspalte blieb sonst 44 Pixel breit. */
  .status-table .col-label,
  .status-table .col-tone,
  .status-table .col-sort,
  .status-table .col-flag,
  .status-table .col-usage,
  .status-table .col-del { width: 100%; text-align: left; }

  .status-table td { white-space: normal; }
  .status-table select,
  .status-table input[type="text"] { width: 100%; }
  .status-table .col-sort input { text-align: left; }
}
.status-table .col-sort input { width: 100%; }

/* Das Kuerzel steht klein unter der Beschriftung - es ist kein Feld,
   sondern die Kennung, an der die Container haengen. */
.status-table .status-code { display: block; font-size: .7rem; line-height: 1.3; }
.status-table .chip { font-size: .7rem; padding: 0 .25rem; }

/* Farbwaehler und Vorschau nebeneinander: die Vorschau ist die Marke
   selbst, wie sie spaeter erscheint - eine Farbe allein sagt wenig
   darueber, ob die Schrift darauf lesbar wird. */
.tone-cell { display: flex; align-items: center; gap: .4rem; min-width: 0; }
.tone-cell input[type="color"] {
  flex: none;
  width: 2rem;
  height: 1.75rem;
  padding: 0;
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  background: none;
  cursor: pointer;
}
.tone-cell .pill { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.status-delete { display: inline-flex; align-items: center; gap: .2rem; white-space: nowrap; cursor: pointer; }
.status-delete .icon { color: var(--ink-3); }
.status-delete:hover .icon { color: var(--accent); }

.result-count { font-size: .9375rem; color: var(--ink-2); margin: 0 0 .75rem; }

.pager { display: flex; flex-wrap: wrap; gap: .35rem; margin-top: 1.25rem; }
.pager a, .pager-current {
  min-width: 2.25rem;
  padding: .35rem .6rem;
  text-align: center;
  border: 1px solid var(--rule);
  background: var(--surface);
  text-decoration: none;
}
.pager-current { background: var(--ink); color: #fff; border-color: var(--ink); }

/* Zurueck und Weiter tragen Text, die Ziffern nicht - deshalb duerfen sie
   breiter werden. Am Rand bleiben sie als abgeblendete Attrappe stehen,
   damit die Leiste beim Blaettern nicht die Breite wechselt. */
.pager-step { padding: .35rem .7rem; white-space: nowrap; }
.pager-step.is-off {
  border: 1px solid var(--rule-soft);
  background: var(--surface-2);
  color: var(--ink-3);
}

.pager-jump {
  display: flex; align-items: center; gap: .4rem;
  margin: 0 0 0 auto; font-size: .875rem; color: var(--ink-2);
}
.pager-jump label { margin: 0; }
.pager-jump input { width: 4.5rem; padding: .3rem .45rem; text-align: center; }
.pager-jump button { padding: .35rem .8rem; font-size: .875rem; }
.pager-of { white-space: nowrap; }

/* Auf schmalen Geraeten unter die Ziffern statt daneben. */
@media (max-width: 47.99rem) {
  .pager-jump { margin: .5rem 0 0; flex-basis: 100%; }
}

/* ---------------- Containerdetail ---------------- */

.back { font-size: .9375rem; text-decoration: none; }
.container-no { font-size: clamp(1.5rem, 4vw, 2.1rem); margin: .5rem 0 1.5rem; word-break: break-all; }

.facts {
  display: grid;
  gap: 1px;
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  background: var(--rule);
  border: 1px solid var(--rule);
  margin-bottom: 2.5rem;
}
.facts > div {
  background: var(--surface);
  padding: .85rem 1rem;
  display: flex;
  flex-direction: column;
  gap: .2rem;
}
.facts .k { font-size: .75rem; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-3); }
.facts .v { font-weight: 600; }

.subscribe-teaser {
  margin-top: 2.5rem;
  border-left: 3px solid var(--accent);
  background: var(--surface);
  padding: 1rem 1.25rem;
}
.subscribe-teaser h2 { margin: 0 0 .25rem; font-size: 1.0625rem; }

/* ---------------- Inhaltsseiten ---------------- */

.prose { background: var(--surface); border: 1px solid var(--rule); }
.prose h1 { margin-top: 0; font-size: clamp(1.6rem, 4vw, 2.2rem); letter-spacing: -.015em; }
.prose h2 { font-size: 1.1875rem; margin-top: 2rem; }
.prose p  { max-width: 42rem; }
.prose .lead { font-size: 1.0625rem; color: var(--ink-2); }

/* Feste Zweierspalte statt auto-fit: bei vier Leistungen bleibt sonst
   je nach Fensterbreite eine Zelle leer. */
.cards {
  display: grid;
  gap: 1px;
  grid-template-columns: 1fr;
  background: var(--rule);
  border: 1px solid var(--rule);
  margin-top: 1.5rem;
}
@media (min-width: 48rem) { .cards { grid-template-columns: repeat(2, 1fr); } }
.cards article { background: var(--surface); padding: 1.25rem; }
.cards h2 { margin: 0 0 .4rem; font-size: 1.0625rem; }
.cards p  { margin: 0; color: var(--ink-2); font-size: .9375rem; }

.map-consent {
  border: 1px solid var(--rule);
  background: var(--surface-2);
  padding: 1.25rem;
  margin-top: 1.5rem;
}

.more { font-weight: 600; text-decoration: none; }
.error-page { text-align: left; }

/* „Aktualisieren"-Links: lädt die Seite mit frischen Daten neu. */
.refresh { margin-top: .9rem; }
.result-count .refresh-inline { margin-left: 1rem; vertical-align: middle; }

/* ---------------- Kontaktformular (Anfahrtsseite) ---------------- */

/* Erfolgsmeldung nach dem Absenden - deutlich grün, mit Häkchen. */
.contact-success {
  display: flex; align-items: flex-start; gap: .6rem;
  background: var(--ok-bg); color: var(--ok);
  border: 1px solid var(--ok); border-left-width: 4px;
  border-radius: .5rem;
  padding: 1rem 1.2rem;
  font-weight: 600;
  margin-top: 1rem;
}
.contact-success .icon { flex: 0 0 auto; color: var(--ok); }

.contact-form { margin-top: 1.25rem; max-width: 42rem; }
.contact-form .field { margin-bottom: 1rem; }
.contact-form input,
.contact-form textarea { width: 100%; }
.contact-form textarea { resize: vertical; min-height: 7rem; }

/* Vor- und Nachname, E-Mail und Telefon zweispaltig, ab Tablet. */
.contact-grid { display: grid; gap: 0 1rem; grid-template-columns: 1fr; }
@media (min-width: 40rem) { .contact-grid { grid-template-columns: 1fr 1fr; } }
.contact-grid .field { margin-bottom: 1rem; }

/* Anrede nebeneinander, ohne Rahmen des Fieldsets. */
.contact-anrede { border: 0; padding: 0; margin: 0 0 1rem; }
.contact-anrede legend { font-weight: 600; margin-bottom: .35rem; padding: 0; }
.contact-anrede label { display: inline-flex; align-items: center; gap: .35rem; margin-right: 1.25rem; font-weight: 400; }
.contact-anrede input { width: auto; }

.contact-captcha input { max-width: 8rem; }

/* Koederfeld gegen Bots: fuer Menschen unsichtbar, aber nicht display:none
   (das ueberspringen manche Bots) - aus dem Fluss und vom Schirm geschoben. */
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

/* ---------------- Fussbereich ---------------- */

.site-foot {
  background: var(--surface);
  border-top: 1px solid var(--rule);
  margin-top: 3rem;
  padding: 2rem 0;
  font-size: .9375rem;
  color: var(--ink-2);
}
.foot-inner { display: grid; gap: 1.5rem; grid-template-columns: 1fr; }
@media (min-width: 48rem) { .foot-inner { grid-template-columns: repeat(3, 1fr); } }
.foot-inner p { margin: 0 0 .35rem; }
.foot-name { font-weight: 600; color: var(--ink); }
.foot-nav { display: flex; flex-direction: column; gap: .35rem; }
/* Dezenter Herkunftshinweis - klein, ganz unten, quer ueber die Breite. */
.foot-colophon {
  max-width: var(--shell);
  margin: 1.75rem auto 0;
  padding: 1.25rem 1.25rem 0;
  border-top: 1px solid var(--rule);
  font-size: .78rem;
  color: var(--ink-2);
  text-align: center;
}
.foot-colophon a { color: inherit; }

/* ---------------- Interner Bereich ---------------- */

.admin-body { background: var(--surface-2); }

/* Voreinstellung fuer den internen Bereich: mittig und schmal. So lesen
   sich Masken und Einstellungen am besten, und so sah es auch vorher aus. */
.admin-shell { max-width: 68rem; margin: 0 auto; padding: 0 1.25rem; }
.admin-main { padding-bottom: 3rem; }

/* Die Ausnahme sind die grossen Arbeitslisten: dort ist die Breite des
   Monitors nuetzlich, weil die Tabelle sonst abgeschnitten ist.
   Die Regel haengt am body, damit Kopfleiste und Inhalt dieselbe Breite
   bekommen - sonst stuende die Navigation weiter links als die Tabelle. */
@media (min-width: 48rem) {
  body.admin-body:has(.table-viewport) .admin-shell { max-width: 110rem; }
}

.admin-head { background: var(--ink); color: #fff; }
.admin-head-inner {
  display: flex; align-items: center; gap: 1.25rem;
  min-height: 3.5rem; flex-wrap: wrap;
}

/* Auf breiten Schirmen bleibt die Leiste einzeilig.
 *
 * Mit flex-wrap: wrap bricht der Browser eine Zeile um, bevor er ein
 * Element schrumpfen laesst - deshalb rutschte die Benutzergruppe nach
 * unten, sobald das Menue drei Punkte laenger wurde. Ohne Umbruch
 * schrumpft stattdessen das Menue und bricht in sich um. */
@media (min-width: 62rem) {
  .admin-head-inner { flex-wrap: nowrap; }
}

/* Die Leiste nutzt die ganze Fensterbreite, der Inhalt darunter nicht.
 *
 * Zwoelf Menuepunkte, Kennzeichnung, der Verweis auf die Website und die
 * Benutzergruppe brauchen zusammen 1.789 Pixel - gemessen, nicht
 * geschaetzt. Beim alten Deckel von 110rem (1.760) haette die
 * beschriftete Fassung auf keinem Bildschirm mehr gepasst, auch nicht
 * auf einem sehr breiten. Eine Bedienleiste ueber die volle Breite ist
 * ohnehin das gewohnte Bild; der Inhalt darunter bleibt bei 74rem,
 * damit Fliesstext lesbar bleibt. */
.admin-head .admin-shell {
  max-width: 122rem;
  padding-left: 1.5rem;
  padding-right: 1.5rem;
}
/* Der interne Bereich soll sich auf den ersten Blick von der oeffentlichen
   Seite unterscheiden - wer hier arbeitet, sieht Kundendaten. Deshalb ein
   Warnton statt schlichtem Weiss. */
.admin-brand {
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  font-size: .8125rem;
  color: var(--warn-signal, #f0b429);
  border: 1px solid currentColor;
  border-radius: 2px;
  padding: .2rem .5rem;
  white-space: nowrap;
}
/* Produkt-Sinnbild neben der Kennzeichnung in der Kopfleiste. */
.admin-brand-lockup { display: inline-flex; align-items: center; gap: .5rem; flex: none; }
.admin-brand-icon { height: 28px; width: 28px; display: block; }
/* Drei Bereiche: Kennzeichnung, Menue, Benutzer.
 *
 * Das Menue darf in sich umbrechen und nimmt den freien Platz; die
 * Benutzergruppe steht fest rechts. Ohne diese Trennung rutschte
 * "Abmelden" in die zweite Zeile nach links, sobald das Menue laenger
 * wurde. */
.admin-nav {
  display: flex;
  gap: .35rem 1.25rem;
  flex-wrap: wrap;
  flex: 1 1 auto;
  min-width: 0;
}
.admin-nav a {
  color: #fff;
  text-decoration: none;
  white-space: nowrap;
  display: inline-flex;
  align-items: center;
  gap: .35rem;
}

/*
 * Zwoelf Menuepunkte sind die Grenze dessen, was in eine Zeile passt.
 *
 * Gemessen bei 1920 Pixeln: die Punkte brauchen 1324, haben aber 1287 -
 * es fehlen 37. Der Browser bricht dann um, und die zweite Zeile faengt
 * linksbuendig unter der ersten an. Das sieht nicht nach Absicht aus,
 * sondern nach Versehen.
 *
 * An der Luecke zu drehen waere ein Pflaster; der naechste Menuepunkt
 * reisst sie wieder auf. Deshalb weicht hier die Beschriftung, nicht
 * die Zeile: unterhalb der Breite, ab der alle Namen nebeneinander
 * passen, bleiben die Sinnbilder allein stehen. Der Name steht dann im
 * title des Verweises und - fuer die Sprachausgabe - weiterhin im
 * Dokument.
 *
 * Der Umschaltpunkt ist gemessen, nicht geschaetzt: bei 96rem passen
 * Kennzeichnung, zwoelf beschriftete Punkte und die Benutzergruppe
 * gerade noch nebeneinander.
 */
@media (min-width: 62rem) and (max-width: 103.99rem) {
  .admin-nav { gap: .9rem; }
  .admin-nav .nav-label,
  .admin-public-label {
    position: absolute;
    width: 1px; height: 1px;
    margin: -1px; padding: 0; border: 0;
    overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%);
    white-space: nowrap;
  }
  /* Ohne Beschriftung liegen die Sinnbilder sonst zu dicht beieinander,
     um sie einzeln zu treffen. */
  .admin-nav a { padding: .35rem .2rem; }
}

/*
 * Ab hier ist Platz fuer die Namen - gemessen, nicht geschaetzt: zwoelf
 * beschriftete Punkte, Kennzeichnung, der Verweis auf die Website und
 * die Benutzergruppe brauchen Platz. Nachgemessen: mit den urspruenglichen
 * zwoelf Punkten waren es 1.789 Pixel - mehr, als selbst ein sehr breiter
 * Bildschirm hergab, weshalb die Schrift kleiner werden musste.
 *
 * Seit Import, Vorlagen, Mailtexte, Inhalte und Mediathek unter
 * "Pflege" liegen, sind es acht Punkte und 1.524 Pixel. Damit passt die
 * Beschriftung in normaler Schriftgroesse - die Verkleinerung ist wieder
 * draussen, und die Grenze steht auf 97rem (1.552), knapp ueber dem
 * gemessenen Wert.
 *
 * Mit der Hilfe als neuntem Punkt reichte das nicht mehr: bei 1.560
 * Pixeln brach die Leiste in zwei Zeilen um. Nachgemessen mit dem
 * laengsten Fall (Administrator, alle Punkte, langer Name): bei 1.635
 * zwei Zeilen, bei 1.650 eine - deutsch wie englisch. Die Grenze steht
 * auf 104rem (1.664).
 *
 * "Sicherheit" war kurz ein zehnter Punkt und schob die Grenze auf
 * 112rem; seit die Seite als Kachel unter Pflege liegt, sind es wieder
 * neun - und die Grenze steht wieder auf 104rem.
 *
 * Die Beschriftung faellt eine Spur kleiner aus als der uebrige Text -
 * ohne das laege die Grenze noch hoeher.
 *
 * Darunter bleiben die Sinnbilder allein stehen. Das ist kein schoener,
 * aber ein ehrlicher Zustand: zwoelf Punkte und ein Verweis passen nun
 * einmal nicht beschriftet in eine Leiste, und die Alternative waere ein
 * Umbruch, der wie ein Versehen aussieht.
 */
@media (min-width: 104rem) {
  .admin-nav { gap: 1.25rem; }
}

/* Schnellsuche in der Kopfleiste: ein helles Feld auf der dunklen Leiste,
   die Trefferliste als weiße Karte darunter. */
.admin-search {
  position: relative; flex: none; display: flex; align-items: center; gap: .4rem;
  width: 14rem; max-width: 40vw;
  padding: .32rem .6rem; border-radius: 6px;
  background: rgba(255, 255, 255, .1); border: 1px solid rgba(255, 255, 255, .22);
}
.admin-search:focus-within { background: rgba(255, 255, 255, .16); border-color: rgba(255, 255, 255, .5); }
.admin-search > .icon { width: 15px; height: 15px; color: rgba(255, 255, 255, .7); flex: none; }
.admin-search-input {
  flex: 1 1 auto; min-width: 0; background: transparent; border: 0; color: #fff;
  font-size: .875rem; padding: .1rem 0;
}
.admin-search-input::placeholder { color: rgba(255, 255, 255, .6); }
.admin-search-input:focus { outline: none; }
.admin-search-list {
  position: absolute; top: calc(100% + .4rem); right: 0; left: 0; z-index: 60;
  margin: 0; padding: .3rem; list-style: none;
  background: var(--surface, #fff); color: var(--ink);
  border: 1px solid var(--rule); border-radius: 8px;
  box-shadow: 0 12px 32px rgba(0, 0, 0, .28);
  max-height: 60vh; overflow: auto; min-width: 16rem;
}
.admin-search-item {
  padding: .5rem .6rem; border-radius: 6px; cursor: pointer;
  font-size: .9rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.admin-search-item.is-active { background: var(--surface-2, #f1f4f6); }
.admin-search-empty { padding: .5rem .6rem; font-size: .875rem; color: var(--ink-3, #8b959c); }
@media (min-width: 62rem) and (max-width: 103.99rem) { .admin-search { width: 11rem; } }
@media (max-width: 61.99rem) {
  /* Eigene Zeile unter Kennzeichnung/Umschalter/Benutzer, über dem Menü. */
  .admin-search { order: 4; flex: 0 0 100%; width: auto; max-width: none; }
  .admin-search-list { min-width: 0; }
}

.admin-user {
  display: flex;
  align-items: center;
  gap: .75rem;
  margin-left: auto;
  flex: none;
}

/*
 * Der Name wird gekuerzt, statt die Leiste zu sprengen.
 *
 * Ohne Grenze haengt die Breite der Leiste davon ab, wie lang der Name
 * des Angemeldeten ist - und damit auch, ob das Menue noch in eine
 * Zeile passt. Eine Oberflaeche, die bei einem Kollegen umbricht und
 * beim naechsten nicht, ist nicht zu warten.
 */
.admin-profile-name {
  max-width: 11rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Auf dem Telefon hinter der Schaltflaeche: acht Punkte nebeneinander
   ergeben dort drei Zeilen Menue ueber jeder Seite. */
.admin-nav-toggle {
  width: 2.5rem; height: 2.5rem;
  border-color: #40505a;
  order: 5;
}
/* Dunkle Kopfleiste: Grund durchsichtig lassen, in jedem Zustand. */
.admin-nav-toggle,
.admin-nav-toggle:focus,
.admin-nav-toggle:active { background: transparent; }
.admin-nav-toggle[aria-expanded="true"] { background: #2b3944; border-color: #8d99a2; }
@media (hover: hover) {
  .admin-nav-toggle:hover { background: #2b3944; }
}
.admin-nav-toggle .nav-toggle-bar,
.admin-nav-toggle .nav-toggle-bar::before,
.admin-nav-toggle .nav-toggle-bar::after { background: #fff; }

@media (max-width: 61.99rem) {
  /*
   * Die Schaltflaeche gehoert zurueck.
   *
   * Die oeffentliche Seite blendet .nav-toggle ab 56rem aus, der interne
   * Bereich schaltet aber erst ab 62rem auf die Leiste um. Dazwischen -
   * zwischen 896 und 992 Pixeln - war das Menue versteckt und die
   * Schaltflaeche dazu: in diesem Fenster gab es im internen Bereich
   * ueberhaupt keine Navigation mehr. Aufgefallen beim Durchmessen der
   * Breiten, nicht im Betrieb; genau dort faellt so etwas auch nie auf,
   * weil kaum jemand sein Fenster auf 900 Pixel zieht.
   */
  .admin-nav-toggle { display: grid; }

  .admin-nav {
    display: none;
    flex: 0 0 100%;
    flex-direction: column;
    gap: .1rem;
    margin: .5rem 0 .75rem;
    order: 10;
  }
  /* Reihenfolge auf schmalen Geraeten: Kennzeichnung, Umschalter,
     Benutzer - und darunter das Menue, wenn es geoeffnet ist. */
  .admin-nav-toggle { order: 2; }
  .admin-user { order: 3; }
  .admin-brand { font-size: .6875rem; padding: .15rem .4rem; letter-spacing: .04em; }
  .admin-brand-icon { height: 24px; width: 24px; }
  .admin-brand-lockup { gap: .35rem; }
  .admin-logout button { padding: .3rem .6rem; font-size: .8125rem; }
  .admin-nav.is-open { display: flex; }
  .admin-nav a {
    padding: .6rem .2rem;
    border-bottom: 1px solid #2b3944;
  }
  .admin-head-inner { padding-top: .5rem; }
}

@media (min-width: 62rem) {
  .admin-nav-toggle { display: none; }
}
.admin-nav-soon { color: #8d99a2; }
.admin-profile {
  display: flex; align-items: center; gap: .5rem;
  color: #fff; text-decoration: none; font-size: .875rem;
}
.admin-profile:hover .admin-profile-name { text-decoration: underline; }
.admin-profile-name { white-space: nowrap; }
@media (max-width: 47.99rem) { .admin-profile-name { display: none; } }

/* ---------------- Profilbilder ---------------- */

/* Rund mit leichter Kontur, wie man es aus Teams kennt. Der Ausschnitt
   entsteht durch object-fit, damit auch ein hochkant aufgenommenes Foto
   mittig sitzt statt gestaucht zu werden. */
.avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  border-radius: 50%;
  overflow: hidden;
  background: var(--surface-2);
  box-shadow: 0 0 0 1px var(--rule), 0 0 0 2px rgba(255, 255, 255, .55);
  text-decoration: none;
  vertical-align: middle;
}
.avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }

.avatar-xs { width: 1.5rem;  height: 1.5rem;  font-size: .625rem; }
.avatar-sm { width: 2rem;    height: 2rem;    font-size: .75rem; }
.avatar-md { width: 2.75rem; height: 2.75rem; font-size: .9375rem; }
.avatar-lg { width: 5.5rem;  height: 5.5rem;  font-size: 1.75rem; }

/* Ohne Foto die Initialen. Der Farbton kommt aus dem Namen, damit
   derselbe Mensch immer dieselbe Farbe traegt. */
.avatar-initials {
  display: flex; align-items: center; justify-content: center;
  width: 100%; height: 100%;
  font-weight: 600; letter-spacing: .02em;
  color: hsl(var(--avatar-hue, 210) 45% 28%);
  background: hsl(var(--avatar-hue, 210) 45% 90%);
}

/* In der dunklen Kopfleiste braucht der Ring den umgekehrten Kontrast. */
.admin-head .avatar { box-shadow: 0 0 0 1px #47555f, 0 0 0 2px rgba(0, 0, 0, .35); }

/* Name mit Bildchen in einer Tabellenzeile. */
.by-person { display: inline-flex; align-items: center; gap: .4rem; text-decoration: none; color: inherit; }
.by-person:hover .by-person-name { color: var(--accent); text-decoration: underline; }
.by-person-name { white-space: nowrap; }

.photo-card, .person-card {
  display: flex; gap: 1.5rem; align-items: flex-start; flex-wrap: wrap;
  background: var(--surface); border: 1px solid var(--rule);
  padding: 1.25rem; margin-bottom: 1.25rem;
}
.photo-actions { display: flex; flex-direction: column; gap: .75rem; flex: 1 1 18rem; }
.photo-actions form { display: flex; flex-direction: column; gap: .5rem; align-items: flex-start; }
.photo-actions form input[type="file"] { max-width: 26rem; }

.person-details { flex: 1 1 18rem; }
.person-details h1 { margin: 0 0 .25rem; }
.person-role { margin: 0 0 1rem; color: var(--ink-2); font-size: .9375rem; }
.person-contact { display: grid; grid-template-columns: auto 1fr; gap: .35rem 1.25rem; margin: 0 0 1rem; }
.person-contact dt { color: var(--ink-2); font-size: .875rem; }
.person-contact dd { margin: 0; }

/* ---------------- Schnellzugriff für Angemeldete ---------------- */

/* Deutlich abgesetzt vom übrigen Inhalt: was hier steht, sieht ein
   Besucher nicht, und das soll man der Leiste ansehen. */
.staff-bar {
  display: flex; flex-wrap: wrap; align-items: center; gap: .6rem;
  background: var(--info-bg);
  border: 1px solid var(--rule);
  border-left: 3px solid var(--info);
  padding: .55rem .8rem;
  margin: 0 0 1.5rem;
  font-size: .875rem;
}
.staff-bar-label { color: var(--info); margin-right: auto; }
.staff-col { white-space: nowrap; }
.admin-logout button {
  background: none;
  border: 1px solid #40505a;
  color: #fff;
  padding: .35rem .8rem;
  font-size: .875rem;
}

.stat-row {
  display: grid;
  gap: 1px;
  grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
  background: var(--rule);
  border: 1px solid var(--rule);
  margin-bottom: 2rem;
}
.stat { background: var(--surface); padding: 1rem 1.1rem; display: flex; flex-direction: column; gap: .1rem; }
.stat-value { font-size: 1.75rem; font-weight: 600; font-variant-numeric: tabular-nums; }
.stat-label { font-size: .8125rem; color: var(--ink-2); }

.login-wrap { display: grid; place-items: center; align-content: center; gap: .25rem; min-height: 100vh; padding: 1.25rem; }
.login {
  width: 100%;
  max-width: 24rem;
  background: var(--surface);
  border: 1px solid var(--rule);
  padding: 1.75rem;
  display: flex;
  flex-direction: column;
  gap: 1rem;
}
.login h1 { margin: 0; font-size: 1.375rem; }
.login button { width: 100%; }

/* ---------------- Einstellungen ---------------- */

.settings-intro { max-width: 44rem; margin-bottom: 1.5rem; }

.settings fieldset {
  border: 1px solid var(--rule);
  background: var(--surface);
  padding: 1.25rem;
  margin: 0 0 1.25rem;
}
.settings legend {
  padding: 0 .5rem;
  font-weight: 600;
  font-size: .9375rem;
}
.settings-grid {
  display: grid;
  gap: 1.1rem;
  grid-template-columns: 1fr;
}
@media (min-width: 44rem) { .settings-grid { grid-template-columns: 1fr 1fr; } }

/* Missbrauchsschutz: das Handsperren-Formular sauber unter der Liste. */
.security-guard { margin-top: 2rem; }
.security-guard .guard-ban { margin-top: 1rem; max-width: 40rem; }
.security-guard .guard-ban-actions { margin-top: 1rem; }
/* Warnung „das ist Ihre eigene Adresse" - deutlich, aber nicht schreiend. */
.guard-ban-warn {
  display: flex; align-items: flex-start; gap: .45rem;
  margin: .9rem 0 0; padding: .6rem .8rem; max-width: 40rem;
  border: 1px solid var(--accent); border-radius: 8px;
  background: #fbeee8;
  background: color-mix(in srgb, var(--accent) 8%, var(--surface));
  color: var(--accent); font-size: .875rem; line-height: 1.4;
}
.guard-ban-warn .icon { flex: none; margin-top: .1rem; }

.settings .hint {
  margin: .3rem 0 0;
  font-size: .8125rem;
  color: var(--ink-3);
  line-height: 1.45;
}
.field-error {
  margin: .3rem 0 0;
  font-size: .8125rem;
  color: var(--accent);
}
/* Zeitfeld mit Knopf daneben, der es leert - ein natives Zeitfeld lässt
   sich auf dem Handy sonst nicht zurücksetzen. */
.input-clear {
  display: flex;
  align-items: center;
  gap: .6rem;
  flex-wrap: wrap;
}
.input-clear input[type="time"] { flex: 0 0 auto; }
.input-clear .is-clear { flex: 0 0 auto; }
.settings select {
  width: 100%;
  padding: .65rem .8rem;
  border: 1px solid var(--rule);
  background: var(--input-bg);
  color: var(--ink);
}
/* Sicherungsliste: Herunterladen und Löschen nebeneinander. */
.backup-actions { display: flex; gap: 1rem; align-items: center; }
.backup-actions form { margin: 0; }

/* Mediathek: wo ein Bild verwendet wird, mit Sprunglinks. */
.media-usage { margin: .5rem 0; }
.media-usage-title { margin: 0 0 .25rem; font-size: .8125rem; color: var(--muted-ink, #6b7280); }
.media-usage-list { margin: 0; padding-left: 1.1rem; font-size: .8125rem; }
.media-usage-list li { margin: .1rem 0; }

/* Anmeldeseite: Produktkennung oben, Urheberrecht unten. */
.login-brand { text-align: center; margin-bottom: 1.5rem; }
.login-logo { width: 300px; max-width: 80%; height: auto; }
.login-brand-name { display: block; font-weight: 700; font-size: 1.15rem; letter-spacing: .01em; }
.login-brand-tag { display: block; font-size: .8125rem; color: var(--muted-ink, #6b7280); margin-top: .1rem; }
.login-foot { margin-top: 1.5rem; text-align: center; font-size: .75rem; color: var(--muted-ink, #6b7280); }

/* Fußzeile des internen Bereichs: Produktname und Urheberrecht. */
.admin-foot { margin-top: 3rem; border-top: 1px solid var(--rule); padding: 1.25rem 0 2rem; }
.admin-foot-inner { display: flex; flex-direction: column; gap: .2rem; }
.admin-foot-logo { width: 140px; max-width: 45%; height: auto; margin-bottom: .4rem; opacity: .85; }
.admin-foot-legal { margin: 0; font-size: .8125rem; color: var(--muted-ink, #6b7280); }
.admin-foot-license { display: block; margin-top: .25rem; opacity: .85; }
.admin-foot-version { margin: .15rem 0 0; font-size: .75rem; color: var(--muted-ink, #6b7280); opacity: .8; }

/* Länderauswahl. Ohne JavaScript bleibt die Liste (No-JS-Rückfall). */
.settings select.country-select { padding: .25rem; min-height: 13rem; }
.settings select.country-select option { padding: .2rem .35rem; }

/* Mit JavaScript: Suche + Chips statt der Liste. */
.cp-row { display: flex; gap: .5rem; align-items: stretch; }
.cp-row .cp-input { flex: 1 1 auto; }
.cp-add { white-space: nowrap; }
.cp-chips { display: flex; flex-wrap: wrap; gap: .4rem; margin-top: .6rem; }
.cp-chip {
  display: inline-flex; align-items: center; gap: .1rem;
  padding: .2rem .3rem .2rem .55rem; border: 1px solid var(--rule);
  border-radius: 999px; background: var(--input-bg); font-size: .875rem;
}
.cp-x {
  border: 0; background: transparent; cursor: pointer; color: var(--muted-ink, #6b7280);
  font-size: 1.1rem; line-height: 1; padding: 0 .25rem; border-radius: 999px;
}
.cp-x:hover { color: var(--accent); }
.cp-none { color: var(--muted-ink, #6b7280); font-size: .875rem; }
.settings-test { margin-top: 2rem; }
.test-row {
  display: grid;
  gap: .75rem;
  grid-template-columns: 1fr;
  align-items: end;
  margin-top: .75rem;
}
@media (min-width: 44rem) { .test-row { grid-template-columns: 1fr auto; } }

/* ---------------- System und Schlüssel ---------------- */
.sys-danger {
  display: flex; align-items: flex-start; gap: .5rem;
  border: 1px solid var(--warn, #b45309); border-left-width: 3px;
  background: var(--warn-bg, #fff7ed); color: var(--ink-2);
  padding: .75rem .9rem; margin: 1rem 0; font-size: .9rem;
}
.sys-danger .icon { flex: 0 0 auto; color: var(--warn, #b45309); }
.sys-group { margin: 1.25rem 0; }
.sys-row { padding: .8rem 0; border-bottom: 1px solid var(--rule); }
.sys-row:last-child { border-bottom: 0; }
.sys-row.is-danger { border-left: 3px solid var(--warn, #b45309); padding-left: .7rem; }
.sys-head { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; }
.sys-label { font-weight: 600; }
.sys-src { font-size: .7rem; color: var(--muted-ink, #6b7280); border: 1px solid var(--rule); border-radius: 2px; padding: 0 .3rem; }
.sys-badge { font-size: .7rem; border-radius: 2px; padding: .05rem .4rem; }
.sys-badge.sys-ok   { background: var(--ok-bg);   color: var(--ok); }
.sys-badge.sys-bad  { background: var(--accent-2, #fde8e8); color: var(--accent, #9c3d19); }
.sys-badge.sys-warn { background: var(--warn-bg, #fff7ed); color: var(--warn, #b45309); }
.sys-value { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; margin: .4rem 0 0; }
.sys-secret, .sys-plain {
  background: var(--surface-2); border: 1px solid var(--rule); border-radius: 2px;
  padding: .2rem .45rem; font-size: .8125rem; word-break: break-all; max-width: 100%;
}
.sys-empty { color: var(--muted-ink, #6b7280); font-style: italic; font-size: .85rem; }
.sys-eye { font-size: .8125rem; }
.sys-note { margin: .35rem 0 0; }
.sys-gen { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; margin: .5rem 0 0; }
.sys-gen-out { flex: 1 1 20rem; min-width: 12rem; padding: .2rem .45rem; border: 1px solid var(--rule); background: var(--input-bg); font-size: .8125rem; }
.sys-gen .hint { flex-basis: 100%; margin: 0; }

/* ---------------- Auftraege ---------------- */

.page-head {
  display: flex; flex-wrap: wrap; gap: 1rem;
  align-items: center; justify-content: space-between;
}
.page-head h1 { margin: 0; }
.page-head-actions { display: flex; flex-wrap: wrap; gap: .6rem; }

/* Einwilligungsnachweis: zwei Schritt-Karten plus Kopf und Rechtshinweis. */
.consent { max-width: 62rem; }
.consent dl { margin: 0; }
.consent-head {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  gap: 1rem 1.5rem; padding: 1rem 1.2rem; margin: 0 0 1.4rem;
  border: 1px solid var(--rule); border-radius: 10px; background: var(--surface-2, #f1f4f6);
}
.consent-head dt, .consent-step dt {
  font-size: .72rem; text-transform: uppercase; letter-spacing: .05em;
  color: var(--ink-3, #8b959c); margin-bottom: .2rem;
}
.consent-head dd, .consent-step dd { margin: 0; font-size: 1rem; }
.consent-steps {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
  gap: 1.2rem; margin-bottom: 1.4rem;
}
.consent-step { border: 1px solid var(--rule); border-radius: 10px; padding: 1rem 1.2rem; }
.consent-step h2 { display: flex; align-items: center; gap: .5rem; font-size: 1.1rem; margin: 0; }
.consent-step dl { display: grid; gap: .7rem; margin-top: .9rem; }
.consent-no {
  display: inline-flex; align-items: center; justify-content: center;
  width: 1.6rem; height: 1.6rem; border-radius: 50%;
  background: var(--accent); color: #fff; font-size: .85rem; font-weight: 600; flex: none;
}
.consent-note {
  padding: .8rem 1rem; border-left: 3px solid var(--accent); border-radius: 6px;
  background: var(--surface-2, #f1f4f6); font-size: .9rem; line-height: 1.5; color: var(--ink-2, #56636c);
}

.order-filters {
  display: grid;
  gap: .9rem;
  grid-template-columns: 1fr;
  background: var(--surface);
  border: 1px solid var(--rule);
  padding: 1.1rem;
  margin: 1.25rem 0;
}
@media (min-width: 44rem) { .order-filters { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 68rem) { .order-filters { grid-template-columns: repeat(4, 1fr); } }
/* Auf breiten Schirmen der Filter flacher - jede eingesparte Zeile im
   Filterkasten ist eine zusaetzliche sichtbare Zeile in der Liste. */
.order-filters .field-wide { grid-column: 1 / -1; }

/* Auf breiten Schirmen der Filter flacher: jede eingesparte Zeile im
   Filterkasten ist eine zusaetzliche sichtbare Zeile in der Liste. Das
   Suchfeld braucht dann auch nicht mehr die ganze Breite. */
@media (min-width: 80rem) {
  .order-filters { grid-template-columns: repeat(6, 1fr); }
  .order-filters .field-wide { grid-column: span 2; }
}
.order-filters select { width: 100%; padding: .6rem .7rem; border: 1px solid var(--rule); background: var(--input-bg); color: var(--ink); }
/* ---------------- Spaltenauswahl ---------------- */

.columns-picker {
  grid-column: 1 / -1;
  border-top: 1px solid var(--rule-soft);
  padding-top: .8rem;
}
.columns-picker summary {
  cursor: pointer;
  font-size: .875rem;
  color: var(--ink-2);
  list-style-position: inside;
}
.columns-picker summary:hover { color: var(--accent); }
.columns-list {
  display: grid;
  gap: .35rem 1.25rem;
  grid-template-columns: repeat(auto-fill, minmax(13.5rem, 1fr));
  margin: .8rem 0 0;
}
.columns-list label {
  display: flex; align-items: center; gap: .45rem;
  font-size: .875rem; color: var(--ink); margin: 0;
}
.columns-list input { width: auto; }
/* Ohne Auftragsnummer, Container und Status ist eine Zeile nicht mehr
   zuzuordnen - die drei bleiben stehen. */
.columns-list label.is-locked { color: var(--ink-3); }
.columns-picker .hint { margin-top: .6rem; }

.field-check { display: flex; align-items: flex-end; }
.field-check label { display: flex; align-items: center; gap: .45rem; font-size: .875rem; color: var(--ink-2); margin: 0; }
.field-check input { width: auto; }

table.orders td { font-size: .9375rem; }
table.orders tr.is-deleted td { background: var(--accent-2); }
.inline-status select { padding: .3rem .4rem; font-size: .8125rem; border: 1px solid var(--rule); background: var(--surface); color: var(--ink); }
.inline-status { margin: 0; }

/* Nebeneinander statt untereinander: gestapelte Schaltflaechen machten
   jede Zeile viermal so hoch, und damit die Liste unuebersichtlich. */
.row-actions { display: flex; flex-wrap: nowrap; gap: .4rem; align-items: center; }
.row-actions form { margin: 0; }
.row-actions .action, .row-actions .action-link { white-space: nowrap; }
/* Wo mehrere Bedienelemente je Zeile stehen - Rolle, Zugang, Passwort -
   duerfen sie umbrechen; sonst wird die Spalte breiter als der Bildschirm. */
.row-actions.is-stacked { flex-wrap: wrap; row-gap: .45rem; }

/* Die Benutzerverwaltung haelt inzwischen sechs Handlungen je Zeile.
   Ohne eine Mindestbreite quetscht die Tabelle die Spalte zusammen, bis
   die Beschriftungen mitten im Wort abgeschnitten sind - sichtbar nur,
   wenn man waagerecht scrollt. Mit Mindestbreite umbrechen sie
   stattdessen. */
.row-actions.is-stacked { min-width: 14rem; }
.row-actions.is-stacked > form,
.row-actions.is-stacked > details { flex: 0 0 auto; }

/* Rolle und Sperre stehen in einer eigenen Reihe: die drei Bedienteile
   nebeneinander sind das breiteste in der Spalte, und alles andere
   muesste sich sonst danach richten. */
.row-actions.is-stacked > .user-access { flex-basis: 100%; }
@media (max-width: 47.99rem) { .row-actions { flex-wrap: wrap; } }

/* In der Arbeitsliste ist eine Zeile eine Zeile.
 *
 * Ohne diese Regel quetscht der Browser die Spalten auf ihre kleinste
 * Breite: aus "CMA CGM Elbe" werden drei Zeilen und aus einem Datensatz
 * ein 90 Pixel hoher Block. Lieber die natuerliche Spaltenbreite und
 * dafuer seitlich rollen - der Rollbalken liegt jetzt ja im Blick.
 */
@media (min-width: 48rem) {
  .table-viewport table.data th,
  .table-viewport table.data td { white-space: nowrap; }

  /* Ausnahme: mehrere Containernummern je Auftrag gehoeren untereinander. */
  .table-viewport table.orders td:nth-child(2) { white-space: normal; min-width: 15rem; }

  /* Lange Freitexte abschneiden. Eine einzige Anschrift in der
     Leerrueckgabe hat die Spalte auf 544 Pixel gebracht; der volle Text
     steht im Tooltip und in der Maske.
     Wie stark gekuerzt wird, stellt jeder selbst ein. */
  .table-viewport .clip {
    display: block;
    max-width: 13rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .table-viewport.width-kompakt .clip { max-width: 8rem; }
  .table-viewport.width-normal  .clip { max-width: 13rem; }
  .table-viewport.width-voll    .clip {
    max-width: none;
    overflow: visible;
    text-overflow: clip;
  }
}

.view-width {
  display: flex; align-items: center; flex-wrap: wrap; gap: .5rem;
  margin-top: .9rem; font-size: .875rem;
}
.view-width label { margin: 0; color: var(--ink-2); }
.view-width select { width: auto; padding: .3rem .5rem; }
.view-width .hint { margin: 0; }
.action, .action-link {
  font-size: .8125rem; padding: .25rem .55rem;
  border: 1px solid var(--rule); background: var(--surface-2);
  color: var(--ink); text-decoration: none; cursor: pointer;
}

/* ---------------- Schaltflaechen: Farbe nach Bedeutung ----------------
 *
 * Gleiche Handlung, gleiche Farbe - im ganzen Projekt. Die Toene sind
 * bewusst blass: eine Liste mit fuenf Schaltflaechen je Zeile wird sonst
 * zum Jahrmarkt. Kraeftig ist nur die Haupthandlung einer Seite.
 *
 *   dunkel gefuellt  Haupthandlung  - Neu, Speichern, Suchen, Anmelden
 *   blau             ansehen/holen  - PDF ansehen, herunterladen, Export
 *   neutral          bearbeiten     - Bearbeiten, Zurueck, Abbrechen
 *   gruen            wiederherstellen
 *   rot              loeschen, sperren
 */

.action-link.danger,
.action.is-delete,
.action-link.is-delete {
  color: var(--accent);
  border-color: #e0c4b7;
  background: var(--accent-2);
}
.action.is-delete:hover, .action-link.is-delete:hover,
.action-link.danger:hover { background: #f0dbd1; }

.action.is-view, .action.is-download, .action.is-export,
button.is-view, button.is-download, button.is-export {
  color: var(--info);
  border-color: #c3d6e1;
  background: var(--info-bg);
}
.action.is-view:hover, .action.is-download:hover, .action.is-export:hover,
button.is-view:hover, button.is-download:hover, button.is-export:hover {
  background: #d4e5ee;
}

.action.is-restore, button.is-restore {
  color: var(--ok);
  border-color: #bcd6c8;
  background: var(--ok-bg);
}
.action.is-restore:hover, button.is-restore:hover { background: #d6e8de; }

.action:hover, .action-link:hover { background: var(--rule-soft); }

/* Sinnbild und Beschriftung nebeneinander, mit gleichem Abstand ueberall. */
.action, .action-link, .button, button {
  display: inline-flex;
  align-items: center;
  gap: .35rem;
}
.icon { flex: none; width: 1em; height: 1em; }
.action .icon, .action-link .icon { width: .95em; height: .95em; }

/* In einer Zeile mit vier Schaltflaechen zaehlt jeder Millimeter: dort
   traegt die Schaltflaeche nur das Sinnbild, der Text steht im Titel. */
.row-actions.is-icons .action span,
.row-actions.is-icons .action-link span { display: none; }
.row-actions.is-icons .action,
.row-actions.is-icons .action-link { padding: .3rem .4rem; }

.pager-gap { padding: .35rem .3rem; color: var(--ink-3); }

.order-form .field-span { grid-column: 1 / -1; }
.order-form textarea {
  width: 100%; padding: .65rem .8rem;
  border: 1px solid var(--rule); background: var(--surface);
  color: var(--ink); font: inherit; border-radius: var(--radius);
}
.order-no-row { display: flex; align-items: center; gap: .4rem; }
.order-no-row input { width: 100%; }
.order-no-row input[size="2"] { width: 4rem; }
.static-value { margin: 0; padding: .65rem 0; font-weight: 600; }

.parsed-containers { list-style: none; margin: .6rem 0 0; padding: 0; display: flex; flex-wrap: wrap; gap: .5rem; }
.parsed-containers li { display: flex; align-items: center; gap: .35rem; font-size: .8125rem; }
.chip { padding: .1rem .4rem; border-radius: 2px; background: var(--surface-2); color: var(--ink-2); font-size: .75rem; }
/* „nur intern": ohne gewaehlte Farbe wie ein gewoehnliches Kennzeichen,
   mit Farbe ueber die von UiTheme gesetzten Variablen (nur im Backend). */
.chip-internal { background: var(--chip-internal-bg, var(--surface-2)); color: var(--chip-internal-fg, var(--ink-2)); }
.chip-ok { background: var(--ok-bg); color: var(--ok); }

/* Container-Feld als Plaettchen mit Suche (JS-Verbesserung). */
.ci-box {
  display: flex; flex-wrap: wrap; align-items: center; gap: .4rem;
  padding: .35rem .4rem; margin-top: .1rem;
  border: 1px solid var(--rule); background: var(--input-bg);
}
.ci-box:focus-within { border-color: var(--accent); }
.ci-chips { display: contents; }
.ci-chip {
  display: inline-flex; align-items: center; gap: .1rem;
  padding: .2rem .3rem .2rem .55rem; border: 1px solid var(--rule);
  border-radius: 999px; background: var(--surface); font-size: .8125rem;
}
.ci-chip .ci-x {
  border: 0; background: transparent; cursor: pointer;
  color: var(--muted-ink, #6b7280); font-size: 1.1rem; line-height: 1;
  padding: 0 .25rem; border-radius: 999px;
}
.ci-chip .ci-x:hover { color: var(--accent); }
.ci-search {
  flex: 1 1 12rem; min-width: 8rem; border: 0; padding: .2rem .1rem;
  background: transparent; font: inherit; color: inherit;
}
.ci-search:focus { outline: none; }
.ci-none { color: var(--muted-ink, #6b7280); font-size: .8125rem; }

.ci-suggest {
  position: relative; list-style: none; margin: .15rem 0 0; padding: .25rem;
  border: 1px solid var(--rule); background: var(--surface);
  box-shadow: 0 6px 18px rgba(0,0,0,.12); z-index: 20;
  max-height: 16rem; overflow-y: auto;
}
.ci-option {
  display: flex; align-items: baseline; justify-content: space-between; gap: .75rem;
  padding: .4rem .55rem; cursor: pointer; border-radius: 2px;
}
.ci-option:hover, .ci-option.is-active { background: var(--surface-2); }
.ci-option-label { font-size: .875rem; }
.ci-option-hint { color: var(--muted-ink, #6b7280); font-size: .75rem; white-space: nowrap; margin-left: auto; }
/* "Auftrag anhängen": der Hinweis traegt Kunde · Terminal · Datum und darf
   auf schmalen Schirmen umbrechen statt seitlich hinauszulaufen. */
.order-attach .ci-option-hint { white-space: normal; text-align: right; }
.order-attach .ci-suggest { margin-bottom: .5rem; }
.ci-option-order {
  font-size: .7rem; white-space: nowrap; border-radius: 2px; padding: .05rem .35rem;
  background: var(--warn-bg, #fff7ed); color: var(--warn, #b45309);
}

.form-actions { display: flex; align-items: center; gap: 1rem; }

/* Verstecktes bleibt versteckt. Ohne diese Regel gewinnt jede eigene
   display-Angabe gegen das hidden-Merkmal des Browsers - die Register
   schalten dann Bereiche um, die trotzdem stehen bleiben. */
[hidden] { display: none !important; }

/* ---------------- Sortierbare Spaltenkoepfe ---------------- */

table.data th a { color: inherit; text-decoration: none; white-space: nowrap; display: inline-block; }
table.data th a:hover { color: var(--accent); }
table.data th.is-sorted { background: var(--rule-soft); }
.sort-arrow { color: var(--accent); font-weight: 700; }

.mark-cell { text-align: center; }
.mark {
  display: inline-block; min-width: 1.3rem;
  font-weight: 700; color: var(--accent);
  cursor: help;
}
.mark-text { display: none; }

/* Telefon: kein Tooltip, also den Text selbst zeigen - gekuerzt auf drei
   Zeilen. Leere Felder fallen ganz weg; eine Zeile "Sonstiges" ohne
   Inhalt ist nur Rauschen. */
@media (max-width: 47.99rem) {
  table.data td.mark-cell { text-align: left; }
  table.data td.mark-cell.is-empty { display: none; }
  table.data td.mark-cell .mark { display: none; }
  table.data td.mark-cell .mark-text {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 3;
    overflow: hidden;
  }
}

.page-actions { display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; }

/* ---------------- Containererfassung ---------------- */

table.positions td { padding: .35rem; }
table.positions input { width: 100%; padding: .4rem .5rem; font-size: .875rem; }
table.positions .pos-no { text-align: center; color: var(--ink-3); font-size: .8125rem; padding-top: .75rem; }
@media (max-width: 47.99rem) { table.positions .pos-no { text-align: left; } }

tr.is-hidden-row td { background: var(--surface-2); }
tr.is-hidden-row .mono { color: var(--ink-2); }

button.secondary { background: var(--surface); color: var(--ink); border-color: var(--rule); }
button.secondary:hover { background: var(--surface-2); }

.container-form .field-check { align-items: flex-start; flex-direction: column; gap: .3rem; }

/* ---------------- Import ---------------- */

.req { color: var(--accent); }
.stat-value.is-bad { color: var(--crit, #a82019); }
.problem { color: var(--accent); font-size: .8125rem; }
.error-list { font-family: var(--mono); font-size: .8125rem; color: var(--accent); }
.pill-create { background: var(--ok-bg); color: var(--ok); }
.pill-update { background: var(--info-bg); color: var(--info); }
.pill-skip   { background: var(--accent-2); color: var(--accent); }
/* Weitere Zeile desselben Containers: kein eigener Vorgang, nur ein Nachtrag. */
.pill-merge  { background: var(--surface-2); color: var(--ink-2); }
input[type="file"] {
  width: 100%; padding: .6rem; border: 1px solid var(--rule);
  background: var(--surface); border-radius: var(--radius);
}

/* ---------------- Verlauf und Haftungsausschluss ---------------- */

.history { list-style: none; margin: 0 0 2rem; padding: 0; border-left: 2px solid var(--rule); }
.history li {
  position: relative;
  padding: .55rem 0 .55rem 1.25rem;
  display: flex; flex-wrap: wrap; gap: .25rem 1rem; align-items: baseline;
}
.history li::before {
  content: ""; position: absolute; left: -5px; top: 1.05rem;
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--rule); border: 2px solid var(--surface);
}
.history li:first-child::before { background: var(--accent); }
.history-date  { font-size: .8125rem; color: var(--ink-3); min-width: 6rem; font-variant-numeric: tabular-nums; }
.history-field { font-size: .8125rem; letter-spacing: .04em; text-transform: uppercase; color: var(--ink-2); }
.history-old   { color: var(--ink-3); text-decoration: line-through; }

/* Genaue Positionsaenderung: je Position eine Zeile, unter dem Feldnamen.
   Volle Breite in der Verlaufszeile, ohne den Zeitstrahl-Punkt der
   umgebenden Liste zu erben. */
.history-positions { list-style: none; margin: .2rem 0 0; padding: 0; flex-basis: 100%; }
.history-positions li {
  display: block; position: static; margin: 0; padding: .12rem 0;
  font-size: .875rem; color: var(--ink-1); font-variant-numeric: tabular-nums;
}
.history-positions li::before { content: none; }

.last-update { font-size: .8125rem; color: var(--ink-3); }

.disclaimer {
  margin-top: 2.5rem;
  border: 1px solid var(--rule);
  background: var(--surface-2);
  padding: 1.25rem 1.4rem;
}
.disclaimer h2 { margin: 0 0 .6rem; font-size: 1rem; }
.disclaimer p { font-size: .875rem; color: var(--ink-2); max-width: 60ch; }
.disclaimer p + p { margin-top: .5rem; }
.disclaimer-note { font-style: italic; }

/* ---------------- Update-Abo ---------------- */

.subscribe {
  margin-top: 2.5rem;
  border: 1px solid var(--rule);
  border-left: 3px solid var(--accent);
  background: var(--surface);
  padding: 1.4rem 1.5rem;
}
.subscribe h2 { margin: 0 0 .4rem; font-size: 1.125rem; }
.subscribe-intro { margin: 0 0 1.1rem; color: var(--ink-2); font-size: .9375rem; max-width: 52ch; }

.subscribe-triggers { border: 0; padding: 0; margin: 0 0 1.1rem; }
.subscribe-triggers legend {
  padding: 0; margin-bottom: .5rem;
  font-size: .8125rem; letter-spacing: .05em; text-transform: uppercase; color: var(--ink-2);
}
.subscribe-triggers label {
  display: inline-flex; align-items: center; gap: .4rem;
  margin: 0 1.25rem .4rem 0; font-size: .9375rem;
}
.subscribe-triggers input { width: auto; }

.subscribe-row { display: flex; flex-wrap: wrap; gap: .6rem; align-items: flex-end; }
.subscribe-row .field { flex: 1 1 18rem; margin: 0; }

.subscribe-consent {
  margin: 1rem 0 0; font-size: .8125rem; line-height: 1.55;
  color: var(--ink-3); max-width: 62ch;
}

.lead.is-error { color: var(--accent); }

@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; }
}

/* ---------------- Vorlagen und Benutzer ---------------- */

.suggest-layout { display: grid; gap: 1.5rem; grid-template-columns: 1fr; }
@media (min-width: 60rem) {
  .suggest-layout { grid-template-columns: 14rem 1fr; align-items: start; }
}

.suggest-fields { display: flex; flex-direction: column; gap: 1px; background: var(--rule); border: 1px solid var(--rule); }
.suggest-fields a {
  display: flex; justify-content: space-between; gap: .5rem;
  padding: .55rem .8rem; background: var(--surface);
  color: var(--ink); text-decoration: none; font-size: .9375rem;
}
.suggest-fields a:hover { background: var(--surface-2); }
.suggest-fields a.is-active { background: var(--ink); color: #fff; }
.suggest-fields a.is-active .muted { color: #b9c3ca; }

.suggest-content h2 { margin-top: 0; }
.suggest-add {
  display: grid; gap: .75rem; align-items: end;
  grid-template-columns: 1fr; margin-bottom: 1.25rem;
  background: var(--surface); border: 1px solid var(--rule); padding: 1rem;
}
@media (min-width: 44rem) { .suggest-add { grid-template-columns: 1fr 1fr auto; } }

.sort-input { width: 5rem; padding: .35rem .5rem; }

.suggest-adopt { list-style: none; margin: .6rem 0 0; padding: 0; display: flex; flex-wrap: wrap; gap: .5rem; }
.suggest-adopt form { margin: 0; }

.user-access { display: flex; flex-wrap: wrap; align-items: center; gap: .35rem; margin: 0; }
.user-access select { padding: .25rem .4rem; font-size: .8125rem; border: 1px solid var(--rule); background: var(--surface); color: var(--ink); }
.user-reset summary { cursor: pointer; font-size: .8125rem; color: var(--ink-2); }
.user-reset form { display: flex; gap: .35rem; margin-top: .35rem; }
.user-reset input { width: 10rem; padding: .25rem .4rem; font-size: .8125rem; }

.export-options { margin: 0 0 1.25rem; }
.export-options .columns-picker {
  border: 1px solid var(--rule); background: var(--surface);
  padding: .8rem 1.1rem; border-top: 1px solid var(--rule);
}
.export-run { display: flex; gap: .5rem; flex-wrap: wrap; margin-top: .9rem; }

/* ---------------- Mailtexte ---------------- */

.mailtexts textarea {
  width: 100%; padding: .55rem .7rem;
  border: 1px solid var(--rule); background: var(--surface);
  color: var(--ink); font: inherit; line-height: 1.5;
  border-radius: var(--radius); resize: vertical;
}
.mailtext-field { margin-bottom: 1.1rem; }
/* Geaenderte Texte bekommen eine Kante, damit man sie im langen Formular
   wiederfindet, ohne jedes Feld zu lesen. */
.mailtext-field.is-changed { border-left: 3px solid var(--info); padding-left: .7rem; }
.mailtext-field label { display: flex; align-items: center; gap: .5rem; }

.mailtext-vars { display: flex; flex-wrap: wrap; align-items: center; gap: .35rem; margin: .4rem 0 0; }
.mailtext-vars .hint { margin: 0; }
.insert-var { font-family: var(--mono); font-size: .8125rem; }

.mailtext-reset { margin: .45rem 0 0; }
.mailtext-reset .is-reset {
  font-size: .8125rem; color: var(--muted-ink, #6b7280);
  background: transparent; border: 1px solid var(--rule);
}
.mailtext-reset .is-reset:hover { color: var(--accent); border-color: var(--accent); }

.remember-templates { margin: 0 0 1rem; display: block; }
.remember-templates label { display: flex; align-items: center; gap: .45rem; }
.remember-templates .hint { margin: .3rem 0 0; }

/* ---------------- Register ---------------- */

/* Ohne JavaScript stehen alle Abschnitte untereinander und die Leiste
   wirkt als Sprungmarkenliste - laenger, aber vollstaendig bedienbar. */
.tabs {
  display: flex; flex-wrap: wrap; gap: .25rem;
  margin: 0 0 1.25rem;
  border-bottom: 1px solid var(--rule);
}
.tab {
  padding: .55rem .9rem;
  color: var(--ink-2); text-decoration: none;
  border: 1px solid transparent; border-bottom: 0;
  border-radius: var(--radius) var(--radius) 0 0;
  font-size: .9375rem;
  margin-bottom: -1px;
}
.tab:hover { color: var(--ink); background: var(--surface-2); }
.tab.is-active {
  background: var(--surface);
  border-color: var(--rule);
  color: var(--ink);
  font-weight: 600;
}

/* ---------------- Symbole in der Navigation ---------------- */

.admin-nav a { display: inline-flex; align-items: center; gap: .35rem; }
.admin-nav .icon { opacity: .75; }
.admin-nav a:hover .icon { opacity: 1; }

/* Auf mittleren Schirmen zaehlt jeder Millimeter - dort tragen die
   Punkte nur noch das Symbol, der Text bleibt im Titel und wird beim
   Zeigen eingeblendet. Neun Punkte mit Beschriftung passen dort sonst
   nicht in eine Zeile, und die Leiste wird doppelt so hoch. */
@media (min-width: 62rem) and (max-width: 91.99rem) {
  .admin-nav { gap: .5rem; }
  .admin-nav .nav-label { display: none; }
  .admin-nav a { padding: .3rem .45rem; border-radius: var(--radius); }
  .admin-nav a:hover { background: #2b3944; }
  .admin-nav .icon { width: 1.15rem; height: 1.15rem; opacity: .9; }
}

/* Auf schmalen Geraeten steht das Menue untereinander - dort gehoert die
   Beschriftung wieder dazu. */
@media (max-width: 61.99rem) {
  .admin-nav .nav-label { display: inline; }
}

/* ---------------- Sinnbilder auf der öffentlichen Seite ---------------- */

/* Zurueckhaltend: sie ordnen, sie schmuecken nicht. Farbe nehmen sie von
   der Schrift, Groesse vom Text - so bleibt der serioese Eindruck. */
.foot-contact { list-style: none; margin: 0; padding: 0; }
.foot-contact li { display: flex; align-items: flex-start; gap: .5rem; margin-bottom: .35rem; }
.foot-contact .icon { margin-top: .2rem; color: var(--ink-3); }

.foot-address { display: flex; align-items: flex-start; gap: .5rem; }
.foot-address .icon { margin-top: .2rem; color: var(--ink-3); flex: none; }

.disclaimer h2 { display: flex; align-items: center; gap: .5rem; }
.disclaimer h2 .icon { color: var(--info); width: 1.1rem; height: 1.1rem; }

/* ---------------- Symbole in Überschriften ---------------- */

/* Zurueckhaltend: ein Sinnbild ordnet die Ueberschrift, es ersetzt sie
   nicht. Groesse aus der Schrift, Farbe gedaempft. */
h1 .icon, h2 .icon, h3 .icon, legend .icon {
  width: .85em; height: .85em;
  color: var(--ink-3);
  vertical-align: -.08em;
  margin-right: .4rem;
  flex: none;
}

/* Ueberschriften bleiben Fliesstext, kein Flexbereich. Als Flexbereich
   bricht eine lange Ueberschrift auf schmalen Geraeten VOR dem Text um -
   das Sinnbild bliebe allein in der ersten Zeile stehen. Inline laeuft
   der Text um das Zeichen herum, wie man es erwartet. */
h1 .icon, h2 .icon, h3 .icon { display: inline-block; }

/* Auf einem Telefon ist eine Ueberschrift von 32px zu gross fuer ein
   Wort wie "Sendungsverfolgung": zusammen mit dem Sinnbild passt sie
   nicht mehr in eine Zeile, und das Zeichen bliebe allein oben stehen.
   Eine Stufe kleiner loest das und liest sich ohnehin besser. */
@media (max-width: 30rem) {
  h1 { font-size: 1.65rem; }
}
legend { display: flex; align-items: center; }
.tab .icon { width: 1em; height: 1em; margin-right: .35rem; opacity: .7; }
.tab.is-active .icon { opacity: 1; color: var(--accent); }

/* ---------------- Flaggen der Sprachumschaltung ---------------- */

.flag {
  border: 1px solid rgba(0, 0, 0, .15);
  border-radius: 2px;
  vertical-align: -.1em;
  margin-right: .35rem;
  flex: none;
}
.site-nav .lang { display: inline-flex; align-items: center; }
.page-actions .action { display: inline-flex; align-items: center; }

/* ---------------- Logo und Dateien ---------------- */

.branding-row {
  display: flex; gap: 1.25rem; flex-wrap: wrap;
  padding: 1rem 0; border-top: 1px solid var(--rule-soft);
}
.branding-row:first-of-type { border-top: 0; }
.branding-preview {
  flex: none; min-width: 8rem;
  display: flex; align-items: center;
}
.branding-preview img { background: var(--surface-2); padding: .35rem; border: 1px solid var(--rule); }
.branding-form { flex: 1 1 20rem; display: flex; flex-direction: column; gap: .6rem; align-items: flex-start; }
.branding-name { margin: 0; font-weight: 600; display: flex; align-items: center; gap: .5rem; }
.branding-form input[type="file"] { max-width: 26rem; }

/* ---------------- Freitext aus dem Backend ---------------- */

.rich-text p { max-width: 42rem; }
.rich-text p:last-child { margin-bottom: 0; }

.confirm-action { display: flex; align-items: center; gap: 1rem; flex-wrap: wrap; margin: 1.5rem 0; }

/* =====================================================================
   Sinnbilder mit Bedeutung, Sortierung, QR-Codes, zweiter Faktor
   ===================================================================== */

/* Einlagerung hinein, Auslieferung hinaus. Das sind die beiden einzigen
   Sinnbilder mit eigener Farbe - bei ihnen ist die Richtung die
   eigentliche Aussage, nicht Schmuck. Alle uebrigen nehmen weiterhin die
   Schriftfarbe ihrer Umgebung an. */
.icon-in  { color: var(--ok); }
.icon-out { color: var(--info); }

/* In Spaltenkoepfen ein wenig zurueckgenommen: die Ueberschrift soll
   fuehren, das Zeichen nur einordnen. */
table.data th .icon { opacity: .75; margin-right: .3rem; vertical-align: -.1em; }
table.data th .icon-in, table.data th .icon-out { opacity: 1; }
table.data td > .icon,
table.data .cell-inline > .icon { opacity: .6; margin-right: .3rem; vertical-align: -.15em; }

/* Haelt Sinnbild und Text einer Zelle zusammen. Noetig wegen der
   Kartenform auf schmalen Geraeten: dort ist jede Zelle ein Raster aus
   Beschriftung und Inhalt, und jedes Element im Inhalt bekaeme sonst
   eine eigene Zeile. */
.cell-inline {
  display: inline-flex;
  align-items: baseline;
  gap: .35rem;
  flex-wrap: wrap;
  min-width: 0;
}
.cell-inline > .icon { align-self: center; margin-right: 0; }

/* Sortierbare Spaltenkoepfe der oeffentlichen Liste. Der ganze Kopf ist
   anklickbar, nicht nur das Wort - das trifft man mit dem Finger. */
table.data th a {
  display: inline-flex;
  align-items: center;
  gap: .2rem;
  color: inherit;
  text-decoration: none;
}
table.data th a:hover { color: var(--accent); }
table.data th a:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
table.data th[aria-sort="none"] a::after {
  /* Ein blasser Doppelpfeil verraet, dass hier sortiert werden kann -
     erst beim Hinsehen, nicht als Dauergeflimmer in jeder Zeile. */
  content: "\2195";
  color: var(--ink-3);
  opacity: 0;
  transition: opacity .12s;
}
table.data th[aria-sort="none"] a:hover::after,
table.data th[aria-sort="none"] a:focus-visible::after { opacity: .7; }

/* Sinnbilder in der Menueleiste der oeffentlichen Seite. */
.site-nav a { display: inline-flex; align-items: center; gap: .4rem; }
.site-nav .icon { opacity: .65; }
.site-nav a:hover .icon { opacity: 1; }

/* --- Nach oben ------------------------------------------------------ */

/* Ein gewoehnlicher Sprunglink. Ohne JavaScript steht er dauerhaft da;
   mit Skript erscheint er erst, wenn es etwas zu scrollen gibt. */
.to-top {
  position: fixed;
  right: 1rem;
  bottom: 1rem;
  z-index: 40;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.6rem;
  height: 2.6rem;
  border: 1px solid var(--rule);
  border-radius: 50%;
  background: var(--surface);
  color: var(--ink-2);
  box-shadow: 0 1px 4px rgba(23, 32, 42, .18);
}
.to-top .icon { width: 1.15rem; height: 1.15rem; }
.to-top:hover { color: var(--accent); border-color: var(--accent); }

/* Nur wenn JavaScript laeuft, wird der Pfeil ueberhaupt versteckt: das
   Skript setzt dafuer eine Kennzeichnung ganz oben im Dokument. Ohne
   Skript greift keine dieser Regeln, und der Pfeil steht dauerhaft da -
   hoechstens ueberfluessig, nie hinderlich. */
html.has-to-top .to-top { opacity: 0; pointer-events: none; }
html.has-to-top .to-top.is-visible { opacity: 1; pointer-events: auto; }

@media (prefers-reduced-motion: no-preference) {
  .to-top { transition: opacity .15s, color .15s, border-color .15s; }
}

/* --- QR-Codes ------------------------------------------------------- */

.qr { display: block; border: 1px solid var(--rule); border-radius: var(--radius); background: #fff; }

.qr-preview { margin: 0 0 1rem; }
.qr-preview summary {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  cursor: pointer;
  color: var(--ink-2);
}
.qr-preview summary:hover { color: var(--accent); }

.qr-box {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1rem;
  margin-top: .75rem;
  padding: 1rem;
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  background: var(--surface);
}
.qr-url { font-size: .8rem; color: var(--ink-2); word-break: break-all; }

/* --- Zweiter Faktor -------------------------------------------------- */

.twofactor-state { display: flex; align-items: center; gap: .5rem; font-weight: 600; }
.twofactor-state.is-on  { color: var(--ok); }
.twofactor-state.is-off { color: var(--ink-2); font-weight: 400; }

.twofactor-on { display: inline-flex; align-items: center; gap: .3rem; color: var(--ok); }

.twofactor-setup {
  display: flex;
  flex-wrap: wrap;
  gap: 1.5rem;
  align-items: flex-start;
  margin-top: 1rem;
}
.twofactor-qr { flex: none; }
.twofactor-steps { flex: 1 1 18rem; }
.twofactor-steps ol { margin: 0 0 1rem; padding-left: 1.2rem; }
.twofactor-secret {
  padding: .5rem .75rem;
  border: 1px dashed var(--rule);
  border-radius: var(--radius);
  background: var(--surface-2);
  letter-spacing: .08em;
  word-break: break-all;
}

.twofactor-actions { display: flex; flex-wrap: wrap; gap: 2rem; margin-top: 1rem; }
.twofactor-actions form { flex: 1 1 16rem; }

/* Die Wiederherstellungscodes werden genau einmal gezeigt. Der Rahmen
   soll das auch aussehen lassen - wer hier weiterklickt, sieht sie nie
   wieder. */
.recovery-box {
  margin: 0 0 1.5rem;
  padding: 1rem 1.25rem;
  border: 2px solid var(--accent);
  border-radius: var(--radius);
  background: var(--accent-2);
}
.recovery-box h3 { display: flex; align-items: center; gap: .4rem; margin: 0 0 .5rem; }
.recovery-warn { margin: 0 0 .75rem; font-weight: 600; color: var(--accent); }

.recovery-codes {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
  gap: .4rem 1rem;
  margin: 0 0 1rem;
  padding-left: 1.5rem;
}
.recovery-codes li { font-size: 1.05rem; letter-spacing: .06em; }
.recovery-actions { display: flex; flex-wrap: wrap; gap: .5rem; }

.login-cancel { max-width: 22rem; margin: .75rem auto 0; text-align: center; }

/* --- Kaestchenlisten in den Einstellungen ---------------------------- */

.field-legend { margin: 0 0 .25rem; font-weight: 600; }

.checkbox-row { display: flex; flex-wrap: wrap; gap: .5rem 1.25rem; margin: .5rem 0; }
.checkbox-row label { display: inline-flex; align-items: center; gap: .4rem; }

.status-list { list-style: none; margin: 1rem 0; padding: 0; }
.status-list li {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .75rem;
  padding: .4rem 0;
  border-bottom: 1px solid var(--rule-soft);
}
.status-list label { display: inline-flex; align-items: center; gap: .5rem; }

/* --- Verlauf --------------------------------------------------------- */

.history-table .chip { margin-left: .4rem; }
.history-table .chip .icon { width: .85em; height: .85em; vertical-align: -.1em; margin-right: .2rem; }

/* ---------------- Protokoll ---------------- */

/* Die Bereiche als Leiste: eine Auswahlliste kann das nicht, weil sich
   eine optgroup nicht anwaehlen laesst - und "zeig mir alle
   Anmeldungen" ist die haeufigste Frage an ein Protokoll. */
.audit-groups { display: flex; flex-wrap: wrap; gap: .35rem; margin: 1rem 0; }

.audit-groups .chip {
  padding: .25rem .6rem;
  border: 1px solid var(--rule);
  border-radius: 999px;
  text-decoration: none;
  font-size: .8rem;
}

.audit-groups .chip:hover { border-color: var(--accent); color: var(--accent); }

.audit-groups .chip.is-active {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}

/* Die Einzelheiten sind Paare aus Schluessel und Wert, verschieden
   viele je Zeile. Umbrechen statt die Zeile zu sprengen. */
.audit-context { display: flex; flex-wrap: wrap; gap: .25rem; }
.audit-context .chip { max-width: 22rem; overflow-wrap: anywhere; }
.audit-context .chip .muted { margin-right: .25rem; }

/* --- Drucken --------------------------------------------------------- */

@media print {
  /* Beim Ausdruck der Wiederherstellungscodes soll nur das Blatt mit den
     Codes herauskommen - nicht die halbe Verwaltungsoberflaeche. */
  .admin-head,
  .site-head,
  .site-foot,
  .tabs,
  .to-top,
  .photo-card,
  .flash { display: none !important; }

  /*
   * Erklaerende Texte gehoeren auf keinen Ausdruck.
   *
   * Ein Hinweis wie "Ein Code, der ins Leere fuehrt, waere schlimmer als
   * keiner" erklaert am Bildschirm, warum etwas so ist. Auf Papier
   * erklaert er niemandem mehr etwas - dort steht er nur im Weg und
   * sieht aus, als gehoerte er zum Auftrag.
   *
   * Ausgenommen sind die Wiederherstellungscodes: dort traegt der
   * Hinweis, dass jeder Code genau einmal gilt, und genau der gehoert
   * mit auf den Zettel.
   */
  .hint,
  .section-note,
  .settings-intro,
  .field-error,
  .remember-templates,
  .order-links,
  .editor-media,
  .user-rights,
  .row-actions,
  .page-actions,
  .form-actions,
  .filters,
  .pager { display: none !important; }

  .recovery-box .hint { display: block !important; }

  /* Eingabefelder auf Papier: Rahmen weg, Inhalt bleibt lesbar. */
  input, textarea, select {
    border: 0 !important;
    padding: 0 !important;
    background: transparent !important;
    color: #000 !important;
  }

  .recovery-box { border-color: #000; background: #fff; }
  .recovery-codes li { font-family: var(--mono); }

  a[href]::after { content: ""; }
}

/* =====================================================================
   Editor, Mediathek, Rechte
   ===================================================================== */

/* --- Bilder im Fliesstext ------------------------------------------- */

/* Ausrichtung und Groesse kommen als Klasse, nie als style-Attribut:
   so entscheidet weiterhin dieses Stylesheet, wie etwas aussieht. Ein
   freies style waere die Hintertuer, durch die sich jede Regel der
   Seite aushebeln liesse. */
.rich-text img { height: auto; border-radius: var(--radius); }

.rich-text .media-center { display: block; margin: 1.25rem auto; }
.rich-text .media-full   { display: block; width: 100%; margin: 1.25rem 0; }
.rich-text .media-left   { float: left;  margin: .35rem 1.25rem .75rem 0; }
.rich-text .media-right  { float: right; margin: .35rem 0 .75rem 1.25rem; }

/* Ausrichtung von Absaetzen, Ueberschriften, Bildern und Tabellen.
   Der Editor schreibt sie als Klasse, nicht als style - so entscheidet
   weiterhin dieses Stylesheet, wie etwas aussieht. */
.rich-text .align-center { display: block; margin-left: auto; margin-right: auto; text-align: center; }
.rich-text .align-left   { text-align: left; }
.rich-text .align-right  { text-align: right; }
.rich-text img.align-left  { float: left;  margin: .35rem 1.25rem .75rem 0; }
.rich-text img.align-right { float: right; margin: .35rem 0 .75rem 1.25rem; }

.rich-text table { border-collapse: collapse; width: 100%; margin: 0 0 1rem; }
.rich-text th, .rich-text td { border: 1px solid var(--rule); padding: .4rem .6rem; text-align: left; }
.rich-text th { background: var(--surface-2); font-weight: 600; }

.rich-text .size-25  { max-width: 25%; }
.rich-text .size-50  { max-width: 50%; }
.rich-text .size-75  { max-width: 75%; }
.rich-text .size-100 { max-width: 100%; }

/* Ein umflossenes Bild darf nicht in den naechsten Abschnitt ragen. */
.rich-text::after { content: ""; display: block; clear: both; }

.rich-text h2 { font-size: 1.25rem; margin: 1.75rem 0 .5rem; }
.rich-text h3 { font-size: 1.0625rem; margin: 1.5rem 0 .5rem; }
.rich-text ul, .rich-text ol { margin: 0 0 1rem; padding-left: 1.35rem; }
.rich-text li { margin: 0 0 .25rem; }
.rich-text blockquote {
  margin: 1rem 0;
  padding: .35rem 0 .35rem 1rem;
  border-left: 3px solid var(--rule);
  color: var(--ink-2);
}
.rich-text a { color: var(--accent); }

/* Textfarben aus der Palette der Seite.
   Eine feste Auswahl statt eines freien Farbwaehlers: welcher Farbwert
   hinter einem Namen steht, entscheidet dieses Stylesheet. Aendert sich
   die Hausfarbe, aendert sie sich ueberall - auch in bereits gepflegten
   Texten. */
.rich-text .text-accent { color: var(--accent); }
.rich-text .text-muted  { color: var(--ink-2); }
.rich-text .text-ok     { color: var(--ok); }
.rich-text .text-warn   { color: var(--warn); }
.rich-text .text-info   { color: var(--info); }
.rich-text .mark-accent { background: var(--accent-2); padding: .05em .25em; border-radius: 2px; }


/* Auf einem Telefon steht ein umflossenes Bild im Weg: unter 34rem
   bleibt kein Platz fuer Text daneben, der noch lesbar waere. */
@media (max-width: 34rem) {
  .rich-text .media-left,
  .rich-text .media-right,
  .rich-text img.align-left,
  .rich-text img.align-right {
    float: none;
    display: block;
    margin: 1rem auto;
  }
  .rich-text .size-25, .rich-text .size-50, .rich-text .size-75 { max-width: 100%; }
}

/* --- Mediathek -------------------------------------------------------- */

.media-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
  gap: 1rem;
  list-style: none;
  margin: 1.5rem 0 0;
  padding: 0;
}

/* Dateiliste (Dokumente) */
.doc-list { list-style: none; margin: 1.5rem 0 0; padding: 0; display: flex; flex-direction: column; gap: .8rem; }
.doc-card { border: 1px solid var(--rule); border-radius: 8px; padding: .8rem 1rem; background: var(--surface); }
.doc-card.is-new { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-2); }
.doc-main { display: flex; align-items: center; gap: .75rem; }
.doc-ext { flex: 0 0 auto; font-size: .75rem; font-weight: 700; color: var(--accent, #9c3d19); border: 1px solid var(--rule); border-radius: 4px; padding: .15rem .4rem; }
.doc-info { min-width: 0; }
.doc-name { font-weight: 600; word-break: break-word; }
.doc-meta { margin: .15rem 0 0; font-size: .8125rem; color: var(--muted-ink, #6b7280); overflow-wrap: anywhere; }
.doc-url { display: block; margin: .5rem 0; }
.doc-url input { width: 100%; box-sizing: border-box; padding: .25rem .45rem; border: 1px solid var(--rule); background: var(--surface-2); font-size: .8125rem; }
.doc-rename { display: flex; gap: .4rem; align-items: center; margin: .3rem 0; }
.doc-rename input { flex: 1 1 auto; min-width: 8rem; padding: .3rem .45rem; border: 1px solid var(--rule); background: var(--input-bg); font: inherit; }

.media-card {
  display: flex;
  flex-direction: column;
  gap: .4rem;
  padding: .75rem;
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  background: var(--surface);
}
.media-card.is-new { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-2); }

.media-thumb {
  display: block;
  background: var(--surface-2);
  border-radius: var(--radius);
  overflow: hidden;
}
.media-thumb img { display: block; width: 100%; height: 9rem; object-fit: contain; }

.media-name {
  margin: 0;
  font-weight: 600;
  font-size: .875rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.media-meta { margin: 0; font-size: .8125rem; color: var(--ink-2); }
.media-url input { width: 100%; font-size: .8125rem; }
.media-alt { display: flex; gap: .35rem; align-items: center; }
.media-alt input { flex: 1 1 auto; min-width: 0; font-size: .8125rem; }
.media-usage { margin: 0; font-size: .8125rem; }

/* --- Rechte ----------------------------------------------------------- */

/* Die Rechte in Spalten statt untereinander. Fuenfzehn Kaestchen in
   einer Reihe waeren eine Liste zum Durchlesen; in vier Gruppen
   nebeneinander sieht man auf einen Blick, was ein Konto darf. */
.permission-columns {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: .75rem 1.25rem;
  margin: .75rem 0;
}

.permission-group { margin: 0; padding: .6rem .85rem; }
.permission-group legend { font-size: .8125rem; color: var(--ink-2); }

.permission-item {
  display: flex;
  align-items: flex-start;
  gap: .45rem;
  padding: .12rem 0;
  font-size: .9375rem;
}
.permission-item input { margin-top: .2rem; flex: none; }

/* Eigene Zeile ueber die volle Tabellenbreite - in der Aktionsspalte
   waere fuer die Kaestchen kein Platz. */
tr.rights-row td { padding-top: 0; border-top: 0; }
tr.rights-row + tr td { border-top: 1px solid var(--rule); }

.user-rights { margin: 0 0 .35rem; }
.user-rights summary { display: inline-flex; align-items: center; gap: .3rem; cursor: pointer; color: var(--ink-2); }
.user-rights summary:hover { color: var(--accent); }
.user-rights[open] summary { color: var(--accent); margin-bottom: .35rem; }

/* --- Verknuepfung Auftrag/Sendungsverfolgung ------------------------ */

.order-links { margin: 1.5rem 0; }

.link-list { list-style: none; margin: .75rem 0 0; padding: 0; }

.link-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .5rem .75rem;
  padding: .55rem 0;
  border-bottom: 1px solid var(--rule-soft);
}
.link-row:last-child { border-bottom: 0; }
.link-label { flex: 0 0 auto; font-weight: 600; }

/* Voller-Breite-Umbruch in der Flex-Zeile: zwingt die folgenden
   Schaltflaechen gemeinsam in die naechste Zeile, statt eine allein
   umbrechen zu lassen. */
.link-break { flex-basis: 100%; height: 0; margin: 0; padding: 0; }
.link-choice select { max-width: 22rem; }

.checkbox-inline { display: inline-flex; align-items: center; gap: .4rem; margin-top: .5rem; }

/* Ein Hinweis, der erklaert, woher ein Teil des Inhalts kommt. */
.section-note {
  display: flex;
  align-items: flex-start;
  gap: .45rem;
  margin: 0 0 1rem;
  padding: .6rem .8rem;
  border-left: 3px solid var(--info);
  background: var(--info-bg);
  color: var(--ink);
}
.section-note .icon { flex: none; color: var(--info); margin-top: .15rem; }

/* =====================================================================
   Auswertung
   ===================================================================== */

/*
 * Die Diagramme kommen als SVG vom Server. Gefaerbt wird hier, nicht
 * dort: sonst muesste die Hausfarbe an zwei Stellen gepflegt werden,
 * und App\Services\Chart wuesste ploetzlich etwas ueber das Aussehen
 * der Seite.
 */

.chart-block { margin: 0 0 2.5rem; }
.chart-block h2 { margin-bottom: .35rem; }

.chart-frame {
  background: var(--surface);
  border: 1px solid var(--rule);
  padding: 1rem .75rem;
  margin: 0 0 .75rem;
}

.chart { display: block; width: 100%; height: auto; }

.chart-bar { fill: var(--accent); }
.chart-grid { stroke: var(--rule-soft); stroke-width: 1; }
.chart-axis { stroke: var(--rule); }

.chart-tick { font-size: 11px; fill: var(--ink-3); }
.chart-tick-left { text-anchor: end; }

.chart-value {
  font-size: 11px;
  fill: var(--ink-2);
  font-variant-numeric: tabular-nums;
}
.chart-value-left { text-anchor: start; }

/* Reicht die Saeule bis an den oberen Rand, steht die Zahl in ihr. */
.chart-value-inside { fill: var(--surface); }
.chart-note { font-size: 10px; fill: var(--ink-3); }

/* Ein Balken, der in eine Liste fuehrt, muss auch danach aussehen. */
.chart-link { cursor: pointer; }
.chart-link:hover .chart-bar,
.chart-link:focus .chart-bar { fill: var(--ink); }
.chart-link:hover .chart-value,
.chart-link:focus .chart-value { fill: var(--ink); }
.chart-link:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Der Satz, wegen dem das Diagramm dasteht. */
.chart-lead {
  margin: 0 0 .75rem;
  font-size: 1rem;
  color: var(--ink);
}

.chart-numbers { margin: 0; }
.chart-numbers > summary {
  cursor: pointer;
  font-size: .8125rem;
  color: var(--ink-2);
  padding: .35rem 0;
}
.chart-numbers > summary:hover { color: var(--accent); }
.chart-numbers .data { margin-top: .5rem; }

/* Eine Kennzahl, die in ihre Liste fuehrt. */
.stat-link { text-decoration: none; color: inherit; }
.stat-link:hover { background: var(--surface-2); }
.stat-link:hover .stat-value { color: var(--accent); }
.stat-label .icon { vertical-align: -.15em; margin-right: .3rem; color: var(--ink-3); }

.num { text-align: right; font-variant-numeric: tabular-nums; }

.gaps-table tr.is-clean td { color: var(--ink-3); }
.gap-clean { color: var(--ok); }
.gap-clean .icon { vertical-align: -.15em; }

@media print {
  /*
   * Auf dem Ausdruck einer Auswertung muss stehen, was weggelassen
   * wurde. Eine Liegezeit ohne den Hinweis, dass 20 Datensaetze wegen
   * Datumsfehlern draussen blieben, ist auf Papier nicht mehr
   * nachvollziehbar - dort kann niemand nachfragen.
   */
  .chart-block .hint,
  .chart-block .section-note { display: block !important; }

  .chart-frame { border-color: #000; break-inside: avoid; }
  .chart-bar { fill: #333 !important; }
  .chart-block { break-inside: avoid; }
}

/* --- Archiv ---------------------------------------------------------- */

/* Was im Archiv liegt, und von wann bis wann.
   Das ist die Angabe, ohne die das Zurueckholen ein Ratespiel ist: das
   Formular verlangt zwei Daten, und welche passen, wusste vorher nur,
   wer sich erinnerte, womit er archiviert hat. */
.archive-holds {
  margin: 0 0 1rem;
  padding: .6rem .8rem;
  border-left: 3px solid var(--info);
  background: var(--info-bg);
  font-variant-numeric: tabular-nums;
}

/* --- Kopfleiste: der Weg zur öffentlichen Website -------------------- */

.admin-public {
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  color: #fff;
  text-decoration: none;
  white-space: nowrap;
  padding: .3rem .55rem;
  border: 1px solid #40505a;
  border-radius: var(--radius);
  font-size: .8125rem;
}
.admin-public:hover { background: #2a3540; }

/* Die Beschriftung folgt derselben Grenze wie die der Menuepunkte -
   siehe dort. Eine eigene waere ein Sonderfall, den spaeter niemand
   mehr erklaeren kann. */

/* --- Einstellungen: Zwischenüberschrift und letzter Lauf ------------- */

.settings-sub {
  margin: 1.75rem 0 .35rem;
  font-size: 1rem;
  border-top: 1px solid var(--rule-soft);
  padding-top: 1.25rem;
}

.settings-lastrun {
  display: flex;
  align-items: center;
  gap: .4rem;
  margin: 1rem 0 0;
  color: var(--ink-2);
  font-size: .8125rem;
}
.settings-lastrun .icon { color: var(--ink-3); }

/* =====================================================================
   Pflege: Übersicht und Wechselleiste
   ===================================================================== */

/*
 * Rahmen an den Karten, nicht als Hintergrund zwischen ihnen.
 *
 * Der uebliche Kniff - ein Gitter mit 1px Luecke auf grauem Grund -
 * zeigt in der letzten Reihe die leeren Zellen als graue Flaeche. Bei
 * fuenf Karten und vier Spalten sieht das aus, als fehle dort etwas.
 */
.upkeep-grid {
  display: grid;
  gap: .75rem;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
}

.upkeep-card {
  display: flex;
  flex-direction: column;
  gap: .3rem;
  padding: 1.25rem 1.35rem;
  background: var(--surface);
  border: 1px solid var(--rule);
  color: inherit;
  text-decoration: none;
}
.upkeep-card:hover { background: var(--surface-2); border-color: var(--accent); }
.upkeep-card:hover .upkeep-label { color: var(--accent); }

.upkeep-icon { color: var(--ink-3); }
.upkeep-card:hover .upkeep-icon { color: var(--accent); }
.upkeep-label { font-weight: 600; font-size: 1.0625rem; }
.upkeep-hint { color: var(--ink-2); font-size: .8125rem; line-height: 1.45; }

/* Die Leiste auf den vier Seiten: derselbe eine Klick wie früher, als
   alle vier in der Kopfleiste standen. */
.upkeep-nav {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .25rem .5rem;
  margin: 0 0 1.5rem;
  padding-bottom: .6rem;
  border-bottom: 1px solid var(--rule-soft);
}

.upkeep-back {
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  color: var(--ink-2);
  text-decoration: none;
  font-size: .8125rem;
  padding: .3rem .5rem .3rem 0;
  margin-right: .35rem;
  border-right: 1px solid var(--rule);
}
.upkeep-back:hover { color: var(--accent); }

.upkeep-tab {
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  padding: .35rem .7rem;
  border-radius: var(--radius);
  color: var(--ink-2);
  text-decoration: none;
  font-size: .875rem;
}
.upkeep-tab:hover { background: var(--surface-2); color: var(--ink); }
.upkeep-tab.is-active {
  background: var(--accent-2);
  color: var(--accent);
  font-weight: 600;
}
.upkeep-tab .icon { color: currentColor; }

/* Der Knopf an der Kennzahl und in den Einstellungen. */
.stat-action { margin-top: .6rem; }
.stat-action button { font-size: .8125rem; padding: .3rem .6rem; }
.settings-dispatch { margin: 1rem 0 0; }

@media print {
  .upkeep-nav, .stat-action, .settings-dispatch { display: none !important; }
}

/* --- Wer hört bei einem Container mit? ------------------------------- */

/* Nur Zahlen, nie eine Adresse. Steht bei den Feldern, die man gerade
   ändert - sonst ändert jemand die ETA, wartet auf eine Mail und
   erfährt nie, dass alle Abonnenten nur den Status abonniert haben. */
.subscriber-note {
  display: flex;
  align-items: flex-start;
  gap: .5rem;
  margin: 0 0 .35rem;
  padding: .6rem .8rem;
  border-left: 3px solid var(--info);
  background: var(--info-bg);
  font-size: .875rem;
}
.subscriber-note > .icon { flex: none; margin-top: .15rem; color: var(--info); }

.subscriber-count {
  display: inline-flex;
  align-items: center;
  gap: .25rem;
  margin-left: .75rem;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.subscriber-count strong { font-variant-numeric: tabular-nums; }
/* Null Abonnenten bleiben stehen, aber zurückhaltend: die Null ist die
   eigentliche Auskunft, nicht das Fehlen der Zeile. */
.subscriber-count.is-zero { color: var(--ink-3); }

.subscriber-hint { margin: 0 0 1.25rem; }

/* Einzelne Abos, maskiert - eine Zeile je Abo, die auf schmalen Geräten
   sauber umbricht. Kein Tabellenzwang: auf dem Smartphone stapeln sich
   Adresse, Felder, Status und Löschen untereinander. */
.subscriber-list { margin: 0 0 1rem; }
.subscriber-list > .field-legend { margin: 0 0 .5rem; }
.subscriber-item {
  display: flex; flex-wrap: wrap; align-items: center; gap: .5rem .75rem;
  padding: .5rem .65rem; border: 1px solid var(--rule); border-radius: 8px;
  margin-bottom: .4rem; background: var(--surface);
}
.subscriber-item-mail { flex: 1 1 12rem; word-break: break-all; }
.subscriber-item-fields { display: flex; flex-wrap: wrap; gap: .3rem; }
.subscriber-item-state { display: flex; flex-wrap: wrap; gap: .3rem; }
.subscriber-item-del { flex: none; margin-left: auto; }

@media print {
  .subscriber-note, .subscriber-hint, .subscriber-list { display: none !important; }
}

/* Selbstverwaltungs-Liste (öffentlich): ein Abo je Zeile, bricht auf
   schmalen Geräten sauber um. */
.manage-list { list-style: none; margin: 0 0 1.5rem; padding: 0; }
.manage-item {
  display: flex; flex-direction: column; align-items: stretch; gap: .75rem;
  padding: .9rem 1rem; border: 1px solid var(--rule); border-radius: 10px;
  margin-bottom: .75rem;
}
.manage-item-main { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem .75rem; }
.manage-item-no { font-weight: 600; font-size: 1.05rem; }
.manage-item-fields { display: flex; flex-wrap: wrap; gap: .3rem; }

/* Abo-Art ändern: Kästchenreihe, PDF-Zeile, Speichern. */
.manage-edit { display: flex; flex-direction: column; gap: .6rem; margin: 0; }
.manage-triggers { border: 0; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: .35rem .9rem; }
.manage-triggers legend { padding: 0 0 .3rem; font-size: .8125rem; color: var(--ink-2); }
.manage-triggers label,
.manage-pdf { display: inline-flex; align-items: center; gap: .35rem; font-size: .9rem; }
.manage-pdf { margin: 0; }
.manage-edit button { align-self: flex-start; }
/* Das Abbestellen deutlich vom Ändern absetzen. */
.manage-remove { margin: 0; padding-top: .6rem; border-top: 1px solid var(--rule); }

/* Gültigkeit des Links: Stunden + Minuten nebeneinander. */
.ttl-row { display: flex; flex-wrap: wrap; gap: 1rem; align-items: flex-end; }

/* Das QR gehört zur Zeile, nicht in die Reihe der Schaltflächen -
   deshalb zurückhaltend und direkt an der Containernummer. */
.chip-qr { background: var(--surface-2); color: var(--ink-2); }
.chip-qr .icon { vertical-align: -.15em; margin-right: .2rem; }

/* Herkunft, nicht Arbeit: klein und am Fuß der Maske. */
.form-meta {
  display: flex;
  align-items: center;
  gap: .4rem;
  margin: 1rem 0 0;
  color: var(--ink-2);
  font-size: .8125rem;
}

@media print { .form-meta { display: none !important; } }

/* --- Blick in den Versand -------------------------------------------- */

.delivery-log { margin: 1.25rem 0 0; }
.delivery-log > summary {
  cursor: pointer;
  font-size: .8125rem;
  color: var(--ink-2);
  padding: .35rem 0;
}
.delivery-log > summary:hover { color: var(--accent); }
.delivery-log .data { margin-top: .6rem; }

.chip-ok  { background: var(--ok-bg);   color: var(--ok); }
.chip-bad { background: var(--accent-2); color: var(--accent); }
.chip-warn { background: var(--warn-bg); color: var(--warn); cursor: help; white-space: nowrap; }
.chip-ok .icon { vertical-align: -.15em; margin-right: .2rem; }

/* --- Hilfe ------------------------------------------------------------ */

/* Die Suche ist das Erste, was man braucht - breit und gut zu treffen,
   mit dem Lupenzeichen im Feld statt davor. */
.help-search { display: flex; flex-wrap: wrap; gap: .6rem; max-width: 42rem; margin: 0 0 .5rem; }
.help-search-field { position: relative; flex: 1 1 16rem; min-width: 0; }
.help-search-field .icon {
  position: absolute; left: .8rem; top: 50%; transform: translateY(-50%);
  width: 1.05rem; height: 1.05rem; color: var(--ink-3); pointer-events: none;
}
.help-search-field input {
  width: 100%;
  padding: .75rem .9rem .75rem 2.5rem;
  font-size: 1.0625rem;
  border: 1px solid var(--rule);
  background: var(--surface);
  color: var(--ink);
}
.help-search-field input:focus { border-color: var(--ink-3); }

.help-count { margin: 0 0 1.25rem; font-size: .875rem; color: var(--ink-2); }

/* Themen als Sprungmarken - auf dem Telefon brechen sie um. */
.help-toc { display: flex; flex-wrap: wrap; gap: .45rem; margin: 0 0 1.75rem; }
.help-toc a {
  display: inline-flex; align-items: center; gap: .35rem;
  padding: .3rem .7rem;
  border: 1px solid var(--rule); border-radius: 999px;
  background: var(--surface);
  color: var(--ink); text-decoration: none; font-size: .875rem;
}
.help-toc a:hover { border-color: var(--ink-3); color: var(--accent); }
.help-toc .icon { color: var(--ink-3); }

.help-section { margin: 0 0 2rem; max-width: 52rem; scroll-margin-top: 1rem; }
.help-section h2 {
  display: flex; align-items: center; gap: .45rem;
  font-size: 1.125rem; margin: 0 0 .7rem;
}
.help-section h2 .icon { color: var(--accent); width: 1.15rem; height: 1.15rem; }

/* Die Fragen als zusammenhaengende Liste: gemeinsame Kanten statt
   einzelner Kaesten mit Luecken dazwischen. */
.help-item {
  background: var(--surface);
  border: 1px solid var(--rule);
  scroll-margin-top: 1rem;
}
.help-item + .help-item { border-top: 0; }
.help-item > summary {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem;
  padding: .8rem 1rem;
  cursor: pointer;
  font-weight: 600;
  list-style: none;
}
.help-item > summary::-webkit-details-marker { display: none; }
.help-item .help-q { flex: 1 1 auto; min-width: 0; }
.help-item > summary::after {
  content: "";
  flex: none;
  width: .5rem; height: .5rem; margin-top: .45rem;
  border-right: 2px solid var(--ink-3); border-bottom: 2px solid var(--ink-3);
  transform: rotate(45deg);
  transition: transform .15s;
}
.help-item[open] > summary::after { transform: rotate(225deg); margin-top: .7rem; }
.help-item > summary:hover { color: var(--accent); }
.help-item[open] > summary { border-bottom: 1px solid var(--rule-soft); }
@media (prefers-reduced-motion: reduce) { .help-item > summary::after { transition: none; } }

.help-answer { padding: .35rem 1rem 1rem; max-width: 46rem; color: var(--ink); }
.help-answer p { margin: .6rem 0 0; }
.help-answer ul, .help-answer ol { margin: .6rem 0 0; padding-left: 1.3rem; }
.help-answer li + li { margin-top: .25rem; }
.help-answer strong { font-weight: 600; }
/* Bedienelemente und Menuewege so, wie sie auf dem Schirm heissen. */
.help-answer .ui {
  padding: 0 .3rem;
  border: 1px solid var(--rule);
  border-radius: 2px;
  background: var(--surface-2);
  font-size: .9em;
  white-space: nowrap;
}
.help-answer .note {
  margin-top: .8rem; padding: .55rem .75rem;
  background: var(--warn-bg); color: var(--warn);
  font-size: .9375rem;
}

mark.help-hit { background: #fbe39b; color: var(--ink); border-radius: 2px; padding: 0 .05em; }

.help-none {
  display: flex; align-items: flex-start; gap: .5rem;
  max-width: 42rem; padding: .8rem 1rem;
  background: var(--info-bg); color: var(--info);
}
.help-none .icon { flex: none; margin-top: .25rem; }

.help-contact {
  max-width: 52rem;
  margin: 2.5rem 0 0; padding: 1.1rem 1.25rem;
  background: var(--surface); border: 1px solid var(--rule);
}
.help-contact h2 { font-size: 1.0625rem; margin: 0 0 .3rem; }
.help-contact p { margin: 0 0 .8rem; }
.help-people { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: .8rem 1.75rem; }
.help-people li { display: flex; align-items: center; gap: .6rem; }
.help-people li > span { display: flex; flex-direction: column; line-height: 1.35; }
.help-people .muted { font-size: .8125rem; }

/* --- Ungewoehnliche Zugriffe: Einzeiler auf der Uebersicht ----------- */

.security-line {
  display: flex; align-items: center; gap: .6rem;
  margin: 0 0 1.75rem; padding: .55rem .9rem;
  border: 1px solid var(--rule); border-left: 3px solid var(--ink-3);
  background: var(--surface); color: var(--ink);
  text-decoration: none; font-size: .9375rem;
}
.security-line .icon { flex: none; width: 1.05rem; height: 1.05rem; color: var(--ink-3); }
.security-line-text { flex: 1 1 auto; }
.security-line-go { flex: none; color: var(--accent); font-size: .875rem; white-space: nowrap; }
.security-line:hover { border-color: var(--ink-3); }
.security-line:hover .security-line-go { text-decoration: underline; }
/* Sind Vorfaelle da, faellt die Zeile ins Auge; ist es ruhig oder aus,
   bleibt sie zurueckhaltend. */
.security-line.is-alert { border-left-color: var(--warn); background: var(--warn-bg); }
.security-line.is-alert .icon { color: var(--warn); }
/* Sind kritische (Angriffs-/Sperr-)Vorfaelle dabei, faellt die Zeile ROT
   ins Auge - staerker als das Bernstein der uebrigen ungewoehnlichen. */
.security-line.is-critical { border-left-color: var(--accent); background: var(--accent-2); }
.security-line.is-critical .icon { color: var(--accent); }
.security-line-crit { color: var(--accent); font-weight: 600; margin-left: .4rem; }
.security-line.is-quiet { border-left-color: var(--ok); }
.security-line.is-quiet .icon { color: var(--ok); }
.security-line.is-off .security-line-text { color: var(--ink-2); }

/* --- Sicherheitsseite ------------------------------------------------- */

.security-controls {
  display: flex; flex-wrap: wrap; align-items: center; gap: .75rem 1.25rem;
  margin: 0 0 1.5rem; padding: .8rem 1rem;
  background: var(--surface-2); border: 1px solid var(--rule);
}
.security-controls form { display: flex; align-items: center; gap: .6rem; margin: 0; }
.security-state { font-weight: 600; display: inline-flex; align-items: center; gap: .35rem; }
.security-state::before { content: ""; width: .6rem; height: .6rem; border-radius: 50%; background: var(--ok); }
.security-state.off { color: var(--ink-2); }
.security-state.off::before { background: var(--ink-3); }
.security-hint-off { display: flex; align-items: center; gap: .5rem; }
.num-alert { color: var(--warn); font-weight: 600; }
table.data tr.is-hot td:first-child { box-shadow: inset 3px 0 0 var(--warn); }

/* Schweregrad eines Vorgangs im Protokoll und auf der Sicherheitsseite.
   Rot (--accent, wie beim Loeschen) = Angriffs- oder Sperrhinweis;
   Bernstein (--warn) = ungewoehnlich, im Alltag aber evtl. harmlos. Das
   Sinnbild uebernimmt die Farbe (fill: currentColor). */
.audit-action.sev-critical { color: var(--accent); font-weight: 600; }
.audit-action.sev-watch    { color: var(--warn); }
.audit-action.sev-critical .icon, .audit-action.sev-watch .icon { color: inherit; }
table.data tr.is-critical td:first-child { box-shadow: inset 3px 0 0 var(--accent); }

/* Unterpositionen: leicht abgesetzt und eingerueckt, mit einem kleinen
   Baumzeichen vor der Nummer (z. B. "7.1"). */
table.data tr.is-subpos td { background: var(--subpos-bg, var(--surface-2, #f7f9fa)); padding-left: 1.65rem; }
table.data tr.is-subpos td:first-child { padding-left: 2.7rem; position: relative; color: var(--ink-2, #56636c); }
table.data tr.is-subpos td:first-child::before {
  content: "\2514"; position: absolute; left: 1.55rem; color: var(--ink-3, #8b959c);
}

/* Musterzeilen im Design-Regler: eine Eltern- und eine Unterzeile, damit
   der gewaehlte Ton sofort im Kontrast zur weissen Elternzeile steht. */
table.data.subpos-sample { width: auto; min-width: 4.5rem; background: var(--surface);
  border: 1px solid var(--rule); font-size: .82rem; }
table.data.subpos-sample td { padding: .28rem .9rem; border: 0; }
table.data.subpos-sample tr.is-subpos td:first-child { padding-left: 2.7rem; }

/* Beim Bearbeitungs-Konflikt betroffene Zeile - rot hinterlegt, damit man
   sofort sieht, welche Position beide angefasst haben. */
.pos-conflict td { background: #fdecea; }
.pos-conflict input { border-color: #d3382b; }

/* Positionsmaske: die beiden kleinen Zeilen-Knoepfe (Unterposition, ATLAS). */
.pos-actions { white-space: nowrap; text-align: right; }
.pos-btn { padding: .22rem .45rem; font-size: .85rem; line-height: 1; }
.pos-btn-x { font-size: .7em; vertical-align: .05em; }
/* Entfernen zurueckhaltend, erst beim Darueberfahren rot - damit man es
   nicht mit dem Uebernehmen oder dem Hinzufuegen verwechselt. */
.pos-btn-del { color: var(--ink-3); }
.pos-btn-del:hover, .pos-btn-del:focus-visible { color: var(--accent); border-color: var(--accent); }
/* Der Muelleimer nimmt die Knopffarbe (currentColor) an und sitzt mittig. */
.pos-ico { display: block; width: 16px; height: 16px; }

/* Europaletten führt nur kleine Zahlen - die Spalte schrumpft auf die
   kurze Überschrift "Europal." (kein Umbruch). Nur am Tisch (breite
   Ansicht); in der Kartenansicht des Handys bleibt das Feld voll. */
@media (min-width: 48rem) {
  table.data th.col-europal, table.data td.col-europal { width: 1%; white-space: nowrap; }
}

/* Rest-Zeile unter den Unterpositionen: was vom Elternwert noch nicht
   verteilt ist. Rot = Rest uebrig, gruen = vollstaendig verteilt. */
tr.pos-rest td { border-top: 0; padding-top: .1rem; padding-bottom: .5rem; background: transparent; }
.pos-rest-label { color: var(--ink-3, #8b959c); font-size: .78rem; padding-left: 1.9rem; }
.pos-rest-val { font-size: .85rem; font-weight: 600; font-variant-numeric: tabular-nums; }
.pos-rest-val.is-rest { color: var(--accent, #9c3d19); }
.pos-rest-val.is-ok   { color: var(--ok, #2c6349); }
.security-controls + h2, .security-hint-off + h2 { margin-top: .5rem; }

.security-controls select { width: auto; padding: .4rem .5rem; }
.security-controls .field-inline { margin: 0; }
.security-controls .prune-hint { flex-basis: 100%; font-size: .8125rem; margin: 0; }
