
  :root {
    --bg: #eef6f6;
    --bg-deep: #e1eff0;
    --blob-a: rgba(95, 197, 219, 0.30);
    --blob-b: rgba(248, 153, 33, 0.14);
    --surface: rgba(255, 255, 255, 0.62);
    --surface-solid: #ffffff;
    --surface-strong: rgba(255, 255, 255, 0.85);
    --border: rgba(1, 74, 80, 0.12);
    --border-strong: rgba(1, 74, 80, 0.2);
    --text: #12292b;
    --text-muted: #4c686b;
    --text-faint: #7c9598;
    --brand: #01919a;
    --brand-deep: #045a62;
    --brand-soft: #d3eef0;
    --cyan: #5fc5db;
    --accent: #f89921;
    --accent-deep: #c96f0a;
    --accent-soft: #fdecd2;
    --status-good-bg: #dcf3e6;
    --status-good-fg: #1f7a48;
    --status-info-bg: #d3eef0;
    --status-info-fg: #045a62;
    --status-critical-bg: #fbe1df;
    --status-critical-fg: #b23a2f;
    --shadow-color: 190, 40%, 30%;
    --sidebar-grad-top: #5fc5db;
    --sidebar-grad-bottom: #016d75;
    --sidebar-text: #eafbfc;
    --sidebar-text-muted: rgba(234, 251, 252, 0.68);
    --sidebar-active-bg: rgba(255, 255, 255, 0.16);
    --focus-ring: #01919a;
  }

  @media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) {
      --bg: #0a1a1c;
      --bg-deep: #0d2226;
      --blob-a: rgba(95, 197, 219, 0.14);
      --blob-b: rgba(248, 153, 33, 0.10);
      --surface: rgba(19, 42, 46, 0.6);
      --surface-solid: #122a2d;
      --surface-strong: rgba(23, 50, 54, 0.9);
      --border: rgba(150, 210, 214, 0.14);
      --border-strong: rgba(150, 210, 214, 0.24);
      --text: #e7f5f5;
      --text-muted: #9fc0c2;
      --text-faint: #6f9295;
      --brand: #5fd3dd;
      --brand-deep: #bdeef2;
      --brand-soft: rgba(95, 211, 221, 0.14);
      --accent: #ffab52;
      --accent-deep: #ffcd94;
      --accent-soft: rgba(255, 171, 82, 0.14);
      --status-good-bg: rgba(58, 178, 118, 0.18);
      --status-good-fg: #7fe0ac;
      --status-info-bg: rgba(95, 211, 221, 0.16);
      --status-info-fg: #a6ecf1;
      --status-critical-bg: rgba(224, 96, 82, 0.2);
      --status-critical-fg: #ff9c8d;
      --shadow-color: 190, 60%, 2%;
      --sidebar-grad-top: #0f3438;
      --sidebar-grad-bottom: #04181a;
      --sidebar-text: #d9f2f3;
      --sidebar-text-muted: rgba(217, 242, 243, 0.6);
      --sidebar-active-bg: rgba(95, 211, 221, 0.14);
      --focus-ring: #5fd3dd;
    }
  }

  :root[data-theme="dark"] {
    --bg: #0a1a1c;
    --bg-deep: #0d2226;
    --blob-a: rgba(95, 197, 219, 0.14);
    --blob-b: rgba(248, 153, 33, 0.10);
    --surface: rgba(19, 42, 46, 0.6);
    --surface-solid: #122a2d;
    --surface-strong: rgba(23, 50, 54, 0.9);
    --border: rgba(150, 210, 214, 0.14);
    --border-strong: rgba(150, 210, 214, 0.24);
    --text: #e7f5f5;
    --text-muted: #9fc0c2;
    --text-faint: #6f9295;
    --brand: #5fd3dd;
    --brand-deep: #bdeef2;
    --brand-soft: rgba(95, 211, 221, 0.14);
    --accent: #ffab52;
    --accent-deep: #ffcd94;
    --accent-soft: rgba(255, 171, 82, 0.14);
    --status-good-bg: rgba(58, 178, 118, 0.18);
    --status-good-fg: #7fe0ac;
    --status-info-bg: rgba(95, 211, 221, 0.16);
    --status-info-fg: #a6ecf1;
    --status-critical-bg: rgba(224, 96, 82, 0.2);
    --status-critical-fg: #ff9c8d;
    --shadow-color: 190, 60%, 2%;
    --sidebar-grad-top: #0f3438;
    --sidebar-grad-bottom: #04181a;
    --sidebar-text: #d9f2f3;
    --sidebar-text-muted: rgba(217, 242, 243, 0.6);
    --sidebar-active-bg: rgba(95, 211, 221, 0.14);
    --focus-ring: #5fd3dd;
  }

  * { box-sizing: border-box; }

  body {
    margin: 0;
    background: var(--bg);
    color: var(--text);
    font-family: "Ruda", "Segoe UI", system-ui, sans-serif;
    -webkit-font-smoothing: antialiased;
  }

  a { color: inherit; }
  button, input, a { font-family: inherit; }
  a:focus-visible, button:focus-visible, .nav-item:focus-visible {
    outline: 2px solid var(--focus-ring);
    outline-offset: 2px;
  }

  /* ---------- Auth page ---------- */

  .auth-page {
    min-height: 100vh;
    display: grid;
    place-items: center;
    padding: 1.5rem;
    position: relative;
    overflow: hidden;
    isolation: isolate;
  }

  .auth-page::before, .auth-page::after {
    content: "";
    position: absolute;
    z-index: -1;
    border-radius: 50%;
    filter: blur(80px);
  }
  .auth-page::before { width: 480px; height: 480px; top: -160px; right: -100px; background: var(--blob-a); }
  .auth-page::after { width: 420px; height: 420px; bottom: -160px; left: -80px; background: var(--blob-b); }

  .auth-card {
    width: 100%;
    max-width: 380px;
    background: var(--surface);
    backdrop-filter: blur(20px);
    -webkit-backdrop-filter: blur(20px);
    border: 1px solid var(--border);
    border-radius: 20px;
    padding: 2rem 1.9rem 1.75rem;
    box-shadow: 0 20px 50px -20px hsla(var(--shadow-color), 0.35);
  }

  .auth-brand {
    display: flex;
    align-items: center;
    gap: 0.65rem;
    margin-bottom: 1.6rem;
  }

  .auth-brand-mark {
    width: 38px;
    height: 38px;
    border-radius: 11px;
    background: linear-gradient(155deg, var(--cyan), var(--brand));
    display: grid;
    place-items: center;
    color: #fff;
    flex-shrink: 0;
  }

  .auth-brand-name { font-weight: 900; font-size: 1.1rem; line-height: 1.1; }
  .auth-brand-sub { font-size: 0.72rem; color: var(--text-muted); letter-spacing: 0.04em; }

  .auth-card h1 {
    font-size: 1.15rem;
    font-weight: 700;
    margin: 0 0 0.3rem;
    text-wrap: balance;
  }

  .field { display: flex; flex-direction: column; gap: 0.35rem; margin-bottom: 1rem; }
  .field label { font-size: 0.78rem; font-weight: 700; color: var(--text-muted); }
  .field input {
    border: 1px solid var(--border-strong);
    background: var(--surface-solid);
    border-radius: 10px;
    padding: 0.65rem 0.8rem;
    font-size: 0.92rem;
    color: var(--text);
  }
  .field input:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 1px; }

  /* Gemeinsame Aussenmasse beider Schaltflaechenarten. Vorher hatten sie
     unterschiedliche Polsterung (0.75/1 gegen 0.7/1.1), unterschiedliche
     Schriftgroesse (0.92 gegen 0.88), nur die eine einen Rahmen und nur die
     andere einen margin-top. Nebeneinander standen sie dadurch verschieden
     hoch UND vertikal versetzt. Alles Massgebliche steht deshalb jetzt an
     EINER Stelle; die Klassen darunter unterscheiden sich nur in der Farbe.
     Der Rahmen ist bei beiden da - bei der primaeren durchsichtig, damit sie
     ohne sichtbaren Rahmen exakt gleich hoch bleibt. */
  .btn-primary, .btn-secondary {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.4rem;
    padding: 0.7rem 1.1rem;
    border: 1px solid transparent;
    border-radius: 10px;
    font-family: inherit;
    font-size: 0.9rem;
    font-weight: 700;
    /* Fest gesetzt: Ohne line-height berechnen Safari und Chrome die Hoehe
       von <button> und <a> unterschiedlich - genau der Effekt, der im Safari
       auf dem Mac auffiel. */
    line-height: 1.25;
    text-decoration: none;
    cursor: pointer;
    white-space: nowrap;
  }

  .btn-primary {
    width: 100%;
    background: linear-gradient(135deg, var(--cyan), var(--brand));
    color: #fff;
  }
  .btn-primary:hover { filter: brightness(1.04); }

  /* Nebeneinander ist volle Breite immer falsch. Das stand bisher als
     style="width:auto" an 24 Stellen quer durch die Views - eine
     Nachbesserung, die man vergessen kann und die genau dann fehlt, wenn
     eine neue Seite dazukommt. */
  .form-actions .btn-primary,
  .form-actions .btn-secondary,
  .panel-head .btn-primary,
  .panel-head .btn-secondary { width: auto; }

  .auth-error {
    background: var(--status-critical-bg);
    color: var(--status-critical-fg);
    border-radius: 10px;
    padding: 0.6rem 0.8rem;
    font-size: 0.83rem;
    font-weight: 600;
    margin-bottom: 1rem;
  }

  .auth-hint {
    margin-top: 1.3rem;
    font-size: 0.76rem;
    color: var(--text-faint);
    line-height: 1.5;
  }

  /* ---------- App shell ---------- */

  .app { display: grid; grid-template-columns: minmax(220px, 260px) 1fr; min-height: 100vh; }

  .sidebar {
    background: linear-gradient(190deg, var(--sidebar-grad-top) 0%, var(--sidebar-grad-bottom) 85%);
    color: var(--sidebar-text);
    padding: 1.75rem 1.25rem 1.5rem;
    display: flex;
    flex-direction: column;
    gap: 2.25rem;
  }

  .brand { display: flex; align-items: center; gap: 0.65rem; padding: 0 0.25rem; }
  .brand-mark {
    width: 34px; height: 34px; border-radius: 10px;
    background: rgba(255, 255, 255, 0.16);
    display: grid; place-items: center; flex-shrink: 0;
  }
  .brand-name { font-weight: 900; font-size: 1.05rem; letter-spacing: 0.01em; line-height: 1.1; }
  .brand-sub { font-size: 0.7rem; color: var(--sidebar-text-muted); letter-spacing: 0.06em; text-transform: uppercase; }

  nav.primary-nav { display: flex; flex-direction: column; gap: 0.2rem; }
  .nav-label { font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.09em; color: var(--sidebar-text-muted); padding: 0.4rem 0.75rem 0.5rem; }

  .nav-item {
    display: flex; align-items: center; gap: 0.7rem;
    padding: 0.6rem 0.75rem; border-radius: 10px;
    color: var(--sidebar-text-muted); text-decoration: none;
    font-size: 0.9rem; font-weight: 700;
    transition: background 0.15s ease, color 0.15s ease;
  }
  .nav-item svg { flex-shrink: 0; opacity: 0.9; }
  .nav-item:hover { background: rgba(255, 255, 255, 0.1); color: var(--sidebar-text); }
  .nav-item.active { background: var(--sidebar-active-bg); color: var(--sidebar-text); box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.14); }

  .sidebar-foot {
    margin-top: auto;
    padding: 0.9rem 0.9rem;
    border-radius: 12px;
    background: rgba(255, 255, 255, 0.08);
    font-size: 0.78rem;
    color: var(--sidebar-text-muted);
    line-height: 1.45;
  }
  .sidebar-foot strong { color: var(--sidebar-text); font-weight: 700; }

  /* min-width: 0 ist hier kein Schoenheitsfehler, sondern die Korrektur eines
     echten Fehlverhaltens: Als Grid-Element hat .main von Haus aus
     min-width:auto und kann damit nicht schmaler werden als sein breitester
     Inhalt. Eine breite Tabelle schob die Spalte ueber den Bildschirmrand
     hinaus - und weil overflow:hidden (noetig fuer die Farbschleier unten)
     das Ueberstehende abschneidet, liess es sich auch nicht heranscrollen.
     Auf dem iPhone quer war der rechte Teil damit unerreichbar. Mit
     min-width:0 bleibt .main in der Breite des Bildschirms, und .table-wrap
     scrollt wie vorgesehen in sich selbst. */
  .main { position: relative; min-width: 0; padding: 2.25rem clamp(1.25rem, 4vw, 3rem) 3rem; overflow: hidden; isolation: isolate; }
  .main::before, .main::after { content: ""; position: absolute; z-index: -1; border-radius: 50%; filter: blur(70px); pointer-events: none; }
  .main::before { width: 520px; height: 520px; top: -180px; right: -120px; background: var(--blob-a); }
  .main::after { width: 420px; height: 420px; bottom: -160px; left: 8%; background: var(--blob-b); }

  .topbar { display: flex; align-items: center; justify-content: space-between; gap: 1.5rem; margin-bottom: 2rem; flex-wrap: wrap; }
  .greeting h1 { font-weight: 900; font-size: clamp(1.4rem, 2.2vw, 1.85rem); margin: 0 0 0.2rem; text-wrap: balance; }
  .greeting p { margin: 0; color: var(--text-muted); font-size: 0.92rem; }

  .topbar-tools { display: flex; align-items: center; gap: 0.9rem; }

  /* --- Farbschema-Umschalter ------------------------------------------
     Drei Zustaende statt zwei: Sonne, Mond und "A" fuer automatisch. Der
     dritte ist der wichtigste - ohne ihn kann man eine einmal getroffene
     Wahl nie wieder an das Geraet zurueckgeben, und wer morgens hell und
     abends dunkel arbeitet, muesste zweimal taeglich von Hand schalten.
     Der Schieber ist reine Zier: Die Zustaende sind Schaltflaechen mit
     aria-pressed, damit auch ohne Blick auf die Farbe erkennbar ist,
     welcher gerade gilt. */
  .thema-schalter {
    position: relative;
    display: inline-flex;
    align-items: center;
    padding: 3px;
    border-radius: 999px;
    background: var(--surface-strong);
    border: 1px solid var(--border);
    gap: 0;
  }

  /* Die ersten beiden Abschnitte tragen ein Sinnbild und sind quadratisch,
     der dritte traegt das Wort "Auto" und ist entsprechend breiter. Feste
     Breiten, weil der Schieber darunter sie kennen muss. */
  .thema-schalter button {
    position: relative; z-index: 1;
    width: 30px; height: 26px;
    display: grid; place-items: center;
    border: none; background: none; cursor: pointer;
    border-radius: 999px;
    color: var(--text-faint);
    font: 700 0.72rem/1 inherit;
    transition: color 0.15s ease;
  }
  .thema-schalter button[data-thema="auto"] { width: 46px; letter-spacing: 0.02em; }
  .thema-schalter button:hover { color: var(--text-muted); }
  .thema-schalter button[aria-pressed="true"] { color: var(--brand-deep); }
  .thema-schalter svg { display: block; }

  /* Der gleitende Reiter. Er liegt hinter den Schaltflaechen und wird ueber
     data-aktiv am Behaelter verschoben - eine Angabe, kein Rechenweg. */
  .thema-schieber {
    position: absolute; top: 3px; left: 3px;
    width: 30px; height: 26px;
    border-radius: 999px;
    background: var(--brand-soft);
    box-shadow: 0 1px 2px hsl(var(--shadow-color) / 0.18);
    transition: transform 0.18s ease, width 0.18s ease;
    pointer-events: none;
  }
  .thema-schalter[data-aktiv="hell"]   .thema-schieber { transform: translateX(0);    width: 30px; }
  .thema-schalter[data-aktiv="dunkel"] .thema-schieber { transform: translateX(30px); width: 30px; }
  .thema-schalter[data-aktiv="auto"]   .thema-schieber { transform: translateX(60px); width: 46px; }

  /* --- Menueklappe (nur schmale Geraete) ------------------------------- */
  .menue-klappe {
    display: none;
    width: 38px; height: 38px;
    border-radius: 10px;
    border: 1px solid rgba(255, 255, 255, 0.22);
    background: rgba(255, 255, 255, 0.12);
    color: var(--sidebar-text);
    cursor: pointer;
    place-items: center;
    flex-shrink: 0;
  }
  .menue-klappe:hover { background: rgba(255, 255, 255, 0.2); }

  .role-chip {
    font-size: 0.72rem; font-weight: 700; padding: 0.4rem 0.75rem;
    border-radius: 999px; background: var(--brand-soft); color: var(--brand-deep);
    white-space: nowrap;
  }

  .avatar {
    width: 40px; height: 40px; border-radius: 12px;
    background: linear-gradient(155deg, var(--cyan), var(--brand));
    color: #fff; display: grid; place-items: center;
    font-weight: 700; font-size: 0.85rem; text-decoration: none;
  }

  .logout-form { display: flex; margin: 0; }
  .logout-form button {
    display: grid; place-items: center; width: 40px; height: 40px;
    border-radius: 12px; background: var(--surface);
    backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px);
    border: 1px solid var(--border); color: var(--brand-deep); cursor: pointer;
    padding: 0; margin: 0; line-height: 1;
  }
  .logout-form button:hover { color: var(--accent-deep); }

  /* ---------- KPI + panels (dashboard content) ---------- */

  .kpi-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 1rem; margin-bottom: 1.75rem; }
  .kpi-card {
    background: var(--surface); backdrop-filter: blur(18px); -webkit-backdrop-filter: blur(18px);
    border: 1px solid var(--border); border-radius: 16px; padding: 1.1rem 1.2rem;
    display: flex; flex-direction: column; gap: 0.6rem;
    box-shadow: 0 1px 2px hsla(var(--shadow-color), 0.06);
    transition: transform 0.18s ease, box-shadow 0.18s ease;
  }
  .kpi-card:hover { transform: translateY(-2px); box-shadow: 0 12px 24px -12px hsla(var(--shadow-color), 0.28); }
  .kpi-top { display: flex; align-items: center; justify-content: space-between; }
  .kpi-icon { width: 34px; height: 34px; border-radius: 10px; display: grid; place-items: center; }
  .kpi-icon.brand { background: var(--brand-soft); color: var(--brand-deep); }
  .kpi-icon.accent { background: var(--accent-soft); color: var(--accent-deep); }
  .kpi-icon.good { background: var(--status-good-bg); color: var(--status-good-fg); }
  .kpi-icon.critical { background: var(--status-critical-bg); color: var(--status-critical-fg); }
  .kpi-trend { font-size: 0.72rem; font-family: "IBM Plex Mono", monospace; color: var(--status-good-fg); font-variant-numeric: tabular-nums; }
  .kpi-trend.down { color: var(--status-critical-fg); }
  .kpi-value { font-family: "IBM Plex Mono", monospace; font-weight: 600; font-size: 1.9rem; font-variant-numeric: tabular-nums; line-height: 1; }
  .kpi-label { font-size: 0.82rem; color: var(--text-muted); }

  .content-grid { display: grid; grid-template-columns: 1.35fr 1fr; gap: 1.25rem; align-items: start; }
  .panel {
    background: var(--surface); backdrop-filter: blur(18px); -webkit-backdrop-filter: blur(18px);
    border: 1px solid var(--border); border-radius: 18px; padding: 1.4rem 1.5rem 1.5rem;
    box-shadow: 0 1px 2px hsla(var(--shadow-color), 0.06);
  }
  .panel-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; margin-bottom: 1.1rem; }
  .panel-head h2 { margin: 0 0 0.15rem; font-weight: 700; font-size: 1.05rem; }
  .panel-head p { margin: 0; font-size: 0.82rem; color: var(--text-muted); }

  .chip {
    display: inline-flex; align-items: center; gap: 0.35rem; padding: 0.3rem 0.65rem;
    border-radius: 999px; font-size: 0.72rem; font-weight: 700; letter-spacing: 0.01em; white-space: nowrap;
  }
  .chip::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
  .chip.good { background: var(--status-good-bg); color: var(--status-good-fg); }
  .chip.info { background: var(--status-info-bg); color: var(--status-info-fg); }
  .chip.critical { background: var(--status-critical-bg); color: var(--status-critical-fg); }

  .chart-legend { display: flex; gap: 1.1rem; flex-wrap: wrap; margin-top: 0.75rem; font-size: 0.78rem; color: var(--text-muted); }
  .chart-legend span { display: inline-flex; align-items: center; gap: 0.4rem; }
  .legend-swatch { width: 14px; height: 3px; border-radius: 2px; display: inline-block; }
  .legend-swatch.solid { background: var(--brand); }
  .legend-swatch.dashed { background: repeating-linear-gradient(90deg, var(--brand) 0 5px, transparent 5px 9px); }
  .legend-swatch.band { background: var(--accent); opacity: 0.55; height: 10px; border-radius: 3px; }
  svg.chart text { font-family: "IBM Plex Mono", monospace; fill: var(--text-faint); font-size: 10px; }

  table.stock { width: 100%; border-collapse: collapse; font-size: 0.86rem; }
  table.stock th {
    text-align: left; font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.06em;
    color: var(--text-faint); font-weight: 700; padding: 0 0.6rem 0.6rem; border-bottom: 1px solid var(--border);
  }
  table.stock td { padding: 0.7rem 0.6rem; border-bottom: 1px solid var(--border); vertical-align: middle; }
  table.stock tbody tr { transition: background 0.15s ease; }
  table.stock tbody tr:hover { background: var(--surface-strong); }
  table.stock tbody tr:last-child td { border-bottom: none; }
  .dog-name { font-weight: 700; }
  .dog-breed { color: var(--text-muted); font-size: 0.78rem; }
  td.num { font-family: "IBM Plex Mono", monospace; font-variant-numeric: tabular-nums; text-align: right; }
  /* Der Export-Knopf sitzt ueber der Tabelle, rechtsbuendig - dort, wo man
     ihn sucht, und ohne die Kopfzeile der Tabelle zu stoeren. Er wird per
     Skript eingesetzt (public/tabellen-export.js), damit ihn jede Liste
     bekommt, auch die, die ihr <table> noch von Hand schreiben. */
  .csv-leiste { display: flex; justify-content: flex-end; margin: 0 0 0.5rem; }

  .csv-export {
    font-size: 0.72rem; font-weight: 700; letter-spacing: 0.04em;
    padding: 0.35rem 0.7rem; border-radius: 8px;
    border: 1px solid var(--border-strong);
    background: var(--surface-strong); color: var(--text-muted);
    cursor: pointer;
    transition: color 0.15s ease, border-color 0.15s ease;
  }
  .csv-export:hover { color: var(--brand-deep); border-color: var(--brand); }

  /* Waagerecht scrollbar - mit sichtbarem Hinweis darauf.
     Ohne den Hinweis sieht eine abgeschnittene Tabelle auf dem Telefon aus
     wie ein Anzeigefehler: Man sieht, dass rechts etwas fehlt, aber nichts
     laedt zum Wischen ein. Genau so wurde es am 02.09. gemeldet.

     Die vier Verlaufsschichten sind der bekannte Kniff dafuer, ganz ohne
     Skript: Die beiden "local"-Schichten scrollen mit dem Inhalt mit und
     decken den Schatten ab, sobald man am jeweiligen Ende angekommen ist -
     der Schatten erscheint also nur, solange es dort wirklich noch etwas
     zu sehen gibt. */
  .table-wrap {
    overflow-x: auto;
    background:
      linear-gradient(to right, var(--surface-solid) 40%, transparent) left center / 28px 100% no-repeat local,
      linear-gradient(to left,  var(--surface-solid) 40%, transparent) right center / 28px 100% no-repeat local,
      radial-gradient(farthest-side at 0 50%, hsl(var(--shadow-color) / 0.22), transparent) left center / 14px 100% no-repeat scroll,
      radial-gradient(farthest-side at 100% 50%, hsl(var(--shadow-color) / 0.22), transparent) right center / 14px 100% no-repeat scroll;
  }
  table.stock th[hidden], table.stock td[hidden] { display: none; }
  table.stock th[draggable="true"] { cursor: grab; user-select: none; }
  table.stock th[draggable="true"]:hover { color: var(--brand-deep); }
  table.stock th.wird-gezogen { opacity: 0.4; }

  .spalten-steuerung { position: relative; display: inline-block; }
  .spalten-toggle {
    display: inline-flex; align-items: center; gap: 0.4rem; padding: 0.4rem 0.75rem;
    border-radius: 999px; border: 1px solid var(--border-strong); background: var(--surface-solid);
    color: var(--text-muted); font-size: 0.78rem; font-weight: 600; cursor: pointer;
  }
  .spalten-toggle:hover { color: var(--brand-deep); border-color: var(--brand); }
  .spalten-panel {
    position: absolute; right: 0; top: calc(100% + 0.4rem); z-index: 20; width: 15rem;
    background: var(--surface-solid); border: 1px solid var(--border-strong); border-radius: 0.75rem;
    padding: 0.75rem; box-shadow: 0 12px 28px hsla(var(--shadow-color), 0.22);
    display: flex; flex-direction: column; gap: 0.4rem;
  }
  .spalten-panel-hint { margin: 0 0 0.2rem; font-size: 0.72rem; color: var(--text-faint); }
  .spalten-panel-item { display: flex; align-items: center; gap: 0.5rem; font-size: 0.82rem; cursor: pointer; }
  .spalten-reset {
    margin-top: 0.3rem; padding: 0.4rem 0.6rem; border-radius: 0.5rem; border: 1px dashed var(--border-strong);
    background: transparent; color: var(--text-muted); font-size: 0.78rem; cursor: pointer; text-align: left;
  }
  .spalten-reset:hover { color: var(--accent-deep); border-color: var(--accent); }

  .dashboard-toolbar { display: flex; justify-content: flex-end; margin-bottom: 0.9rem; }
  .dashboard-grid {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(340px, 1fr));
    gap: 1.25rem; align-items: start;
  }
  .dashboard-panel-wrap { position: relative; }
  .dashboard-panel-wrap.full { grid-column: 1 / -1; }
  .dashboard-panel-wrap[hidden] { display: none; }
  .dashboard-drag-handle {
    position: absolute; top: 0.6rem; right: 0.6rem; z-index: 5; cursor: grab;
    width: 1.6rem; height: 1.6rem; display: flex; align-items: center; justify-content: center;
    border-radius: 0.4rem; color: var(--text-faint); opacity: 0.5; transition: opacity 0.15s ease, color 0.15s ease;
  }
  .dashboard-panel-wrap:hover .dashboard-drag-handle { opacity: 1; }
  .dashboard-drag-handle:hover { color: var(--brand-deep); background: var(--surface-strong); }
  .dashboard-panel-wrap.wird-gezogen { opacity: 0.4; }
  .panel.full { grid-column: 1 / -1; }

  .placeholder-panel {
    display: flex; flex-direction: column; gap: 0.5rem;
    align-items: flex-start; padding: 3rem 1.5rem;
  }
  .placeholder-panel h2 { margin: 0; font-weight: 700; font-size: 1.2rem; }
  .placeholder-panel p { margin: 0; color: var(--text-muted); font-size: 0.9rem; }

  /* ---------- 2FA / Profil ---------- */

  .btn-secondary {
    border-color: var(--border-strong);
    background: var(--surface-solid);
    color: var(--text);
  }
  .btn-secondary:hover { border-color: var(--accent); color: var(--accent-deep); }

  .btn-link {
    border: none; background: none; padding: 0; margin: 0;
    color: var(--text-muted); font-size: 0.82rem; font-weight: 600;
    cursor: pointer; text-decoration: underline;
  }
  .btn-link:hover { color: var(--brand-deep); }

  /* stretch statt center: So sind die Schaltflaechen zwingend gleich hoch,
     auch wenn eine Beschriftung einmal umbrechen sollte. */
  .form-actions { display: flex; align-items: stretch; gap: 0.75rem; margin-top: 0.4rem; }

  .mfa-status-row {
    display: flex; align-items: center; justify-content: space-between; gap: 1rem;
    padding: 1rem 1.1rem; margin: 1rem 0;
    background: var(--surface-strong); border: 1px solid var(--border); border-radius: 14px;
  }
  .mfa-status-row > div:first-child { display: flex; flex-direction: column; gap: 0.2rem; }
  .mfa-status-row .subtext { font-size: 0.82rem; color: var(--text-muted); }

  .qr-box {
    display: grid; place-items: center; padding: 1.25rem;
    background: #fff; border: 1px solid var(--border); border-radius: 14px; margin-bottom: 1rem;
  }
  .qr-box img { width: 190px; height: 190px; }

  .mfa-secret {
    font-size: 0.82rem; color: var(--text-muted); text-align: center;
    margin: 0 0 1.3rem;
  }
  .mfa-secret code {
    font-family: "IBM Plex Mono", monospace; background: var(--surface-strong);
    padding: 0.15rem 0.4rem; border-radius: 6px; color: var(--text);
  }

  .notice-banner {
    display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap;
    background: var(--accent-soft); border: 1px solid var(--border);
    border-radius: 14px; padding: 0.9rem 1.2rem; margin-bottom: 1.25rem;
  }
  .notice-banner p { margin: 0; font-size: 0.86rem; color: var(--text); }
  .notice-banner strong { color: var(--accent-deep); }
  .notice-banner-actions { display: flex; align-items: center; gap: 1rem; flex-shrink: 0; }

  @media (max-width: 880px) {
    /* grid-template-rows ist hier noetig, nicht kosmetisch: Ein Raster mit
       min-height:100vh und automatischen Zeilen verteilt den freien Platz auf
       beide Zeilen - die Seitenleiste waere damit ueber den halben Bildschirm
       hoch, auch wenn nur eine Zeile darin steht. "auto 1fr" gibt ihr die
       Hoehe ihres Inhalts und den Rest dem Arbeitsbereich. */
    .app { grid-template-columns: 1fr; grid-template-rows: auto 1fr; }

    /* Bis 2026-09-02 wurde die Seitenleiste hier zu einer waagerecht
       scrollenden Leiste. Das zeigte alle Punkte gleichzeitig, aber keinen
       davon vollstaendig - man musste blind seitwaerts wischen, um zu sehen,
       was es ueberhaupt gibt. Stattdessen jetzt eine Klappe: geschlossen
       nimmt sie eine Zeile ein, geoeffnet zeigt sie die Punkte untereinander
       und damit lesbar. */
    .sidebar {
      flex-direction: column;
      gap: 0;
      padding: 0.85rem 1rem;
    }
    .sidebar .brand { padding: 0; }
    .menue-klappe { display: grid; }

    .sidebar-kopf {
      display: flex; align-items: center; justify-content: space-between;
      gap: 1rem; width: 100%;
    }

    nav.primary-nav { display: none; padding-top: 0.85rem; }
    .app.nav-offen nav.primary-nav { display: flex; }
    .nav-label { display: none; }

    /* Die Fusszeile der Seitenleiste (Adresse und Rolle) haengt an der
       Navigation: Sie zeigt dasselbe wie die Kopfleiste rechts und ist
       geschlossen nur Wiederholung. */
    .sidebar-foot { display: none; margin-top: 0.85rem; }
    .app.nav-offen .sidebar-foot { margin-top: 0.85rem; }
    .app.nav-offen .sidebar-foot { display: block; }

    /* !important ist hier bewusst gesetzt und die einzige Regel im ganzen
       Stylesheet, die es braucht. Grund: Acht Ansichten geben ihre
       Spaltenaufteilung als style-Attribut mit
       (style="grid-template-columns:1fr 1fr"), und ein Inline-Stil schlaegt
       jede Regel aus dem Stylesheet. Ohne !important blieben die Formulare
       auf dem Telefon zweispaltig - gemessen am 02.09.: 722px Inhalt in
       einem 500px breiten Bereich, den overflow:hidden dann abschneidet.
       Genau das war der Fehler "auf dem iPhone laesst sich nicht waagerecht
       scrollen": Es gab nichts zu scrollen, das Fehlende war weggeschnitten.

       Die saubere Loesung waeren Klassen statt style-Attribute in den
       Ansichten. Das ist der eigentliche Mangel und gehoert nachgezogen;
       bis dahin faengt diese Regel alle acht Dateien auf einmal ab - auch
       die Stelle in samenbankTypsystem.js, die ihre Spalten erst zur
       Laufzeit zusammensetzt und sich schlecht in eine Klasse uebersetzen
       laesst. */
    .content-grid { grid-template-columns: 1fr !important; }

    /* Rasterkinder koennen ohne min-width:0 nicht unter ihre Inhaltsbreite
       schrumpfen - eine lange E-Mail-Adresse oder Chipnummer sprengt sonst
       weiterhin die Spalte, auch wenn nur noch eine da ist. */
    .content-grid > * { min-width: 0; }
    .panel { min-width: 0; }

    /* Die Werkzeuge rechts oben duerfen umbrechen, statt die Kopfzeile zu
       sprengen. */
    .topbar-tools { flex-wrap: wrap; gap: 0.6rem; }
  }

  @media (prefers-reduced-motion: reduce) {
    * { transition: none !important; animation: none !important; }
  }

  /* --- Unterschriftsfeld (Zustimmungs-Gate) ---------------------------- */
  .unterschrift-rahmen {
    border: 1px dashed var(--border-strong); border-radius: 12px; background: #fff;
    display: inline-block; touch-action: none;
  }
  .unterschrift-rahmen canvas { display: block; width: 100%; max-width: 600px; height: 200px; cursor: crosshair; }

  .mandant-umschalter select {
    border: 1px solid var(--border-strong); background: var(--surface-solid); color: var(--text);
    border-radius: 999px; padding: 0.35rem 0.7rem; font-size: 0.78rem; font-weight: 600; cursor: pointer;
  }
  .mandant-umschalter select:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 1px; }

  /* --- Newsletter-Editor (Baustufe D) -------------------------------- */
  .table-actions { display: flex; gap: 0.75rem; justify-content: flex-end; }
  .table-empty { text-align: center; color: var(--text-muted); padding: 1.5rem 0 !important; }

  .nl-titel-input, .nl-betreff-input {
    display: block; border: none; background: transparent; font-family: inherit; color: var(--text);
    padding: 0.1rem 0; margin: 0 0 0.15rem; width: 100%;
  }
  .nl-titel-input { font-weight: 700; font-size: 1.05rem; }
  .nl-betreff-input { font-size: 0.82rem; color: var(--text-muted); }
  .nl-titel-input:focus-visible, .nl-betreff-input:focus-visible {
    outline: 2px solid var(--focus-ring); outline-offset: 2px; border-radius: 4px;
  }

  .nl-editor { display: grid; grid-template-columns: 15rem 1fr 20rem; gap: 1.25rem; align-items: start; margin-top: 0.5rem; }
  .nl-sidebar-block { margin-bottom: 1.25rem; }
  .nl-sidebar-block h3 { margin: 0 0 0.2rem; font-size: 0.82rem; }
  .nl-palette, .nl-platzhalter { display: flex; flex-direction: column; gap: 0.4rem; margin-top: 0.5rem; }
  .nl-palette-item, .nl-platzhalter-item {
    border: 1px solid var(--border-strong); background: var(--surface-solid); border-radius: 10px;
    padding: 0.5rem 0.7rem; font-size: 0.8rem; text-align: left; cursor: pointer; color: var(--text);
  }
  .nl-palette-item:hover, .nl-platzhalter-item:hover { border-color: var(--brand); color: var(--brand-deep); }
  .nl-palette-item:disabled, .nl-platzhalter-item:disabled { opacity: 0.4; cursor: not-allowed; }

  .nl-canvas-wrap { min-height: 20rem; }
  .nl-canvas { display: flex; flex-direction: column; gap: 0.75rem; min-height: 8rem; }
  .nl-canvas-empty { text-align: center; padding: 2rem 1rem; border: 1px dashed var(--border-strong); border-radius: 12px; }

  .nl-block { border: 1px solid var(--border); border-radius: 12px; background: var(--surface-solid); overflow: hidden; }
  .nl-block-head {
    display: flex; align-items: center; gap: 0.5rem; padding: 0.4rem 0.6rem;
    background: var(--surface-strong); border-bottom: 1px solid var(--border); font-size: 0.75rem;
  }
  .nl-block-handle { cursor: grab; color: var(--text-faint); }
  .nl-block-typ { font-weight: 700; color: var(--text-muted); flex: 1; }
  .nl-block-remove {
    border: none; background: transparent; color: var(--text-faint); cursor: pointer; font-size: 0.85rem;
    padding: 0.1rem 0.35rem; border-radius: 6px;
  }
  .nl-block-remove:hover { color: var(--status-critical-fg); background: var(--status-critical-bg); }
  .nl-block-body { padding: 0.75rem 0.9rem; display: flex; flex-direction: column; gap: 0.5rem; }
  .nl-block-body input {
    border: 1px solid var(--border-strong); border-radius: 8px; padding: 0.45rem 0.6rem;
    font-family: inherit; font-size: 0.85rem; background: var(--surface-solid); color: var(--text);
  }
  .nl-block-toolbar { display: flex; gap: 0.35rem; }
  .nl-block-toolbar button {
    border: 1px solid var(--border-strong); background: var(--surface-solid); border-radius: 6px;
    width: 1.8rem; height: 1.8rem; cursor: pointer; font-size: 0.8rem; color: var(--text);
  }
  .nl-block-content {
    border: 1px solid var(--border-strong); border-radius: 8px; padding: 0.6rem 0.7rem;
    min-height: 3rem; font-size: 0.85rem; line-height: 1.5;
  }
  .nl-block-content:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 1px; }
  .nl-block-trenner-vorschau { border-top: 1px solid var(--border-strong); margin: 0.5rem 0; }

  .nl-preview-wrap { border: 1px solid var(--border); border-radius: 12px; overflow: hidden; background: var(--surface-solid); }
  .nl-preview-head {
    display: flex; align-items: center; justify-content: space-between; gap: 0.5rem;
    padding: 0.6rem 0.8rem; border-bottom: 1px solid var(--border);
  }
  .nl-preview-head h3 { margin: 0; font-size: 0.82rem; }
  .nl-preview-frame { width: 100%; height: 32rem; border: none; }

  @media (max-width: 1180px) {
    .nl-editor { grid-template-columns: 1fr; }
  }
  /* -------------------------------------------------------------------
     Zustellbox der Rechnungsmail
     -------------------------------------------------------------------
     Die Stufen liegen auf einer Linie, weil sie eine Abfolge sind und keine
     Aufzaehlung: Angenommen -> Zugestellt -> Geoeffnet. Erreichte Stufen
     tragen Farbe, noch nicht erreichte nur einen Umriss - der Blick findet
     damit ohne Lesen, wie weit die Mail gekommen ist.

     Gebaut als <details>, nicht mit Skript: Das Aufklappen funktioniert
     ohne JavaScript, ist ueber die Tastatur bedienbar und braucht keinen
     eigenen Zustand, der mit dem Serverzustand auseinanderlaufen koennte. */
  .zustellung { border: 1px solid var(--border); border-radius: 12px; background: var(--surface); }
  .zustellung > summary {
    list-style: none; cursor: pointer; padding: 0.55rem 0.7rem;
    display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap;
  }
  .zustellung > summary::-webkit-details-marker { display: none; }
  .zustellung > summary:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; border-radius: 12px; }
  .zustellung .aufklapp {
    margin-left: auto; font-size: 0.72rem; color: var(--text-muted); white-space: nowrap;
    display: inline-flex; align-items: center; gap: 0.25rem;
  }
  .zustellung .aufklapp::after { content: "▾"; transition: transform .15s ease; }
  .zustellung[open] .aufklapp::after { transform: rotate(180deg); }

  .zustellweg { display: flex; align-items: flex-start; gap: 0; flex-wrap: wrap; }
  .zustellstufe {
    display: flex; flex-direction: column; align-items: center; gap: 0.15rem;
    min-width: 5.4rem; position: relative; padding: 0 0.15rem;
  }
  /* Verbindungslinie zur naechsten Stufe. Sie sitzt auf halber Punkthoehe
     und endet vor dem naechsten Punkt, damit sie nicht durch ihn laeuft. */
  .zustellstufe:not(:last-child)::after {
    content: ""; position: absolute; top: 5px; left: calc(50% + 8px); right: calc(-50% + 8px);
    height: 2px; background: var(--border-strong);
  }
  .zustellstufe.erreicht:not(:last-child)::after { background: var(--status-good-fg); }
  .zustellpunkt {
    width: 12px; height: 12px; border-radius: 50%;
    border: 2px solid var(--border-strong); background: var(--surface-solid); z-index: 1;
  }
  .zustellstufe.erreicht .zustellpunkt { border-color: var(--status-good-fg); background: var(--status-good-fg); }
  .zustellstufe.gestoert .zustellpunkt { border-color: var(--status-critical-fg); background: var(--status-critical-fg); }
  .zustellstufe .stufe-label { font-size: 0.7rem; font-weight: 700; color: var(--text-faint); text-align: center; }
  .zustellstufe.erreicht .stufe-label { color: var(--text); }
  .zustellstufe.gestoert .stufe-label { color: var(--status-critical-fg); }
  .zustellstufe .stufe-zeit { font-size: 0.66rem; color: var(--text-muted); font-variant-numeric: tabular-nums; text-align: center; }

  .zustell-inhalt { border-top: 1px solid var(--border); padding: 0.7rem; }
  .zustell-inhalt table { width: 100%; border-collapse: collapse; font-size: 0.76rem; }
  .zustell-inhalt th {
    text-align: left; font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.04em;
    color: var(--text-faint); padding: 0 0.5rem 0.35rem 0; font-weight: 700;
  }
  .zustell-inhalt td { padding: 0.35rem 0.5rem 0.35rem 0; border-top: 1px solid var(--border); vertical-align: top; }
  .zustell-inhalt td.zeit { font-variant-numeric: tabular-nums; white-space: nowrap; }
  .zustell-inhalt .smtp-antwort { color: var(--text-muted); word-break: break-word; }

  .chip.warn { background: var(--accent-soft); color: var(--accent-deep); }
  .zustell-hinweis { margin: .6rem 0 0; font-size: .74rem; line-height: 1.5; color: var(--text-muted); }

