/* =====================================================================
   Maréchaux Seitenportal — eigenes Stylesheet, bewusst OHNE geteilte
   Dateien mit anderen Stacks. Gleiche Bildsprache wie die Rapport-App:
   Graphit-Basis, Maréchaux-Rot als Aktionsfarbe, Helvetica.
   ===================================================================== */
/* Tokens wortgleich mit dem Backend der Rapport-App
 * (`rapport_work/rapportapp/public/css/app.css`). Beide Verwaltungen sollen
 * sich gleich anfühlen; wer Farben ändert, ändert sie an beiden Orten. */
:root {
  --font: 'Helvetica Neue', Helvetica, Arial, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --mono: 'SF Mono', 'Cascadia Code', Consolas, monospace;

  /* Maréchaux-Rot: Marken- und Aktionsfarbe */
  --accent: #e60000;
  --accent-strong: #c40000;
  --accent-soft: #fff4f4;
  --accent-text: #c40000;

  /* Statusfarben bewusst NICHT im Markenrot: sonst wäre ein Fehlerhinweis
     von einem Aktionsknopf nicht zu unterscheiden. */
  --ok: #3d7a2a;      --ok-soft: #c9e1bd;
  --warn: #8a6414;    --warn-soft: #f4daa6;
  --err: #b3231a;     --err-soft: #f9c9bf;
  --info: #2c5f8a;    --info-soft: #dde8f2;

  --bg: #f4f4f4;
  --bg-card: #ffffff;
  --bg-inset: #eeeeee;
  --bg-hover: #f7f7f7;
  --border: #dfdfdf;
  --border-strong: #cccccc;
  --text: #141414;
  --text-2: #555555;
  --text-3: #8a8a8a;
  --shadow: 0 1px 2px rgba(0,0,0,.05), 0 4px 16px rgba(0,0,0,.06);
  --shadow-lg: 0 8px 32px rgba(0,0,0,.16);
  --radius: 11px;
  --radius-sm: 8px;

  /* Abstandsraster in 4er-Schritten. Vorher standen im Portal rohe px-Werte
     (12, 14, 18, 20, 28), die zu nichts passten. */
  --s-1: 4px;  --s-2: 8px;  --s-3: 12px;
  --s-4: 16px; --s-5: 24px; --s-6: 32px;

  --fs-mini:  12px;   /* Zusatzangaben, Chips           */
  --fs-klein: 13px;   /* Beschriftungen, Tabellenknöpfe */
  --fs-text:  15px;   /* Fliesstext, Eingabefelder      */
  --fs-h2:    16px;   /* Abschnitt, Dialogtitel         */
  --fs-h1:    22px;   /* Seitentitel                    */

  --radius-pille: 999px;
  --ziel-min:     44px;
  --zeile-h:      48px;
  --dialog-breit: 720px;
  /* Am 15.09.2026 im Browser gemessen: die .topbar ist 64.5px hoch. Auf 65px
     aufgerundet, sonst scheint unter dem klebenden Tabellenkopf ein halber
     Pixel Text durch. */
  --topbar-h:     65px;
}
@media (prefers-color-scheme: dark) {
  :root {
    --accent: #ff3b30;
    --accent-strong: #ff5c52;
    --accent-soft: #3a1a19;
    --bg: #121212;
    --bg-card: #1c1c1c;
    --bg-inset: #171717;
    --border: #303030;
    --text: #ededed;
    --text-2: #b0b0b0;
    --text-3: #7d7d7d;
    --err: #ef7368;
    --err-soft: #3d1f1c;
    --shadow: 0 1px 2px rgba(0,0,0,.3), 0 4px 16px rgba(0,0,0,.3);

    /* Bis 15.09.2026 fehlten diese Tokens im Dunkelmodus: ein --border-strong
       von #cccccc auf einer Karte in #1c1c1c ist ein grell leuchtender Rahmen,
       und die Statusfarben des Hellmodus sind auf dunklem Grund unlesbar. */
    --accent-text: #ff7a72;
    --ok:   #6cc27f;   --ok-soft:   #1e3323;
    --warn: #e0b055;   --warn-soft: #3a3018;
    --info: #7cadd6;   --info-soft: #1d2f3e;
    --bg-hover:      #262626;
    --border-strong: #454545;
    --shadow-lg: 0 8px 32px rgba(0,0,0,.5);
  }
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
/* `hidden` muss stärker sein als jede display-Regel weiter unten: `button`
   bekommt hier display:inline-flex, und das sticht die Browser-Vorgabe für
   [hidden] aus — der «Ausnahme aufheben»-Knopf blieb sonst immer sichtbar. */
[hidden] { display: none !important; }
body {
  margin: 0; font-family: var(--font);
  background: var(--bg); color: var(--text);
  font-size: var(--fs-text); line-height: 1.5;
}
.muted { color: var(--text-2); }
.small { font-size: var(--fs-klein); }
.mono { font-family: var(--mono); font-variant-numeric: tabular-nums; }
/* Nur dort, wo unteilbare Zeichenketten stehen (E-Mail, Pfad) */
.brich-ueberall, .brich-ueberall td { overflow-wrap: anywhere; }
.spacer { flex: 1; }

/* ---- Kopfzeile ---- */
.topbar {
  display: flex; align-items: center; gap: var(--s-3);
  padding: var(--s-3) var(--s-5); background: var(--bg-card);
  border-bottom: 1px solid var(--border);
  position: sticky; top: 0; z-index: 10;
}
.topbar .marke {
  font-weight: 700; letter-spacing: .02em; text-decoration: none; color: var(--text);
}
.topbar .marke b { color: var(--accent); }
.topbar .platz { flex: 1; }
.topbar .wer { color: var(--text-2); font-size: var(--fs-klein); }
.topbar form { margin: 0; }

/* ---- Knöpfe & Eingaben ----
 * Grundzustand NEUTRAL. Vorher war jeder <button> rot; auf einer Seite mit
 * «Bearbeiten», «alle», «keine», «Filter zurücksetzen» wäre alles rot und
 * nichts mehr betont. Rot trägt nur noch `.primary`. */
button, .btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  font: inherit; font-size: var(--fs-klein); font-weight: 600;
  padding: 9px 16px; border-radius: var(--radius-sm);
  border: 1px solid var(--border-strong);
  background: var(--bg-card); color: var(--text);
  cursor: pointer; text-decoration: none;
  transition: background .12s, border-color .12s;
}
button:hover, .btn:hover { background: var(--bg-hover); }
button:disabled, .btn:disabled { opacity: .45; cursor: not-allowed; }
button:disabled:hover { background: var(--bg-card); }
.btn.primary, button.primary {
  background: var(--accent); border-color: var(--accent); color: #fff;
}
.btn.primary:hover, button.primary:hover { background: var(--accent-strong); border-color: var(--accent-strong); }
.btn.ghost, button.ghost,
/* `.leise` ist der alte Name desselben Knopfs — bleibt, damit die Abmelde-
   Knöpfe in views/start.html unverändert weiterlaufen. */
button.leise {
  border-color: var(--border-strong); background: var(--bg-inset); color: var(--text-2);
}
.btn.ghost:hover, button.ghost:hover, button.leise:hover { background: var(--bg-hover); color: var(--text); }
.btn.plain, button.plain { border-color: transparent; background: transparent; color: var(--text-2); }
.btn.plain:hover, button.plain:hover { background: var(--bg-hover); color: var(--text); }
.btn.danger, button.danger { background: var(--err); border-color: var(--err); color: #fff; }
.btn.danger:hover, button.danger:hover { filter: brightness(.92); }
.btn.danger-ghost, button.danger-ghost { border-color: var(--err); background: var(--err-soft); color: var(--err); }
.btn.sm, button.sm { padding: 5px 11px; font-size: var(--fs-mini); }
.btn.icon, button.icon {
  padding: 0; width: var(--ziel-min); height: var(--ziel-min);
  font-size: 20px; line-height: 1; border-color: transparent; background: transparent; color: var(--text-2);
}
.btn.icon:hover, button.icon:hover { background: var(--bg-hover); color: var(--text); }
.btn.block, button.block { width: 100%; }

input, select, textarea {
  font: inherit; font-size: var(--fs-text); color: var(--text);
  background: var(--bg-card); border: 1px solid var(--border);
  border-radius: var(--radius-sm); padding: 9px 12px; width: 100%;
  /* Ohne min-width:0 ist ein <select> so breit wie seine längste Option —
     das sprengt am Handy die Zeile und damit die ganze Seite. */
  min-width: 0;
}
select { text-overflow: ellipsis; }
textarea { resize: vertical; min-height: 64px; }
input:focus, select:focus, textarea:focus { outline: 2px solid var(--accent); outline-offset: 0; border-color: transparent; }
/* Sichtbarer Fokusring auch für alles, was kein Eingabefeld ist — Knöpfe,
   Reiter, Modulzeilen und Tabellenzeilen hatten bisher keinen. */
button:focus-visible, .btn:focus-visible, a:focus-visible,
[tabindex]:focus-visible, .mod-zeile:focus-within {
  outline: 2px solid var(--accent); outline-offset: 2px;
}
label { display: block; font-size: var(--fs-klein); color: var(--text-2); margin: var(--s-3) 0 var(--s-1); }
label.field { display: block; margin-bottom: var(--s-3); }
label.field > span { display: block; font-size: var(--fs-mini); font-weight: 600; color: var(--text-2); margin-bottom: var(--s-1); }
label.field > span.pflicht::after { content: ' *'; color: var(--accent-text); }
.field-row { display: flex; gap: var(--s-3); flex-wrap: wrap; }
.field-row > label.field { flex: 1; min-width: 150px; }
/* Feste Breiten für kurze Werte (Symbol, Sortierzahl) */
.field-row > label.field.b-schmal { flex: 0 0 90px; min-width: 0; }
.field-row > label.field.b-mittel { flex: 0 0 130px; min-width: 0; }
label.field.eng { margin-bottom: 0; }
.abgesetzt { margin-top: var(--s-3); }
.check { display: flex; align-items: flex-start; gap: var(--s-2); font-size: var(--fs-text); margin: var(--s-2) 0; }
.check input { width: auto; margin-top: 3px; flex: none; }
.check label, .check > span { margin: 0; font-size: inherit; color: var(--text); }
.check .feldhinweis { display: block; }
.feldhinweis { font-size: var(--fs-mini); color: var(--text-3); margin: var(--s-1) 0 0; line-height: 1.45; }
/* Feldbezogener Fehler: roter Rahmen plus Text unter dem Feld */
.feldfehler { font-size: var(--fs-mini); color: var(--err); font-weight: 600; margin: var(--s-1) 0 0; }
input.hat-fehler, select.hat-fehler { border-color: var(--err); }

/* ---- Chips ---- */
.chip {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 2px 9px; border-radius: var(--radius-pille);
  font-size: var(--fs-mini); font-weight: 600;
  background: var(--bg-inset); color: var(--text-2); white-space: nowrap;
}
.chip.ok { background: var(--ok-soft); color: var(--ok); }
.chip.warn { background: var(--warn-soft); color: var(--warn); }
.chip.err { background: var(--err-soft); color: var(--err); }
.chip.info { background: var(--info-soft); color: var(--info); }
.chip.accent { background: var(--accent-soft); color: var(--accent-text); }

/* ---- Anmeldeseite ---- */
.login-buehne {
  min-height: 100dvh; display: grid; place-items: center; padding: var(--s-5);
}
.login-karte {
  width: 100%; max-width: 360px; background: var(--bg-card);
  border: 1px solid var(--border); border-radius: var(--radius);
  box-shadow: var(--shadow); padding: 28px;
}
.login-karte h1 { margin: 0 0 var(--s-1); font-size: 20px; }
.login-karte h1 b { color: var(--accent); }
.login-karte .unter { color: var(--text-3); font-size: var(--fs-klein); margin: 0 0 var(--s-3); }
/* Erklaerung unter dem Anmeldefeld: welche Zugangsdaten hier gelten */
.login-karte .hinweis { color: var(--text-3); font-size: var(--fs-mini); line-height: 1.45; margin: 6px 0 14px; }
.login-karte button { width: 100%; margin-top: 18px; font-size: var(--fs-text); }
.fehler {
  background: var(--err-soft); color: var(--err);
  border-radius: var(--radius-sm); padding: 9px 12px;
  font-size: var(--fs-klein); margin-top: var(--s-3);
}

/* ---- Startseite: Kacheln ---- */
.inhalt { max-width: 1100px; margin: 0 auto; padding: var(--s-5) var(--s-5) 60px; }
.inhalt h1 { font-size: var(--fs-h1); margin: var(--s-2) 0 2px; }
.inhalt .unter { color: var(--text-3); margin: 0 0 var(--s-5); font-size: 14px; }
.kacheln {
  display: grid; gap: 8px;
  grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
}
.gruppe-titel {
  font-size: var(--fs-klein); font-weight: 700;
  text-transform: uppercase; letter-spacing: .06em;
  color: var(--text-3);
  margin: 28px 0 10px;
}
.gruppe-titel:first-of-type { margin-top: 6px; }
/* Symbol und Titel nebeneinander, eine Zeile hoch. Die Beschreibung steht nur noch im
   Tooltip (title am Link, siehe views/start.html): sie machte die Kachel dreimal so
   hoch, und wer die Kachel anklickt, kennt sein Modul. */
.kachel {
  display: flex; align-items: center; gap: 8px;
  text-decoration: none; color: var(--text);
  background: var(--bg-card); border: 1px solid var(--border);
  border-radius: var(--radius); box-shadow: var(--shadow);
  padding: 9px 11px; min-width: 0;
}
.kachel:hover { border-color: var(--accent); }
/* Am Handy wird getippt, nicht geklickt: 44 px Mindesthoehe als Tippziel. Am Desktop
   darf die Kachel flacher bleiben, dort zielt die Maus genauer. */
@media (max-width: 640px) { .kachel { min-height: 44px; } }
.kachel .icon { font-size: 18px; line-height: 1; flex: none; }
/* Ein langer Titel bricht auf zwei Zeilen, statt die Kachel zu sprengen. Die
   Silbentrennung ist noetig, weil ein einzelnes langes Wort sonst gar nicht umbricht:
   «Obligationenrecht» und «Starkstromverordnung» wurden ohne sie abgeschnitten. Sie
   braucht das `lang="de"` am <html> — ohne das trennt der Browser nicht.
   `overflow-wrap: anywhere` waere der harte Weg: gleiches Ergebnis, aber Umbruch
   mitten im Wort ohne Trennstrich («Obligationenrech|t»). Deshalb nur die Trennung. */
.kachel .titel {
  font-weight: 700; font-size: 13.5px; line-height: 1.25; min-width: 0;
  hyphens: auto;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.leer, .empty {
  background: var(--bg-card); border: 1px dashed var(--border);
  border-radius: var(--radius); padding: var(--s-6) var(--s-4); text-align: center;
  color: var(--text-3);
}
.empty .btn { margin-top: var(--s-3); }

/* =====================================================================
   Verwaltung (/admin)
   ===================================================================== */
.card {
  background: var(--bg-card); border: 1px solid var(--border);
  border-radius: var(--radius); box-shadow: var(--shadow); padding: 18px 20px;
}
.card + .card { margin-top: var(--s-4); }
/* Bewusst OHNE `overflow: hidden`: das macht die Karte zum Scrollrahmen und
   der sticky Tabellenkopf klebte dann an ihr statt am Fensterrand. Nichts im
   Inneren ragt über die runden Ecken hinaus. */
.card.pad-0 { padding: 0; }
.card-head { display: flex; align-items: center; gap: var(--s-2); margin-bottom: var(--s-3); flex-wrap: wrap; }
.card-head h2 { margin: 0; font-size: var(--fs-h2); }

/* ---- Reiterleiste ---- */
.tabs {
  display: flex; gap: 2px; border-bottom: 1px solid var(--border);
  margin: var(--s-4) 0 var(--s-4);
  overflow-x: auto; scroll-snap-type: x proximity; overscroll-behavior-x: contain;
  scrollbar-width: none;
}
.tabs::-webkit-scrollbar { display: none; }
.tabs button {
  scroll-snap-align: start;
  padding: 10px 14px; border: none; border-bottom: 2px solid transparent;
  background: none; color: var(--text-2); white-space: nowrap;
  border-radius: 0; font-size: 14px;
}
.tabs button:hover { background: var(--bg-hover); color: var(--text); }
.tabs button[aria-selected="true"] { color: var(--accent-text); border-bottom-color: var(--accent); }
.tab-zahl {
  margin-left: 6px; padding: 1px 7px; border-radius: var(--radius-pille);
  background: var(--bg-inset); color: var(--text-3); font-size: var(--fs-mini); font-weight: 700;
}
.tabs button[aria-selected="true"] .tab-zahl { background: var(--accent-soft); color: var(--accent-text); }

/* ---- Werkzeugzeile über einer Tabelle ---- */
.filterzeile {
  display: flex; gap: var(--s-3); flex-wrap: wrap; align-items: flex-end;
  padding: var(--s-3) var(--s-4); border-bottom: 1px solid var(--border);
}
.filterzeile label.field { margin-bottom: 0; }
.filterzeile .f-suche { flex: 2 1 240px; }
.filterzeile .f-wahl { flex: 1 1 130px; }
.filterzeile .filter-aktion { flex: none; }
/* Erklärsatz anstelle der Filter (Reiter «Module» und «Gruppen») */
.filter-info { margin: 0; flex: 1 1 220px; }
.trefferzeile {
  margin: 0; padding: var(--s-2) var(--s-4);
  font-size: var(--fs-mini); color: var(--text-3);
  border-bottom: 1px solid var(--border);
}

/* ---- Tabellen ----
 * Bewusst OHNE eigenen Scrollrahmen: ein `overflow-x: auto` am Umschlag macht
 * den Tabellenkopf-Sticky wirkungslos. Die Zellen brechen stattdessen um, und
 * unter 900px wird die Tabelle ohnehin zu gestapelten Blöcken. */
.table-wrap { min-width: 0; }
table { width: 100%; border-collapse: collapse; font-size: 14px; }
th, td { text-align: left; padding: var(--s-2) var(--s-3); border-bottom: 1px solid var(--border); vertical-align: top; }
td { overflow-wrap: break-word; }
th {
  color: var(--text-3); font-weight: 650; font-size: var(--fs-mini);
  text-transform: uppercase; letter-spacing: .04em;
  position: sticky; top: var(--topbar-h); z-index: 2;
  background: var(--bg-card);
}
tbody tr:last-child td { border-bottom: none; }
/* `--text-2` statt `--text-3`: Bei 12 px braucht Text 4.5:1 Kontrast, und
 * #8a8a8a auf Weiss erreicht nur 3.45:1 (Mobilo am 15.09.2026 gemessen).
 * Hier steht nicht bloss Zierat, sondern die E-Mail-Zeile unter jedem Namen —
 * bei ähnlichen Namen ist sie die einzige Unterscheidung zwischen zwei Leuten. */
td .mini, .mini { font-size: var(--fs-mini); color: var(--text-2); line-height: 1.45; }
.inaktiv { opacity: .55; }
.zeile-aktionen { display: flex; gap: 6px; flex-wrap: wrap; }
.td-aktionen { text-align: right; white-space: nowrap; }
/* Sortierknopf im Tabellenkopf: sieht aus wie die Überschrift, ist aber ein
   echter Knopf — sonst wäre Sortieren nur mit der Maus möglich. */
.th-sort {
  border: none; background: none; padding: 0; color: inherit;
  font: inherit; text-transform: inherit; letter-spacing: inherit;
  cursor: pointer; display: inline-flex; gap: 4px; align-items: center;
}
.th-sort:hover { color: var(--text); background: none; }
.sort-ind { font-size: 9px; opacity: .85; }
/* Anzeigename in Spalte 1: öffnet den Dialog, ohne Maus erreichbar */
.zeilen-knopf {
  border: none; background: none; padding: 0; margin: 0;
  font: inherit; font-weight: 700; font-size: 14px; color: var(--text);
  text-align: left; cursor: pointer;
}
.zeilen-knopf:hover { background: none; text-decoration: underline; }
.tabellenzeile--klickbar { cursor: pointer; }
.tabellenzeile--klickbar:hover { background: var(--bg-hover); }
/* Zwischenüberschrift je Gruppe im Reiter «Module» */
tr.gruppen-zeile td {
  background: var(--bg-inset); border-bottom: 1px solid var(--border);
  font-size: var(--fs-mini); font-weight: 700; color: var(--text-3);
  text-transform: uppercase; letter-spacing: .06em; padding: 6px var(--s-3);
}
/* Die eben gespeicherte Zeile leuchtet kurz auf — beantwortet «welche war es?» */
@keyframes frisch-auf {
  from { background: var(--accent-soft); }
  to   { background: transparent; }
}
tr.frisch td { animation: frisch-auf 1.2s ease-out; }
@media (prefers-reduced-motion: reduce) {
  tr.frisch td { animation: none; }
}

/* Platzhalterzeilen beim Laden */
.skeleton {
  background: linear-gradient(90deg, var(--bg-inset) 25%, var(--bg-hover) 50%, var(--bg-inset) 75%);
  background-size: 200% 100%; animation: sk 1.2s infinite; border-radius: var(--radius-sm);
  height: 14px; width: 70%;
}
@keyframes sk { to { background-position: -200% 0; } }
@media (prefers-reduced-motion: reduce) { .skeleton { animation: none; } }

/* Fehlerband über einer Tabelle (Ladefehler) */
.fehlerband {
  display: flex; gap: var(--s-3); align-items: center; flex-wrap: wrap;
  background: var(--err-soft); color: var(--err);
  padding: var(--s-3) var(--s-4); font-size: var(--fs-klein); font-weight: 600;
  border-bottom: 1px solid var(--border);
}

/* ---- Dialoge ----
 * <dialog> statt eigenem Overlay: Fokusfalle, Esc und der inerte Hintergrund
 * kommen vom Browser und sind dadurch nicht selbst gebaut und halb richtig. */
dialog.modal {
  padding: 0; border: none; background: var(--bg-card); color: var(--text);
  border-radius: var(--radius); box-shadow: var(--shadow-lg);
  width: min(560px, 100%); max-height: 88vh; overflow: hidden;
}
dialog.modal.modal-breit { width: min(var(--dialog-breit), 100%); }
dialog.modal::backdrop { background: rgba(15,13,10,.55); }
.modal-rahmen { display: flex; flex-direction: column; max-height: 88vh; }
.modal-kopf {
  display: flex; align-items: flex-start; gap: var(--s-3); flex-wrap: wrap;
  padding: var(--s-4) var(--s-4) var(--s-3);
  border-bottom: 1px solid var(--border); flex: none;
}
.modal-kopf h2 { margin: 0; font-size: var(--fs-h2); }
.modal-kopf .kopf-text { flex: 1; min-width: 200px; }
.modal-kopf .kopf-chips { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 6px; }
.modal-koerper { padding: var(--s-4); overflow-y: auto; flex: 1; min-height: 0; }
.modal-fuss {
  display: flex; gap: var(--s-2); align-items: center; flex-wrap: wrap;
  padding: var(--s-3) var(--s-4);
  border-top: 1px solid var(--border); background: var(--bg-card); flex: none;
}
.modal-fuss .spacer { flex: 1; min-width: 0; }
.dialog-abschnitt { border-top: 1px solid var(--border); margin-top: var(--s-5); padding-top: var(--s-4); }
.dialog-abschnitt:first-child { border-top: none; margin-top: 0; padding-top: 0; }
.dialog-abschnitt h3 { margin: 0 0 var(--s-3); font-size: 14px; }
.hinweis-kasten {
  background: var(--bg-inset); border-radius: var(--radius-sm);
  padding: var(--s-3); font-size: var(--fs-klein); color: var(--text-2);
  line-height: 1.5; margin: var(--s-2) 0;
}
.hinweis-kasten.warn { background: var(--warn-soft); color: var(--warn); }
.hinweis-kasten strong { color: inherit; }

/* Schalterleiste: Hauptrolle und Kontoart. Zeigt im Gegensatz zu einem
   Auswahlfeld auch, wo der gewählte Wert im Gefüge liegt. */
.schalterleiste { display: flex; gap: 0; flex-wrap: wrap; }
.schalterleiste button {
  flex: 1 1 0; min-width: 96px; justify-content: center;
  border-radius: 0; border-right-width: 0;
  background: var(--bg-card); color: var(--text-2); font-weight: 600;
}
.schalterleiste button:first-child { border-radius: var(--radius-sm) 0 0 var(--radius-sm); }
.schalterleiste button:last-child { border-radius: 0 var(--radius-sm) var(--radius-sm) 0; border-right-width: 1px; }
.schalterleiste button.aktiv {
  background: var(--accent-soft); color: var(--accent-text);
  border-color: var(--accent); z-index: 1;
}
.schalterleiste button.aktiv + button { border-left-color: var(--accent); }
.schalterleiste button:disabled { opacity: .45; cursor: not-allowed; }

/* ---- Modulzuordnung im Benutzerdialog ---- */
.mod-kopf { display: flex; align-items: baseline; gap: var(--s-2); flex-wrap: wrap; }
.mod-kopf h3 { margin: 0; }
.dlg-text { margin: 0; }
.mod-zaehler { font-size: var(--fs-mini); color: var(--text-3); font-weight: 700; }
.mod-sammel { display: flex; gap: var(--s-1); }
.mod-sammel button {
  border-color: transparent; background: transparent; color: var(--accent-text);
  padding: 4px 8px; font-size: var(--fs-mini); text-decoration: underline;
}
.mod-sammel button:hover { background: var(--bg-hover); }
.mod-gruppe { margin-top: var(--s-3); }
.mod-gruppe-kopf {
  position: sticky; top: 0; z-index: 1;
  display: flex; align-items: center; gap: var(--s-2); flex-wrap: wrap;
  background: var(--bg-card); border-bottom: 1px solid var(--border);
  padding: 6px 0; margin-bottom: 2px;
  font-size: var(--fs-mini); font-weight: 700; color: var(--text-3);
  text-transform: uppercase; letter-spacing: .06em;
}
.mod-gruppe-kopf .spacer { flex: 1; }
.mod-zeile {
  display: flex; align-items: center; gap: var(--s-3);
  min-height: var(--zeile-h); padding: 6px var(--s-2);
  border-radius: var(--radius-sm); cursor: pointer; margin: 0;
  font-size: 14px; color: var(--text);
}
.mod-zeile:hover { background: var(--bg-hover); }
.mod-zeile.gewaehlt { background: var(--accent-soft); }
/* Die Klickfläche des Kästchens umfasst Kästchen und Text — also fast die
   ganze Zeile. Nur das Rollenfeld daneben fängt seinen eigenen Klick ab.
   (Ein <select> IM <label> wäre ungültiges HTML: ein Label darf nur ein
   beschriftbares Element enthalten.) */
.mod-haupt {
  display: flex; align-items: center; gap: var(--s-3);
  flex: 1; min-width: 0; margin: 0; cursor: pointer;
  font-size: 14px; color: var(--text); min-height: var(--zeile-h);
}
.mod-zeile input[type="checkbox"] { width: 18px; height: 18px; flex: none; margin: 0; }
.mod-zeile .mod-text { display: flex; flex-direction: column; gap: 1px; flex: 1; min-width: 0; }
.mod-zeile .mod-titel { font-weight: 600; overflow-wrap: break-word; }
.mod-zeile .mod-chips { display: inline-flex; gap: 5px; margin-left: 6px; vertical-align: middle; }
.mod-zeile.inaktiv { opacity: .7; }
/* Ein Auswahlfeld, zwei Erscheinungsbilder: der Normalfall «es gilt die
   Hauptrolle» bleibt leise, die Ausnahme trägt Farbe und Rahmen. */
.mod-rolle {
  flex: none; width: auto; max-width: 190px;
  border-color: transparent; background: transparent;
  color: var(--text-3); font-size: var(--fs-mini); padding: 4px 6px;
}
.mod-rolle:hover:enabled, .mod-rolle:focus { border-color: var(--border-strong); background: var(--bg-card); }
.mod-rolle.ausnahme {
  border-color: var(--accent); background: var(--accent-soft);
  color: var(--accent-text); font-weight: 600;
}
.mod-rolle:disabled { opacity: .55; }
.mod-ausnahme-weg {
  flex: none; border-color: transparent; background: transparent;
  color: var(--text-3); padding: 4px 8px; font-size: var(--fs-text); line-height: 1;
}
.mod-ausnahme-weg:hover { background: var(--bg-hover); color: var(--err); }

/* ---- Zugriffsliste im Moduldialog (Benutzer statt Module) ---- */
.zug-gruppe { margin-top: var(--s-3); }
.zug-gruppe-kopf {
  position: sticky; top: 0; z-index: 1;
  display: flex; align-items: center; gap: var(--s-2); flex-wrap: wrap;
  background: var(--bg-card); border-bottom: 1px solid var(--border);
  padding: 6px 0; margin-bottom: 2px;
  font-size: var(--fs-mini); font-weight: 700; color: var(--text-3);
  text-transform: uppercase; letter-spacing: .06em;
}
.zug-gruppe-kopf .spacer { flex: 1; }
.zug-fest {
  display: flex; align-items: center; gap: var(--s-1) var(--s-3); flex-wrap: wrap;
  min-height: var(--zeile-h); padding: 6px var(--s-2); font-size: 14px; color: var(--text-2);
}

/* ---- Toast ---- */
#toasts {
  position: fixed; bottom: var(--s-4); left: var(--s-4); z-index: 200;
  display: flex; flex-direction: column; gap: var(--s-2); width: min(400px, calc(100vw - 32px));
}
.toast {
  padding: 11px var(--s-4); border-radius: var(--radius-sm);
  background: var(--text); color: var(--bg);
  font-size: var(--fs-klein); font-weight: 600; box-shadow: var(--shadow-lg);
  animation: toast-auf .18s ease-out;
}
.toast.err { background: var(--err); color: #fff; }
.toast.ok { background: var(--ok); color: #fff; }
@keyframes toast-auf { from { opacity: 0; transform: translateY(8px); } }
@media (prefers-reduced-motion: reduce) { .toast { animation: none; } }

/* ---- Abgelaufene Sitzung: ganzflächig statt Fehlerband je Anfrage ---- */
#sitzung-weg {
  position: fixed; inset: 0; z-index: 300;
  display: grid; place-items: center; padding: var(--s-5);
  background: rgba(15,13,10,.65);
}
#sitzung-weg .kasten {
  background: var(--bg-card); border-radius: var(--radius); box-shadow: var(--shadow-lg);
  padding: var(--s-5); max-width: 380px; text-align: center;
}
#sitzung-weg h2 { margin: 0 0 var(--s-2); font-size: var(--fs-h2); }
#sitzung-weg p { margin: 0 0 var(--s-4); color: var(--text-2); font-size: var(--fs-klein); }

/* =====================================================================
   Schmale Fenster
   ===================================================================== */
@media (max-width: 900px) {
  /* Tabellen werden zu gestapelten Blöcken — so muss niemand seitlich
     schieben, um eine lange Beschreibung zu lesen. */
  .stack-table thead { display: none; }
  .stack-table, .stack-table tbody, .stack-table tr, .stack-table td { display: block; width: 100%; }
  .stack-table tr {
    border: 1px solid var(--border); border-radius: var(--radius-sm);
    padding: 10px 12px; margin-bottom: var(--s-2); background: var(--bg-card);
  }
  .stack-table tr:last-child { margin-bottom: 0; }
  .stack-table td { border: none; padding: 3px 0; }
  .stack-table td:empty { display: none; }
  .stack-table td[data-label]::before {
    content: attr(data-label); display: block;
    font-size: 11px; text-transform: uppercase; letter-spacing: .05em;
    color: var(--text-3); font-weight: 650;
  }
  .stack-table td.td-aktionen {
    display: flex; flex-wrap: wrap; gap: var(--s-2); margin-top: var(--s-2); text-align: left;
  }
  .stack-table td.td-aktionen .btn,
  .stack-table td.td-aktionen button { flex: 1 1 auto; min-height: var(--ziel-min); }
  .stack-table tr.gruppen-zeile { border: none; background: none; padding: 0; margin: var(--s-4) 0 var(--s-2); }
  .stack-table tr.gruppen-zeile td { background: none; padding: 0; }
  .stack-table .table-liste { padding: 10px 12px; }
  /* Innerhalb der randlosen Karte braucht die gestapelte Liste eigenen Rand */
  .card.pad-0 .table-wrap { padding: var(--s-3); }
  .zeilen-knopf { min-height: 32px; font-size: var(--fs-text); }
}

@media (max-width: 700px) {
  .inhalt { padding: var(--s-4) var(--s-3) 60px; }
  .topbar { padding: 10px var(--s-3); }
  dialog.modal, dialog.modal.modal-breit {
    width: 100%; max-width: 100%; max-height: 100dvh; height: 100dvh;
    border-radius: 0; margin: 0;
  }
  .modal-rahmen { max-height: 100dvh; height: 100dvh; }
  /* Modulzeile zweizeilig: Kästchen und Titel oben, Rollenfeld darunter */
  .mod-zeile { flex-wrap: wrap; }
  .mod-haupt { flex: 1 1 100%; }
  .mod-zeile .mod-rolle { margin-left: 30px; max-width: calc(100% - 70px); }

  /* Antippflächen am Finger statt am Mauszeiger ausgerichtet. Am Schreibtisch
   * darf das Rollenfeld leise und klein sein — am Handy war es 26 px hoch, die
   * Sammelaktionen 28 px mit 4 px Abstand (Mobilo, 15.09.2026). Ein Fehltreffer
   * auf «alle» schaltet eine ganze Gruppe frei. */
  .mod-rolle { min-height: var(--ziel-min); padding: 8px 10px; font-size: var(--fs-klein); }
  .mod-ausnahme-weg { min-width: var(--ziel-min); min-height: var(--ziel-min); }
  .mod-sammel { gap: var(--s-2); }
  .mod-sammel button { min-height: 40px; padding: 8px 14px; font-size: var(--fs-klein); }

  /* 16 px, damit iOS Safari beim Fokussieren nicht in das Feld hineinzoomt.
   * Darunter zoomt es und die Seite steht danach verschoben da. */
  input, select, textarea { font-size: 16px; }
  .schalterleiste button { flex: 1 1 calc(50% - 1px); min-width: 0; }
  .schalterleiste button:nth-child(2) { border-right-width: 1px; border-radius: 0 var(--radius-sm) 0 0; }
  .schalterleiste button:nth-child(1) { border-radius: var(--radius-sm) 0 0 0; }
  .schalterleiste button:nth-child(3) { border-radius: 0 0 0 var(--radius-sm); }
  .schalterleiste button:nth-child(4) { border-radius: 0 0 var(--radius-sm) 0; }
  .filterzeile .f-suche, .filterzeile .f-wahl { flex: 1 1 100%; }
  .filterzeile .f-wahl { flex: 1 1 calc(50% - 6px); }
  /* Etwas enger, damit die drei Reiter bei 375px ohne Wischen ganz sichtbar
     sind — scrollen könnten sie, aber ein halb abgeschnittener Reiter sieht
     nach Fehler aus. */
  .tabs button { padding: 10px 11px; }
}

/* ---- Meine Ansicht: jeder waehlt seine Kacheln selbst ---- */
/* Der Hinweis neben «Deine freigeschalteten Bereiche» fuehrt zur Auswahl und sagt,
   wie viele Kacheln der Benutzer selbst abgewaehlt hat. */
.ansicht-link { margin-left: 10px; color: var(--accent); text-decoration: none; font-weight: 600; white-space: nowrap; }
.ansicht-link:hover { text-decoration: underline; }
.ansicht-link .zahl {
  margin-left: 6px; font-weight: 400; font-size: var(--fs-mini);
  color: var(--text-3); border: 1px solid var(--border); border-radius: 999px; padding: 1px 7px;
}

.wahlliste { list-style: none; margin: 0 0 var(--s-4); padding: 0; display: grid; gap: 6px; }
/* `min-width: 0` auch hier: ein Grid-Kind ist von Haus aus so breit wie sein
   laengster Inhalt und ignoriert die Spaltenbreite. Ohne das ragten die Zeilen am
   Handy 1323 px weit aus der 351 px breiten Liste — die ganze Seite scrollte. */
.wahlliste li {
  background: var(--bg-card); border: 1px solid var(--border);
  border-radius: var(--radius); min-width: 0;
}
/* Das ganze Feld ist das Klickziel, nicht nur das Kaestchen — am Handy waere das
   Kaestchen allein zu klein. Mindesthoehe 44 px aus demselben Grund. */
.wahlliste label {
  display: flex; align-items: center; gap: 10px; min-height: 44px;
  padding: 8px 12px; cursor: pointer;
}
.wahlliste input[type="checkbox"] { width: 18px; height: 18px; flex: none; accent-color: var(--accent); }
.wahlliste .icon { font-size: 18px; line-height: 1; flex: none; }
/* `min-width: 0` UND `overflow: hidden` — beides zusammen. Ein Flex-Kind wird sonst
   so breit wie sein laengster nicht umbrechender Text, und das Kuerzen mit Ellipsis
   greift gar nicht: am Handy war die Seite dadurch 1336 statt 375 px breit. */
.wahl-text { display: flex; flex-direction: column; min-width: 0; overflow: hidden; }
.wahl-text .titel,
.wahl-text .text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wahl-text .titel { font-weight: 600; }
.wahl-text .text { color: var(--text-3); font-size: var(--fs-mini); }
/* Abgewaehltes bleibt lesbar, tritt aber zurueck. */
.wahlliste li:has(input:not(:checked)) { opacity: .55; }

.wahl-fuss { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-top: var(--s-5); }
.wahl-fuss .leise { margin-left: auto; }
.hinweis-ok {
  background: var(--ok-soft); color: var(--ok); border-radius: var(--radius);
  padding: 8px 12px; margin: 0 0 var(--s-4); font-size: var(--fs-klein);
}
