/* ============================================================================
   Cockpit — Design-System (Umsetzung von docs/STYLEGUIDE.md)
   Identität: Swiss precision + financial trust. Deep-Teal, warme Teal-Grau-
   Neutrale, ruhige Elevation, ein Semantik-Set. Nur Tokens in Komponenten-
   Regeln, keine Inline-Styles, @layer-Ordnung, BEM-nah, erweitern-nicht-
   duplizieren. Living-Demo: /styleguide.
   ============================================================================ */
@layer reset, base, tokens, layout, components, utilities;

/* Inter (B-58) — selbst gehostet (wwwroot/fonts, SIL OFL), Variable Font 100-900.
   Bewusst KEIN CDN: die App ist lokal/offline-first. @font-face bleibt ausserhalb der Layer. */
@font-face {
  font-family: 'Inter';
  src: url('fonts/InterVariable.woff2') format('woff2');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Inter';
  src: url('fonts/InterVariable-Italic.woff2') format('woff2');
  font-weight: 100 900;
  font-style: italic;
  font-display: swap;
}

/* ==================== TOKENS ==================== */
@layer tokens {
  :root {
    /* Flächen & Rahmen */
    --bg: #eef2f5;
    --surface: #ffffff;
    --surface-2: #f4f7f9;
    --border: #dce3e9;
    /* Text */
    --text: #15212b;
    --text-muted: #4c5c6a;
    --text-faint: #7e8e9b;
    --on-accent: #ffffff;
    /* Akzent (Deep-Teal) */
    --accent: #0d6e78;
    --accent-ink: #0a565e;
    --accent-soft: #d8ecee;
    /* Allokations-Tonleiter (B-99, Teal-Familie) — Vermögensaufteilung/Donut, grösste Position = dunkelster Ton */
    --alloc-1: #0a565e; --alloc-2: #0d6e78; --alloc-3: #3f9aa4; --alloc-4: #78bcc4; --alloc-5: #aedadf;
    /* Netzwerk-Knotentypen (B-105): Aliase auf die bestehende Palette (Teal-Familie, Hypothek = Passivum rot,
       Dokument neutral). Dark-Mode erbt automatisch über die referenzierten Tokens. */
    --node-person: var(--accent-ink); --node-firma: var(--accent); --node-liegenschaft: var(--alloc-3);
    --node-vorsorge: var(--ok); --node-kontodepot: var(--alloc-2); --node-fahrzeug: var(--open);
    --node-police: var(--warn); --node-hypothek: var(--crit); --node-beteiligung: var(--alloc-4);
    --node-dokument: var(--surface-2);
    /* Semantik: ok / warn / crit / open (neutral) — je Vollton/Soft/Ink */
    --ok: #2f8a4e;   --ok-soft: #dcefe1;   --ok-ink: #1f6b3a;
    --warn: #b7791f; --warn-soft: #f6ecd6; --warn-ink: #875812;
    --crit: #c0392b; --crit-soft: #f6ddd9; --crit-ink: #8f271c;
    --open: #5c6f7e; --open-soft: #e6ebee; --open-ink: #41515d;
    /* Typo */
    --font-mono: "Cascadia Mono", "Consolas", ui-monospace, monospace;
    --font-sans: 'Inter', "Segoe UI", system-ui, -apple-system, Arial, sans-serif;
    --fs-xs: 12px; --fs-sm: 13px; --fs-md: 14px; --fs-base: 15px; --fs-lg: 20px; --fs-xl: 28px;
    /* Spacing (4-Punkt-Raster) */
    --space-1: 4px; --space-2: 8px; --space-3: 12px; --space-4: 16px; --space-5: 24px; --space-6: 32px;
    /* Radien */
    --r-sm: 6px; --r-md: 10px; --r-lg: 14px;
    /* EINE Symbolgroesse (B-181, R-015853). Gemessen am 13.10.2026 auf /dokumente trugen die
       Symbole vier verschiedene Groessen -- 13px der Blitz im Spaltenkopf, 16px der Schalter der
       Seitenleiste, 17px das Abmelden, 18px die sieben der Navigation -- jede von ihrer Komponente
       selbst erfunden. 18px ist der Wert, den 7 von 10 schon trugen; die anderen folgen ihm.
       Bewacht von SymbolGroesseTests, damit die naechste Komponente ihn erbt statt sich einen
       auszudenken. */
    --icon-size: 18px;
    /* B-163/B-133: der Pillen-Radius. 999px und 99px standen beide im Stylesheet; benannt wird
       nur die 999 -- die vier 99er zu vereinheitlichen waere eine Entscheidung, keine Benennung. */
    --r-pill: 999px;
    /* Rahmenbreite. 1px kam 72x roh vor und hatte kein Token; `outline-offset: 1px` ist bewusst
       NICHT gemeint -- ein Abstand ist keine Breite. */
    --border-width: 1px;
    /* Content-Breite: hoher Container-Cap (nur gegen absurde Ultrawide-Streckung, deckelt NICHT die
       datendichten Seiten) + Lesbarkeits-Mass für Fliesstext (Zeilenlänge ~66–75 Zeichen). */
    --content-max: 1600px; --measure: 68ch;
    /* Schatten */
    --shadow-1: 0 1px 2px rgba(16, 33, 43, .05), 0 10px 30px -18px rgba(16, 33, 43, .25);
    --shadow-2: 0 2px 6px rgba(16, 33, 43, .08), 0 18px 40px -20px rgba(16, 33, 43, .32);
    --shadow-3: 0 8px 24px rgba(0, 0, 0, .12);
    /* Overlay-Hintergrund (Dokument-Viewer B-63) */
    --backdrop: rgba(16, 33, 43, .5);
    /* Fokus */
    --focus: 2px solid var(--accent);
    /* Marken-Panel (B-57, Login-Split): dunkler als --accent, eigener Token statt Inline-Berechnung */
    --brand-panel: #0a3a40;
    /* Text AUF dem Marken-Panel. Eigene Tokens, weil --on-accent hier nicht passt: das Panel
       bleibt in beiden Themes nahezu schwarz, --on-accent wird im Dark Mode aber dunkel
       (#06232a) -- es waere dort dunkel auf dunkel und damit unlesbar. In app.css standen
       deshalb die einzigen rohen Farbwerte ausserhalb des tokens-Layers; diese zwei Tokens
       ersetzen sie wertgleich, also ohne jede sichtbare Aenderung. */
    --on-brand-panel: #ffffff;
    --on-brand-panel-muted: rgba(255, 255, 255, .8);
  }

  /* B-174 (R-015526): Die Dark-Palette haengt am Attribut, NICHT an der Media-Query.
     Warum nicht beides: die Palette ist ein Block von rund 40 Tokens, und CSS kann denselben
     Block nicht an eine Media-Query UND einen Attribut-Selektor haengen, ohne ihn zu doppeln.
     Zwei Kopien laufen auseinander, und die zweite waere die ungepflegte. Deshalb loest der
     Browser die Einstellung "System" selbst zu "hell" oder "dunkel" auf (matchMedia, inkl.
     Nachfuehrung bei Aenderung) und setzt data-theme auf einen konkreten Wert -- das Stylesheet
     kennt nur noch zwei Zustaende und fuehrt die Palette genau einmal.
     Gesetzt wird das Attribut von einem Inline-Skript im <head>, also VOR dem ersten Zeichnen;
     ohne das blitzte bei jedem Aufruf kurz das helle Thema auf. */
  :root[data-theme="dark"] {
      --bg: #0c141b;
      --surface: #141f28;
      --surface-2: #1b2933;
      --border: #293a46;
      --text: #e8eef2;
      --text-muted: #a9b9c5;
      --text-faint: #7a92a1;
      --on-accent: #06232a;
      --accent: #3fb6c2;
      --accent-ink: #8ad6dd;
      --accent-soft: #123840;
      --alloc-1: #3fb6c2; --alloc-2: #2f97a2; --alloc-3: #3f7f88; --alloc-4: #4d6d74; --alloc-5: #5c6f7e;
      --ok: #57c07a;   --ok-soft: #12301f;   --ok-ink: #8ed9a5;
      --warn: #e0aa4b; --warn-soft: #33270f; --warn-ink: #efc987;
      --crit: #e8776a; --crit-soft: #331812; --crit-ink: #f0a99f;
      --open: #8ea4b3; --open-soft: #1c2a34; --open-ink: #b2c4d0;
      --shadow-1: 0 1px 2px rgba(0, 0, 0, .35), 0 12px 34px -18px rgba(0, 0, 0, .7);
      --shadow-2: 0 2px 6px rgba(0, 0, 0, .45), 0 20px 46px -20px rgba(0, 0, 0, .8);
      --shadow-3: 0 8px 24px rgba(0, 0, 0, .55);
      --backdrop: rgba(0, 0, 0, .65);
      --brand-panel: #041418;
      /* Unveraendert weiss: das Panel ist im Dark Mode noch dunkler, nicht heller. */
      --on-brand-panel: #ffffff;
      --on-brand-panel-muted: rgba(255, 255, 255, .8);
  }
}

/* ==================== RESET / Framework-Boilerplate ==================== */
@layer reset {
  * { box-sizing: border-box; }

  h1:focus { outline: none; }

  .valid.modified:not([type=checkbox]) { outline: var(--border-width) solid var(--ok); }
  .invalid { outline: var(--border-width) solid var(--crit); }
  .validation-message { color: var(--crit); }

  .blazor-error-boundary {
    background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, var(--crit);
    padding: 1rem 1rem 1rem 3.7rem;
    color: var(--on-accent);
  }
  .blazor-error-boundary::after { content: "An error has occurred."; }

  .darker-border-checkbox.form-check-input { border-color: #929292; }
  .form-floating > .form-control-plaintext::placeholder,
  .form-floating > .form-control::placeholder { color: var(--text-faint); text-align: end; }
  .form-floating > .form-control-plaintext:focus::placeholder,
  .form-floating > .form-control:focus::placeholder { text-align: start; }
}

/* ==================== BASE ==================== */
@layer base {
  body {
    margin: 0;
    background: var(--bg);
    color: var(--text);
    font-family: var(--font-sans);
    font-size: var(--fs-base);
    line-height: 1.55;
  }

  /* Formularfelder — einheitliche Höhe/Padding (B-25) für input/select/textarea. */
  input[type=text], input[type=number], input[type=date], input[type=password], input[type=email],
  select, textarea {
    width: 100%;
    box-sizing: border-box;
    font-family: inherit;
    font-size: var(--fs-md);
    line-height: 1.4;
    padding: 9px 11px;
    border: var(--border-width) solid var(--border);
    border-radius: var(--r-sm);
    background: var(--surface-2);
    color: var(--text);
  }
  select {
    appearance: none; -webkit-appearance: none; -moz-appearance: none;
    cursor: pointer;
    padding-right: 28px;
    background-image: linear-gradient(45deg, transparent 50%, var(--text-faint) 50%),
                      linear-gradient(135deg, var(--text-faint) 50%, transparent 50%);
    background-position: calc(100% - 17px) center, calc(100% - 12px) center;
    background-size: 5px 5px, 5px 5px;
    background-repeat: no-repeat;
  }
  select::-ms-expand { display: none; }
  input[type=text]:focus, input[type=number]:focus, input[type=date]:focus,
  input[type=password]:focus, input[type=email]:focus, select:focus, textarea:focus {
    outline: var(--focus); outline-offset: 1px; border-color: var(--accent);
  }
}

/* ==================== LAYOUT ==================== */
@layer layout {
  /* UI-05: minmax(0, 1fr) statt 1fr — dieselbe Ursache wie B-114, nur eine Ebene hoeher.
     `1fr` ist `minmax(auto, 1fr)`, und das automatische Minimum ist die Min-Content-Breite des
     Inhalts. Eine zu breite Tabelle liess die Spalte deshalb ueber den Viewport hinauswachsen und
     zog die Seite — samt Sidebar — in den horizontalen Scroll. Mit einem Minimum von 0 bleibt die
     Spalte begrenzt und `.datagrid-wrap.table-scroll` scrollt, wie vorgesehen, selbst. */
  .app { display: grid; grid-template-columns: 264px minmax(0, 1fr); min-height: 100vh; }

  /* UI-29: vorher scrollte die GANZE Seitenleiste, sobald ihr Inhalt nicht mehr passte — bei 800 px
     Fensterhoehe 159 px Ueberschuss, und die Benutzerkarte unten verschwand aus dem Bild. Durch die
     Gruppen-Ueberschriften (UI-25) wurde das schlimmer, nicht besser. Jetzt scrollt nur die
     Linkliste; Marke oben und Benutzerkarte unten bleiben in jeder Fensterhoehe stehen. */
  /* UI-B170a (09.10.2026): `.sidebar` statt des blanken `aside`. Gemessen am laufenden System:
     diese Regel traf auch <aside class="detail-panel"> in /dokumente und /audit sowie
     <aside class="graph__detail"> in /netzwerk und gab ihnen height:100vh + overflow:hidden.
     Im Dokumente-Panel standen dadurch 2029px Inhalt in 1259px sichtbarer Hoehe -- 770px waren
     weder sichtbar noch scrollbar, sondern schlicht weg. Genau der Fall, vor dem die Hausregel
     "keine blanken Element-Selektoren" warnt: die Regel wusste nichts von den drei spaeteren
     Panels, und niemand sah den Zusammenhang. */
  .sidebar {
    position: sticky; top: 0; height: 100vh;
    background: var(--surface); border-right: var(--border-width) solid var(--border);
    display: flex; flex-direction: column; padding: 20px 14px; gap: var(--space-1);
    overflow: hidden;
  }
  /* min-height:0 ist zwingend: ohne sie hat ein Flex-Kind ein automatisches Mindestmass in
     Hauptachsen-Richtung und wuerde den Container weiterhin aufdruecken, statt zu scrollen. */
  .sidebar > nav { flex: 1 1 auto; min-height: 0; overflow-y: auto; }
  /* --- Seitenleiste ein- und ausklappbar (B-180, R-015727) --- */
  /* Der Zustand steht als data-nav am <html> und wird von navleiste.js RENDER-BLOCKIEREND gesetzt
     (Muster von B-174): spaeter gesetzt springt die Leiste bei jedem Seitenaufruf sichtbar von 264
     auf 64 px. Nichts davon laeuft ueber Blazor -- der Umschalter aendert nur das Aussehen, und das
     kann das Stylesheet allein. */
  :root[data-nav="schmal"] .app { grid-template-columns: 64px minmax(0, 1fr); }
  :root[data-nav="schmal"] .sidebar { padding-inline: var(--space-2); }
  /* Eingeklappt verschwinden die Woerter, nicht die Elemente: der Text bleibt im DOM, damit eine
     Sprachausgabe und die Suche des Browsers ihn weiterhin finden. */
  :root[data-nav="schmal"] .nav-i__text,
  :root[data-nav="schmal"] .brand,
  :root[data-nav="schmal"] .user-card__info,
  :root[data-nav="schmal"] .about-line { display: none; }
  :root[data-nav="schmal"] .nav-i { justify-content: center; padding-inline: 0; gap: 0; }
  /* Der Zaehler ueberlebt als Punkt am Symbol. Ohne das verschwaende die eine Information, die den
     Eintrag ueberhaupt interessant macht (Dokumente 76, Aufgaben 42). */
  :root[data-nav="schmal"] .nav-i__zahl {
    position: absolute; inset-block-start: var(--space-1); inset-inline-end: 6px;
    min-inline-size: 7px; block-size: 7px; padding: 0; margin: 0;
    font-size: 0; color: transparent; background: var(--accent);
  }
  :root[data-nav="schmal"] .nav-i { position: relative; }
  :root[data-nav="schmal"] .brand-zeile { justify-content: center; }
  :root[data-nav="schmal"] .user-row { justify-content: center; }
  :root[data-nav="schmal"] .nav-schalter svg { transform: rotate(180deg); }

  .brand-zeile { display: flex; align-items: flex-start; gap: var(--space-1); }
  .brand-zeile .brand { flex: 1 1 auto; min-width: 0; }
  .nav-schalter {
    flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center;
    inline-size: 28px; block-size: 28px; margin-block-start: var(--space-1); padding: 0;
    background: none; border: var(--border-width) solid transparent; border-radius: var(--r-sm);
    color: var(--text-faint); cursor: pointer;
  }
  .nav-schalter:hover { background: var(--surface-2); color: var(--text); }
  .nav-schalter:focus-visible { outline: var(--focus); outline-offset: 1px; }
  .nav-schalter svg { inline-size: var(--icon-size); block-size: var(--icon-size); transition: transform .12s ease; }
  /* Das Symbol darf nie schrumpfen: in einer 64px-Spalte ist es das Einzige, was den Eintrag
     unterscheidet. */
  .nav-i__symbol { flex: 0 0 auto; inline-size: var(--icon-size); block-size: var(--icon-size); }

  .brand { padding: 6px 10px 14px; }
  .brand .k { font-size: var(--fs-xs); letter-spacing: .14em; text-transform: uppercase; color: var(--accent-ink); font-weight: 800; }
  .brand .t { font-size: 17px; font-weight: 700; margin-top: 3px; }
  .brand .d { font-size: var(--fs-xs); color: var(--text-faint); margin-top: 2px; }

  nav { display: flex; flex-direction: column; gap: var(--space-1); }
  .nav-i {
    display: flex; align-items: center; gap: 11px;
    /* UI-29 hatte 9 -> 7px gedrueckt, um ueber 13 Eintraege ~52px zu sparen. Seit die Leiste nur
       noch sieben Zeilen fuehrt (UI-Runde 2), ist der Platz da und die Zeilen duerfen wieder atmen —
       groessere Klickflaeche, ruhigeres Bild. */
    padding: 9px 11px; border-radius: var(--r-md);
    color: var(--text-muted); font-size: var(--fs-md); font-weight: 600;
    text-decoration: none; border: var(--border-width) solid transparent;
    transition: background .12s ease, color .12s ease, border-color .12s ease;
  }
  .nav-i:hover { background: var(--surface-2); color: var(--text); }
  .nav-i:focus-visible { outline: var(--focus); outline-offset: 1px; }
  .nav-i.active {
    background: var(--accent-soft); color: var(--accent-ink);
    border-color: color-mix(in srgb, var(--accent) 28%, transparent);
  }
  .nav-i .badge {
    margin-left: auto; font-size: 11px; font-weight: 700; font-variant-numeric: tabular-nums;
    background: var(--crit-soft); color: var(--crit-ink);
    border-radius: var(--r-pill); padding: 1px var(--space-2); min-width: 22px; text-align: center;
  }
  /* UI-25: Gruppen-Zwischenueberschriften und Zahl-Chips in der Navigation. Bewusst sehr leise —
     die Gruppe soll gliedern, nicht mit den Eintraegen um Aufmerksamkeit konkurrieren. */
  .nav-gruppe { font-size: 10.5px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
    color: var(--text-faint); padding: 10px 10px 3px; }
  .nav-gruppe:first-child { padding-top: 2px; }
  .nav-i__zahl { margin-left: auto; font-size: 11px; font-weight: 700; color: var(--text-muted);
    background: var(--surface-2); border-radius: var(--r-pill); padding: 1px 7px; }

  /* UI-Runde 2: Trennlinie und leiser Verwaltungs-Eintrag. Die sechs Arbeitsschritte oben sind das
     Angebot der App; Einstellungen ist Werkzeug und soll nicht mit ihnen um Aufmerksamkeit
     konkurrieren — deshalb abgesetzt und gedaempft statt unter einer vierten Ueberschrift. */
  .nav-trenner { height: 1px; background: var(--border); margin: var(--space-3) 11px; }
  .nav-i--leise { font-weight: 500; color: var(--text-faint); }
  .nav-i--leise:hover { color: var(--text-muted); }
  .side-foot { margin-top: auto; padding: var(--space-3) 10px 2px; font-size: 11px; color: var(--text-faint); }

  /* min-width: 0 gehoert zwingend dazu: als Grid-Item hat `main` selbst ein automatisches
     Mindestmass und wuerde die Spalte sonst trotz minmax(0, …) weiterhin aufdruecken. */
  /* UI-Runde 2 (01.10.2026): KEIN globaler Deckel mehr. Vorher begrenzte --content-max (1600px)
     jede Seite gleich — auf einem 3400px breiten Bildschirm blieben 1790px weiss, und das trifft
     ausgerechnet die Seiten, die Breite brauchen: die Dokumententabelle mit 76 Zeilen, die
     Immobilien-Tabelle, das Audit-Protokoll, der Graph. Die Lesebreite gehoert nicht an den
     Rahmen, sondern an den Text — dafuer gibt es .lesebreite (utilities), das die
     textlastigen Seiten um ihren Inhalt legen. Eine Regel je Inhaltsart statt eine fuer alles. */
  main { padding: var(--space-6) clamp(20px, 4vw, 52px) 72px; min-width: 0; }

  @media (max-width: 820px) {
    .app { grid-template-columns: 1fr; }
    .sidebar { position: static; height: auto; }
    main { padding-top: 22px; }
  }
}

/* ==================== COMPONENTS ==================== */
@layer components {

  /* --- Seitenkopf --- */
  .vhead { margin-bottom: var(--space-5); }
  .vhead .ey { font-size: var(--fs-xs); letter-spacing: .12em; text-transform: uppercase; color: var(--accent-ink); font-weight: 700; }
  .vhead h1 { font-size: clamp(21px, 3vw, var(--fs-xl)); margin: .25em 0 .15em; text-wrap: balance; }
  .vhead p { margin: 0; color: var(--text-muted); max-width: var(--measure); }

  /* --- KPI-Kacheln --- */
  /* UI-26: minmax(160px, …) ergab bei zehn Kacheln 7+3 — die zweite Reihe liess ein Drittel der
     Breite leer und wirkte wie ein Umbruch-Unfall. Eine groessere Mindestbreite fuehrt zu 5+5.
     grid-auto-rows: 1fr gibt allen Reihen dieselbe Hoehe; vorher zwang die Kachel mit fuenf Zeilen
     Unterschrift nur IHRE Reihe in die Hoehe und das Raster verlor seinen Rhythmus. */
  /* UI-Runde 2: seit main keinen Breiten-Deckel mehr hat, zog auto-fit die zehn Kacheln in EINE
     Reihe — noch weniger Hierarchie als vorher in 5+5. Der Deckel gehoert an die Kachelreihe, nicht
     an die Seite: fuenf Kacheln pro Reihe sind die Zahl, bei der Titel und Fusszeile ohne Umbruch
     lesbar bleiben. */
  .kpis { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); grid-auto-rows: 1fr;
    gap: 13px; margin-bottom: 18px; max-width: 1700px; }
  /* Gruppentitel ueber einer Kachelreihe. Leise — er ordnet, er konkurriert nicht mit den Zahlen. */
  .kpi-gruppe { font-size: var(--fs-xs); font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
    color: var(--text-faint); margin: var(--space-5) 0 var(--space-2); }
  .kpi-gruppe:first-of-type { margin-top: 0; }
  .kpi {
    background: var(--surface); border: var(--border-width) solid var(--border); border-radius: var(--r-lg);
    padding: var(--space-4); box-shadow: var(--shadow-1); position: relative; overflow: hidden;
  }
  .kpi .rail { position: absolute; left: 0; top: 0; bottom: 0; width: 4px; background: var(--accent); }
  .kpi.warn .rail { background: var(--warn); }
  .kpi.open .rail { background: var(--open); }
  .kpi.ok .rail { background: var(--ok); }
  .kpi .cap { font-size: 11px; text-transform: uppercase; letter-spacing: .05em; color: var(--text-faint); font-weight: 700; }
  .kpi .val { font-size: 21px; font-weight: 600; margin-top: 7px; line-height: 1.05; letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
  .kpi .ft { font-size: 11.5px; color: var(--text-muted); margin-top: 5px; }

  /* --- KPI-Kachel als Link (B-51): ganze Kachel klickbar, kein <button>/JS-Handler — die Kachel
     IST der <a>. Kein Unterstrich auf dem Inhalt (text-decoration: none), Hover/Focus statt
     Underline signalisieren Interaktivität (Hover-Elevation via --shadow-2, Fokusring via --focus). */
  .kpi--link { display: block; color: inherit; text-decoration: none; cursor: pointer; transition: box-shadow .12s ease, transform .12s ease, border-color .12s ease; }
  .kpi--link:hover { box-shadow: var(--shadow-2); transform: translateY(-1px); border-color: color-mix(in srgb, var(--accent) 30%, var(--border)); }
  .kpi--link:focus-visible { outline: var(--focus); outline-offset: 2px; }

  /* B-99: native Datums-Eingabe (Hypothek-Ablauf/Laufzeit). */
  .wert-input { width: 150px; }
  /* B-99: segmentierter Umschalter (Hypothekentyp, Amortisationsart) statt nativem select. */
  .seg { display: inline-flex; border: var(--border-width) solid var(--border); border-radius: var(--r-sm); overflow: hidden; }
  .seg-btn { padding: var(--space-1) 11px; border: 0; border-right: var(--border-width) solid var(--border); background: var(--surface); color: var(--text-muted); font: inherit; font-size: 12.5px; cursor: pointer; }
  .seg-btn:last-child { border-right: 0; }
  .seg-btn:hover { background: var(--surface-2); color: var(--text); }
  .seg-btn.is-active { background: var(--accent); color: var(--on-accent); font-weight: 600; }
  /* B-99 Redesign: Immobilien-Karte — Kennzahlen-Sektionen (Substanz/Finanzierung/Ertrag) statt Tabelle. */
  .panel-lede { color: var(--text-muted); font-size: var(--fs-sm); margin: -4px 0 var(--space-4); max-width: var(--measure); }
  .immo { border: var(--border-width) solid var(--border); border-radius: var(--r-md); padding: var(--space-4) var(--space-5); margin-bottom: var(--space-3); }
  .immo__head { display: flex; justify-content: space-between; align-items: flex-start; gap: var(--space-4); padding-bottom: var(--space-3); border-bottom: var(--border-width) solid var(--border); }
  .immo__head h4 { margin: 0; font-size: 16px; font-weight: 700; letter-spacing: -.01em; }
  .immo__val { text-align: right; display: flex; flex-direction: column; align-items: flex-end; }
  .immo__val .cap { font-size: 11px; text-transform: uppercase; letter-spacing: .06em; color: var(--text-faint); font-weight: 700; }
  .immo__val .wert-inline { font-size: var(--fs-lg); font-weight: 700; margin-top: 2px; max-width: 175px; text-align: right; }
  .immo__sec { padding-top: var(--space-4); }
  .immo__sec-t { display: flex; align-items: center; gap: var(--space-3); font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .07em; color: var(--text-faint); margin-bottom: var(--space-3); }
  .kf { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--space-3) var(--space-4); }
  .kf__i { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
  .kf__i .cap { font-size: 11px; text-transform: uppercase; letter-spacing: .05em; color: var(--text-faint); font-weight: 700; }
  .kf__v { font-variant-numeric: tabular-nums; font-size: var(--fs-base); font-weight: 600; padding: 2px 0; }
  .kf__v--hl { color: var(--accent-ink); font-weight: 700; }
  .tranche { margin-top: var(--space-3); padding: var(--space-3) var(--space-4); background: var(--surface-2); border-radius: var(--r-sm); }
  .tranche__t { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--accent-ink); margin-bottom: var(--space-3); }
  .tiles { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--space-3); margin-top: var(--space-4); }
  .tile { background: var(--surface-2); border-radius: var(--r-sm); padding: 10px var(--space-3); }
  .tile--hl { background: var(--accent-soft); }
  .tile__v { display: block; font-variant-numeric: tabular-nums; font-size: var(--fs-lg); font-weight: 700; letter-spacing: -.02em; }
  .tile--hl .tile__v { color: var(--accent-ink); }
  .tile__k { display: block; font-size: 11px; color: var(--text-faint); margin-top: 2px; }
  /* Inline-editierbarer Wert: sieht aus wie Text, wird bei Fokus zum Feld; speichert bei Änderung (kein Button). */
  .wert-inline { font-variant-numeric: tabular-nums; font-size: var(--fs-base); font-weight: 600; color: var(--text); background: transparent; border: var(--border-width) solid transparent; border-radius: var(--r-sm); padding: 2px 6px; width: 100%; max-width: 150px; }
  .wert-inline:hover { border-color: var(--border); background: var(--surface); }
  .wert-inline:focus { outline: var(--focus); outline-offset: 1px; border-color: transparent; background: var(--surface); }
  .wert-inline--offen { color: var(--warn-ink); font-family: var(--font-sans); font-weight: 600; font-size: var(--fs-sm); }
  .wert-inline--offen::placeholder { color: var(--warn-ink); opacity: .95; }
  /* Positionsliste (Konten/Vorsorge/Fahrzeuge/Schulden) — ruhige Zeilen mit Inline-Erfassung rechts. */
  .poslist { list-style: none; margin: 0; padding: 0; }
  .poslist__i { display: flex; justify-content: space-between; align-items: center; gap: var(--space-4); padding: 13px 0; border-bottom: var(--border-width) solid var(--border); }
  .poslist__i:last-child { border-bottom: none; }
  .poslist__l { min-width: 0; }
  .poslist__name { font-weight: 600; font-size: 14.5px; }
  .poslist__meta { font-size: var(--fs-xs); color: var(--text-faint); margin-top: 1px; }
  .poslist__v { flex: 0 0 auto; }
  .poslist__v .wert-inline { text-align: right; font-size: 16px; font-weight: 700; }
  .btn--sm { padding: 3px 10px; font-size: var(--fs-xs); }
  @media (max-width: 680px) { .kf, .tiles { grid-template-columns: repeat(2, 1fr); } }
  .hint { font-size: 11.5px; color: var(--text-muted); margin: 6px 0 0; max-width: var(--measure); }
  /* B-99/B-102: AUTO-Layout-Tabelle für Zeilen mit Inline-Erfassung (Personen-AHV, Bilanz-Werterfassung) —
     bewusst NICHT .data/table-layout:fixed, sonst wird das Eingabefeld+Button abgeschnitten (overflow:hidden)
     bzw. läuft in die Nachbarspalte. Zellen wachsen mit dem Inhalt. */
  .erfass-tabelle { width: 100%; border-collapse: collapse; font-size: var(--fs-sm); margin-top: var(--space-1); }
  .erfass-tabelle th { text-align: left; padding: 6px var(--space-4) 6px 0; font-size: 11px; text-transform: uppercase; letter-spacing: .05em; color: var(--text-faint); font-weight: 700; border-bottom: var(--border-width) solid var(--border); white-space: nowrap; }
  .erfass-tabelle td { text-align: left; padding: 9px var(--space-4) 9px 0; border-bottom: var(--border-width) solid var(--border); vertical-align: middle; white-space: nowrap; }
  .erfass-tabelle td.n { text-align: right; font-variant-numeric: tabular-nums; }
  .ahv-edit { display: inline-flex; gap: var(--space-2); align-items: center; }
  .ahv-input { width: 150px; padding: var(--space-1) var(--space-2); border: var(--border-width) solid var(--border); border-radius: var(--r-sm); background: var(--surface); color: var(--text); font-size: var(--fs-sm); font-variant-numeric: tabular-nums; }
  .ahv-meldung { font-size: 11.5px; color: var(--text-muted); white-space: nowrap; }

  /* B-99 Redesign: Hero — Reinvermögen als Bilanz-Statement + Vermögensaufteilung (Legende mit Anteilsbalken je Zeile). */
  .hero { display: grid; grid-template-columns: 1.05fr .95fr; gap: var(--space-4); margin-bottom: var(--space-4); }
  .stmt .cap, .alloc .cap, .stmt__tax .cap { font-size: 11px; text-transform: uppercase; letter-spacing: .06em; color: var(--text-faint); font-weight: 700; }
  .stmt__net { font-variant-numeric: tabular-nums; font-size: clamp(32px, 5vw, 44px); font-weight: 700; letter-spacing: -.03em; line-height: 1.05; margin: 6px 0 var(--space-4); }
  .stmt__cur { font-size: .42em; font-weight: 700; color: var(--text-faint); vertical-align: .42em; margin-right: .35em; }
  .ledger { border-top: var(--border-width) solid var(--border); }
  .ledger__row { display: flex; justify-content: space-between; align-items: baseline; gap: var(--space-4); padding: 9px 0; border-bottom: var(--border-width) solid var(--border); font-size: var(--fs-md); color: var(--text-muted); }
  .ledger__row .num { font-variant-numeric: tabular-nums; font-size: var(--fs-base); color: var(--text); }
  .ledger__row--tot { color: var(--text); font-weight: 600; border-bottom: none; }
  .ledger__row--tot .num { font-weight: 700; }
  .stmt__tax { display: flex; justify-content: space-between; align-items: flex-end; gap: var(--space-4); margin-top: var(--space-4); padding-top: var(--space-4); border-top: var(--border-width) dashed var(--border); }
  /* UI-34a: Zusatz zur Kapitaelchen-Ueberschrift — erklaert den Bezug, ohne ihn zu dominieren. */
  .cap__zusatz { text-transform: none; letter-spacing: 0; font-weight: 600; color: var(--text-faint); }
  /* B-142: das Wort vor einer Summe, die eine Untergrenze ist. Leise und klein -- die Zahl
     bleibt die Hauptsache, aber sie steht nicht mehr allein da, als waere sie vollstaendig. */
  .stmt__mind { font-size: var(--fs-sm); font-weight: 600; color: var(--text-muted); margin-right: var(--space-2); }
  .stmt__taxnum { font-variant-numeric: tabular-nums; font-size: 19px; font-weight: 700; margin-top: 2px; }
  /* UI-24: eine negative Schluesselkennzahl ist eine Aussage, keine beliebige Zahl. */
  .stmt__taxnum--negativ { color: var(--crit-ink); }
  .note { font-size: var(--fs-xs); color: var(--text-muted); margin: 0; }
  .alloc__body { display: flex; align-items: center; gap: var(--space-5); margin: var(--space-4) 0; }
  .legend { list-style: none; margin: 0; padding: 0; flex: 1; min-width: 0; }
  .legend__i { display: grid; grid-template-columns: auto 1fr auto; align-items: center; column-gap: 10px; padding: 7px 0; border-bottom: var(--border-width) solid var(--border); }
  .legend__i:last-child { border-bottom: none; }
  .sw { width: 10px; height: 10px; border-radius: 3px; display: inline-block; }
  .sw--1 { background: var(--alloc-1); } .sw--2 { background: var(--alloc-2); }
  .sw--3 { background: var(--alloc-3); } .sw--4 { background: var(--alloc-4); } .sw--5 { background: var(--alloc-5); }
  .sw--open { background: repeating-linear-gradient(45deg, var(--border), var(--border) 2px, transparent 2px, transparent 4px); border: var(--border-width) solid var(--border); }
  .legend__name { font-size: 13.5px; font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .legend__name.is-open { color: var(--text-faint); }
  .legend__r { display: flex; align-items: baseline; gap: var(--space-3); }
  .legend__num { font-variant-numeric: tabular-nums; font-size: 13.5px; font-weight: 600; }
  .legend__pct { font-variant-numeric: tabular-nums; font-size: var(--fs-xs); color: var(--text-faint); width: 42px; text-align: right; }
  .legend__bar { grid-column: 1 / -1; height: 5px; margin-top: var(--space-1); background: var(--surface-2); border-radius: var(--r-pill); overflow: hidden; }
  .legend__bar-fill { display: block; height: 100%; border-radius: var(--r-pill); background: var(--alloc-1); }
  .legend__bar-fill--1 { background: var(--alloc-1); }
  .legend__bar-fill--2 { background: var(--alloc-2); }
  .legend__bar-fill--3 { background: var(--alloc-3); }
  .legend__bar-fill--4 { background: var(--alloc-4); }
  .legend__bar-fill--5 { background: var(--alloc-5); }
  .legend__bar-fill--open { background: var(--border); }
  .vollstaendig .ft { font-size: 11.5px; color: var(--text-muted); }
  @media (max-width: 860px) { .hero { grid-template-columns: 1fr; } }
  @media (max-width: 520px) { .alloc__body { flex-direction: column; align-items: stretch; } }
  .vollstaendig { display: flex; align-items: center; gap: 10px; margin-top: 14px; padding-top: var(--space-3); border-top: var(--border-width) solid var(--border); }
  .vollstaendig__bar { flex: 0 1 260px; height: 6px; border-radius: 99px; background: var(--surface-2); overflow: hidden; }
  .vollstaendig__bar span { display: block; height: 100%; background: var(--ok); border-radius: 99px; }
  /* Kopfzeile eines Kategorie-Tab-Panels: Name links, Kategorie-Summe rechts. */
  .kat-kopf { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-3); flex-wrap: wrap; margin-bottom: var(--space-4); padding-bottom: 10px; border-bottom: var(--border-width) solid var(--border); }
  .kat-kopf__name { font-size: var(--fs-base); font-weight: 700; }
  .kat-kopf__tot { font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; }
  /* B-175: der Zusatz neben einem Reihen-Titel -- was in dieser Reihe NICHT variiert und
     deshalb einmal oben steht statt in jeder Zeile (Styleguide 3a.3). Bewusst leise: der
     Titel traegt die Aussage, das hier ist seine Fussnote. */
  .reihe-kopf { font-size: var(--fs-xs); font-weight: 400; color: var(--text-muted); margin-left: var(--space-2); }
  /* B-99: Hover-Tooltip mit 250ms-Verzögerung (Rendite-Erklärung u. a.). */
  .tip { position: relative; cursor: help; border-bottom: var(--border-width) dotted var(--text-faint); }
  .tip::after {
    content: attr(data-tip);
    position: absolute; left: 0; top: calc(100% + 6px); z-index: 20;
    width: max-content; max-width: 260px;
    background: var(--surface); color: var(--text);
    border: var(--border-width) solid var(--border); border-radius: var(--r-lg); box-shadow: var(--shadow-2);
    padding: 7px 10px; font-size: 11.5px; font-weight: 400; line-height: 1.4; white-space: normal;
    opacity: 0; visibility: hidden; transition: opacity .12s ease; transition-delay: 0s;
  }
  .tip:hover::after, .tip:focus-visible::after { opacity: 1; visibility: visible; transition-delay: 250ms; }

  /* --- Karten --- */
  .card {
    background: var(--surface); border: var(--border-width) solid var(--border); border-radius: var(--r-lg);
    padding: var(--space-5); box-shadow: var(--shadow-1); margin-bottom: var(--space-4);
  }
  .card h3 { margin: 0 0 10px; font-size: 15.5px; display: flex; gap: var(--space-2); align-items: center; flex-wrap: wrap; }
  .card p { margin: .4em 0; font-size: 13.5px; color: var(--text-muted); }
  .card p strong { color: var(--text); }
  .card .money { margin-left: auto; font-weight: 600; font-variant-numeric: tabular-nums; }

  /* --- „Nächster Schritt"-Panel --- */
  .next {
    background: linear-gradient(180deg, var(--accent-soft), transparent);
    border: var(--border-width) solid color-mix(in srgb, var(--accent) 30%, transparent);
    border-radius: var(--r-lg); padding: var(--space-4) 18px; margin-bottom: var(--space-4);
  }
  .next h3 { margin: 0 0 5px; font-size: var(--fs-base); color: var(--accent-ink); }
  .next p { margin: 0; font-size: 13.7px; }
  .next a { color: var(--accent-ink); font-weight: 600; }

  /* --- Callout --- */
  .callout { display: flex; align-items: baseline; gap: 10px; border-radius: var(--r-md); padding: var(--space-3) 14px; font-size: var(--fs-sm); border: var(--border-width) solid var(--border); margin-top: var(--space-3); margin-bottom: var(--space-4); background: var(--surface-2); }
  /* Symbol als CSS-Glyphe (kein Emoji, Style Guide): "i" für Info/Neutral, "!" für warn/flag. */
  .callout::before { content: "i"; flex: none; width: 18px; height: 18px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; font-size: 11px; font-weight: 700; line-height: 1; background: var(--open-soft); color: var(--open-ink); border: var(--border-width) solid color-mix(in srgb, var(--open) 40%, transparent); align-self: flex-start; margin-top: 1px; }
  .callout.info { background: var(--accent-soft); border-color: color-mix(in srgb, var(--accent) 32%, transparent); }
  .callout.info::before { background: var(--surface); color: var(--accent-ink); border-color: color-mix(in srgb, var(--accent) 45%, transparent); }
  .callout.flag { background: var(--crit-soft); border-color: color-mix(in srgb, var(--crit) 32%, transparent); }
  .callout.flag::before { content: "!"; background: var(--surface); color: var(--crit-ink); border-color: color-mix(in srgb, var(--crit) 45%, transparent); }
  .callout.warn { background: var(--warn-soft); border-color: color-mix(in srgb, var(--warn) 32%, transparent); }
  .callout.warn::before { content: "!"; background: var(--surface); color: var(--warn-ink); border-color: color-mix(in srgb, var(--warn) 45%, transparent); }

  /* --- Fortschrittsbalken --- */
  .progress {
    display: flex; align-items: center; gap: 14px;
    background: var(--surface); border: var(--border-width) solid var(--border); border-radius: var(--r-lg);
    padding: 14px 18px; box-shadow: var(--shadow-1); margin-bottom: 18px;
  }
  .progress .bar { flex: 1; height: 9px; border-radius: 99px; background: var(--surface-2); overflow: hidden; }
  .progress .fill { height: 100%; background: var(--accent); border-radius: 99px; transition: width .35s ease; }
  .progress .lab { font-size: var(--fs-sm); font-weight: 700; white-space: nowrap; }

  /* Schlanke Variante fuer Per-Dokument-Fortschritt in Tabellenzeilen (B-36) — dieselben .bar/.fill-Regeln,
     nur kompakter (kein Card-Rahmen/Schatten, kleinere Balkenhoehe). */
  .progress.progress--row { padding: 0; gap: var(--space-2); background: none; border: none; box-shadow: none; margin-bottom: 0; white-space: normal; max-width: 170px; }
  .progress--row .bar { height: 5px; min-width: 60px; }
  .progress--row .lab { font-size: 10.5px; font-weight: 700; color: var(--text-muted); }

  /* --- Ziel-/Gruppenkopf --- */
  .goal-h { display: flex; align-items: center; gap: 10px; margin: 22px 0 10px; }
  .goal-h .g { font-weight: 700; color: var(--accent-ink); border: var(--border-width) solid var(--accent); border-radius: 7px; padding: 2px 9px; font-size: 12.5px; }
  .goal-h h3 { margin: 0; font-size: 16px; }

  /* --- Frage-/Checklisten-Zeile --- */
  .q {
    display: flex; gap: 13px; align-items: flex-start;
    background: var(--surface); border: var(--border-width) solid var(--border); border-radius: var(--r-md);
    padding: 13px 15px; margin-bottom: 9px; box-shadow: var(--shadow-1); cursor: pointer;
  }
  .q:hover { border-color: color-mix(in srgb, var(--accent) 40%, transparent); }
  .q input { margin-top: 3px; width: 20px; height: 20px; flex: none; accent-color: var(--ok); cursor: pointer; }
  .q .body { flex: 1; min-width: 0; }
  .q .qt { font-size: var(--fs-md); font-weight: 600; display: flex; gap: var(--space-2); align-items: baseline; flex-wrap: wrap; }
  .q.done .qt { text-decoration: line-through; color: var(--text-faint); }

  /* --- Badges/Tags --- */
  .pri { font-size: 10px; font-weight: 800; color: var(--crit-ink); letter-spacing: .05em; border: var(--border-width) solid color-mix(in srgb, var(--crit) 35%, transparent); padding: 1px 6px; border-radius: 5px; }
  .who { font-size: 10.5px; font-weight: 800; letter-spacing: .04em; text-transform: uppercase; padding: 3px 9px; border-radius: var(--r-pill); white-space: nowrap; flex: none; background: var(--open-soft); color: var(--open-ink); }
  .chip { display: inline-flex; align-items: center; font-size: 11.5px; font-weight: 600; padding: 2px 9px; border-radius: var(--r-pill); background: var(--surface-2); color: var(--text-muted); border: var(--border-width) solid var(--border); margin-left: var(--space-1); }
  .sev { font-size: 10.5px; font-weight: 800; letter-spacing: .04em; text-transform: uppercase; padding: 2px var(--space-2); border-radius: var(--r-sm); color: var(--on-accent); }
  .sev.critical { background: var(--crit); }
  .sev.high { background: var(--warn); }
  /* UI-19: war var(--accent). Der Styleguide verlangt das Semantik-Set "farblich klar vom Akzent
     getrennt, damit Status nie mit Aktion verwechselt wird" — eine Severity in der Aktionsfarbe
     verletzt genau das. Weiche Warn-Stufe statt Teal: die Rampe laeuft damit crit (voll) → warn
     (voll) → warn (weich) → open → faint und bleibt auf jeder Stufe unterscheidbar. */
  .sev.medium { background: var(--warn-soft); color: var(--warn-ink); }
  .sev.low { background: var(--open); }
  .sev.info { background: var(--text-faint); }

  /* --- Status-Pill (Dokumente) --- */
  .vstat { display: inline-flex; align-items: center; font-size: 10.5px; font-weight: 800; letter-spacing: .04em; text-transform: uppercase; padding: 3px 9px; border-radius: var(--r-pill); white-space: nowrap; }
  .vstat-open { background: var(--open-soft); color: var(--open-ink); }
  .vstat-ok { background: var(--ok-soft); color: var(--ok-ink); }
  .vstat-warn { background: var(--warn-soft); color: var(--warn-ink); }
  .vstat-flag { background: var(--crit-soft); color: var(--crit-ink); }

  /* --- Tabellen --- */
  /* table-layout: fixed + explizite Spaltenbreiten (th) = deterministisch KEIN horizontales
     Scrollen bei normaler Breite; Text-Spalten ellipsen. .table-scroll bleibt Sicherheitsnetz
     fuer wirklich schmale Fenster (Feedback CC — Verifikation per scrollWidth<=clientWidth). */
  table.data { border-collapse: collapse; width: 100%; table-layout: fixed; font-size: var(--fs-sm); margin-top: var(--space-1); }
  table.data th, table.data td { text-align: left; padding: 6px var(--space-2); border-bottom: var(--border-width) solid var(--border); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  table.data th.col-eingang { width: 86px; }
  table.data th.col-status { width: 128px; }
  table.data th.col-doktyp { width: 120px; }
  table.data th.col-periode { width: 72px; }
  table.data th.col-subjekt { width: 90px; }
  table.data th.col-aktion { width: 176px; }
  table.data th.col-zeit { width: 138px; }
  table.data th.col-akteur { width: 150px; }
  table.data th.col-audit-aktion { width: 130px; }
  table.data th.col-entitaet { width: 130px; }
  /* --- Audit-Diff (B-64): aufklappbares Alt/Neu-Detail unter einer Audit-Zeile --- */
  .audit-diff { padding: var(--space-2) var(--space-3); background: var(--surface-2); border-radius: var(--r-sm); }
  .audit-diff table { width: 100%; border-collapse: collapse; font-size: var(--fs-xs); table-layout: fixed; }
  .audit-diff th, .audit-diff td { text-align: left; padding: var(--space-1) var(--space-2); border-bottom: var(--border-width) solid var(--border); overflow-wrap: anywhere; white-space: normal; }
  .audit-diff th { font-size: 10.5px; text-transform: uppercase; letter-spacing: .04em; color: var(--text-faint); }
  .audit-diff td.alt { color: var(--crit-ink); }
  .audit-diff td.neu { color: var(--ok-ink); }
  table.data tr[tabindex]:focus-visible { outline: var(--focus); outline-offset: -2px; }
  table.data th { font-size: 11px; text-transform: uppercase; letter-spacing: .04em; color: var(--text-faint); font-weight: 700; }
  table.data td.n { text-align: right; font-variant-numeric: tabular-nums; }
  table.data tr:last-child td { border-bottom: none; }
  table.data tr.clickable { cursor: pointer; }
  table.data tr.clickable:hover { background: var(--surface-2); }
  table.data tr.sel { background: var(--accent-soft); }
  table.data tr.geloescht { opacity: .55; } /* B-34: gelöschte Dokumente greyed in der Liste ("Gelöschte anzeigen") */

  /* Layout-Fix Tabelle: breite Tabellen scrollen in ihrem eigenen Container statt Card/Seite zu
     sprengen (Style-Guide-Regel). Wiederverwendbar für jede table.data mit vielen Spalten. */
  .table-scroll { overflow-x: auto; }
  table.data td.col-actions { text-align: right; overflow: visible; text-overflow: clip; }
  /* Fliesstext-Zellen (z. B. colspan-Bestaetigungszeilen): nowrap/ellipsis der Fixed-Layout-Regel aufheben. */
  table.data td.cell-flow { white-space: normal; overflow: visible; text-overflow: clip; }

  /* ==================== DataGrid (B-107) ==================== */
  /* QuickGrid erbt die table.data-Optik (class="data datagrid"); hier nur die Grid-Spezifika.
     Content-Fit (auto) statt table.data's fixed → Inhalt (z.B. Zeitpunkt) schneidet nicht ab;
     nach erstem Drag-Resize schaltet das JS die Tabelle auf .dg-fixed (stabile Breiten). */
  table.datagrid { table-layout: auto; }
  table.datagrid.dg-fixed { table-layout: fixed; }
  table.datagrid th { position: relative; }
  /* Steuer-Spalten (Select/Button) NICHT abschneiden (Review-Fix M6, analog td.col-actions). */
  table.datagrid td.dg-col--control, table.datagrid th.dg-col--control {
    overflow: visible; white-space: normal; text-overflow: clip;
  }
  /* UI-31: die Aktionen brachen untereinander um, wodurch jede Zeile doppelt hoch wurde und die
     unterste abschnitt. Nebeneinander halten; zu schmal wird die Spalte nicht, weil der
     .table-scroll-Wrapper den Ueberlauf uebernimmt. Steht NACH .dg-col--control: gleiche
     Spezifitaet, und deren white-space:normal wuerde sonst gewinnen. */
  table.datagrid td.dg-col-aktion { white-space: nowrap; }
  /* Kappung auf dem inneren Element — `max-width` direkt auf einem `td` ist bei
     `table-layout: auto` nur ein Vorschlag, den der Browser uebergehen darf.
     B-178: die Regel hing vorher an `td.dg-col--kappen > *`, also am ersten beliebigen
     KINDELEMENT. Eine Spalte ohne Vorlage rendert aber blanken Text OHNE Element — die Regel traf
     damit nichts, fuer jede reine Wert-Spalte, seit B-107. Am laufenden System gemessen
     (11.10.2026): Namenszelle `firstElementChild = null`, `max-inline-size: none`, Name-Spalte
     678px von 1263px Container, Tabelle 1381px, 118px Ueberlauf — hinausgeschoben wurde die Spalte
     mit dem Detail-Knopf. Jetzt rendert die Komponente eine eigene Klasse, auf die diese Regel
     zielt; `.dg-kappen` statt `> *` trifft ausserdem nicht mehr zufaellig das erste Element einer
     Vorlage. */
  table.datagrid .dg-kappen { display: inline-block; max-inline-size: 44ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; vertical-align: bottom; }

  /* B-185: die ZELLE entscheidet die Ausrichtung, nicht die Spalte. Der Verlauf hat eine
     gemeinsame Wert-Spalte fuer 368 Zahlen und 121 Texte bzw. Daten; eine Spalte kann nur eines
     von beiden tragen. Ein Datum rechtsbuendig unter „Wert" sah aus wie ein Fehler (B-175) — also
     bleibt es links, waehrend die Zahlen rechts stehen und sich vergleichen lassen. */
  /* Gekappt wird am Wert-Span und NICHT ueber .dg-kappen: dessen inline-block wuerde die
     Rechtsbuendigkeit der Zahlen zerstoeren, weil der Kasten dann schmaler waere als die Zelle.
     Gemessen 14.10.2026: ein einziger 73-Zeichen-Text zog die Spalte auf 515 px und die
     Spaltensumme auf 1'650 px in einem 1'263 px breiten Container. */
  table.datagrid .dg-wert {
    display: block; max-inline-size: 30ch;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
  table.datagrid .dg-wert--zahl { text-align: right; font-variant-numeric: tabular-nums; }

  /* Die Blaetter-Leiste (B-185). Die Knoepfe sind .btn.ghost — hier steht nur die Anordnung. */
  .dg-blaettern {
    display: flex; align-items: center; gap: var(--space-3);
    margin-block-start: var(--space-2); padding-block-start: var(--space-2);
    border-block-start: var(--border-width) solid var(--border);
    color: var(--text-muted); font-size: var(--fs-sm);
  }
  .dg-blaettern__total { color: var(--text-faint); }

  /* QuickGrid fuellt eine geblaetterte Seite IMMER auf ItemsPerPage Zeilen auf und laesst die
     ueberzaehligen leer, damit die Hoehe beim Blaettern nicht springt. Bei vier Treffern auf einer
     Seite von sechzig sind das 56 leere Streifen -- gesehen am 14.10.2026, und es sieht nach einem
     Fehler aus. Getroffen werden nur Zeilen, in denen JEDE Zelle leer ist, und nur in Tabellen,
     die ueberhaupt blaettern; eine Datenzeile ganz ohne Inhalt gibt es nicht. */
  table.datagrid--seiten tbody tr:not(:has(td:not(:empty))) { display: none; }
  .dg-resize {
    position: absolute; inset-block: 0; inset-inline-end: 0; inline-size: 6px;
    cursor: col-resize; user-select: none; touch-action: none;
  }
  .dg-resize:hover { background: var(--accent-soft); }
  /* --- Spaltenprioritaeten auf schmalen Schirmen (B-176) --- */
  /* Die Schwellen stehen NUR hier. C# zaehlt die Spalten je Band, das Stylesheet entscheidet, ob
     das Band gilt -- eine Wahrheit, und zwar dort, wo die Breite ueberhaupt bekannt ist.
     Gemessen wird der CONTAINER und nicht das Fenster: auf /dokumente und /audit steht die Tabelle
     neben einem Seitenpanel, und bei offenem Panel ist der Platz schmal, obwohl das Fenster breit
     ist (die Spur war dort mit 1422px + 280px in 1446px Container gemessen, UI-05/B-114).
     Der Container ist die aeussere .datagrid-box und NICHT der scrollende .datagrid-wrap: der
     Hinweissatz steht neben der Tabelle und nicht in ihr (sonst wuerde er mitscrollen), und eine
     @container-Abfrage gilt nur fuer Nachfahren ihres Containers. */
  .datagrid-box { container-type: inline-size; container-name: dgrid; }
  /* Der Hinweissatz ist standardmaessig AUS; sichtbar macht ihn genau das Band, das ausblendet. */
  .dg-schmal { display: none; margin-block-start: var(--space-2); font-size: var(--fs-xs); color: var(--text-faint); }
  /* Die Schwellen sind GEMESSEN und nicht geschaetzt (11.10.2026, /dokumente am laufenden System).
     Erster Versuch waren 899px und 619px -- beide zu tief: bei 1000px Container lief die Tabelle
     schon 92px ueber, waehrend noch nichts wich. Gemessen wurde je Breite der Ueberlauf
     (scrollWidth - clientWidth) und welche Spalten verschwinden. 1100 / 960 sind die Breiten, bei
     denen der Ueberlauf tatsaechlich einsetzt -- 760 war der zweite Fehlversuch: zwischen 760 und
     1100 wich nur die Zusatz-Spalte, und bei 860px Container blieben 105px Ueberlauf. */
  @container dgrid (max-width: 1100px) {
    table.datagrid th.dg-rang--zusatz, table.datagrid td.dg-rang--zusatz { display: none; }
  }
  @container dgrid (max-width: 960px) {
    table.datagrid th.dg-rang--wichtig, table.datagrid td.dg-rang--wichtig { display: none; }
    /* Die Kappung muss mitschrumpfen. Sonst bleiben allein Name (44ch = 360px), Status und Aktion
       zusammen 675px breit, und unter 675px hilft kein Ausblenden mehr -- gemessen: bei 560px
       Container noch 102px Ueberlauf, obwohl nur noch Kern-Spalten standen. */
    table.datagrid .dg-kappen { max-inline-size: 24ch; }
  }
  /* Die beiden Baender sind fuer den Hinweis EXKLUSIV -- sonst stehen bei 500px zwei Saetze mit
     zwei verschiedenen Zahlen untereinander. */
  @container dgrid (max-width: 1100px) and (min-width: 961px) { .dg-schmal--mittel { display: block; } }
  @container dgrid (max-width: 960px) { .dg-schmal--eng { display: block; } }

  /* --- Aktionsmenue je Zeile (B-179) --- */
  /* Entscheid Chris 11.10.2026: die Zeilen-Aktionen wandern hinter drei Punkte, der Spaltenkopf
     traegt einen Blitz. Anlass war die rote Wand aus 76 vollflaechigen "Loeschen"-Knoepfen und die
     181px breite Aktionsspalte, die auf schmalen Schirmen mit drueckt (gemessen B-178). */
  .aktmenue { display: inline-flex; }
  .aktmenue__punkte {
    display: inline-flex; align-items: center; justify-content: center;
    inline-size: 28px; block-size: 28px; padding: 0;
    background: none; border: var(--border-width) solid transparent; border-radius: var(--r-sm);
    color: var(--text-faint); cursor: pointer; line-height: 1;
  }
  .aktmenue__punkte:hover { background: var(--surface-2); color: var(--text); }
  .aktmenue__punkte:focus-visible { outline: var(--focus); outline-offset: 1px; }
  /* Das Zeichen U+22EF sitzt auf der Grundlinie wie Satzpunkte; ohne diese Anhebung klebt es
     unten am Knopfrand statt in seiner Mitte zu stehen. */
  .aktmenue__punkte-zeichen { font-size: 18px; transform: translateY(-2px); }
  /* Der Kopf traegt ein Inline-SVG und kein Emoji: ein Emoji-Zeichen wird je nach Schriftart farbig
     gerendert und hoert nicht auf currentColor, taugt also in einem Designsystem nicht. */
  .aktmenue__kopf { display: inline-block; inline-size: var(--icon-size); block-size: var(--icon-size); vertical-align: -4px; }
  .aktmenue__flaeche {
    /* position/left/top setzt aktionsmenue.js, weil ein popover in der Top-Layer liegt und seinen
       Platz im Dokumentfluss verliert. */
    inline-size: max-content; min-inline-size: 168px;
    padding: var(--space-1); margin: 0; border: var(--border-width) solid var(--border);
    border-radius: var(--r-md); background: var(--surface); box-shadow: var(--shadow-1);
  }
  .aktmenue__flaeche:not(:popover-open) { display: none; }
  .aktmenue__eintrag {
    display: block; inline-size: 100%; text-align: left;
    padding: var(--space-1) var(--space-2); border: 0; border-radius: var(--r-sm);
    background: none; color: var(--text); font: inherit; font-size: var(--fs-sm); cursor: pointer;
  }
  .aktmenue__eintrag:hover:not(:disabled) { background: var(--surface-2); }
  .aktmenue__eintrag:focus-visible { outline: var(--focus); outline-offset: -2px; }
  .aktmenue__eintrag:disabled { color: var(--text-faint); cursor: default; }
  .aktmenue__eintrag--gefahr { color: var(--crit-ink); }
  .aktmenue__frage { padding: var(--space-1) var(--space-2); font-size: var(--fs-xs); color: var(--text-faint); }

  .dg-filterbar { display: flex; flex-wrap: wrap; gap: var(--space-3); margin-block-end: var(--space-2); }
  .dg-filter { display: flex; flex-direction: column; gap: 2px; font-size: var(--fs-sm); }
  .dg-filter__label { font-size: 11px; text-transform: uppercase; letter-spacing: .04em; color: var(--text-faint); }
  .dg-filter__input { min-inline-size: 12ch; }

  /* Generisches Detail-Split-Layout (Review-Fix M7 — NICHT graph__*): Grid + sticky Seitenpanel.
     Wiederverwendbar (Audit-Diff, künftige Master-Detail-Seiten). */
  /* UI-05: die Basis-Regel setzte GAR KEINE grid-template-columns. Die implizite Spur ist dann
     `auto`, und deren Minimum ist die Min-Content-Breite des Inhalts — bei der Dokumente-Tabelle
     1421px in einem 1205px breiten Container. B-114 hatte nur den GEOEFFNETEN Zustand korrigiert;
     geschlossen lief derselbe Fehler weiter und schob die ganze Seite samt Sidebar in den
     horizontalen Scroll. Am Live-System gemessen (30.09.2026): Spur 1421.35px bei 1205px Container,
     Dokument-Scrollbreite 1762px gegen 1623px Viewport. */
  .detail-split { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-4); }
  /* Grid-Items haben selbst ein automatisches Mindestmass und wuerden die Spur sonst trotz
     minmax(0, …) weiterhin aufdruecken. */
  .detail-split > * { min-width: 0; }
  /* Zweite Spur nur wenn das Panel offen ist (.detail-split--offen) — sonst behält die Tabelle die volle
     Breite (Review: sonst dauerhaft ~300px verschenkt, konterkariert das Lesbarkeits-Ziel). */
  @media (min-width: 1100px) {
    /* B-114: minmax(0, 1fr), NICHT 1fr. `1fr` ist `minmax(auto, 1fr)`, und dieses auto-Minimum ist die
       volle Inhaltsbreite der Tabelle — die Spur wuchs dadurch auf die Tabellenbreite, drueckte das
       Panel auf sein Minimum und schob die Seite in den horizontalen Scroll. Am Live-System gemessen:
       Spuren 1422px + 280px in einem 1446px breiten Container, 388px Seitenueberlauf. Mit minmax(0, …)
       darf die Spur schrumpfen, der innere .table-scroll uebernimmt das Scrollen: 0px Ueberlauf,
       Panel auf seinen vorgesehenen 360px. Gilt fuer /dokumente und /audit gleichermassen. */
    .detail-split--offen { grid-template-columns: minmax(0, 1fr) minmax(280px, 360px); align-items: start; }
  }
  .detail-panel {
    background: var(--surface); border: var(--border-width) solid var(--border); border-radius: var(--r-lg);
    box-shadow: var(--shadow-1); padding: var(--space-4); position: sticky; top: var(--space-4);
    /* Das Panel klebt, also darf es nie hoeher werden als das Fenster -- sonst waechst es aus dem
       Bild heraus und sein unterer Teil ist unerreichbar, weil die SEITE scrollt und nicht das
       Panel. Deshalb eigene Hoehe plus eigenes Scrollen, statt sich auf eine fremde Regel zu
       verlassen (die es vorher zufaellig begrenzt und dabei abgeschnitten hat). */
    max-height: calc(100vh - var(--space-4) * 2); overflow-y: auto;
  }
  .detail-panel__head { display: flex; align-items: center; gap: var(--space-2); margin-block-end: var(--space-3); }
  .detail-panel__head h3 { flex: 1; margin: 0; }
  .btn.btn--sm { padding: var(--space-1) 9px; font-size: var(--fs-xs); }

  /* --- Dokumente-Toolbar (B-34/B-35): Kartenkopf mit Filter, Checkbox, Aktions-Button --- */
  .doc-toolbar { display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-3); }
  .doc-toolbar__action { margin-left: auto; }
  .check-inline { display: inline-flex; align-items: center; gap: 6px; font-size: var(--fs-sm); font-weight: 600; color: var(--text-muted); text-transform: none; }

  /* --- Buttons --- */
  .btn {
    font-family: inherit; font-size: 12.5px; font-weight: 600;
    padding: 6px 13px; border-radius: var(--r-sm);
    border: var(--border-width) solid var(--accent); background: var(--accent); color: var(--on-accent);
    cursor: pointer; text-decoration: none; display: inline-flex; align-items: center; gap: 6px;
    transition: background .12s ease, border-color .12s ease, opacity .12s ease;
  }
  .btn:hover { background: var(--accent-ink); border-color: var(--accent-ink); }
  .btn:focus-visible { outline: var(--focus); outline-offset: 2px; }
  /* UI-20: reines opacity:.5 liess aus dem gefuellten Teal-Knopf ein blasses Teal auf Weiss werden,
     das kaum noch als Knopf lesbar war. Ein eigener neutraler Zustand ist als Knopf erkennbar UND
     klar vom aktiven unterscheidbar. */
  .btn:disabled { background: var(--surface-2); color: var(--text-faint); border-color: var(--border); box-shadow: none; cursor: not-allowed; }
  .btn.ghost:disabled { background: transparent; color: var(--text-faint); }

  .btn.ghost { background: none; border-color: transparent; color: var(--accent-ink); }
  .btn.ghost:hover { background: var(--accent-soft); border-color: transparent; }
  .btn.danger { background: var(--crit); border-color: var(--crit); color: var(--on-accent); }
  .btn.danger:hover { background: var(--crit-ink); border-color: var(--crit-ink); }
  /* UI-21: destruktive Aktionen (Loeschen, Key entfernen, Deaktivieren) standen als schlichte
     Textknoepfe da — gleiche Farbe, gleiches Gewicht, gleicher Stil wie "Details" daneben. Die
     bestehende .danger-Konvention bekommt hier ihre Ghost-Variante; NACH .btn.ghost, sonst gewinnt
     dessen Akzentfarbe (gleiche Spezifitaet, spaetere Regel). */
  .btn.ghost.danger { color: var(--crit-ink); }
  .btn.ghost.danger:hover { background: var(--crit-soft); }

  /* --- Formularkarte + Zeilen --- */
  .form-card {
    background: var(--surface); border: var(--border-width) dashed color-mix(in srgb, var(--accent) 40%, var(--border));
    border-radius: var(--r-md); padding: var(--space-4); margin-bottom: 18px; box-shadow: var(--shadow-1);
  }
  .form-card h3 { margin: 0 0 var(--space-3); font-size: var(--fs-md); }
  .form-row { display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 10px; }
  .form-row > * { flex: 1; min-width: 140px; }
  .form-row label, .form-card label {
    font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: .04em;
    color: var(--text-faint); font-weight: 700; display: block; margin-bottom: var(--space-1);
  }
  .form-card label { margin-top: 10px; margin-bottom: 3px; }
  .form-row textarea { min-height: 56px; resize: vertical; }
  .form-card input[type=checkbox], .form-card input[type=radio],
  .card input[type=checkbox], .card input[type=radio] {
    width: 16px; height: 16px; accent-color: var(--ok); cursor: pointer; vertical-align: middle; margin-right: 6px;
  }
  .empf { font-size: 11px; color: var(--text-faint); margin-top: 3px; font-weight: 600; }

  /* --- Subsection-Überschrift (Einstellungen B-09) --- */
  .section-head { margin: 28px 0 10px; font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: .08em; color: var(--text-faint); font-weight: 800; }

  /* --- Intake: Frage/Antwort-Karte + Uploadbeleg --- */
  .qcard { background: var(--surface); border: var(--border-width) solid var(--border); border-radius: var(--r-md); margin-bottom: 10px; box-shadow: var(--shadow-1); overflow: hidden; }
  .qcard.done { border-color: color-mix(in srgb, var(--ok) 45%, transparent); }
  .qhead { display: flex; gap: 13px; align-items: flex-start; padding: 13px 15px; }
  .qhead input[type=checkbox] { margin-top: 3px; width: 20px; height: 20px; flex: none; accent-color: var(--ok); cursor: pointer; }
  .qhead .body { flex: 1; min-width: 0; }
  .qhead .qt { font-size: var(--fs-md); font-weight: 600; display: flex; gap: var(--space-2); align-items: baseline; flex-wrap: wrap; }
  .qcard.done .qt { text-decoration: line-through; color: var(--text-faint); }
  .qanswer { padding: 0 15px 13px 48px; display: flex; flex-direction: column; gap: var(--space-2); }
  /* UI-27 / UI-28: einklappbare Erfassungs- bzw. Antwortbereiche. Die Zusammenfassung ist der
     Auslöser und muss wie ein Bedienelement aussehen, nicht wie eine Ueberschrift. */
  .form-card--klappbar > summary { cursor: pointer; list-style: none; display: flex; align-items: center; gap: var(--space-2); }
  .form-card--klappbar > summary::-webkit-details-marker { display: none; }
  .form-card--klappbar > summary::before { content: "+"; font-weight: 700; color: var(--accent-ink);
    width: 18px; height: 18px; display: inline-flex; align-items: center; justify-content: center;
    border: var(--border-width) solid var(--border); border-radius: var(--r-sm); background: var(--surface-2); }
  .form-card--klappbar[open] > summary::before { content: "2"; }
  .form-card--klappbar > summary h3 { margin: 0; }
  .qanswer--klappbar > summary { cursor: pointer; font-size: var(--fs-sm); color: var(--accent-ink);
    font-weight: 600; padding: var(--space-1) 0; }
  /* Im geschlossenen Zustand traegt der Container nur noch seine Zusammenfassung — Innenabstand und
     Spaltenabstand gehoeren zum aufgeklappten Inhalt. Vorher belegte die eingeklappte Box 49 px je
     Aufgabe, bei 56 Aufgaben also fast drei Bildschirme fuer nichts. */
  .qanswer--klappbar:not([open]) { padding-bottom: 6px; gap: 0; }
  /* Lag zuerst neben .side-foot und damit in @layer layout — .qanswer steht in @layer components,
     und components gewinnt unabhaengig von der Spezifitaet. Genau dafuer ist die Layer-Ordnung da;
     die Regel gehoert deshalb hierher, nicht in einen Override-Stapel. */
  .qanswer textarea { min-height: 56px; font-size: var(--fs-sm); background: var(--surface-2); resize: vertical; }
  .qactions { display: flex; gap: var(--space-3); align-items: center; flex-wrap: wrap; }
  .docchip { display: inline-flex; align-items: center; gap: 6px; font-size: var(--fs-xs); background: var(--accent-soft); color: var(--accent-ink); border-radius: var(--r-sm); padding: 3px 9px; }
  /* B-63: klickbarer Docchip (öffnet Dokument-Viewer) — Button-Reset + Hover/Fokus */
  .docchip--btn { border: 0; font-family: inherit; cursor: pointer; transition: background .12s ease; }
  .docchip--btn:hover { background: color-mix(in srgb, var(--accent) 16%, var(--accent-soft)); }
  .docchip--btn:focus-visible { outline: var(--focus); outline-offset: 2px; }
  .saved { font-size: var(--fs-xs); color: var(--ok-ink); background: var(--ok-soft); border-radius: var(--r-sm); padding: 6px 10px; }

  /* --- Interview-Repeater (Liegenschaften/Fahrzeuge/Firmen) --- */
  .repeater-liste { display: flex; flex-direction: column; gap: var(--space-2); margin-bottom: 14px; }
  .repeater-card { display: flex; justify-content: space-between; align-items: center; gap: var(--space-3); background: var(--surface); border: var(--border-width) solid var(--border); border-radius: var(--r-md); padding: 10px 14px; box-shadow: var(--shadow-1); }
  .repeater-card .rc-info { display: flex; flex-direction: column; gap: 2px; }
  .repeater-card .rc-title { font-weight: 600; font-size: var(--fs-md); }
  .repeater-card .rc-meta { font-size: 12.5px; color: var(--text-faint); }

  /* --- Entfernbare Chips (3a-Anbieter B-19) --- */
  .chips-liste { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 10px; }
  .chip-removable { background: var(--accent-soft); color: var(--accent-ink); border-color: color-mix(in srgb, var(--accent) 30%, transparent); gap: 6px; padding: 3px 6px 3px 10px; }
  .chip-x { background: none; border: none; color: inherit; font-size: var(--fs-md); line-height: 1; cursor: pointer; padding: 0 2px; font-weight: 700; }
  .chip-x:hover { color: var(--crit-ink); }

  /* --- Interview-Übersicht (B-21) --- */
  .fakt-row .fakt-edit { margin-left: auto; flex: none; }

  /* --- Dokument-Detail: Fakten-Review --- */
  details summary { cursor: pointer; font-weight: 600; font-size: var(--fs-sm); color: var(--accent-ink); }
  .excerpt { font-size: var(--fs-xs); white-space: pre-wrap; max-height: 320px; overflow: auto; background: var(--surface-2); border-radius: var(--r-sm); padding: 10px; margin-top: var(--space-2); }
  /* UI-34c: im Seitenpanel, das selbst scrollt, ist ein zweiter Scrollbereich eine Falle —
     gerendertes Markdown braucht ausserdem kein pre-wrap. */
  .excerpt--flow { max-height: none; overflow: visible; white-space: normal; }
  .fakt-list { display: flex; flex-direction: column; gap: 6px; margin-top: var(--space-2); }
  .fakt-row { display: flex; align-items: center; gap: 10px; padding: var(--space-2) 10px; border: var(--border-width) solid var(--border); border-radius: var(--r-sm); background: var(--surface-2); flex-wrap: wrap; }
  .fakt-row .fakt-key { font-weight: 600; font-size: var(--fs-sm); min-width: 140px; }
  .fakt-row .fakt-val { margin-right: auto; }

  /* Review-Variante der Interview-Übersicht (B-104): Frage als kleine, gedämpfte Kaption,
     Antwort gross & dunkel in der Zeile darunter — klare Q/A-Trennung. Modifier auf .fakt-row,
     damit die geteilte kv-Zeile (auch auf /dokumente) unverändert bleibt. */
  .fakt-list--review { gap: var(--space-2); }
  .fakt-row--review {
    display: grid;
    grid-template-columns: 1fr auto;
    grid-template-areas: "key key" "val edit";
    align-items: baseline;
    gap: var(--space-1) var(--space-3);
    padding: var(--space-3) var(--space-4);
  }
  .fakt-row--review .fakt-key {
    grid-area: key; min-width: 0;
    font-weight: 600; font-size: var(--fs-xs); letter-spacing: .02em;
    color: var(--text-muted);
  }
  .fakt-row--review .fakt-val {
    grid-area: val; margin-right: 0;
    font-weight: 600; font-size: var(--fs-base); line-height: 1.3; color: var(--text);
  }
  .fakt-row--review .fakt-edit { grid-area: edit; align-self: start; }

  /* --- Dropzone (B-27): unsichtbares InputFile über der ganzen Zone; Klick + nativer Drag&Drop --- */
  .dropzone {
    position: relative; display: block;
    border: 2px dashed color-mix(in srgb, var(--accent) 40%, var(--border));
    border-radius: var(--r-lg); padding: var(--space-5);
    text-align: center; background: var(--surface-2); color: var(--text-muted);
    font-size: var(--fs-sm); cursor: pointer; margin-bottom: 14px;
    transition: border-color .12s ease, background .12s ease;
  }
  .dropzone:hover { border-color: var(--accent); background: color-mix(in srgb, var(--accent-soft) 45%, var(--surface-2)); }
  .dropzone:focus-within { outline: var(--focus); outline-offset: 2px; border-color: var(--accent); }
  .dropzone__input { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; cursor: pointer; }
  .dropzone__title { font-weight: 600; color: var(--text); }
  .dropzone__hint { font-size: var(--fs-xs); color: var(--text-faint); margin-top: var(--space-1); }
  .dropzone--compact { padding: var(--space-3) var(--space-4); margin-bottom: 0; display: inline-block; min-width: 240px; }
  .dropzone--busy { opacity: .6; pointer-events: none; }

  /* --- Dokument-Viewer (B-63): eingebettete PDF/Bild-Vorschau im Overlay (Klick auf Docchip).
     Der Frame zeigt den auth-geschützten Inline-Endpunkt /dokumente/{id}/datei (B-44). --- */
  .viewer { position: fixed; inset: 0; z-index: 100; background: var(--backdrop); display: flex; align-items: center; justify-content: center; padding: var(--space-5); }
  .viewer:focus { outline: none; } /* Overlay wird programmatisch fokussiert (Esc-Handling) — kein Ring um den ganzen Screen */
  .viewer__panel { display: flex; flex-direction: column; width: min(960px, 100%); height: min(88vh, 1100px); background: var(--surface); border-radius: var(--r-lg); box-shadow: var(--shadow-3); overflow: hidden; }
  .viewer__head { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-2) var(--space-3); border-bottom: var(--border-width) solid var(--border); }
  .viewer__title { flex: 1; min-width: 0; font-size: var(--fs-md); font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .viewer__close { font-size: var(--fs-md); }
  .viewer__frame { flex: 1; width: 100%; border: 0; background: var(--surface-2); }

  /* --- KI-Chat (B-28): Konversationsansicht --- */
  .chat {
    display: flex; flex-direction: column;
    background: var(--surface); border: var(--border-width) solid var(--border); border-radius: var(--r-lg);
    box-shadow: var(--shadow-1); overflow: hidden;
    height: calc(100vh - 240px); min-height: 440px;
  }
  .chat__log { flex: 1; overflow-y: auto; padding: var(--space-5); display: flex; flex-direction: column; gap: var(--space-3); }
  .chat__empty { margin: auto; text-align: center; max-width: 46ch; color: var(--text-muted); }
  /* Leerzustand einer Seite (01.10.2026). Teilt Typografie und Breite mit .chat__empty, das es
     zuerst gab — zwei verschieden aussehende Leerzustaende waeren genau das Gebastel, das der
     Styleguide verbietet. Unterschied: .chat__empty zentriert sich per margin:auto in einem
     Flex-Container ueber die volle Hoehe, der Seiten-Leerzustand steht im normalen Fluss. */
  .chat__empty h3, .leerzustand h3 { margin: 0 0 6px; font-size: var(--fs-lg); color: var(--text); }
  .chat__empty p, .leerzustand p { margin: 0 0 var(--space-4); font-size: var(--fs-sm); }
  .leerzustand {
    text-align: center; max-width: 46ch; margin: var(--space-6) auto; color: var(--text-muted);
    padding: var(--space-6) var(--space-4);
    border: var(--border-width) dashed var(--border); border-radius: var(--r-lg);
  }
  /* Der Willkommens-Block ist der ERSTE Bildschirm einer frischen Instanz — er traegt mehr als die
     Meldung "hier ist noch nichts" und darf deshalb mehr Raum nehmen als ein gewoehnlicher
     Leerzustand mitten auf einer Seite. */
  .leerzustand--gross { max-width: 62ch; padding: var(--space-6) var(--space-6); }
  .leerzustand--gross h3 { font-size: var(--fs-xl); }
  .leerzustand--gross p { font-size: var(--fs-base); }
  .prompt-chips { display: flex; flex-wrap: wrap; gap: var(--space-2); justify-content: center; }
  .prompt-chip {
    font-family: inherit; font-size: var(--fs-sm); text-align: left;
    background: var(--surface-2); color: var(--accent-ink);
    border: var(--border-width) solid var(--border); border-radius: var(--r-md);
    padding: var(--space-2) var(--space-3); cursor: pointer; max-width: 100%;
    transition: border-color .12s ease, background .12s ease;
  }
  .prompt-chip:hover { border-color: var(--accent); background: var(--accent-soft); }
  .prompt-chip:focus-visible { outline: var(--focus); outline-offset: 2px; }

  .bubble { max-width: 82%; display: flex; flex-direction: column; gap: var(--space-1); }
  .bubble__meta { font-size: 10.5px; text-transform: uppercase; letter-spacing: .05em; font-weight: 800; color: var(--text-faint); display: flex; gap: var(--space-2); align-items: baseline; }
  .bubble__time { font-weight: 600; letter-spacing: 0; text-transform: none; color: var(--text-faint); }
  .bubble__body {
    padding: 11px 14px; border-radius: var(--r-lg); font-size: var(--fs-md); line-height: 1.55;
    white-space: pre-wrap; overflow-wrap: anywhere; box-shadow: var(--shadow-1);
  }
  .bubble__actions { margin-top: 2px; }
  .bubble--user { align-self: flex-end; align-items: flex-end; }
  .bubble--user .bubble__body { background: var(--accent-soft); color: var(--text); border: var(--border-width) solid color-mix(in srgb, var(--accent) 25%, transparent); border-bottom-right-radius: var(--r-sm); }
  .bubble--expert { align-self: flex-start; }
  .bubble--expert .bubble__body { background: var(--surface); color: var(--text); border: var(--border-width) solid var(--border); border-bottom-left-radius: var(--r-sm); }
  .bubble--typing .bubble__body { color: var(--text-faint); font-style: italic; }

  .composer {
    display: flex; gap: var(--space-2); align-items: flex-end;
    padding: var(--space-3); border-top: var(--border-width) solid var(--border); background: var(--surface-2);
  }
  .composer__zweck { width: auto; flex: none; min-width: 150px; font-size: var(--fs-sm); padding: var(--space-2) 28px var(--space-2) 10px; }
  .composer__input { flex: 1; min-height: 44px; max-height: 180px; font-size: var(--fs-md); resize: none; field-sizing: content; background: var(--surface); }

  /* --- Chat-Markdown (B-39/B-12): sicheres HTML aus KI-Antworten (ChatMarkdown.ZuHtml) ---
     Überschriften bewusst kleiner als im Rest der App — innerhalb einer Bubble wäre ein h1/h2 in
     Seitenkopf-Grösse überdimensioniert. */
  .md { white-space: normal; }
  .md > :first-child { margin-top: 0; }
  .md > :last-child { margin-bottom: 0; }
  .md h1, .md h2 { font-size: var(--fs-base); font-weight: 700; margin: 14px 0 6px; line-height: 1.3; }
  .md h3, .md h4, .md h5, .md h6 { font-size: var(--fs-md); font-weight: 700; margin: var(--space-3) 0 5px; }
  .md p { margin: 0 0 10px; }
  .md ul, .md ol { margin: 0 0 10px; padding-left: 22px; }
  .md li { margin-bottom: 3px; }
  .md li > ul, .md li > ol { margin-top: 3px; margin-bottom: 0; }
  .md a { color: var(--accent-ink); text-decoration: underline; text-decoration-color: transparent; transition: text-decoration-color .12s ease; }
  .md a:hover { text-decoration-color: currentColor; }
  .md code { font-family: var(--font-mono); font-size: .92em; background: var(--surface-2); border-radius: 4px; padding: 1px 5px; }
  .md pre { font-family: var(--font-mono); font-size: var(--fs-sm); background: var(--surface-2); border: var(--border-width) solid var(--border); border-radius: var(--r-sm); padding: var(--space-3); overflow-x: auto; margin: 0 0 10px; }
  .md pre code { background: none; padding: 0; }
  .md blockquote { margin: 0 0 10px; padding: 2px 14px; border-left: 3px solid var(--border); color: var(--text-muted); }
  .md hr { border: none; border-top: var(--border-width) solid var(--border); margin: 14px 0; }
  /* Kein Wrapper-Div möglich (Markdig rendert <table> direkt) — table-scroll-Äquivalent per
     display:block auf der Tabelle selbst: sie scrollt bei Bedarf horizontal wie ein .table-scroll. */
  .md table { display: block; max-width: 100%; overflow-x: auto; border-collapse: collapse; font-size: var(--fs-sm); margin: 0 0 10px; }
  .md table th, .md table td { text-align: left; padding: 6px 10px; border: var(--border-width) solid var(--border); }
  .md table th { background: var(--surface-2); font-weight: 700; white-space: nowrap; }

  /* --- Register/Tabs (B-30): client-seitige Sektions-Navigation --- */
  .tabs { margin-bottom: var(--space-4); }
  .tabs__list { display: flex; flex-wrap: wrap; gap: var(--space-4); border-bottom: var(--border-width) solid var(--border); margin-bottom: var(--space-5); }
  .tabs__tab {
    font-family: inherit; font-size: var(--fs-md); font-weight: 600;
    background: none; border: none; border-bottom: 2px solid transparent;
    padding: var(--space-3) var(--space-1); margin-bottom: -1px;
    color: var(--text-muted); cursor: pointer;
    transition: color .12s ease, border-color .12s ease;
  }
  .tabs__tab:hover { color: var(--text); }
  .tabs__tab:focus-visible { outline: var(--focus); outline-offset: 2px; }
  .tabs__tab--active { color: var(--accent-ink); border-bottom-color: var(--accent); }
  .tabs__panel:focus-visible { outline: var(--focus); outline-offset: 2px; }
  /* Kategorie-Betrag + „offen"-Punkt in der Finanzen-Tab-Leiste. */
  .tab-betrag { margin-left: 7px; font-size: var(--fs-xs); font-weight: 600; color: var(--text-faint); font-variant-numeric: tabular-nums; }
  .tabs__tab--active .tab-betrag { color: var(--text-muted); }
  .tab-offen { display: inline-block; width: 6px; height: 6px; margin-left: 6px; border-radius: 50%; background: var(--warn-ink); vertical-align: middle; }
}

/* ==================== UTILITIES ==================== */
@layer utilities {
  /* Das `hidden`-Attribut muss verstecken, auch wenn eine Komponente `display` setzt (z. B.
     .form-grid{display:grid} im components-Layer). Im utilities-Layer gewinnt diese Invariante
     per @layer-Ordnung ohne !important — sonst leaken die Modal-Tab-Panels (B-103). */
  [hidden] { display: none; }
  /* B-13/B-67: .why ist die Begruendungszeile unter einem Label oder Eintrag ("warum steht das
     hier"). Sie war NUR innerhalb von .q und .qhead gestylt — auf /audit, /findings, /szenarien,
     /einstellungen, /dokumente, /beratung, /chat, /netzwerk und im Interview fiel sie auf
     Fliesstextgroesse und volle Textfarbe zurueck. 39 Verwendungen, 2 gestylt.
     WARUM HIER und nicht bei .hint im components-Layer: dort verlor sie gegen
     `.card p { font-size: 13.5px }` — gleiche Ebene, hoehere Spezifitaet (0,1,1 gegen 0,1,0). Die
     Klasse haette dann je nach Umgebung zwei Groessen gehabt, also genau das Problem, das sie
     loesen soll. Im utilities-Layer gewinnt sie per @layer-Ordnung, ohne !important und ohne eine
     Spezifitaets-Spirale — dasselbe Muster wie [hidden] darueber. Gemessen nach dem ersten Versuch:
     /audit 13px, Karte 13.5px.
     12.5px wurde dabei auf --fs-sm (13px) gezogen: ein Zwischenwert ausserhalb der Typo-Skala hat
     keinen Grund. */
  .why { font-size: var(--fs-sm); color: var(--text-muted); margin-top: var(--space-1); max-width: var(--measure); }
  /* Lesebreite fuer textlastige Seiten (UI-Runde 2). Eine Zeile Fliesstext ueber die ganze Breite
     eines 3400px-Bildschirms liest niemand gern; Tabellen und Raster dagegen gewinnen durch jede
     zusaetzliche Spalte. Deshalb traegt der Text die Begrenzung, nicht der Rahmen.
     Etwas grosszuegiger als --measure (68ch): die Karten enthalten neben dem Text auch Eingabe-
     felder und Knopfreihen, die bei reiner Lesebreite gedraengt wirken. */
  .lesebreite { max-width: 1040px; }
  /* Geprueftre Qualitaets-Befunde treten zurueck, verschwinden aber nicht: die Beurteilung muss
     nachlesbar und zuruecknehmbar bleiben. */
  .q-geprueft { opacity: .62; }
  .q-geprueft:hover { opacity: 1; }
  .num { font-variant-numeric: tabular-nums; letter-spacing: -.01em; }
  .block { display: block; }
  /* UI-32: Formularfelder tragen bewusst width:100% (B-25, fuer Formularraster). Ein Select, das
     allein in einer Werkzeugleiste steht, soll der Breite seines Inhalts folgen. */
  .w-auto { width: auto; max-inline-size: 22rem; }
  .mt-8 { margin-top: var(--space-2); }
  .mt-10 { margin-top: 10px; }
  .mt-12 { margin-top: var(--space-3); }
  .mt-18 { margin-top: 18px; }
  .mb-8 { margin-bottom: var(--space-2); }
  /* Styleguide-Demo: Farb-Swatches */
  .sg-swatches { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: var(--space-3); }
  .sg-swatch { border: var(--border-width) solid var(--border); border-radius: var(--r-md); overflow: hidden; background: var(--surface); }
  .sg-swatch__chip { height: 56px; }
  .sg-swatch__meta { padding: var(--space-2) 10px; }
  .sg-swatch__name { font-family: var(--font-mono); font-size: var(--fs-xs); font-weight: 700; }
  .sg-swatch__val { font-family: var(--font-mono); font-size: 11px; color: var(--text-faint); }
  .sg-type > * { margin: 0 0 var(--space-2); }
  .sg-row { display: flex; gap: var(--space-3); flex-wrap: wrap; align-items: center; margin-bottom: var(--space-3); }
  /* Styleguide-Demo: Token-Farbflächen (nur Token-Referenzen, keine rohen Hex) */
  .sg-c-bg { background: var(--bg); }
  .sg-c-surface { background: var(--surface); }
  .sg-c-surface-2 { background: var(--surface-2); }
  .sg-c-border { background: var(--border); }
  .sg-c-text { background: var(--text); }
  .sg-c-text-muted { background: var(--text-muted); }
  .sg-c-text-faint { background: var(--text-faint); }
  .sg-c-accent { background: var(--accent); }
  .sg-c-accent-ink { background: var(--accent-ink); }
  .sg-c-accent-soft { background: var(--accent-soft); }
  .sg-c-ok { background: var(--ok); }
  .sg-c-ok-soft { background: var(--ok-soft); }
  .sg-c-warn { background: var(--warn); }
  .sg-c-warn-soft { background: var(--warn-soft); }
  .sg-c-crit { background: var(--crit); }
  .sg-c-crit-soft { background: var(--crit-soft); }
  .sg-c-open { background: var(--open); }
  .sg-c-open-soft { background: var(--open-soft); }
}

/* ==================== AUTH (B-10/B-57): Login / Ersteinrichtung / Benutzer ==================== */
@layer components {
  /* Benutzerverwaltung: Aktiv/Inaktiv-Badge */
  .chip.ok { background: var(--ok-soft); color: var(--ok-ink); border-color: color-mix(in srgb, var(--ok) 32%, transparent); }
  .chip.flag { background: var(--crit-soft); color: var(--crit-ink); border-color: color-mix(in srgb, var(--crit) 32%, transparent); }

  /* Sidebar-Footer (B-42): User-Card (Klick -> /profil) + Logout-Icon-Button + About-Zeile,
     ersetzt die frühere Status-Zeile + das ausgeschriebene "Abmelden"-Button-Formular. */
  .user-row { display: flex; align-items: center; gap: var(--space-2); }
  .user-card {
    display: flex; align-items: center; gap: 10px; flex: 1; min-width: 0;
    padding: var(--space-2); border-radius: var(--r-md); text-decoration: none; color: inherit;
    border: var(--border-width) solid transparent; transition: background .12s ease, border-color .12s ease;
  }
  .user-card:hover { background: var(--surface-2); }
  .user-card:focus-visible { outline: var(--focus); outline-offset: 1px; }
  .user-card__avatar {
    flex: none; width: 34px; height: 34px; border-radius: 50%;
    background: var(--accent-soft); color: var(--accent-ink);
    display: flex; align-items: center; justify-content: center;
    font-size: var(--fs-xs); font-weight: 800; letter-spacing: .01em;
  }
  .user-card__info { min-width: 0; display: flex; flex-direction: column; gap: 1px; }
  .user-card__name { font-size: var(--fs-sm); font-weight: 700; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .user-card__role { font-size: 11px; color: var(--text-faint); }

  .logout-form { margin: 0; }
  .icon-btn {
    flex: none; width: 34px; height: 34px; display: inline-flex; align-items: center; justify-content: center;
    background: none; border: var(--border-width) solid transparent; border-radius: var(--r-md);
    color: var(--text-faint); cursor: pointer; padding: 0;
    transition: background .12s ease, color .12s ease, border-color .12s ease;
  }
  .icon-btn:hover { background: var(--crit-soft); color: var(--crit-ink); }
  .icon-btn:focus-visible { outline: var(--focus); outline-offset: 1px; }
  .icon-btn svg { inline-size: var(--icon-size); block-size: var(--icon-size); }

  .about-line { margin-top: var(--space-2); padding: 0 var(--space-2); font-size: 11px; color: var(--text-faint); }

  /* Login / Ersteinrichtung (B-57): Split-Screen im Taxopus-Familien-Design (Vorlage:
     effrx.clockopus.cloud) — linkes dunkles Marken-Panel mit Radial-Glow + rechte helle
     Card-Fläche. Unter ~900px Viewport-Breite wird das Marken-Panel ausgeblendet
     (Card-only-Fallback, siehe Media-Query unten). */
  .login-split { min-height: 100vh; display: flex; }

  .login-brand {
    flex: 1 1 50%;
    display: flex; align-items: center; justify-content: center;
    padding: var(--space-6);
    /* UI-34e: hier lagen zwei uebereinandergelegte Verlaeufe. Der Styleguide schliesst unter
       "Restraint over flash" Gradient-Heroes ausdruecklich aus — es ist die Regel, die das Dokument
       selbst setzt, und die Anmeldemaske ist der erste Eindruck der Anwendung. Flaeche statt Verlauf. */
    background: var(--brand-panel);
    color: var(--on-brand-panel);
  }
  .login-brand__inner { max-width: 380px; }
  .login-brand__wordmark { font-size: 34px; font-weight: 800; letter-spacing: -.01em; }
  .login-brand__tagline { margin: var(--space-3) 0 0; font-size: var(--fs-base); line-height: 1.5; color: var(--on-brand-panel-muted); }

  .login-surface {
    flex: 1 1 50%;
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    padding: var(--space-5); background: var(--bg);
  }
  .login-card {
    width: 100%; max-width: 400px; background: var(--surface);
    border-radius: var(--r-lg); box-shadow: var(--shadow-3); padding: var(--space-6) var(--space-5);
  }
  .login-card__h1 { font-size: var(--fs-lg); margin: 0 0 var(--space-1); color: var(--text); }
  .login-card__sub { font-size: var(--fs-sm); color: var(--text-muted); margin: 0 0 var(--space-5); }
  .login-error { margin-top: 0; margin-bottom: var(--space-4); }
  .login-form { display: flex; flex-direction: column; gap: 14px; }
  .login-field { display: flex; flex-direction: column; gap: 5px; }
  .login-field label { font-size: var(--fs-xs); font-weight: 600; color: var(--text-muted); }
  .login-checkbox-row { display: flex; align-items: center; gap: var(--space-2); font-size: var(--fs-sm); color: var(--text-muted); }
  .login-checkbox-row input[type=checkbox] { width: auto; }
  .login-submit { width: 100%; padding: 14px 13px; font-size: var(--fs-md); margin-top: var(--space-1); }
  .login-version { margin-top: var(--space-4); font-size: var(--fs-xs); color: var(--text-faint); }

  @media (max-width: 900px) {
    .login-brand { display: none; }
  }
}

/* ==================== BERATUNG (B-75): Stale-Banner, Frage-Karten, Strategie-Anzeige ==================== */
@layer components {
  /* UI-34b: Aktion als eigener Block, die Erlaeuterung darunter statt daneben. */
  .beratung__start { display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-2); margin-bottom: var(--space-3); }
  .beratung__stale {
    background: var(--warn-soft);
    color: var(--warn-ink);
    border-radius: var(--r-sm);
    padding: var(--space-2) var(--space-3);
    margin-block-end: var(--space-3);
  }
  .beratung__frage textarea { inline-size: 100%; }
  .beratung__frage-aktionen { display: flex; gap: var(--space-2); margin-block-start: var(--space-2); }
  .beratung__historie { margin-block-start: var(--space-4); }
  .beratung__version { margin-block-start: var(--space-2); }
  .beratung__strategie { overflow-x: auto; }

  /* B-90: Live-Fortschritt des Analyse-Laufs — Phase, verstrichene Zeit, Zähler, Verlauf. */
  .beratung__lauf { display: flex; flex-direction: column; gap: var(--space-3); }
  .beratung__lauf-kopf { display: flex; align-items: center; gap: var(--space-3); }
  .beratung__spinner {
    inline-size: 18px; block-size: 18px; flex: none; border-radius: 50%;
    border: 2px solid var(--accent-soft); border-block-start-color: var(--accent);
    animation: beratung-spin .8s linear infinite;
  }
  .beratung__lauf-titel { display: flex; flex-direction: column; gap: 2px; min-inline-size: 0; }
  .beratung__phase { color: var(--accent-ink); font-size: var(--fs-sm); }
  .beratung__dauer {
    margin-inline-start: auto; align-self: flex-start;
    font-variant-numeric: tabular-nums;
    color: var(--text-muted); font-size: var(--fs-sm);
  }
  .beratung__stats { display: flex; flex-wrap: wrap; gap: var(--space-2); margin: 0; }
  .beratung__stat {
    display: flex; flex-direction: column; gap: 2px; min-inline-size: 96px;
    padding: var(--space-2) var(--space-3); border: var(--border-width) solid var(--border);
    border-radius: var(--r-sm); background: var(--surface-2);
  }
  .beratung__stat dt { font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: .04em; color: var(--text-faint); }
  .beratung__stat dd { margin: 0; font-size: var(--fs-md); font-variant-numeric: tabular-nums; color: var(--text); }
  .beratung__stat-max { color: var(--text-faint); }
  /* Kein Scroll-Container: der aktuelle Schritt (▸) steht immer sichtbar zuoberst, nur die neuesten
     Schritte werden gezeigt (Take im Markup) — niemand muss scrollen (Feedback CC 2026-08-29). */
  .beratung__log { list-style: none; margin: 0; padding: 0; }
  .beratung__log-item {
    display: flex; align-items: baseline; gap: var(--space-2);
    padding-block: var(--space-1); font-size: 12.5px; color: var(--text-muted);
    border-block-start: var(--border-width) solid var(--border);
  }
  .beratung__log-item::before { content: "·"; color: var(--text-faint); }
  .beratung__log-item:first-child { color: var(--text); }
  .beratung__log-item:first-child::before { content: "▸"; color: var(--accent); }
  /* Zeitangabe je Zeile: schmale, ziffern-gleiche Spalte, damit die Zeiten untereinander fluchten. */
  .beratung__log-zeit { flex: none; min-inline-size: 3.4em; font-variant-numeric: tabular-nums; color: var(--text-faint); }
  .beratung__log-item:first-child .beratung__log-zeit { color: var(--accent); }
  .beratung__log-text { flex: 1 1 auto; min-inline-size: 0; }
  /* Live tickende „läuft seit …"-Dauer am aktuellen Schritt: Akzent, damit die Bewegung auffaellt. */
  .beratung__log-seit { color: var(--accent); font-variant-numeric: tabular-nums; white-space: nowrap; }
}

@keyframes beratung-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .beratung__spinner { animation: none; } }

/* ==================== FINANZEN (B-103): Immobilien-Übersichtstabelle ==================== */
@layer components {
  /* B-103: Immobilien-Übersichtstabelle */
  /* B-162: die Tabelle ist breiter als ihr Platz (gemessen 08.10.2026: 901px Tabelle gegen
     389px Rahmen). Ohne diese Zeile schiebt sie die GANZE SEITE waagrecht, statt selbst zu
     scrollen — der Wrapper stand auf overflow-x: visible. Am Desktop ändert sich nichts. */
  .immo-tabelle { overflow-x: auto; }
  .immo-tabelle__kopf { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); margin-bottom: var(--space-3); }
  .immo-tabelle__kopf-r { display: flex; align-items: center; gap: var(--space-3); }
  .immo-tabelle__t { width: 100%; border-collapse: collapse; }
  .immo-tabelle__t th { text-align: left; font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: .06em; color: var(--text-muted); padding: var(--space-2) var(--space-3); border-bottom: var(--border-width) solid var(--border); }
  .immo-tabelle__t th.n, .immo-tabelle__t td.n { text-align: right; font-variant-numeric: tabular-nums; }
  .immo-tabelle__t td { padding: var(--space-3); border-bottom: var(--border-width) solid var(--border); }
  .immo-tabelle__zeile { cursor: pointer; }
  .immo-tabelle__zeile:hover { background: var(--surface-2); }
  .immo-tabelle__name { font-weight: 650; }
  .immo-tabelle__offen { display: inline-block; width: 7px; height: 7px; border-radius: 50%; background: var(--warn); margin: 0 var(--space-2); vertical-align: middle; }
  .immo-tabelle__akt { text-align: right; white-space: nowrap; }
  .immo-tabelle__foot td { font-weight: 700; border-top: 2px solid var(--border); border-bottom: none; }

  /* B-103: Formular-Modal + Tabs */
  .modal__overlay { position: fixed; inset: 0; background: var(--backdrop); display: flex; align-items: flex-start; justify-content: center; padding: var(--space-6) var(--space-4); z-index: 50; overflow-y: auto; }
  .modal__box { background: var(--surface); border: var(--border-width) solid var(--border); border-radius: var(--r-md); box-shadow: var(--shadow-3); width: min(760px, 100%); }
  .modal__head { display: flex; align-items: center; justify-content: space-between; padding: var(--space-4) var(--space-5); border-bottom: var(--border-width) solid var(--border); }
  .modal__x { background: none; border: none; font-size: var(--fs-lg); cursor: pointer; color: var(--text-muted); }
  .modal__body { padding: var(--space-5); }
  .modal__foot { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-4) var(--space-5); border-top: var(--border-width) solid var(--border); }
  .modal__foot-spacer { flex: 1; }
  .modal__del:hover { color: var(--crit-ink); }
  .form-tabs__list { display: flex; gap: var(--space-1); padding: 0 var(--space-5); border-bottom: var(--border-width) solid var(--border); }
  .form-tabs__tab { background: none; border: none; padding: var(--space-3) var(--space-3); cursor: pointer; color: var(--text-muted); border-bottom: 2px solid transparent; }
  .form-tabs__tab.is-active { color: var(--accent-ink); border-bottom-color: var(--accent); font-weight: 650; }
  .form-tabs__aktion { margin-bottom: var(--space-3); }
  .form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-3) var(--space-4); }
  .form-feld { display: flex; flex-direction: column; gap: var(--space-1); font-size: var(--fs-xs); color: var(--text-muted); }
  .form-feld--wide { grid-column: 1 / -1; }
  .form-feld output { font-size: var(--fs-md); color: var(--text); font-variant-numeric: tabular-nums; }
  @media (max-width: 640px) { .form-grid { grid-template-columns: 1fr; } }
}

/* ==================== NETZWERK (B-105): Knowledge-Graph-Ansicht ==================== */
@layer components {
  /* UI-01: minmax(0, 1fr) — gleiche Ursache wie bei .app und .detail-split. Mit `1fr` nahm die
     Spur die Min-Content-Breite des Graphen an, statt der Zeichenflaeche die volle Inhaltsbreite
     zu geben. */
  .graph { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-3); }
  .graph__schalter { display: inline-flex; align-items: center; gap: 6px; font-size: var(--fs-xs); color: var(--text-muted); cursor: pointer; white-space: nowrap; }
  .graph__bar { display: flex; align-items: center; justify-content: space-between; gap: var(--space-4); flex-wrap: wrap; }
  .graph__modi { display: flex; gap: var(--space-2); }
  .graph__legende { display: flex; flex-wrap: wrap; gap: var(--space-3); font-size: var(--fs-xs); color: var(--text-muted); }
  .graph__leg { display: inline-flex; align-items: center; gap: 5px; }
  /* UI-14: der Beleg-Punkt ist --surface-2 und damit auf weissem Grund unsichtbar. Im SVG traegt
     der Knoten eine Kontur, die HTML-Legende hatte keine. Eine Kontur fuer ALLE Punkte haelt die
     Legende einheitlich, statt einen Sonderfall einzubauen. */
  .graph__leg-sw { width: 12px; height: 12px; border-radius: 50%; border: var(--border-width) solid var(--border); box-sizing: border-box; }

  .graph__canvas { background: var(--surface); border: var(--border-width) solid var(--border); border-radius: var(--r-lg); box-shadow: var(--shadow-1); overflow: hidden; }
  .graph__svg { display: block; width: 100%; height: min(72vh, 720px); touch-action: none; cursor: grab; background: var(--surface); }
  .graph__svg:active { cursor: grabbing; }

  .graph__edge { stroke: var(--border); stroke-width: 1.6px; }
  .graph__edge--hypothekauf { stroke: var(--crit); stroke-width: 1.9px; }
  .graph__edge--belegquelle { stroke: color-mix(in srgb, var(--text-faint) 60%, transparent); stroke-width: 1.3px; stroke-dasharray: 5 4; }
  .graph__edge--ehepaar { stroke: var(--accent); stroke-width: 1.9px; }

  .graph__node { cursor: pointer; }
  .graph-node { stroke: var(--surface); stroke-width: 2px; transition: filter .12s ease; }
  .graph__node:hover .graph-node { filter: brightness(1.08); }
  .graph__node.is-selected .graph-node { stroke: var(--accent-ink); stroke-width: 3px; }
  .graph__label { fill: var(--text); font-size: var(--fs-xs); font-weight: 600; text-anchor: middle; paint-order: stroke; stroke: var(--surface); stroke-width: 3px; pointer-events: none; }

  /* Knoten-Füllung je Typ (auch Legende-Swatch): nur Token, kein rohes Hex. */
  .graph-fill--person { fill: var(--node-person); background: var(--node-person); }
  .graph-fill--firma { fill: var(--node-firma); background: var(--node-firma); }
  .graph-fill--liegenschaft { fill: var(--node-liegenschaft); background: var(--node-liegenschaft); }
  .graph-fill--vorsorge { fill: var(--node-vorsorge); background: var(--node-vorsorge); }
  .graph-fill--kontodepot { fill: var(--node-kontodepot); background: var(--node-kontodepot); }
  .graph-fill--fahrzeug { fill: var(--node-fahrzeug); background: var(--node-fahrzeug); }
  .graph-fill--police { fill: var(--node-police); background: var(--node-police); }
  .graph-fill--hypothek { fill: var(--node-hypothek); background: var(--node-hypothek); }
  .graph-fill--beteiligung { fill: var(--node-beteiligung); background: var(--node-beteiligung); }
  .graph-fill--dokument { fill: var(--node-dokument); stroke: var(--border); background: var(--node-dokument); }

  .graph__detail { background: var(--surface); border: var(--border-width) solid var(--border); border-radius: var(--r-lg); box-shadow: var(--shadow-1); padding: var(--space-4); }
  .graph__detail-head { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; margin-bottom: var(--space-3); }
  .graph__detail-head h3 { margin: 0; font-size: var(--fs-md); flex: 1; }
  .graph__belege { margin-top: var(--space-3); display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: center; }
  .graph__belege .ey { width: 100%; font-size: var(--fs-xs); letter-spacing: .1em; text-transform: uppercase; color: var(--text-muted); }

  @media (min-width: 1100px) {
    /* UI-01: die zweite Spur nur, wenn ein Knoten gewaehlt ist (.graph--detail). Vorher reservierte
       .graph oberhalb 1100px IMMER 280-340px fuer die Detail-Seitenleiste, auch wenn keine offen war
       — die Zeichenflaeche blieb dadurch dauerhaft ~350px schmaler als der Inhaltsbereich (live
       gemessen: 1144px Flaeche bei 1600px Inhalt). Genau diese Verschwendung vermeidet
       .detail-split bereits bewusst; hier zieht die Netzwerk-Ansicht nach. */
    .graph--detail { grid-template-columns: minmax(0, 1fr) minmax(280px, 340px); grid-template-areas: "bar bar" "canvas detail"; }
    /* Die Bereichsnamen existieren nur im Detail-Zustand — unbedingt zugewiesen wuerden sie sonst
       als Linien-Namen gelesen und erzeugten zwei leere implizite Spuren ("0px 0px 1472px"). */
    .graph--detail > .graph__bar { grid-area: bar; }
    .graph--detail > .graph__canvas { grid-area: canvas; }
    .graph--detail > .graph__detail { grid-area: detail; align-self: start; position: sticky; top: var(--space-4); }
  }
}
