/* ============================================================
   Design tokens — artboard v23 (redesign/artboard/_tokens.css) is the source.
   The pre-existing --ea-* / --fs-* / --ok-* names are KEPT and carry the board values
   (they already matched: ink, accent, paper, line, the six status triplets). New names
   only where the board has a value the app had no token for. Dark counterparts: html.dark
   further down (search "Dark mode (v2.0)" and "Redesign v23 — dark tokens").
   ============================================================ */
:root {
  --ea-ink: #0b1a2b;          /* board: body text, h1, primary button fill */
  --ea-ink-2: #1e2c3d;
  --ea-paper: #f7f8fa;        /* board: page background */
  --ea-line: #e2e8f0;         /* board: every 1px border */
  --ea-accent: #14506b;       /* board: links, active underline, chart fill, focus */
  --ea-accent-2: #2a7a99;
  --ea-amber: #b97a04;
  --ea-red: #b42318;
  --ea-green: #056b3f;
  --ea-violet: #5b3a8e;
  /* new in v23 */
  --ea-text-2: #475569;       /* labels (.lbl), table heads, tabs, pills — slate-600 */
  --ea-subtle: #f8fafc;       /* table head / group row / button hover — slate-50 */
  --ea-accent-soft: #e6eff4;  /* selected pill / segment / row */
  --ea-accent-line: #b7cfdb;  /* border of the selected pill / segment */
  --ea-accent-ink: #14506c;   /* text on --ea-accent-soft */
  --neu-t: #475569; --neu-s: #f1f5f9; --neu-b: #e2e8f0;   /* the neutral chip triplet */
  --btn-primary-bg: #0b1a2c; --btn-primary-line: #0b1a2c; --btn-primary-hover: #1e2c3d; --btn-primary-t: #ffffff;
  --r-sm: 4px; --r-md: 6px; --r-lg: 8px; --r-xl: 12px; --r-pill: 9999px;
  --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
  --lh-xs: 15px; --lh-sm: 17px; --lh-md: 20px; --lh-xl: 32px; --lh-hero: 44px;
  --sp-1: 4px; --sp-2: 8px; --sp-3: 12px; --sp-4: 16px; --sp-5: 20px; --sp-6: 24px; --sp-8: 32px; --sp-10: 40px;
  --h-header: 52px; --h-subnav: 40px; --h-ctl: 32px; --h-ctl-sm: 28px;
  --shadow-pop: 0 12px 32px rgba(11,26,43,.16);
}

html, body { font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; }
/* --- EINE Schrift (Eine-Schrift-Pass, DESIGN.md 2.4) ------------------------------------
   Die Monospace-Familie ist Geschichte. Die Spalten-Flucht kam nie aus der Monospace-Familie,
   sondern aus den TABELLENZIFFERN — und die hat Inter (font-variant-numeric: tabular-nums).
   .mono und .tnum sind ab jetzt SYNONYME: beide Inter + tabular-nums, beide bleiben im Markup
   stehen (.mono an ~620 Stellen, kein Markup-Edit). Die alte B0-Trennlinie "Spalte = Mono,
   freistehend = Inter" ist retired — es gibt nur noch eine Zahl-Behandlung.
   ⚠ font-feature-settings: 'tnum' steht ZUSAETZLICH zu font-variant-numeric: stehen beide
   Klassen am selben Knoten oder erbt ein Kind eine Low-Level-Angabe, fordern beide dasselbe.
   ⚠ Es gibt BEWUSST keine benannte .code-Mono-Ausnahme: die vier gemessenen Kandidaten
   (zwei Paste-Textareas, ein Fehler-Banner, ein <pre> mit Fehlertext) sind Daten-Eingabe bzw.
   Diagnose, kein Code-Block, den man zeilenweise liest. Kommt je ein echter SQL-/JSON-Block,
   ist das der Ort fuer eine schmale, benannte Ausnahme — nicht ein globales Monospace. */
.mono { font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; font-variant-numeric: tabular-nums; font-feature-settings: 'tnum'; }
.tnum { font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; font-variant-numeric: tabular-nums; font-feature-settings: 'tnum'; }
/* Tailwind-Utility `font-mono` (zwei Paste-Textareas) und das UA-/Preflight-Monospace von <pre>
   werden hier abgefangen, ohne Markup-Edit. ⚠ `html`-Praefix ist load-bearing: Tailwind wird
   als <style> NACH styles.css injiziert (gemessen, s. .btn-quiet) — ein blosses .font-mono
   (0,1,0) bzw. pre (0,0,1) verloere gegen die spaetere, gleich spezifische Preflight-Regel. */
html .font-mono { font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; font-variant-numeric: tabular-nums; }
html pre { font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; font-variant-numeric: tabular-nums; }

.tab-active { background: var(--ea-ink); color: white; }
.tab-inactive { background: transparent; color: var(--ea-ink); }
.tab-inactive:hover { background: rgba(11,26,43,0.06); }

.gate-pass { background: #e8f5ee; color: #056b3f; border: 1px solid #c4e7d2; }
.gate-passnote { background: #fdf4e3; color: #8c5b03; border: 1px solid #f1d99a; }
.gate-partial { background: #fdf4e3; color: #8c5b03; border: 1px solid #f1d99a; }
.gate-fail { background: #fdecea; color: #b42318; border: 1px solid #f4c1bb; }
.gate-pending { background: #f1f5f9; color: #475569; border: 1px solid #e2e8f0; }
.gate-na { background: #f5f3ff; color: #6d28d9; border: 1px solid #ddd6fe; }

.badge { display: inline-flex; align-items: center; padding: 2px 8px; border-radius: 9999px; font-size: 11px; font-weight: 500; letter-spacing: 0.01em; border: 1px solid transparent; }
/* Rollen-Varianten des Badges — DESIGN.md §4.4 schreibt sie seit dem Audit vor, im CSS
   fehlten sie. Bewusst auf denselben Rollen-Tokens wie .r-* (§5), damit ein Badge und ein
   Provenienz-Chip nebeneinander nicht zwei Grüns zeigen; die .gate-*-Sätze bleiben als
   Bestand unverändert, bis sie beim Anfassen migriert werden. */
.badge--ok       { color: var(--ok-t);   background: var(--ok-s);   border-color: var(--ok-b); }
.badge--caution  { color: var(--caut-t); background: var(--caut-s); border-color: var(--caut-b); }
.badge--fail     { color: var(--fail-t); background: var(--fail-s); border-color: var(--fail-b); }
.badge--info     { color: var(--info-t); background: var(--info-s); border-color: var(--info-b); }
.badge--na       { color: var(--na-t);   background: var(--na-s);   border-color: var(--na-b); }
.badge--neutral  { color: var(--muted);  background: var(--ea-paper); border-color: var(--ea-line); }
.chip { display: inline-flex; align-items: center; padding: 3px 10px; border-radius: 6px; font-size: 12px; font-weight: 500; background: #eef2f7; color: #1e2c3d; border: 1px solid #dbe3ec; }
.chip-link { display: inline-flex; align-items: center; padding: 3px 10px; border-radius: 6px; font-size: 12px; font-weight: 500; background: var(--ea-ink, #0b1a2b); color: #fff; border: 1px solid var(--ea-ink, #0b1a2b); text-decoration: none; transition: opacity .15s; }
.chip-link:hover { opacity: .85; }

/* --- .btn-quiet — der tertiaere Text-Button (DESIGN.md §4.3) -----------------------------
   War bis hierher UNDEFINIERT: die Klasse steht an 25 Knoepfen, trug aber nichts bei — jeder
   erbte Farbe und Groesse von seinem Elter, also sah derselbe Knopf je Kontext anders aus
   (gemessen: slate-900 in einer Registry-Zeile, slate-500 in einer Karte, rose in einer
   Fehler-Box) und hatte weder Hover- noch Fokus-Zustand. DESIGN.md §4.3 definiert ihn als
   „transparent, slate-500, underline on hover" fuer tertiaere Aktionen und Inline-Links;
   das hier ist genau diese Zeile, in CSS.
   ⚠ BEWUSST OHNE font-size. 20 der 25 Nutzungen tragen ihre Groesse schon selbst
   (`text-[12px]`), die uebrigen 5 stehen MITTEN IN EINEM SATZ (13/14 px) und muessen mit ihm
   fliessen — ein fixes 12px liesse sie dort wie einen Tippfehler aussehen. Die Groesse bleibt
   Sache der Aufrufstelle; die Klasse vereinheitlicht Farbe, Zustand und Fokus. (Tailwind wird
   ohnehin NACH dieser Datei injiziert, eine Groesse hier verloere gegen jedes `text-[12px]`.)
   ⚠ Kein Fill, kein Rahmen und nur 1px/4px Polsterung — ein Inline-Link darf seinen Satz
   nicht auseinanderschieben. Der Radius traegt deshalb nur den Fokus-Ring.
   ⚠ Die Farbe steht NICHT auf !important: die semantisch eingefaerbten Aufrufstellen
   (caution/fail in einer Alert-Box) setzen sie inline und gewinnen damit weiterhin.
   Token-getrieben, also ohne eigenen Dark-Mode-Block: html.dark remappt --muted und --ea-ink
   bereits (DESIGN.md §8). */
.btn-quiet { display: inline-block; background: transparent; border: 0; border-radius: 8px; padding: 1px 4px; color: var(--muted); font-weight: 500; cursor: pointer; text-decoration: none; transition: color .12s ease; }
.btn-quiet:hover { color: var(--ea-ink); text-decoration: underline; }
.btn-quiet:focus-visible { outline: 2px solid var(--ea-accent); outline-offset: 2px; text-decoration: underline; }
.btn-quiet:disabled { opacity: .4; cursor: default; text-decoration: none; }

.scrollbar-thin::-webkit-scrollbar { height: 8px; width: 8px; }
.scrollbar-thin::-webkit-scrollbar-thumb { background: #cbd5e1; border-radius: 4px; }
.scrollbar-thin::-webkit-scrollbar-track { background: transparent; }

table.matrix th, table.matrix td { border-bottom: 1px solid var(--ea-line); padding: 10px 12px; text-align: left; vertical-align: top; font-size: 13px; }
table.matrix th { background: #f1f5f9; font-weight: 600; color: var(--ea-ink); position: sticky; top: 0; z-index: 1; }
table.matrix tr:hover td { background: #f8fafc; }
table.matrix td.num { text-align: right; font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; font-variant-numeric: tabular-nums; font-feature-settings: 'tnum'; }

.score-bar { height: 6px; background: #e2e8f0; border-radius: 3px; overflow: hidden; }
.score-bar > div { height: 100%; background: linear-gradient(90deg, #14506b 0%, #2a7a99 100%); }

.card { background: white; border: 1px solid var(--ea-line); border-radius: 12px; }
.card-pad { padding: 20px 22px; }

/* KPI-Kachel. B0: das Label faellt auf Satzschreibung (UPPERCASE ist ab jetzt ein
   STRUKTUR-Signal — Rahmen gegen Inhalt —, kein Label-Stil; DESIGN.md 2.4), der Wert
   waechst mit --fs-xl und laeuft in Inter mit Tabellenziffern statt in Mono.
   ⚠ `--muted` statt des fruher hartkodierten #64748b: im Light Mode derselbe Hex, im
   Dark Mode remappt 8 ihn — das Label war dort bisher als einziges nicht mitgewandert. */
.kpi-label { font-size: var(--fs-xs); letter-spacing: 0; color: var(--muted); font-weight: 600; }
.kpi-value { font-size: var(--fs-xl); line-height: 32px; font-weight: 600; color: var(--ea-ink); font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; font-variant-numeric: tabular-nums; }
.kpi-sub { font-size: var(--fs-sm); color: var(--muted); }

/* --- .kpi--hero — die EINE Held-Zahl einer Ansicht (B0, DESIGN.md 2.4) -----------------
   EIN Modifikator, drei Andockpunkte (Registry-Kachel, Mandats-Kachel, Entity-Kachel), damit
   "Held" ueberall dasselbe heisst und nicht je Flaeche neu erfunden wird (P6).
   ⚠ Die RATION ist der Mechanismus, nicht die Groesse: 800 traegt nur, solange es selten ist
   (Von Restorff). Ein zweites 800 auf demselben Schirm fuegt keinen zweiten Helden hinzu, es
   nimmt den ersten weg. Hoechstens EINE Kachel je Ansicht traegt die Klasse; alle uebrigen
   prominenten Zahlen bleiben sichtbar eine Stufe darunter bei 600. Eine Ansicht ohne
   eindeutigen Anker bekommt gar keine — das ist ein gueltiges Ergebnis, keine Luecke.
   ⚠ FLUID, nicht fest 38px — gemessen, nicht geschaetzt. Das Mandats-Band ist ein 5-up-Raster
   und bleibt es bis 1000px hinunter; dort ist die Spalte ~168px breit, und ein fester 38px-Wert
   sprengt sie ab neun Zeichen ("12'450.00" = 189px). `clamp` erreicht die vollen 38px ab
   ~1310px Viewport (also auf jedem Arbeitsplatz-Bildschirm) und faellt darunter stufenlos bis
   auf die KPI-Groesse zurueck — dann traegt das GEWICHT den Helden allein. Ein Breakpoint haette
   an derselben Stelle eine Kante erzeugt, ohne den Fall zu loesen.
   `line-height` ist relativ (1.12), weil die Groesse jetzt variiert; ein fester px-Wert klemmte
   die Zeile beim Herunterskalieren.
   */
.kpi--hero .kpi-value,
.kpi--hero.pv-kpi .val,
.kpi--hero.ep-kpi .val { font-size: clamp(var(--fs-xl), 2.9vw, var(--fs-2xl)); line-height: 1.12; font-weight: 800; letter-spacing: -.02em; }

button.primary { background: var(--ea-ink); color: white; padding: 8px 14px; border-radius: 8px; font-weight: 500; font-size: 13px; }
button.primary:hover { background: var(--ea-ink-2); }
/* H1 — Dark Mode: `--ea-ink` ist die TINTEN-Farbe und kippt in §8 auf HELL. Ohne diesen
   Override rendert der Primary-Knopf dort fast weiss auf weiss (gemessen 1.17:1, unlesbar).
   Gleiche Behandlung und gleiche Werte wie `.pv-btn.primary` / `.mon-btn.primary` weiter unten
   — kein neuer Farbwert. Der Hover muss mit, sonst kippt er über `--ea-ink-2` ebenfalls hell.
   ⚠ GEMESSEN und bewusst in Kauf genommen: `button.primary` hat — anders als die zwei
   Geschwister — in der Basisregel gar keinen Rahmen (Tailwind-Preflight setzt border-width:0),
   der Knopf ist im Dark Mode also 2px breiter und höher als im Light Mode. Konsistenz mit
   `.mon-btn.primary` schlägt hier die 2px; Light Mode bleibt unberührt. */
html.dark button.primary { background: #1d2b3e; border: 1px solid #2d3e52; color: #fff; }
html.dark button.primary:hover { background: #24384e; }
button.ghost { background: transparent; color: var(--ea-ink); padding: 8px 14px; border-radius: 8px; font-weight: 500; font-size: 13px; border: 1px solid var(--ea-line); }
button.ghost:hover { background: #f1f5f9; }

input.field, select.field, textarea.field { width: 100%; padding: 8px 12px; border: 1px solid var(--ea-line); border-radius: 8px; font-size: 13px; background: white; }
input.field:focus, select.field:focus, textarea.field:focus { outline: none; border-color: var(--ea-accent); box-shadow: 0 0 0 3px rgba(20,80,107,0.1); }

.section-h { font-size: 16px; font-weight: 600; color: var(--ea-ink); letter-spacing: -0.01em; }
.section-sub { font-size: 12px; color: #64748b; }

.doc-row { display: grid; grid-template-columns: 50px 1fr 110px 130px 90px; gap: 10px; padding: 8px 0; border-bottom: 1px solid #f1f5f9; font-size: 13px; align-items: center; }
.doc-row:last-child { border-bottom: none; }
.doc-row .code { font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; font-variant-numeric: tabular-nums; color: #64748b; font-size: 12px; }

/* ⚠ TOT (gemessen 05.09., B0): `.funnel-stage` / `.funnel-count` / `.funnel-label` haben im
   ganzen Repo NULL Aufrufstellen — der Funnel ist mit dem Katalog-Pfad weggefallen, seine
   lebende Nachfolgerin ist die Universe-Headline (`kpi('Fund universe', …)`). Der Block bleibt
   deshalb UNVERAENDERT stehen, statt im Typo-Pass mitgestylt zu werden: eine Regel zu pflegen,
   die nichts zeichnet, kostet beim naechsten Mal dieselbe Messung noch einmal. Loeschen ist ein
   eigener Aufraeumschritt, kein Nebenprodukt dieses Passes. */
.funnel-stage { padding: 14px 16px; border-radius: 8px; background: white; border: 1px solid var(--ea-line); }
.funnel-count { font-size: 28px; font-weight: 700; color: var(--ea-ink); line-height: 1; }
.funnel-label { font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; color: #64748b; font-weight: 600; margin-top: 4px; }

.diff-pos { color: var(--ea-green); }
.diff-neg { color: var(--ea-red); }

.tag-stage { font-size: 10px; padding: 2px 6px; border-radius: 4px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; }
.tag-pre { background: #eef2f7; color: #475569; }
.tag-prelim { background: #fef3c7; color: #92400e; }
.tag-final { background: #ddd6fe; color: #5b21b6; }
.tag-ic { background: #dbeafe; color: #1d4ed8; }
.tag-committed { background: #d1fae5; color: #065f46; }
.tag-passed { background: #fee2e2; color: #991b1b; }

.skel { background: linear-gradient(90deg, #f1f5f9 0%, #e2e8f0 50%, #f1f5f9 100%); background-size: 200% 100%; animation: shimmer 1.5s infinite; border-radius: 6px; }
@keyframes shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }

[hidden] { display: none !important; }
/* Always show the vertical scrollbar track, so the layout does not shift sideways by the scrollbar width when moving between a short and a long page. `scrollbar-gutter: stable` would be the lighter tool, but measured in Chrome 152 it did not reserve the gutter on the root; `overflow-y: scroll` does. Overlay-scrollbar platforms (iPad, macOS default) are unaffected. */
html{ overflow-y: scroll; }

/* mobile responsive (v1.9) */
@media (max-width: 767px){
  main .overflow-hidden:has(table){ overflow-x:auto; -webkit-overflow-scrolling:touch; }
  main table{ font-size:11px; }
  main{ padding-bottom:2rem; }
  /* iOS-friendly tap targets (44px guideline) */
  nav button{ min-height:44px; }
}

/* iOS safe-area insets — notch + home indicator, esp. standalone PWA (v3.7) */
@supports (padding: max(0px, env(safe-area-inset-top))){
  .ios-safe-top{ padding-top: max(0.75rem, env(safe-area-inset-top)) !important; }
  .ios-safe-head{ padding-top: max(1.25rem, env(safe-area-inset-top)) !important; }
  .ios-safe-foot{ padding-bottom: max(0.75rem, env(safe-area-inset-bottom)) !important; }
  aside{ padding-left: env(safe-area-inset-left); }
  main{ padding-right: env(safe-area-inset-right); }
}

/* ===== Dark mode (v2.0) ===== */
html.dark { color-scheme: dark; --ea-ink:#e8eef5; --ea-ink-2:#cdd8e4; --ea-paper:#0b1220; --ea-line:#243244; --ea-accent:#3b9ec4; --ea-accent-2:#56b6d6; }
/* Redesign v23 — dark tokens (derived; the board is light only). */
html.dark {
  --ea-text-2:#aab6c4; --ea-subtle:#16212e; --ea-accent-soft:#16324a; --ea-accent-line:#25536a; --ea-accent-ink:#9fd4ea;
  --neu-t:#c7d2de; --neu-s:#1a2533; --neu-b:#2d3e52;
  --btn-primary-bg:#1d2b3e; --btn-primary-line:#2d3e52; --btn-primary-hover:#24384e; --btn-primary-t:#ffffff;
  --shadow-pop: 0 12px 32px rgba(0,0,0,.5);
}
html.dark body { background:#0b1220; color:#e8eef5; }
/* surfaces */
html.dark .bg-white{ background-color:#111a27 !important; }
html.dark .bg-slate-50, html.dark .bg-slate-50\/50{ background-color:#0e1726 !important; }
html.dark .bg-slate-100{ background-color:#1a2533 !important; }
/* text */
html.dark .text-slate-900{ color:#e8eef5 !important; }
html.dark .text-slate-800{ color:#dde6f0 !important; }
html.dark .text-slate-700{ color:#c7d2de !important; }
html.dark .text-slate-600{ color:#aab6c4 !important; }
html.dark .text-slate-500{ color:#8b98a8 !important; }
html.dark .text-slate-400{ color:#717f8f !important; }
/* borders */
html.dark .border-slate-200{ border-color:#243244 !important; }
html.dark .border-slate-300{ border-color:#2d3e52 !important; }
html.dark .border-slate-100{ border-color:#1c2937 !important; }
html.dark .divide-slate-100 > :not([hidden]) ~ :not([hidden]){ border-color:#1c2937 !important; }
html.dark .divide-slate-200 > :not([hidden]) ~ :not([hidden]){ border-color:#243244 !important; }
/* hovers */
html.dark .hover\:bg-slate-50:hover{ background-color:#16212e !important; }
html.dark .hover\:bg-slate-100:hover{ background-color:#1f2c3b !important; }
html.dark .hover\:bg-white:hover{ background-color:#16212e !important; }
html.dark .hover\:bg-slate-700:hover{ background-color:#27384e !important; }
/* primary (slate-900) buttons: keep distinct on dark */
html.dark .bg-slate-900{ background-color:#1d2b3e !important; }
/* pastel info panels + their text */
html.dark .bg-emerald-50{ background-color:#10231b !important; } html.dark .text-emerald-800,html.dark .text-emerald-700{ color:#6ee7b7 !important; }
html.dark .bg-rose-50{ background-color:#241315 !important; } html.dark .text-rose-800,html.dark .text-rose-700{ color:#fca5a5 !important; }
html.dark .bg-amber-50{ background-color:#241d0e !important; } html.dark .text-amber-900,html.dark .text-amber-800{ color:#fcd34d !important; }
html.dark .bg-blue-50{ background-color:#0e1d30 !important; } html.dark .text-blue-800,html.dark .text-blue-700{ color:#93c5fd !important; }
html.dark .bg-violet-50{ background-color:#1b1533 !important; } html.dark .text-violet-900,html.dark .text-violet-800,html.dark .text-violet-700{ color:#c4b5fd !important; }
html.dark .border-violet-200{ border-color:#3b2e63 !important; }
html.dark .text-slate-300{ color:#5a6675 !important; }
/* custom components */
html.dark .card{ background:#111a27; border-color:#243244; }
html.dark table.matrix th{ background:#16212e; color:#e8eef5; }
html.dark table.matrix th, html.dark table.matrix td{ border-color:#243244; }
html.dark table.matrix tr:hover td{ background:#16212e; }
html.dark input.field, html.dark select.field, html.dark textarea.field{ background:#0e1726; color:#e8eef5; border-color:#243244; }
html.dark .chip{ background:#1a2533; color:#c7d2de; border-color:#2d3e52; }
html.dark .funnel-stage{ background:#111a27; border-color:#243244; }
html.dark .skel{ background:linear-gradient(90deg,#16212e 0%,#1f2c3b 50%,#16212e 100%); }
html.dark .score-bar{ background:#243244; }
/* charts on a light tile so axis labels stay readable */
html.dark canvas{ background:#f7f8fa; border-radius:8px; }
/* comparison-matrix sticky row-label column: override inline light bg in dark mode */
html.dark table.matrix td[style*="sticky"],
html.dark table.matrix th[style*="sticky"]{ background:#16212e !important; color:#e8eef5 !important; }

/* ============================================================
   Entity page (fund) — EA-DEV-023 Teil 2
   ============================================================
   Zwei Blöcke:
   1) SEMANTISCHE ROLLEN-TOKENS (DESIGN.md §2.2) — global, weil sie das Vokabular
      des ganzen Produkts sind, nicht Deko dieser einen Seite. Die Hex-Werte sind
      exakt die Tailwind-Ramps aus §2.2 (emerald/amber/rose/sky/violet-700/50/200),
      hier nur als Custom Properties kodifiziert, damit Dark Mode ein Token-Remap
      bleibt (§8) und nicht die nächste `html.dark .tw-class{…!important}`-Zeile wird.
   2) KOMPONENTEN der Entity-Page — alle unter `.ep` gescoped. Die Seite ist rein
      additiv (EA-DEV-023 Teil 2): kein bestehender Screen darf sich mitverändern,
      also darf auch keine Regel hier ausserhalb von `.ep` greifen. Ausnahmen sind
      nur `.prov` / `.der` / `.miss` / `.r-*` — die sind bewusst wiederverwendbar
      (Provenienz-Layer §5) und tragen keinen Seiten-Kontext. */
:root{
  /* Typo-Skala — B0 (05.09.). Bewusst NICHT gleichmaessig gewachsen: die dichte
     Daten-Ebene (xs/sm) steht still, alles ab md waechst, die Signal-Ebene am meisten.
     Repariert wurde nicht "zu klein", sondern "zu wenig Spreizung" — 11 12 13 16 20 liess
     einen KPI-Wert keine zwei Stufen von einer Fussnote entfernt stehen. Siehe DESIGN.md
     2.4; die Zeilenhoehen stehen an den Komponenten, nicht hier. */
  --fs-xs:11px; --fs-sm:12px; --fs-md:14px; --fs-lg:18px; --fs-xl:26px; --fs-2xl:38px; --fs-3xl:46px;
  --muted:#64748b; --muted-2:#94a3b8; --surface:#ffffff;
  --ok-t:#047857;   --ok-s:#ecfdf5;   --ok-b:#a7f3d0;
  --caut-t:#92400e; --caut-s:#fffbeb; --caut-b:#fde68a;
  --fail-t:#be123c; --fail-s:#fff1f2; --fail-b:#fecdd3;
  --info-t:#0369a1; --info-s:#f0f9ff; --info-b:#bae6fd;
  --na-t:#6d28d9;   --na-s:#f5f3ff;   --na-b:#ddd6fe;
}
html.dark{
  --muted:#8b98a8; --muted-2:#5a6675; --surface:#111a27;
  --ok-t:#6ee7b7;   --ok-s:#10231b;   --ok-b:#1e3a2c;
  --caut-t:#fcd34d; --caut-s:#241d0e; --caut-b:#3d3115;
  --fail-t:#fca5a5; --fail-s:#241315; --fail-b:#3d1f22;
  --info-t:#7dd3fc; --info-s:#0e1d30; --info-b:#17324a;
  --na-t:#c4b5fd;   --na-s:#1b1533;   --na-b:#3b2e63;
}

/* Provenienz-Marker (§5). `rep` neutral, `derived` info, `assumed` caution.
   .der ist die TYPOGRAFIE des hochgerechneten Werts selbst (kursiv + info) und
   gehört an die Zahl, nicht an den Chip. */
/* font-family explizit: der Chip steht oft INNERHALB einer .mono-Zelle, ist aber Prosa —
   .mono gilt nur für Zahlen und Code-Identifier, nie für Labels. */
.prov{ font-family:'Inter',-apple-system,BlinkMacSystemFont,sans-serif; font-size:var(--fs-xs); line-height:15px; font-weight:600; padding:1px 5px; border-radius:4px; border:1px solid; white-space:nowrap; }
/* Redesign v23: the board sets derived figures in italic INK; blue stays on the `derived` chip
   (`.prov.r-info`) only. --ea-ink remaps in dark mode. */
.der{ font-style:italic; color:var(--ea-ink); }
/* F-98 — der Grund unter einem blockierten IRR („—" / „n.m."). Er steht INNERHALB der
   .mono-Zelle der Per-Position-Tabelle, ist aber Prosa: dieselbe Begründung wie bei .prov
   darüber. Kein neuer Token, keine neue Farbe — den Ton setzt die Aufrufstelle je Klasse
   (amber = Daten fehlen · slate = strukturell), weil er die AUSSAGE trägt, nicht die Form. */
.irr-why{ font-family:'Inter',-apple-system,BlinkMacSystemFont,sans-serif; font-feature-settings:normal; }
.miss{ color:var(--muted-2); }
.r-ok{ color:var(--ok-t); background:var(--ok-s); border-color:var(--ok-b); }
.r-caut{ color:var(--caut-t); background:var(--caut-s); border-color:var(--caut-b); }
.r-fail{ color:var(--fail-t); background:var(--fail-s); border-color:var(--fail-b); }
.r-info{ color:var(--info-t); background:var(--info-s); border-color:var(--info-b); }
.r-na{ color:var(--na-t); background:var(--na-s); border-color:var(--na-b); }
.r-neutral{ color:var(--muted); background:var(--ea-paper); border-color:var(--ea-line); }

/* --- Seiten-Chrome --- */
.ep{ padding:20px clamp(20px,3vw,48px); max-width:1480px; margin:0 auto; }
.ep-top{ display:flex; align-items:center; gap:12px; flex-wrap:wrap; margin-bottom:18px; }
.ep-crumb{ font-size:var(--fs-sm); color:var(--muted); }
.ep-crumb b{ color:var(--ea-ink); font-weight:600; }
.ep-badge{ font-size:var(--fs-xs); font-weight:600; color:var(--ok-t); background:var(--ok-s); border:1px solid var(--ok-b); padding:3px 9px; border-radius:6px; }
.ep-badge--caut{ color:var(--caut-t); background:var(--caut-s); border-color:var(--caut-b); }

/* --- Kopf --- */
.ep-head{ display:flex; gap:16px; align-items:flex-start; margin-bottom:18px; }
.ep-crest{ width:52px; height:52px; border-radius:12px; background:linear-gradient(135deg,var(--ea-accent),var(--ea-accent-2)); color:#fff; display:grid; place-items:center; font-weight:700; font-size:var(--fs-lg); flex:none; }
.ep h1{ font-size:var(--fs-xl); line-height:32px; margin:0 0 4px; font-weight:600; letter-spacing:-.01em; color:var(--ea-ink); }
.ep-sub{ font-size:var(--fs-sm); color:var(--muted); }
.ep-sub a, .ep .link{ color:var(--ea-accent); text-decoration:none; font-weight:600; cursor:pointer; }
.ep-sub a:hover, .ep .link:hover{ text-decoration:underline; }
.ep-chips{ display:flex; gap:6px; flex-wrap:wrap; margin-top:8px; align-items:center; }
.ep .chip.stage{ background:rgba(20,80,107,.08); border-color:transparent; color:var(--ea-accent); }
html.dark .ep .chip.stage{ background:rgba(86,182,214,.12); color:var(--ea-accent-2); }
.ep .eyebrow{ font-size:var(--fs-xs); line-height:15px; letter-spacing:0; font-weight:600; color:var(--muted); }
.ep .meta{ font-size:var(--fs-xs); line-height:15px; color:var(--muted); }

/* --- Ebenen-Band + KPI-Reihen ---
   5-up ist die Ausnahme aus DESIGN.md §6: die fünf Kennzahlen sind ein FESTES
   Berichts-Set (Grösse · NAV · TVPI · DPI · IRR) und die vertikale Deckung
   Fonds ↔ Beteiligung ist die Aussage der Seite. Umbruch auf 2-up < 1000px. */
.ep-band{ display:flex; align-items:center; gap:10px; margin:0 0 10px; }
.ep-band .t{ font-size:var(--fs-xs); font-weight:600; letter-spacing:0; color:var(--muted); }
.ep-band .t.ours{ color:var(--ea-accent-2); }
.ep-band .rule{ height:1px; background:var(--ea-line); flex:1; }
.ep-band .src{ font-size:var(--fs-xs); color:var(--muted-2); }
.ep-kpis{ display:grid; grid-template-columns:repeat(5,minmax(0,1fr)); gap:12px; margin-bottom:20px; }
.ep-kpis--ours{ margin-bottom:14px; }
/* F-100: sechs Kacheln im OUR-Band (DPI kam dazu, damit die Praezedenz je Kachel pruefbar ist).
   Eigener Modifier statt auto-fit auf `.ep-kpis`, damit das Fonds-Band unveraendert fuenfspaltig
   bleibt; die Zwei-Spalten-Regel unter 900px greift ueber `.ep-kpis` fuer beide. */
.ep-kpis--6{ grid-template-columns:repeat(6,minmax(0,1fr)); }
/* Schmalere Kacheln heisst: ein langes Label plus Provenienz-Chip bricht auf zwei Zeilen
   („Participation quote" + `assumed`). Die WERTE duerfen davon nicht wandern — eine Reihe
   KPIs, deren Zahlen auf verschiedenen Hoehen sitzen, liest sich als Unfall. Deshalb Flex mit
   `margin-top:auto`: das Label darf wachsen, der Wert bleibt an der Unterkante buendig.
   Kein magischer min-height-Wert, der beim naechsten Label wieder nicht passt. */
.ep-kpis--6 .ep-kpi{ display:flex; flex-direction:column; }
.ep-kpis--6 .ep-kpi .val{ margin-top:auto; }
.ep-kpi{ padding:12px 14px; }
.ep-kpi .lab{ margin-bottom:6px; display:flex; gap:6px; align-items:center; flex-wrap:wrap; }
/* B0 — der KPI-Wert traegt in app.js die Klasse `mono`; diese Regel ist mit (0,2,0)
   spezifischer und holt ihn nach Inter zurueck. Er steht FUER SICH und wird nicht als
   Spalte hinuntergescannt, gehoert also auf die Inter-Seite der Trennlinie (DESIGN.md 2.4).
   Die dichten Tabellen darunter bleiben unangetastet in Mono. */
.ep-kpi .val{ font-size:var(--fs-xl); line-height:32px; font-weight:600; color:var(--ea-ink); font-family:'Inter',-apple-system,BlinkMacSystemFont,sans-serif; font-variant-numeric:tabular-nums; font-feature-settings:'tnum'; }
.ep .unit{ color:var(--muted-2); font-size:var(--fs-xs); }
.ep-kpi.ours{ border-left:3px solid var(--ea-accent-2); }
.ep-kpi.ours .eyebrow{ color:var(--ea-accent-2); }

/* --- Zwei-Spalten-Block --- */
.ep-two{ display:grid; grid-template-columns:1.4fr 1fr; gap:16px; margin-top:4px; align-items:start; }
.ep-sec-h{ font-size:var(--fs-md); font-weight:600; color:var(--ea-ink); padding:11px 14px; border-bottom:1px solid var(--ea-line); display:flex; align-items:center; justify-content:space-between; gap:8px; }
.ep table.matrix{ width:100%; border-collapse:collapse; }
.ep table.matrix th{ font-size:var(--fs-xs); text-transform:uppercase; letter-spacing:.08em; color:var(--muted); position:static; }
/* Header-Ausrichtung folgt der Spalte (DESIGN.md §4.5) — td.num ist rechts, th.num auch. */
.ep table.matrix th.num{ text-align:right; }
.ep table.matrix th, .ep table.matrix td{ padding:8px 14px; font-size:var(--fs-sm); vertical-align:middle; }
.ep table.matrix tfoot td{ font-weight:600; border-bottom:0; }
.ep-note{ font-size:var(--fs-xs); line-height:16px; color:var(--muted); padding:10px 14px; border-top:1px solid var(--ea-line); background:var(--ea-paper); }
html.dark .ep-note{ background:#0e1726; }

/* --- Konsistenz-Panel --- */
.ep-pr{ padding:14px; }
.ep-pr .row{ display:flex; justify-content:space-between; align-items:baseline; gap:12px; padding:7px 0; border-bottom:1px dashed var(--ea-line); }
.ep-pr .row:last-child{ border-bottom:0; }
.ep-pr .k{ color:var(--muted); font-size:var(--fs-sm); }
.ep-pr .v{ font-weight:600; font-size:var(--fs-sm); color:var(--ea-ink); text-align:right; }
/* EA-DEV-025 — zweiter Rechenblock in derselben Karte (Kapitalseite / Ausschüttungsseite
   im ILPA-Rollforward). Durchgezogene Linie statt gestrichelt: sie trennt zwei RECHNUNGEN,
   nicht zwei Zeilen derselben. Keine neuen Tokens (DESIGN.md §1). */
.ep-pr + .ep-pr{ border-top:1px solid var(--ea-line); }

/* --- Legende --- */
.ep-legend{ display:flex; gap:14px; flex-wrap:wrap; font-size:var(--fs-xs); color:var(--muted); margin-top:16px; padding:10px 14px; border:1px dashed var(--ea-line); border-radius:12px; }
.ep-legend b{ color:var(--ea-ink); }

/* --- F-46b: das Portfolio-/Hebel-Readout unter einem Band ---------------------------------
   Dieselben Werte wie `.ep-legend` (dasselbe --fs-xs, dasselbe --muted, dieselbe gestrichelte
   --ea-line, derselbe 12px-Radius, dasselbe 10/14-Padding) — KEIN neuer Token. Der einzige
   Unterschied ist die Flussrichtung: die Legende ist eine Chip-REIHE (flex), das Readout ist
   eine Aussage mit einem Satz darunter (block). Es sitzt eng unter den Kacheln, zu denen es
   gehört, und schiebt sich deshalb in deren 20px-Untermarge hinein. */
.ep-lev{ display:block; font-size:var(--fs-xs); line-height:17px; color:var(--muted); margin:-12px 0 20px; padding:10px 14px; border:1px dashed var(--ea-line); border-radius:12px; }
.ep-lev b{ color:var(--ea-ink); }
.ep-lev .lab{ color:var(--muted-2); letter-spacing:0; }
.ep-lev .why{ margin-top:4px; }

/* F-100: sechs Kacheln brauchen frueher Luft als fuenf — eine eigene Zwischenstufe, damit
   „Participation quote" nicht auf zwei Zeilen bricht, waehrend das Fondsband daneben noch
   sitzt. Darunter greift die bestehende Zwei-Spalten-Regel fuer beide Baender. */
@media(max-width:1240px){
  .ep-kpis--6{ grid-template-columns:repeat(3,minmax(0,1fr)); }
}

@media(max-width:1000px){
  .ep-kpis{ grid-template-columns:repeat(2,minmax(0,1fr)); }
  .ep-two{ grid-template-columns:1fr; }
}

/* ============================================================
   Portfolio-Ansicht (Mandat · Positionen) — EA-DEV-024
   ============================================================
   Der gelockte Kit aus wireframe_portfolio_2.html, 1:1 übernommen, aber unter
   `.pv` gescoped — exakt aus demselben Grund wie `.ep` oben: der Umbau ist
   additiv, kein anderer Screen darf sich mitverändern. Die Rollen-Tokens
   (--ok-t …), `.prov` / `.der` / `.miss` / `.r-*` stehen bereits global oben
   und werden hier NICHT nochmal definiert — sie sind das gemeinsame
   Provenienz-Vokabular von Entity-Page und Portfolio (DESIGN.md §5).
   Diese Seite ist die Zoomstufe zwischen Mandats-Liste und Entity-Page und
   trägt deshalb bewusst dieselbe Typo- und Tabellen-Sprache wie `.ep`. */
.pv{ padding:4px 0 0; }
.pv-head{ display:flex; align-items:center; justify-content:space-between; margin-bottom:16px; gap:12px; flex-wrap:wrap; }
.pv-headL{ display:flex; align-items:center; gap:16px; flex-wrap:wrap; }
.pv h2{ font-size:var(--fs-xl); line-height:32px; margin:0 0 3px; font-weight:600; letter-spacing:-.01em; color:var(--ea-ink); }
.pv .meta{ font-size:var(--fs-xs); line-height:15px; color:var(--muted); font-weight:400; }
.pv .meta b{ color:var(--ea-ink); font-weight:600; }
.pv .eyebrow{ font-size:var(--fs-xs); line-height:15px; letter-spacing:0; font-weight:600; color:var(--muted); }
.pv-pins{ display:flex; gap:6px; align-items:center; flex-wrap:wrap; }
.pv-pin{ font-size:var(--fs-xs); color:var(--ea-accent); background:rgba(20,80,107,.08); padding:4px 9px; border-radius:6px; font-weight:600; display:inline-flex; align-items:center; gap:6px; }
.pv-pin.fx{ color:var(--muted); background:var(--ea-paper); border:1px solid var(--ea-line); }
html.dark .pv-pin{ background:rgba(86,182,214,.12); }
/* Datums-Input im Pin: erbt Pin-Typo, kein eigener Rahmen — der Pin IST das Control. */
.pv-pin input[type=date]{ font-family:inherit; font-size:var(--fs-xs); font-weight:600; color:inherit; background:transparent; border:0; padding:0; cursor:pointer; }

/* Controls — `button,input,select` erben die Schrift nicht automatisch (Kit-Regel §0). */
.pv button, .pv input, .pv select{ font-family:inherit; }
.pv-seg{ display:flex; border:1px solid var(--ea-line); border-radius:8px; overflow:hidden; }
.pv-seg button{ border:0; background:transparent; color:var(--muted); padding:7px 14px; font-size:var(--fs-sm); font-weight:500; cursor:pointer; }
.pv-seg button.on{ background:var(--ea-ink); color:#fff; }
html.dark .pv-seg button.on{ background:#1d2b3e; }
.pv-btn{ border:1px solid var(--ea-line); background:var(--surface); color:var(--ea-ink); border-radius:8px; padding:7px 12px; font-size:var(--fs-sm); font-weight:500; cursor:pointer; }
.pv-btn:hover{ background:var(--ea-paper); }
.pv-btn.primary{ background:var(--ea-ink); color:#fff; border-color:var(--ea-ink); }
html.dark .pv-btn.primary{ background:#1d2b3e; border-color:#2d3e52; }
.pv-toolbar{ display:flex; align-items:center; gap:8px; margin-bottom:8px; flex-wrap:wrap; }
.pv-toolbar .spacer{ flex:1; }
.pv-cap{ font-size:var(--fs-xs); line-height:16px; color:var(--muted); margin:0 2px 8px; }
.pv-cap b{ color:var(--ea-ink); font-weight:600; }

/* KPI-Band — 5-up wie die Entity-Page (DESIGN.md §6-Ausnahme: festes Berichts-Set). */
.pv-kpis{ display:grid; grid-template-columns:repeat(5,minmax(0,1fr)); gap:12px; margin-bottom:16px; }
.pv-kpi{ padding:12px 14px; }
.pv-kpi .lab{ margin-bottom:6px; display:flex; gap:6px; align-items:center; flex-wrap:wrap; }
/* B0 — der KPI-Wert traegt in app.js die Klasse `mono`; diese Regel ist mit (0,2,0)
   spezifischer und holt ihn nach Inter zurueck. Er steht FUER SICH und wird nicht als
   Spalte hinuntergescannt, gehoert also auf die Inter-Seite der Trennlinie (DESIGN.md 2.4).
   Die dichten Tabellen darunter bleiben unangetastet in Mono. */
.pv-kpi .val{ font-size:var(--fs-xl); line-height:32px; font-weight:600; color:var(--ea-ink); font-family:'Inter',-apple-system,BlinkMacSystemFont,sans-serif; font-variant-numeric:tabular-nums; font-feature-settings:'tnum'; }
.pv .unit{ color:var(--muted-2); font-size:var(--fs-xs); }

/* Tabelle. `.twrap` trägt Rahmen + Radius, damit die sticky-Kopfzeile nicht
   über die abgerundete Ecke läuft. */
.pv-twrap{ border:1px solid var(--ea-line); border-radius:12px; overflow:hidden; background:var(--surface); }
.pv-scroll{ overflow-x:auto; }
.pv table.matrix{ width:100%; border-collapse:collapse; background:transparent; }
.pv table.matrix th{ background:var(--ea-paper); font-size:var(--fs-xs); line-height:15px; text-transform:uppercase; letter-spacing:.08em; font-weight:600; color:var(--muted); white-space:nowrap; position:static; padding:7px 11px; text-align:left; vertical-align:middle; }
html.dark .pv table.matrix th{ background:#16212e; color:var(--muted); }
.pv table.matrix td{ font-size:var(--fs-sm); line-height:17px; padding:7px 11px; text-align:left; vertical-align:middle; border-bottom:1px solid var(--ea-line); }
.pv table.matrix td.n, .pv table.matrix th.n{ text-align:right; white-space:nowrap; }
.pv table.matrix td.c, .pv table.matrix th.c{ text-align:center; }
.pv table.matrix tbody tr:hover td{ background:rgba(20,80,107,.03); }
html.dark .pv table.matrix tbody tr:hover td{ background:#16212e; }
.pv table.matrix tr.pv-row{ cursor:pointer; }
.pv table.matrix tfoot td{ font-weight:600; border-top:1px solid var(--ea-line); border-bottom:0; background:var(--ea-paper); }
html.dark .pv table.matrix tfoot td{ background:#16212e; }
/* Kompakte Dichte — nur Polsterung, NIE die Schriftgrösse (die ist §2.4-Skala). */
.pv.dense table.matrix th, .pv.dense table.matrix td{ padding:4px 11px; }
.pv .fund{ font-weight:600; color:var(--ea-accent); text-decoration:none; cursor:pointer; font-size:var(--fs-md); }
.pv .fund:hover{ text-decoration:underline; }
/* Nicht am Hub verknüpft: kein Link, aber auch kein toter Blaustich. */
.pv .fund-plain{ font-weight:600; color:var(--ea-ink); font-size:var(--fs-md); }
.pv .ccy{ font-size:var(--fs-xs); font-weight:600; color:var(--muted); }
.pv .grp td{ background:var(--ea-paper); font-size:var(--fs-xs); line-height:15px; letter-spacing:0; font-weight:600; color:var(--muted); }
html.dark .pv .grp td{ background:#0e1726; }
.pv .nm{ color:var(--muted-2); }
.pv-foot{ font-size:var(--fs-xs); line-height:16px; color:var(--muted); margin-top:12px; padding:10px 14px; border:1px dashed var(--ea-line); border-radius:12px; }
.pv-foot b{ color:var(--ea-ink); font-weight:600; }
.pv-act{ display:inline-flex; gap:4px; }
.pv-act button{ font-size:var(--fs-xs); padding:3px 7px; border:1px solid var(--ea-line); background:var(--surface); color:var(--ea-ink); border-radius:6px; cursor:pointer; }
.pv-act button:hover{ background:var(--ea-paper); }
.pv-act button.danger{ color:var(--fail-t); border-color:var(--fail-b); }

@media(max-width:1000px){ .pv-kpis{ grid-template-columns:repeat(2,minmax(0,1fr)); } }
@media(max-width:600px){ .pv-kpis{ grid-template-columns:1fr; } }

/* ============================================================
   Monitoring-Erfassungsfenster (ILPA-Kapitalkonto) — EA-025
   ============================================================
   Eingabe-Modal, kein Drawer: DESIGN.md §4.6 trennt die beiden ausdrücklich —
   Drawer ZEIGEN eine Herleitung, Modale ERFASSEN Daten. Hier wird erfasst.
   Wie `.ep` und `.pv` gescoped und ohne EINEN neuen Token: Farben, Radien,
   Schriftgrössen und Abstände kommen alle aus §2. Neu ist nur die Anordnung —
   links das Statement wie es abgetippt wird, rechts dieselben Zahlen als
   Rechnung. Die zweispaltige Form IST die Aussage der Fläche: was eingegeben
   wird und was daraus folgt, stehen nebeneinander statt nacheinander.
   `.eyebrow` / `.meta` / `.unit` sind in `.ep`/`.pv` gescoped und werden hier
   für denselben Zweck wiederholt — nicht neu erfunden, nur erreichbar gemacht. */
.mon{ background:var(--surface); width:100%; max-width:1160px; border:1px solid var(--ea-line); border-radius:12px; box-shadow:0 20px 25px -5px rgba(0,0,0,.1),0 8px 10px -6px rgba(0,0,0,.1); margin:24px 0; display:flex; flex-direction:column; max-height:calc(100vh - 48px); }
html.dark .mon{ background:#111a27; }
.mon button, .mon input, .mon select{ font-family:inherit; }
.mon .eyebrow{ font-size:var(--fs-xs); line-height:15px; letter-spacing:0; font-weight:600; color:var(--muted); }
.mon .meta{ font-size:var(--fs-xs); line-height:15px; color:var(--muted); font-weight:400; }
.mon .unit{ color:var(--muted-2); font-size:var(--fs-xs); }

.mon-head{ display:flex; align-items:flex-start; justify-content:space-between; gap:12px; padding:14px 18px; border-bottom:1px solid var(--ea-line); }
.mon-title{ font-size:var(--fs-lg); line-height:24px; font-weight:600; color:var(--ea-ink); margin:2px 0 3px; letter-spacing:-.01em; }
.mon-x{ background:transparent; border:0; color:var(--muted-2); font-size:22px; line-height:1; cursor:pointer; padding:0 4px; }
.mon-x:hover{ color:var(--ea-ink); }
.mon-scroll{ overflow-y:auto; padding:14px 18px; flex:1; }
.mon-foot{ display:flex; align-items:center; gap:8px; padding:11px 18px; border-top:1px solid var(--ea-line); background:var(--ea-paper); border-radius:0 0 12px 12px; flex-wrap:wrap; }
html.dark .mon-foot{ background:#0e1726; }

/* Perioden-Leiste. Neueste links — das ist die, an die „New period" anhängt.
   Der Punkt markiert eine Periode, die NICHT hier erfasst wurde (Batch/Import):
   dieselbe Zeile, andere Herkunft, und das darf man sehen. */
.mon-strip{ display:flex; gap:6px; flex-wrap:wrap; align-items:center; margin-bottom:12px; }
.mon-chip{ display:inline-flex; align-items:center; gap:5px; font-size:var(--fs-xs); font-weight:600; color:var(--muted); background:var(--surface); border:1px solid var(--ea-line); border-radius:6px; padding:4px 9px; cursor:pointer; }
.mon-chip:hover{ background:var(--ea-paper); }
.mon-chip.on{ background:var(--ea-ink); border-color:var(--ea-ink); color:#fff; }
html.dark .mon-chip.on{ background:#1d2b3e; border-color:#2d3e52; }
.mon-chip.new{ color:var(--ea-accent); border-style:dashed; }
.mon-chip.new.on{ color:#fff; border-style:solid; }
.mon-dot{ width:5px; height:5px; border-radius:50%; background:var(--caut-t); display:inline-block; }

.mon-two{ display:grid; grid-template-columns:1.15fr 1fr; gap:14px; align-items:start; }
.mon-body{ padding:14px; }
.mon-sec{ font-size:var(--fs-xs); line-height:15px; text-transform:uppercase; letter-spacing:.08em; font-weight:600; color:var(--muted); padding:14px 14px 6px; border-top:1px solid var(--ea-line); }
.mon-body > .mon-sec:first-child{ border-top:0; padding-top:0; }
.mon-body .mon-sec{ padding-left:0; padding-right:0; }
.mon-grid{ display:grid; grid-template-columns:1fr 1fr; gap:10px 12px; padding:0 0 4px; }
.mon-body > .ep-note, .mon-two .ep-note{ border-radius:8px; border:1px dashed var(--ea-line); border-top:1px dashed var(--ea-line); margin-top:8px; }
.mon-f{ display:flex; flex-direction:column; gap:4px; }
.mon-f .field{ margin-top:2px; }
.mon-f input.mono{ text-align:right; }
.mon-f .meta{ line-height:14px; }

/* F-22 — das Feld, dessen Inhalt keine Zahl ist. Rein token-getrieben (`--fail-*`), damit der
   Dark Mode ohne eigenen Block mitkommt (DESIGN.md §8).
   ⚠ Die Markierung bleibt AUCH IM FOKUS stehen: sie steht später im Stylesheet als
   `input.field:focus` und hat dieselbe Spezifität, gewinnt also. Das ist Absicht — die
   Rückmeldung kommt beim Tippen, und ein Feld, das seine Warnung genau dann ablegt, wenn man
   es korrigiert, ist keine Rückmeldung. Der Fokus bleibt trotzdem sichtbar: der Ring wird nur
   umgefärbt, nicht weggenommen.
   Global gesetzt, nicht auf `.mon` beschränkt — die Klasse ist eine Aussage über ein
   Eingabefeld, nicht über dieses eine Fenster.
   ⚠ Das führende `html` ist NICHT Kosmetik: `html.dark input.field` (Z. 178) trägt (0,2,2)
   und schlüge ein blosses `input.field.bad` (0,2,1) — die Markierung war im Dark Mode
   gemessen unsichtbar. Mit `html` davor steht es gleichauf und gewinnt über die Position.
   Ein eigener `html.dark`-Block wäre die falsche Antwort: die `--fail-*`-Tokens remappen
   bereits, es fehlte nur die Spezifität (DESIGN.md §8). */
html input.field.bad, html select.field.bad, html textarea.field.bad{
  border-color:var(--fail-t); background:var(--fail-s); color:var(--fail-t);
}
input.field.bad:focus, select.field.bad:focus, textarea.field.bad:focus{
  outline:none; border-color:var(--fail-t); box-shadow:0 0 0 3px var(--fail-b);
}

/* Rechnungs-Zeilen: dieselben `.ep-pr`-Regeln, nur zwei Rollen ergänzt —
   `.sub` für die eingerückte Davon-Zeile, `.tot` für das Ergebnis. */
.mon .ep-pr .row.sub .k, .mon .ep-pr .row.sub .v{ color:var(--muted-2); font-weight:500; }
.mon .ep-pr .row.tot{ border-bottom:0; border-top:1px solid var(--ea-line); margin-top:3px; padding-top:9px; }
.mon .ep-pr .row.tot .k{ color:var(--ea-ink); font-weight:600; }
/* Gate-Zeile: drei Grössen (abgeleitet · gemeldet · Δ) passen nicht neben ein Label.
   Gestapelt statt gequetscht — Label oben, Rechnung rechtsbündig darunter. */
.mon .ep-pr .row.gate{ display:block; }
.mon .ep-pr .row.gate .k{ display:block; margin-bottom:3px; }
.mon .ep-pr .row.gate .v{ display:block; text-align:right; line-height:20px; }

.mon-alert{ font-size:var(--fs-sm); line-height:17px; padding:8px 12px; border-radius:8px; border:1px solid; margin-bottom:10px; }
.mon-alert.fail{ color:var(--fail-t); background:var(--fail-s); border-color:var(--fail-b); }
.mon-alert.warn{ color:var(--caut-t); background:var(--caut-s); border-color:var(--caut-b); }
/* F-39: dritte Tonlage neben fail/warn — eine bestätigende Aussage („nichts wurde addiert",
   „so viele Zeilen sind umgezogen"). Keine neue Farbe: dieselben --ok-* Tokens, die die
   Badges schon führen (DESIGN.md §Tokens), nur an dieser Komponente noch nicht verdrahtet. */
.mon-alert.ok{ color:var(--ok-t); background:var(--ok-s); border-color:var(--ok-b); }
/* Vierte Tonlage: ein ZEIGER, kein Urteil („N Fonds liegen im Triage-Stapel"). Weder Fehler
   noch Warnung noch Bestätigung — dieselben --info-* Tokens, die `.badge--info` und der
   Kalender-Balken schon führen; keine neue Farbe. */
.mon-alert.info{ color:var(--info-t); background:var(--info-s); border-color:var(--info-b); }

.mon-btn{ border:1px solid var(--ea-line); background:var(--surface); color:var(--ea-ink); border-radius:8px; padding:7px 12px; font-size:var(--fs-sm); font-weight:500; cursor:pointer; }
.mon-btn:hover{ background:var(--ea-paper); }
.mon-btn.primary{ background:var(--ea-ink); color:#fff; border-color:var(--ea-ink); }
html.dark .mon-btn.primary{ background:#1d2b3e; border-color:#2d3e52; }
/* Bestätigte Zerstörung = gefüllt rose-600 mit weisser Schrift, exakt wie die
   bestehenden Confirm-Buttons der App. NICHT var(--fail-t): das ist im Dark Mode
   ein helles Rosa und trüge weisse Schrift unlesbar. */
.mon-btn.danger{ background:#e11d48; color:#fff; border-color:#e11d48; }
.mon-btn.danger:hover{ background:#be123c; border-color:#be123c; }
.mon-btn.danger-out{ color:var(--fail-t); border-color:var(--fail-b); }
.mon-btn:disabled{ opacity:.4; cursor:default; }
.mon-del{ display:inline-flex; align-items:center; gap:8px; flex-wrap:wrap; }

/* Mehrfach-Auswahl im Stammdaten-Formular (050). Kein neues UI-Vokabular: die gesetzten
   Werte sind `.chip` — der neutrale Deskriptor aus §4.4, den die App für Sektor/Region/
   Strategie ohnehin führt — und darunter steht ein gewöhnliches `.field`-Select zum
   Hinzufügen. Neu sind nur zwei Modifier: `.chip-x` (entfernen) und `.chip.off` für einen
   Wert, den die aktuelle Anlageklasse nicht kennt. `.off` ist gestrichelt statt farbig:
   off-list ist KEIN Fehler, nur eine Herkunft. */
.fu-multi{ display:flex; flex-direction:column; gap:5px; }
.fu-chips{ display:flex; flex-wrap:wrap; gap:5px; }
.fu-chips .chip{ gap:5px; padding-right:5px; }
.chip-x{ border:0; background:transparent; color:var(--muted-2); font-size:14px; line-height:1;
  cursor:pointer; padding:0 2px; }
.chip-x:hover{ color:var(--fail-t); }
.chip.off{ border-style:dashed; color:var(--muted); }
/* `html.dark .chip` ist spezifischer als `.chip.off` und würde die gedämpfte Schrift
   sonst überschreiben — der gestrichelte Rand allein trüge das Signal. */
html.dark .chip.off{ color:var(--muted); }
/* F-28 (§4.9): ein noch nicht promoteter Taxonomie-Vorschlag. CAUTION-getönt, nicht fail —
   das ist eine offene Entscheidung, kein Fehler. Bewusst eine ANDERE Achse als `.off`
   (Rahmenstil vs. Farbe), damit ein Wert beides gleichzeitig tragen kann. */
.chip.prop{ background:var(--caut-s); border-color:var(--caut-b); color:var(--caut-t); }
html.dark .chip.prop{ background:var(--caut-s); border-color:var(--caut-b); color:var(--caut-t); }
.chip .chip-tag{ font-size:10px; font-weight:600; text-transform:uppercase; letter-spacing:.04em; opacity:.7; margin-left:2px; }

@media(max-width:1000px){
  .mon-two{ grid-template-columns:1fr; }
  .mon-grid{ grid-template-columns:1fr; }
}

/* ============================================================
   Deal-Pipeline (DD-Funnel Track 1) + Deal-Erfassung — Milestone B
   ============================================================
   Zwei Flächen, aber nur EINE neue Komponente:

   1. Das BOARD (`.dlb`) ist neu. Eine Pipeline nach Reifegrad ist weder Tabelle
      noch KPI-Band — die Spalte IST die Aussage („wo steckt der Deal"), und eine
      Tabelle mit einer Stage-Spalte würde genau das verstecken. Deshalb Spalten.
   2. Das ERFASSUNGS-MODAL bekommt hier KEINE eigene Shell: es benutzt `.mon`
      (DESIGN.md §4.8) unverändert weiter — links was getippt wird, rechts was
      daraus folgt. Ergänzt sind nur die drei Stücke, die das Monitoring-Fenster
      nicht kennt: Reiter (`.dl-tabs`), der Company-Typeahead (`.dl-pick`) und
      die Financials-Liste (`.dl-fin`).

   Kein neuer Token (DESIGN.md §1): Farben, Radien, Schriftgrössen und Abstände
   kommen alle aus §2. `.prov` / `.der` / `.miss` / `.ep-pr` / `.ep-note` sind
   global und werden auch hier wiederverwendet, nicht neu erfunden. */
.dlb{ padding:20px clamp(20px,3vw,48px); max-width:1480px; margin:0 auto; }
.dlb button, .dlb input, .dlb select, .dlb textarea{ font-family:inherit; }
.dlb h2{ font-size:var(--fs-xl); line-height:32px; margin:0 0 3px; font-weight:600; letter-spacing:-.01em; color:var(--ea-ink); }
.dlb .eyebrow{ font-size:var(--fs-xs); line-height:15px; letter-spacing:0; font-weight:600; color:var(--muted); }
.dlb .meta{ font-size:var(--fs-xs); line-height:15px; color:var(--muted); }
.dlb .meta b{ color:var(--ea-ink); font-weight:600; }
.dlb-head{ display:flex; align-items:flex-start; justify-content:space-between; gap:12px; flex-wrap:wrap; margin-bottom:16px; }
.dlb-tools{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; }

/* Der Funnel. Waagerecht scrollend statt umbrechend: die Reihenfolge der Stufen
   ist die Aussage, und ein Umbruch würde sie in zwei Zeilen zerschneiden. */
/* 198px ist die kleinste Breite, bei der eine Karte (Name + Kennzahl + Stage-Select) noch
   ohne Umbruch trägt — und sechs davon passen damit auf einen 1280er Schirm, statt die
   letzte Stufe hinter den Rand zu schieben. Darunter scrollt das Board waagerecht. */
.dlb-board{ display:grid; grid-auto-flow:column; grid-auto-columns:minmax(198px,1fr); gap:10px; overflow-x:auto; align-items:start; padding-bottom:8px; }
.dlb-col{ background:var(--ea-paper); border:1px solid var(--ea-line); border-radius:12px; padding:8px; }
html.dark .dlb-col{ background:#0e1726; }
.dlb-colh{ display:flex; align-items:baseline; justify-content:space-between; gap:8px; padding:2px 4px 8px; }
.dlb-colh .n{ font-size:var(--fs-xs); font-weight:600; color:var(--muted-2); }
.dlb-empty{ font-size:var(--fs-xs); line-height:16px; color:var(--muted-2); padding:4px; }

.dlb-card{ background:var(--surface); border:1px solid var(--ea-line); border-radius:8px; padding:8px 10px; margin-bottom:6px; }
.dlb-card:last-child{ margin-bottom:0; }
.dlb-co{ font-size:var(--fs-md); line-height:20px; font-weight:600; color:var(--ea-accent); cursor:pointer; background:none; border:0; padding:0; text-align:left; }
.dlb-co:hover{ text-decoration:underline; }
.dlb-sub{ font-size:var(--fs-xs); line-height:15px; color:var(--muted); margin-top:2px; }
.dlb-fig{ display:flex; align-items:baseline; justify-content:space-between; gap:8px; margin-top:6px; padding-top:6px; border-top:1px dashed var(--ea-line); }
.dlb-fig .k{ font-size:var(--fs-xs); color:var(--muted); }
.dlb-fig .v{ font-size:var(--fs-sm); font-weight:600; color:var(--ea-ink); }
.dlb-move{ margin-top:7px; }
.dlb-move select{ width:100%; font-size:var(--fs-xs); font-weight:500; padding:3px 6px; border:1px solid var(--ea-line); border-radius:6px; background:var(--surface); color:var(--ea-ink); cursor:pointer; }
/* Inline-Einspruch der Maske: das Gate und die Pass-Begründung erscheinen IN der
   Karte, nicht als Toast — beide verlangen eine Antwort an genau dieser Zeile. */
.dlb-hold{ margin-top:7px; padding:7px 8px; border-radius:8px; border:1px solid var(--caut-b); background:var(--caut-s); }
.dlb-hold .t{ font-size:var(--fs-xs); line-height:16px; color:var(--caut-t); }
.dlb-hold textarea{ width:100%; margin-top:6px; padding:5px 8px; font-size:var(--fs-xs); line-height:16px; border:1px solid var(--ea-line); border-radius:6px; background:var(--surface); color:var(--ea-ink); resize:vertical; }
.dlb-hold .acts{ display:flex; gap:6px; margin-top:6px; flex-wrap:wrap; }
/* In einer Spalte von ~200px ist der Standard-Knopf zu breit für zwei nebeneinander. */
.dlb-hold .acts .mon-btn{ padding:4px 8px; font-size:var(--fs-xs); border-radius:6px; }

.dlb-term{ margin-top:16px; }
.dlb-termh{ display:flex; align-items:center; gap:10px; margin-bottom:8px; }
.dlb-termh .rule{ height:1px; background:var(--ea-line); flex:1; }
.dlb-grid{ display:grid; grid-template-columns:repeat(auto-fill,minmax(216px,1fr)); gap:10px; }

/* --- Modal-Ergänzungen (die `.mon`-Shell trägt den Rest) --- */
.dl-tabs{ display:flex; gap:6px; align-items:center; margin-bottom:12px; flex-wrap:wrap; }
.dl-g3{ display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:10px 12px; padding:0 0 4px; }
.dl-pick{ display:flex; flex-direction:column; gap:4px; }
.dl-res{ border:1px solid var(--ea-line); border-radius:8px; background:var(--surface); max-height:184px; overflow-y:auto; margin-top:6px; }
.dl-res button{ display:block; width:100%; text-align:left; padding:6px 10px; font-size:var(--fs-sm); line-height:17px; border:0; border-bottom:1px solid var(--ea-line); background:transparent; color:var(--ea-ink); cursor:pointer; }
.dl-res button:last-child{ border-bottom:0; }
.dl-res button:hover{ background:var(--ea-paper); }
.dl-res .sub{ display:block; font-size:var(--fs-xs); color:var(--muted); }
.dl-sel{ display:flex; align-items:center; justify-content:space-between; gap:8px; padding:7px 10px; border:1px solid var(--ea-line); border-radius:8px; background:var(--ea-paper); }
html.dark .dl-sel{ background:#0e1726; }
.dl-sel .nm{ font-size:var(--fs-md); font-weight:600; color:var(--ea-ink); }
.dl-fin table{ width:100%; border-collapse:collapse; }
.dl-fin th{ font-size:var(--fs-xs); line-height:15px; text-transform:uppercase; letter-spacing:.08em; font-weight:600; color:var(--muted); text-align:left; padding:6px 10px; background:var(--ea-paper); white-space:nowrap; }
html.dark .dl-fin th{ background:#16212e; }
.dl-fin td{ font-size:var(--fs-sm); line-height:17px; padding:6px 10px; border-bottom:1px solid var(--ea-line); vertical-align:middle; }
.dl-fin td.n, .dl-fin th.n{ text-align:right; white-space:nowrap; }
.dl-fin td:first-child{ white-space:nowrap; }   /* ISO-Datum bricht sonst mitten im Jahr um */
.dl-fin tr.on td{ background:rgba(20,80,107,.05); }
html.dark .dl-fin tr.on td{ background:#16212e; }

@media(max-width:1000px){ .dl-g3{ grid-template-columns:1fr; } }

/* ============================================================
   Look-through-Explorer (F-32)
   ============================================================
   KEINE neue Modal-Komponente und keine neuen Tokens: die Shell ist dasselbe `.mon` wie bei
   der Deal-Erfassung und der Einzelanlage, Knöpfe sind `.mon-btn`, Felder `.field`, der
   Kontext-Chip ist `.chip`. Neu ist nur das Master-Detail-LAYOUT, das die `.mon-scroll`-Zeile
   ersetzt: eine feste Filterzeile, darunter zwei Spalten, die je für sich scrollen. Genau das
   ist der Punkt der Sicht — die Trefferliste darf dreistellig sein, ohne dass das Detail
   wegwandert oder die Filter aus dem Bild scrollen. */
.ltx{ max-width:1240px; }
.ltx-filters{ display:grid; grid-template-columns:1.5fr repeat(4,1fr); gap:8px; padding:10px 18px;
  border-bottom:1px solid var(--ea-line); align-items:end; }
.ltx-f{ display:flex; flex-direction:column; gap:3px; min-width:0; }
.ltx-f .field{ margin-top:1px; }
/* min-height:0 an beiden Stellen ist Pflicht, nicht Kosmetik: ohne das weigern sich Flex- und
   Grid-Kinder zu schrumpfen und die inneren overflow-y greifen nie — dann scrollt das ganze
   Overlay statt der Liste, und die Filterzeile ist weg. */
.ltx-body{ display:grid; grid-template-columns:1.5fr 1fr; flex:1; min-height:0; }
.ltx-list{ overflow-y:auto; min-height:0; padding:10px 12px 14px 18px; border-right:1px solid var(--ea-line); }
.ltx-detail{ overflow-y:auto; min-height:0; padding:12px 18px 16px 14px; background:var(--ea-paper); }
html.dark .ltx-detail{ background:#0e1726; }

.ltx-tbl table{ width:100%; border-collapse:collapse; }
.ltx-tbl th{ font-size:var(--fs-xs); line-height:15px; text-transform:uppercase; letter-spacing:.08em;
  font-weight:600; color:var(--muted); text-align:left; padding:6px 8px; background:var(--ea-paper);
  white-space:nowrap; position:sticky; top:0; z-index:1; }
html.dark .ltx-tbl th{ background:#16212e; }
.ltx-tbl td{ font-size:var(--fs-sm); line-height:17px; padding:6px 8px; border-bottom:1px solid var(--ea-line); vertical-align:top; }
.ltx-tbl td.n, .ltx-tbl th.n{ text-align:right; white-space:nowrap; }
.ltx-tbl td.sm{ font-size:var(--fs-xs); color:var(--muted); }
.ltx-tbl .nm{ font-weight:600; color:var(--ea-ink); }
.ltx-tbl .sub{ font-size:var(--fs-xs); line-height:14px; color:var(--muted); }
.ltx-tbl tbody tr{ cursor:pointer; }
.ltx-tbl tbody tr:hover td{ background:var(--ea-paper); }
html.dark .ltx-tbl tbody tr:hover td{ background:#16212e; }
.ltx-tbl tr.on td{ background:rgba(20,80,107,.07); }
html.dark .ltx-tbl tr.on td{ background:#1a2534; }

.ltx-cap{ margin-top:10px; padding:8px 11px; border:1px dashed var(--ea-line); border-radius:8px;
  font-size:var(--fs-xs); line-height:16px; color:var(--muted); }
.ltx-empty, .ltx-hint{ font-size:var(--fs-sm); line-height:18px; color:var(--muted); padding:14px 2px; }
.ltx-dh{ margin-bottom:8px; }
.ltx-dh .mon-title{ margin:2px 0 2px; }
.ltx-kv{ display:flex; align-items:baseline; justify-content:space-between; gap:12px; padding:5px 0;
  border-bottom:1px solid var(--ea-line); font-size:var(--fs-sm); line-height:17px; }
.ltx-kv .k{ color:var(--muted); }
.ltx-kv .k .sub{ color:var(--muted-2); font-size:var(--fs-xs); }
.ltx-kv .v{ font-weight:600; color:var(--ea-ink); text-align:right; }
.ltx-acts{ display:flex; gap:6px; flex-wrap:wrap; align-items:center; margin-top:2px; }

/* ── F-66 · Aggregat-Panel-Balken (Schicht A) ─────────────────────────────
   Der Balken hat GENAU EINEN Job: Magnitude. Länge = gemeldeter Anteil des Terms,
   ein Hue, sequenziell — keine kategoriale Palette. Die zweite Aussage („wie viel
   davon trägt einen Namen") sitzt als TEXTUR im Balken, nicht im Unterschied
   zwischen gefüllt und unsichtbar: solide = zerlegt, 45°-Schraffur = gemeldet,
   undekomponiert. Vorher war reported-only `#cbd5e1` auf `#f1f5f9` — ein
   vollständig undekomponierter Term war damit optisch abwesend, und genau das
   las sich als „keine Exposure". Der Schraffur-Ton MUSS gegen die Panel-Fläche
   lesbar bleiben; das ist der ganze Bug. */
:root{ --ltagg-solid:#0f6e56; --ltagg-hatch-bg:#9ec9bc; --ltagg-hatch-line:#0f6e56; --ltagg-track:#f1f5f9; }
.ltagg-bar{ height:8px; border-radius:4px; background:var(--ltagg-track); overflow:hidden; }
/* min-width hält einen 1-%-Term sichtbar, statt ihn auf null kollabieren zu lassen. */
.ltagg-fill{ height:100%; display:flex; gap:2px; border-radius:4px; overflow:hidden; min-width:3px; }
.ltagg-seg{ display:block; height:100%; flex-basis:0; flex-shrink:1; }
.ltagg-seg--dec{ background:var(--ltagg-solid); }
.ltagg-seg--und, .ltagg-swatch{ background-color:var(--ltagg-hatch-bg);
  background-image:repeating-linear-gradient(45deg,
    var(--ltagg-hatch-line) 0 2px, rgba(255,255,255,0) 2px 5px); }
/* Legenden-Chip in der Panel-Erklärung — dieselben zwei Töne wie im Balken. */
.ltagg-swatch{ display:inline-block; width:14px; height:8px; border-radius:2px;
  vertical-align:-1px; margin:0 1px; }
/* Dark Mode wird NICHT geflippt, sondern neu gesetzt: derselbe Hue, gegen die
   dunkle Fläche aufgehellt. Ein invertierter Grünton läge sonst unter der Surface. */
html.dark{ --ltagg-solid:#3fa889; --ltagg-hatch-bg:#2a4a42; --ltagg-hatch-line:#5cc0a4;
  --ltagg-track:#1a2533; }

/* ── F-63 · untagged-Bucket der Struktur-/Sleeve-Achse ────────────────────
   Dasselbe Idiom wie F-66 — die Textur trägt die zweite Aussage, nicht die
   Sättigung —, aber bewusst NEUTRAL im Ton: der grüne Hue dort bedeutet
   „gemeldet", und gemeldet ist hier gerade nichts. Ein grauer VOLLbalken las
   sich wie ein vierter Strukturtyp („70 % unbekannter Typ"); die Schraffur
   liest sich als Zustand — der GP hat es nicht gemeldet —, und genau das ist
   die Aussage. Der Track bleibt der Tailwind-`bg-slate-100` der anderen vier
   Balken: nur die Füllung wechselt, die Geometrie nicht. */
:root{ --ituntag-bg:#e2e8f0; --ituntag-line:#94a3b8; }
.it-untag-fill{ border-radius:0; min-width:3px;
  background-color:var(--ituntag-bg);
  background-image:repeating-linear-gradient(45deg,
    var(--ituntag-line) 0 2px, rgba(255,255,255,0) 2px 5px); }
/* Dark Mode neu gesetzt statt geflippt (wie bei --ltagg-*): eine invertierte
   Schraffur läge sonst heller als die Fläche, die sie qualifiziert. */
html.dark{ --ituntag-bg:#334155; --ituntag-line:#64748b; }

@media(max-width:1000px){
  .ltx-filters{ grid-template-columns:1fr 1fr; }
  .ltx-body{ grid-template-columns:1fr; }
  .ltx-list{ border-right:0; border-bottom:1px solid var(--ea-line); }
}

/* ── F-93 · Chart-Drill-Through ────────────────────────────────────────────
   Ein Chart-Segment ist ein Hit-Target, kein Bild. Drei Dinge macht diese
   Klasse, und keines davon berührt die Geometrie des Balkens darin:
   (a) MIN-HEIGHT 24px inkl. der Lücke — die Guideline-Untergrenze für eine
       Zeigefläche; die gemalten Pixel eines 12px-Balkens sind zu wenig.
   (b) Hover/Fokus HEBEN das Segment (Paper-Fläche + Kontur), statt die
       Balkenfarbe zu verändern: die Farbe kodiert die Kategorie, und sie beim
       Zeigen zu verbiegen hiesse, die Kodierung für einen Zustand zu opfern.
   (c) Ein sichtbarer :focus-visible-Ring auf dem Accent (DESIGN.md §10) — das
       Segment ist tastatur-fokussierbar, also muss man sehen, wo man steht.
   Ohne Konstituenten wird die Klasse gar nicht erst gesetzt (`drillSeg` gibt
   den Balken unverändert zurück): eine Zeigehand über einem Segment, das
   nichts öffnet, wäre ein Versprechen ohne Deckung. */
.drill-seg{ min-height:24px; display:block; cursor:pointer; border-radius:6px;
  margin:0 -6px; padding:1px 6px; border:1px solid transparent;
  transition:background-color .12s ease, border-color .12s ease; }
.drill-seg:hover{ background:var(--ea-paper); border-color:var(--ea-line); }
.drill-seg:focus-visible{ outline:none; background:var(--ea-paper);
  border-color:var(--ea-accent); box-shadow:0 0 0 3px rgba(20,80,107,.12); }
html.dark .drill-seg:focus-visible{ box-shadow:0 0 0 3px rgba(59,158,196,.20); }
/* Padding und Rahmen halten den Aussenabstand des Kindes (`mb-2` bei den
   Look-through-Kacheln) INNERHALB des Wrappers — margin-collapsing findet
   nicht statt, die Balkenabstände bleiben also exakt die bisherigen. */

/* ── CMP · Comparison Matrix (Redesign) ────────────────────────────────────
   Zwei Ebenen, zwei Flächen: das Auswahl-Panel in `#root` und die druckbare
   Matrix als Overlay daneben. Alles hier ist token-getrieben (§8), es gibt
   deshalb bis auf zwei Stellen keinen eigenen Dark-Mode-Block — `--muted`,
   `--ea-line`, `--surface` und `--ea-paper` remappen von selbst.
   Kein neuer Farbwert, keine neue Schriftgrösse, kein neuer Radius. */
.cmp-two{ display:grid; grid-template-columns:1.15fr 1fr; gap:16px; align-items:start; }
.cmp-secthead{ display:flex; align-items:flex-start; justify-content:space-between;
  gap:12px; padding:12px 14px; border-bottom:1px solid var(--ea-line); }
.cmp-secthead .eyebrow{ font-size:var(--fs-xs); line-height:15px; text-transform:uppercase;
  letter-spacing:.08em; font-weight:600; color:var(--muted); }
.cmp-secthead .meta{ font-size:var(--fs-xs); line-height:15px; color:var(--muted); margin-top:2px; }

/* Die Fondsliste scrollt IN der Karte, statt die Seite zu verlängern: das
   Dimensions-Panel daneben soll auch bei 191 Fonds ohne Scrollen erreichbar
   bleiben. Gedeckelt wird nichts — die Liste ist vollständig. */
.cmp-list{ max-height:420px; overflow-y:auto; }
.cmp-row{ display:grid; grid-template-columns:auto 1fr auto; grid-template-rows:auto auto;
  column-gap:10px; align-items:center; padding:7px 14px; cursor:pointer;
  border-bottom:1px solid var(--ea-line); }
.cmp-row:last-child{ border-bottom:0; }
.cmp-row:hover{ background:var(--ea-paper); }
.cmp-row input{ grid-row:1 / span 2; accent-color:var(--ea-accent); cursor:pointer; }
.cmp-name{ font-size:var(--fs-md); font-weight:500; color:var(--ea-ink); }
.cmp-sub{ grid-column:2; font-size:var(--fs-xs); line-height:15px; color:var(--muted); }
.cmp-row .tag-stage{ grid-column:3; grid-row:1 / span 2; justify-self:end; white-space:nowrap; }
/* Ohne manuelle Feinwahl zählen ALLE Zeilen mit — die Box ist dann bewusst nicht
   abgehakt (der erste Klick soll „nur diesen" heissen, nicht „diesen abwählen").
   Der Zustand steht deshalb als Ton an der Zeile, nicht als Haken: was
   mitzählt, trägt die volle Tinte, der Rest ist gedämpft. */
.cmp-row:not(.in) .cmp-name{ color:var(--muted); }
.cmp-row:not(.in){ opacity:.55; }
.cmp-empty{ padding:20px 14px; font-size:var(--fs-sm); color:var(--muted); text-align:center; }

.cmp-dims{ padding:12px 14px; }
.cmp-dimgrp + .cmp-dimgrp{ margin-top:12px; }
.cmp-dimgrp .eyebrow{ font-size:var(--fs-xs); line-height:15px;
  letter-spacing:0; font-weight:600; color:var(--muted); margin-bottom:6px; }
.cmp-dimchips{ display:flex; gap:6px; flex-wrap:wrap; }
.cmp-vint{ display:inline-flex; align-items:center; gap:6px; }
.cmp-vint .eyebrow{ font-size:var(--fs-xs); letter-spacing:0;
  font-weight:600; color:var(--muted); }
.cmp-vint .field{ width:82px; }

/* Die Matrix selbst. Sie erbt `table.matrix` (Rahmen, Polsterung, sticky
   Kopfzeile) und ergänzt nur, was diese Fläche zusätzlich braucht: eine
   klebende Dimensions-Spalte links und die Gruppen-Trennzeilen. */
.cmp-matrix{ width:100%; border-collapse:collapse; }
.cmp-matrix td.cmp-dim, .cmp-matrix th.cmp-dim{ position:sticky; left:0; z-index:2;
  background:var(--ea-paper); font-weight:500; white-space:nowrap; }
html.dark .cmp-matrix td.cmp-dim{ background:#16212e; }
.cmp-matrix tr.cmp-grp td{ background:var(--ea-paper); font-size:var(--fs-xs);
  text-transform:uppercase; letter-spacing:.08em; font-weight:600; color:var(--muted);
  padding:7px 12px; position:sticky; left:0; }
html.dark .cmp-matrix tr.cmp-grp td{ background:#16212e; }
.cmp-miss{ color:var(--muted-2); }
.cmp-foot{ font-size:var(--fs-xs); line-height:16px; color:var(--muted); padding:12px 2px 0; }
/* Der Blattkopf trägt Titel und Scope für den AUSDRUCK — am Bildschirm sagt das
   der Modal-Kopf darüber, deshalb ist er dort verborgen. */
.cmp-printhead{ display:none; }
.cmp-printtitle{ font-size:var(--fs-lg); font-weight:600; color:var(--ea-ink); }
.cmp-printmeta{ font-size:var(--fs-xs); color:var(--muted); margin-top:2px; }

@media(max-width:1100px){
  .cmp-two{ grid-template-columns:1fr; }
}

/* ── Druckansicht ──────────────────────────────────────────────────────────
   Gescoped auf `html.cmp-open` — die Klasse steht, solange das Matrix-Pop-up
   offen ist, und `renderCmpMatrix` nimmt sie beim Schliessen wieder weg.
   Damit hängt der Druck NICHT am „Print"-Knopf: ein Ctrl+P des Nutzers
   erzeugt dasselbe Blatt. Ein Knopf, der der einzige Weg zum korrekten
   Ausdruck wäre, hätte genau eine Route zu viel.
   Freigestellt wird genau EIN Knoten (`#cmp-overlay`) — deshalb liegt das
   Pop-up ausserhalb von `#root`. */
@media print {
  @page { size: A4 landscape; margin: 10mm; }

  /* ⚠ `body.bg-slate-50` steht mit dabei, und das ist nicht Zierde: der Dark-Mode-Override
     `html.dark .bg-slate-50` (Zeile ~150) trägt (0,2,0) und ebenfalls `!important` — ein
     blosses `html.cmp-open body` (0,1,1) verliert dagegen, und ein Nutzer, der im Dark Mode
     mit „Hintergrundgrafiken" druckt, bekäme ein schwarzes Blatt. Gemessen, nicht vermutet. */
  html.cmp-open, html.cmp-open body, html.cmp-open body.bg-slate-50{ background:#fff !important; }
  /* Alles ausser dem Overlay fällt weg — Sidebar, Auswahl-Panel, jeder andere
     Drawer. `> *` statt einer Klassenliste, damit ein später dazukommendes
     Overlay nicht stillschweigend mitgedruckt wird. */
  html.cmp-open body > *:not(#cmp-overlay){ display:none !important; }
  html.cmp-open #cmp-overlay{ position:static !important; inset:auto !important;
    display:block !important; padding:0 !important; margin:0 !important;
    background:none !important; overflow:visible !important; z-index:auto !important; }
  html.cmp-open .cmp-sheet{ display:block !important; max-width:none !important;
    max-height:none !important; margin:0 !important; border:0 !important;
    border-radius:0 !important; box-shadow:none !important; background:#fff !important; }
  html.cmp-open .cmp-scroll{ overflow:visible !important; max-height:none !important;
    padding:0 !important; }
  html.cmp-open .cmp-noprint{ display:none !important; }
  html.cmp-open .cmp-printhead{ display:block !important; margin-bottom:8px; }

  /* Der Bildschirm-Kontrast wird nicht mitgedruckt: die Tokens können im Dark
     Mode stehen, und ein dunkles Blatt wäre weder lesbar noch druckbar. Deshalb
     hier explizite Werte statt Tokens — die einzige Stelle im Stylesheet, an der
     das richtig ist. */
  html.cmp-open .cmp-printtitle{ color:#0b1a2b !important; }
  html.cmp-open .cmp-printmeta, html.cmp-open .cmp-foot{ color:#475569 !important; }
  html.cmp-open table.cmp-matrix{ width:100% !important; table-layout:fixed; }
  html.cmp-open table.cmp-matrix th,
  html.cmp-open table.cmp-matrix td{ position:static !important; font-size:10px !important;
    padding:5px 7px !important; color:#0b1a2b !important; background:#fff !important;
    border-color:#cbd5e1 !important; word-break:break-word; }
  html.cmp-open table.cmp-matrix th,
  html.cmp-open table.cmp-matrix td.cmp-dim,
  html.cmp-open table.cmp-matrix tr.cmp-grp td{ background:#f1f5f9 !important; }
  html.cmp-open table.cmp-matrix tr.cmp-grp td{ color:#475569 !important; }
  html.cmp-open .cmp-miss{ color:#94a3b8 !important; }
  /* Eine Dimensionszeile wird nie über zwei Seiten zerrissen, und die Fondsnamen
     stehen auf jeder Seite noch einmal oben — sonst wäre Seite 2 eine Tabelle
     ohne Spaltenköpfe. */
  html.cmp-open table.cmp-matrix thead{ display:table-header-group; }
  html.cmp-open table.cmp-matrix tr{ break-inside:avoid; page-break-inside:avoid; }
  html.cmp-open table.cmp-matrix tr.cmp-grp{ break-after:avoid; page-break-after:avoid; }
}

/* ── F-27 · Kapitalstack — die Rang-Marke ──────────────────────────────────
   Die Leiter braucht genau EIN neues Zeichen: die Ebenen-Nummer 1–8 vor dem
   Namen. Sie ist kein Badge (kein Status) und kein Chip (kein Wert, den man
   entfernen könnte) — sie ist eine Ordnungszahl, und ihr einziger Job ist,
   die Reihenfolge senior→junior auch dann lesbar zu halten, wenn eine Sprosse
   fehlt (der Sprung 2 → 5 IST die Aussage).
   Kein neuer Token: Fläche, Linie und Ton kommen aus --ea-paper / --ea-line /
   --muted, die Ziffern in Inter mit Tabellenziffern wie jede andere Zahl im
   Haus (Eine-Schrift-Pass). Dark Mode deshalb ohne eigenen Block — die drei Variablen sind in
   §8 bereits remapped. */
.stack-rank{ display:inline-flex; align-items:center; justify-content:center;
  min-width:18px; height:18px; padding:0 4px; border-radius:6px;
  background:var(--ea-paper); border:1px solid var(--ea-line); color:var(--muted);
  font-family:'Inter',-apple-system,BlinkMacSystemFont,sans-serif; font-variant-numeric:tabular-nums;
  font-size:10px; font-weight:600; line-height:1; font-feature-settings:'tnum'; }

/* ── Demo-Paket (A) · Fund Registry als Pipeline-Board ─────────────────────
   Die Spalten und Karten REUSEN das Deal-Board (`.dlb-board` / `.dlb-col` /
   `.dlb-card` / `.dlb-co` / `.dlb-sub`) — dieselbe Form für dieselbe Aussage
   (ein Funnel, Stufen als Spalten). Hier steht nur, was die Registry-Karte
   zusätzlich braucht: die eigene Spaltenbreite, das vertikale Scrollen JE
   Spalte, die Fundraising-Mini oben rechts und die gedämpfte Aktionszeile.
   Token-getrieben (§8), kein eigener Dark-Mode-Block, kein neuer Farbwert. */
.reg-scope{ display:flex; flex-direction:column; gap:8px; }
.reg-scope .eyebrow, .cal-head .eyebrow{ font-size:var(--fs-xs); line-height:15px; letter-spacing:0; font-weight:600; color:var(--muted); }
.reg-scope-head{ display:flex; align-items:center; gap:10px; }
.reg-scope-grp{ display:flex; align-items:center; gap:6px; flex-wrap:wrap; }
.reg-scope-grp .eyebrow{ min-width:82px; }
/* 232px: Name + Fundraising-Badge + Meta-Zeile tragen ohne Umbruch; acht Spalten
   scrollen damit auf 1480px waagerecht IM Board, nie im Body. */
.reg-board{ grid-auto-columns:minmax(232px,1fr); }
.reg-col-body{ max-height:62vh; overflow-y:auto; padding-right:2px; }
.reg-card-h{ display:flex; align-items:flex-start; justify-content:space-between; gap:8px; }
.reg-card-h .dlb-co{ flex:1; min-width:0; }
.reg-card-raise{ flex-shrink:0; text-align:right; }
.reg-card-raise .badge{ font-size:10px; padding:1px 7px; }
.reg-gp{ padding:0; font-size:var(--fs-xs); font-weight:500; }
.reg-meta{ font-size:var(--fs-xs); line-height:15px; color:var(--muted); margin-top:4px; }
.reg-tags{ display:flex; gap:4px; flex-wrap:wrap; align-items:center; margin-top:6px; }
.reg-tag{ font-size:10px; padding:1px 6px; }
.reg-dd{ margin-left:auto; }
.reg-acts{ display:flex; gap:6px; align-items:center; margin-top:6px; padding-top:6px; border-top:1px dashed var(--ea-line); opacity:.55; transition:opacity .12s; }
.reg-card:hover .reg-acts, .reg-card:focus-within .reg-acts{ opacity:1; }
.reg-acts .btn-quiet{ font-size:var(--fs-xs); }
/* Stufen-Drift Registry ⟷ Fund DD — EINE Zeile für Board-Karte UND Tabellen-Stufenzelle.
   Kein neuer Farbwert und kein eigener Dark-Mode-Block: das Badge trägt `.badge--caution`
   (Tokens, §8 remappt sie), die Aktionen `.btn-quiet`. Hier steht nur der Fluss. */
.reg-drift{ display:flex; align-items:center; gap:6px; flex-wrap:wrap; margin-top:6px; }
.reg-drift .badge{ font-size:10px; padding:1px 7px; }
.reg-drift .btn-quiet{ font-size:var(--fs-xs); }
.reg-solo .dlb-colh{ align-items:center; }

/* ── Demo-Paket (B) · Forward-Looking-Kalender ─────────────────────────────
   Ein Gantt aus CSS-Grid: JEDE Zeile ist ein eigenes Grid mit demselben
   Spalten-Template (inline gesetzt, weil die Quartalszahl 4/8/12 variiert);
   die Quartalszellen liegen in grid-row 1, der Balken darüber (z-index) in
   derselben Zeile mit `grid-column: start / end`. So sitzen Balken und Raster
   per Konstruktion auf denselben Spalten. Balkenfarbe = Fundraising-Status,
   dieselben Token wie die Badges (`fuRaisingCell`). */
.cal-wrap{ overflow-x:auto; }
.cal-head{ display:grid; border-bottom:1px solid var(--ea-line); min-width:720px; align-items:end; }
.cal-head .cal-lbl{ padding:8px 12px; }
.cal-head .q{ border-left:1px solid var(--ea-line); padding:6px 4px; text-align:center; }
.cal-head .q .l{ font-size:var(--fs-xs); font-weight:600; color:var(--ea-ink); white-space:nowrap; }
.cal-head .q .s{ font-size:10px; line-height:13px; color:var(--muted); margin-top:2px; white-space:nowrap; }
.cal-head .q.now{ background:rgba(20,80,107,.06); }
.nowtag{ display:block; font-family:'Inter',-apple-system,sans-serif; font-size:9px; line-height:10px; font-weight:600; text-transform:uppercase; letter-spacing:.08em; color:var(--ea-accent); }
.cal-row{ display:grid; align-items:center; border-bottom:1px solid var(--ea-line); min-height:36px; min-width:720px; }
.cal-row:last-child{ border-bottom:0; }
.cal-row.gp{ background:var(--ea-paper); }
html.dark .cal-row.gp{ background:#0e1726; }
.cal-lbl{ padding:6px 12px; min-width:0; }
.cal-lbl .nm{ font-size:var(--fs-sm); font-weight:500; color:var(--ea-accent); background:none; border:0; padding:0; cursor:pointer; text-align:left; }
.cal-lbl .nm:hover{ text-decoration:underline; }
.cal-lbl .nm.muted{ color:var(--muted); cursor:default; }
.cal-row.gp .nm{ font-weight:600; color:var(--ea-ink); }
.cal-lbl .sub{ font-size:var(--fs-xs); line-height:15px; color:var(--muted); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.cal-cell{ align-self:stretch; border-left:1px solid var(--ea-line); }
.cal-cell.now{ background:rgba(20,80,107,.05); }
.cal-bar{ height:22px; margin:0 3px; border-radius:6px; border:1px solid; display:flex; align-items:center; padding:0 8px; font-size:10px; font-weight:600; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; z-index:1; }
.cal-bar.coming{ color:var(--info-t); background:var(--info-s); border-color:var(--info-b); }
.cal-bar.open{ color:var(--ok-t); background:var(--ok-s); border-color:var(--ok-b); }
.cal-bar.closed{ color:var(--muted); background:var(--ea-paper); border-color:var(--ea-line); }
.cal-bar.none{ color:var(--na-t); background:var(--na-s); border-color:var(--na-b); }
.cal-bar.mark{ justify-content:center; padding:0 4px; }
/* Der GP-Summenbalken ist eine SPANNE, kein Status — dünn und ohne Ton. */
.cal-bar.gp{ height:6px; padding:0; border-radius:3px; background:var(--muted-2); border-color:var(--muted-2); opacity:.6; }
.cal-legend{ display:flex; gap:6px; align-items:center; }
.cal-legend .cal-bar{ height:18px; margin:0; font-weight:500; }

/* ── Pipeline-Bereinigung · Triage-Worklist ────────────────────────────────
   Der Stapel der ungestuften Fonds ist eine ARBEITSLISTE, keine zweite Tabelle:
   sie reused `.card` / `.matrix` / `.field` / `.btn-quiet` / `.mon-alert` und
   bringt nur mit, was die Disposition braucht — die Kopfzeile mit dem Weg
   zurück und die zweiteilige Aktionszelle. Token-getrieben (§8), kein eigener
   Dark-Mode-Block, kein neuer Farbwert. */
.reg-tri-head{ display:flex; align-items:flex-start; justify-content:space-between; gap:12px; flex-wrap:wrap; }
.reg-tri-note{ display:flex; align-items:center; justify-content:space-between; gap:12px; flex-wrap:wrap; }
.reg-tri-note-acts{ display:flex; align-items:center; gap:6px; flex-shrink:0; }
/* Die Disposition steht rechts in der Zeile: erst der Weg IN die Pipeline, dann
   der Weg heraus. Nebeneinander und NICHT umbrechend: die Disposition ist der Zweck dieser
   Tabelle, also bekommt ihre Spalte die Breite und die Textspalten brechen um. Auf schmalen
   Schirmen scrollt die Tabelle in ihrem eigenen Container (.card.overflow-auto). */
.reg-disp{ display:flex; align-items:center; justify-content:flex-end; gap:8px; flex-wrap:nowrap; white-space:nowrap; }
.reg-disp-sel{ width:auto; min-width:132px; padding:4px 8px; font-size:var(--fs-xs); }

/* ═══════════════════════════════════════════════════════════════════════
   EA UI Primitives — die Bausteine der Seiten-Grammatik
   (assets/ui-primitives.js, `window.EAUI`)
   ═══════════════════════════════════════════════════════════════════════
   Fuenf Bausteine, drei Zonen: Signal (kpi/kpiRow) · Konsequenz (targetBar) ·
   Detail (section = Collapsible + RollupHead), quer dazu der EINE Drawer.

   ⚠ DORMANT: dieser Block stylt AUSSCHLIESSLICH `.ea-*`-Klassen, die es vor
   diesem Bau nirgends gab. Keine bestehende Ansicht aendert sich.

   ⚠ ES KOMMT KEIN NEUER FARBWERT UND KEIN NEUES TOKEN DAZU. Der Contract
   nennt ein `--warn`-Triplett als „das eine neue Token-Set" fuer den
   Mittel-Zustand — gemessen existiert es bereits als `--caut-t/-s/-b`
   (Z. 263/271, im Dark Mode remappt) und traegt schon `.badge--caution`,
   `.mon-alert.warn`, `.ep-badge--caut` und `.chip.prop`. Ein zweites Set mit
   denselben Werten waere die Sorte Kopie, die beim ersten Nachjustieren
   auseinanderlaeuft; DESIGN.md §2.2 sagt zudem ausdruecklich „sechs Rollen,
   es gibt keine siebte". Der API-Zustand heisst weiter `warn`, er zeigt nur
   auf das vorhandene Token.

   ⚠ KEIN `var(--r-lg)`: DESIGN.md §2.6 fuehrt die vier Radius-Tokens, in
   DIESER Datei sind sie nicht definiert. Eine undefinierte Custom Property
   faellt still auf „kein Radius" zurueck. Deshalb rohe px auf der
   dokumentierten Skala (6 / 8 / 12), wie im ganzen Rest des Stylesheets.

   Token-getrieben, also OHNE eigenen `html.dark`-Block: --muted, --surface,
   --ea-ink, --ea-line, --ea-accent und die Semantik-Tripel remappen in §8
   von selbst. Die einzige feste Farbe ist der Drawer-Backdrop — er ist per
   DESIGN.md §4.6 slate-900/40 und in beiden Themes dieselbe Abdunklung.  */

/* Visuell fort, im Accessibility-Baum da. Traegt das Zustandswort der
   targetBar: der Zustand darf NIE nur ueber Farbe kodiert sein (§4.4, §10,
   WCAG 1.4.1), und ein sichtbarer Zustands-Chip waere Flaeche fuer eine
   Aussage, die der Satz daneben schon macht. */
.ea-sr{ position:absolute; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip:rect(0 0 0 0); clip-path:inset(50%); white-space:nowrap; border:0; }

/* ── Zone 1 · die KPI-Reihe ──────────────────────────────────────────────
   ⚠ Die Spaltenuntergrenze ist eine LAENGE, nicht `auto`. B0 §2c hat gemessen,
   dass `repeat(N,1fr)` die Spalten NICHT gleich breit haelt — `1fr` ist
   `minmax(auto,1fr)`, die Spalte waechst also mit ihrem Inhalt, und eine
   Reihe mit einer langen Zahl stand danach schief. Mit `minmax(180px,1fr)`
   ist die Untergrenze fix und die Spalten sind gleich.
   Die Kachel selbst bringt kein eigenes CSS mit: sie ist `.card.card-pad` +
   `.kpi-label` / `.kpi-value` / `.kpi-sub` / `.kpi--hero` aus B0, damit der
   spaetere Umzug der Bestandsaufrufer ein Austausch bleibt. */
.ea-kpirow{ display:grid; grid-template-columns:repeat(auto-fit,minmax(180px,1fr)); gap:12px; }
/* Die KLICKBARE Kachel (Performance-Pilot, `EAUI.kpi({onclick})`): ein <button>
   mit den Kartenklassen. Was hier steht, ist NUR, was ein Button anders macht
   als ein div — Ausrichtung, Breite, Schrift (Preflight setzt `text-align`
   nicht zurueck, der Browser zentriert) — plus Zeigerflaeche, Hover, Fokus
   und die Drill-Affordanz aus EA-DEV-005 (gepunktete Unterstreichung am Wert,
   Pfeil am Label). Farben, Rahmen und Dark Mode kommen weiter aus `.card`. */
button.ea-kpi--drill{ display:block; width:100%; text-align:left; font:inherit; cursor:pointer;
  transition:background-color .12s ease; }
button.ea-kpi--drill:hover{ background:#f8fafc; }  /* = slate-50, der Hover von drillKpi */
html.dark button.ea-kpi--drill:hover{ background:#16223a; }
button.ea-kpi--drill:focus-visible{ outline:2px solid var(--ea-accent); outline-offset:2px; }
.ea-kpi--drill .kpi-value{ text-decoration:underline dotted var(--ea-line); text-underline-offset:5px; }
.ea-kpi__arrow{ color:var(--muted); font-weight:400; }
button.ea-kpi--drill:hover .ea-kpi__arrow{ color:var(--ea-ink); }

/* ── Zone 2 · targetBar — die Konsequenz-Zeile ───────────────────────────
   Dieselbe Form wie `.mon-alert`: Text, Flaeche und Rahmen aus EINEM
   Semantik-Tripel. Punkt, Toleranzband und Marker laufen ueber
   `currentColor` und wandern damit mit, statt jede Farbe noch einmal zu
   nennen. */
.ea-tb{ display:flex; align-items:center; gap:12px; flex-wrap:wrap;
  padding:10px 14px; border-radius:8px; border:1px solid;
  font-size:var(--fs-sm); line-height:18px; }
.ea-tb--ok    { color:var(--ok-t);   background:var(--ok-s);   border-color:var(--ok-b); }
.ea-tb--warn  { color:var(--caut-t); background:var(--caut-s); border-color:var(--caut-b); }
.ea-tb--breach{ color:var(--fail-t); background:var(--fail-s); border-color:var(--fail-b); }
.ea-tb__dot{ width:8px; height:8px; border-radius:50%; background:currentColor; flex-shrink:0; }
.ea-tb__txt{ flex:1; min-width:0; display:flex; align-items:baseline; gap:8px; flex-wrap:wrap; }
.ea-tb__label{ font-weight:600; flex-shrink:0; }
.ea-tb__msg{ font-weight:400; }
/* Das Handeln steht im FESTEN rechten Slot — eine Konsequenz-Zeile ohne
   Handlung ist eine Feststellung, und dann ruft der Aufrufer `action` gar
   nicht. Rahmen statt Fuellung: die Fuellung traegt hier schon der Zustand. */
.ea-tb__act{ flex-shrink:0; margin-left:auto; font-size:var(--fs-sm);
  font-weight:600; color:inherit; text-decoration:none;
  padding:4px 10px; border-radius:8px; border:1px solid currentColor;
  background:transparent; cursor:pointer; opacity:.9;
  transition:opacity .12s ease, background-color .12s ease; }
.ea-tb__act:hover{ opacity:1; background:rgba(255,255,255,.35); }
html.dark .ea-tb__act:hover{ background:rgba(255,255,255,.06); }
.ea-tb__act:focus-visible{ outline:2px solid var(--ea-accent); outline-offset:2px; }

/* Ziel gegen Ist. Die Skala setzt `tbBar()` in der JS-Datei; hier ist nur die
   Geometrie. Band, Mittellinie und Marker sind Abstufungen DESSELBEN
   Zustands, nicht drei eigene Farben. */
.ea-tb__bar{ position:relative; display:block; width:100%; max-width:260px;
  height:8px; border-radius:4px; background:var(--ea-line); overflow:hidden; }
.ea-tb__band{ position:absolute; top:0; bottom:0; background:currentColor; opacity:.20; }
.ea-tb__center{ position:absolute; top:0; bottom:0; left:50%; width:1px;
  background:currentColor; opacity:.45; }
.ea-tb__marker{ position:absolute; top:0; bottom:0; width:3px; border-radius:2px;
  background:currentColor; transform:translateX(-50%); }

/* ── Zone 3 · section — Collapsible mit RollupHead ───────────────────────
   Die Sektion IST eine `.card` (Hintergrund, Rahmen und der Dark-Mode kommen
   von dort). Neu ist nur der Kopf und die Auf/Zu-Mechanik. */
.ea-sec{ overflow:hidden; }
.ea-sec__head{ display:flex; align-items:center; justify-content:space-between;
  gap:12px; flex-wrap:wrap; }
.ea-sec.is-open .ea-sec__head{ border-bottom:1px solid var(--ea-line); }
/* Der Knopf traegt NUR Titel und Zaehler; Rollup und Fortschritt stehen als
   Geschwister daneben. Im Knopf waeren sie Teil seines Accessible Name, und
   die Ansage („Positions 24 NAV 204.4 Commitment 312.0 …") waere unbrauchbar. */
.ea-sec__toggle{ flex:1; min-width:0; display:flex; align-items:center; gap:8px;
  padding:12px 16px; background:transparent; border:0; cursor:pointer;
  font-size:var(--fs-md); font-weight:600; color:var(--ea-ink); text-align:left; }
.ea-sec__toggle:focus-visible{ outline:2px solid var(--ea-accent); outline-offset:-2px;
  border-radius:8px; }
/* Chevron aus Rahmen statt aus einem Glyph: er dreht sich, statt ausgetauscht
   zu werden — die Bewegung sagt „dasselbe Ding, anderer Zustand". */
.ea-sec__chev{ width:0; height:0; flex-shrink:0;
  border-left:5px solid currentColor; border-top:4px solid transparent;
  border-bottom:4px solid transparent; transition:transform .15s ease; }
.ea-sec.is-open .ea-sec__chev{ transform:rotate(90deg); }
.ea-sec__title{ min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.ea-sec__count{ flex-shrink:0; font-size:var(--fs-xs); font-weight:600; color:var(--muted);
  background:var(--ea-paper); border:1px solid var(--ea-line);
  padding:1px 6px; border-radius:6px; }

.ea-sec__meta{ display:flex; align-items:center; gap:18px; flex-wrap:wrap;
  padding:12px 16px 12px 0; }
/* RollupHead: die verdichteten Aggregate, die den ZUGEKLAPPTEN Zustand
   tragbar machen — man muss die Sektion nicht oeffnen, um ihre Summe zu sehen. */
.ea-sec__roll{ display:flex; align-items:flex-start; gap:18px; flex-wrap:wrap; }
.ea-sec__rollitem{ display:flex; flex-direction:column; gap:1px; }
.ea-sec__rolllab{ font-size:var(--fs-xs); font-weight:600; color:var(--muted); }
.ea-sec__rollval{ font-size:var(--fs-sm); font-weight:600; color:var(--ea-ink); }
/* Goal-Gradient / Zeigarnik: die Rest-Arbeit als Zahl UND als Weg. */
.ea-sec__prog{ display:flex; flex-direction:column; gap:4px; min-width:140px; }
.ea-sec__progtxt{ font-size:var(--fs-xs); font-weight:600; color:var(--muted); }
.ea-sec__progtrack{ display:block; height:4px; border-radius:2px;
  background:var(--ea-line); overflow:hidden; }
.ea-sec__progfill{ display:block; height:100%; border-radius:2px; background:var(--ea-accent); }

/* ⚠ Auf/Zu laeuft ueber eine KLASSE, nicht ueber das `hidden`-Attribut — und
   der Grund ist GEMESSEN, nicht vermutet: Z. 169 DIESER Datei fuehrt seit
   jeher `[hidden]{ display:none !important }`. Ein `!important` schlaegt jede
   Klassenregel unabhaengig von Spezifitaet und Reihenfolge; ein per `hidden`
   zugeklapptes Panel liesse sich also gar nicht mehr per Klasse aufklappen.
   (Tailwinds Preflight faehrt daneben `[hidden]:where(:not([hidden=
   "until-found"]))` ohne `!important` — DAS haette die Klassenregel gewonnen.
   Die harte Regel ist unsere eigene.)
   Folge, die ein spaeterer Verbraucher wissen muss: wer `hidden` auf
   `.ea-sec__body` setzt, ueberstimmt `is-open`. Die Primitive tut es nirgends. */
.ea-sec__body{ display:none; }
.ea-sec.is-open > .ea-sec__body{ display:block; }

/* ── Der EINE Drawer ─────────────────────────────────────────────────────
   DESIGN.md §4.6 (rechts angeschlagen, Backdrop slate-900/40, volle Hoehe,
   fuer die HERLEITUNG) und §2.8 (Overlay-Band = z-index 50; die ad-hoc-Leiter
   z-[80]/z-[90] ist dort ausdruecklich zurueckgezogen). Er ist ein
   SINGLETON: ein zweites `open` ersetzt den Inhalt, es stapelt nicht.
   Geschlossen ist er `visibility:hidden` — das nimmt ihn auch aus dem
   Accessibility-Baum und aus der Tab-Reihenfolge; `opacity:0` allein liesse
   ihn in beiden stehen. */
/* ⚠ `visibility` steht BEWUSST NICHT in der Transition — es wird geschaltet.
   Zwei gemessene Gruende, beide aus dem Bau (05.09.):
   (a) Steht es drin, ist der berechnete Wert direkt nach
       `classList.add('is-open')` noch `hidden` (bei t=0 gilt der Startwert),
       und ein Element in einem `visibility:hidden`-Teilbaum ist NICHT
       fokussierbar: `panel.focus()` war ein stiller No-Op, der Tastaturnutzer
       blieb hinter dem Drawer in der Seite stehen, die `aria-modal` gerade
       als abwesend ausgibt.
   (b) Der sonst uebliche Ausweg — Ausblende ueber `visibility 0s linear .18s`
       — macht den ZUSTAND von einer laufenden Transition abhaengig, und eine
       Transition braucht Frames. In einer Umgebung, die nicht malt, blieb der
       geschlossene Drawer damit `visibility:visible` (opacity 0) und stand
       weiter in der Tab-Reihenfolge.
   Der Preis ist die Ausblende BEIM SCHLIESSEN: das Panel verschwindet sofort
   statt zu verblassen. Das ist genau das Verhalten der acht bestehenden
   Drawer der App (die entfernen ihr Overlay schlicht) — Determiniertheit
   schlaegt hier die Zierde. Die EINfahrt animiert unveraendert. */
.ea-drawer{ position:fixed; inset:0; z-index:50; display:flex; justify-content:flex-end;
  background:rgba(15,23,42,.4);
  opacity:0; visibility:hidden; pointer-events:none;
  transition:opacity .18s ease; }
.ea-drawer.is-open{ opacity:1; visibility:visible; pointer-events:auto; }
.ea-drawer--left{ justify-content:flex-start; }

.ea-drawer__panel{ position:relative; display:flex; flex-direction:column;
  width:100%; max-width:720px; height:100%;
  background:var(--surface); border-left:1px solid var(--ea-line);
  box-shadow:0 20px 25px -5px rgba(0,0,0,.25), 0 8px 10px -6px rgba(0,0,0,.2);
  transform:translateX(100%); transition:transform .2s ease; }
.ea-drawer--left .ea-drawer__panel{ border-left:0; border-right:1px solid var(--ea-line);
  transform:translateX(-100%); }
.ea-drawer.is-open .ea-drawer__panel{ transform:none; }
.ea-drawer__panel:focus{ outline:none; }
.ea-drawer__panel:focus-visible{ outline:2px solid var(--ea-accent); outline-offset:-2px; }

.ea-drawer__head{ display:flex; align-items:flex-start; justify-content:space-between;
  gap:12px; padding:16px 20px; border-bottom:1px solid var(--ea-line); flex-shrink:0; }
.ea-drawer__title{ margin:0; min-width:0; font-size:var(--fs-lg); line-height:24px;
  font-weight:600; color:var(--ea-ink); }
.ea-drawer__x{ flex-shrink:0; background:transparent; border:0; cursor:pointer;
  font-size:18px; line-height:1; padding:2px 4px; border-radius:6px; color:var(--muted);
  transition:color .12s ease; }
.ea-drawer__x:hover{ color:var(--ea-ink); }
.ea-drawer__x:focus-visible{ outline:2px solid var(--ea-accent); outline-offset:2px; }
.ea-drawer__body{ flex:1; min-height:0; overflow:auto; }

/* Bewegung ist hier Orientierung („woher kommt das Panel"), nicht Zierde —
   wer sie abbestellt hat, bekommt denselben Zustand ohne den Weg dorthin. */
@media (prefers-reduced-motion: reduce){
  .ea-drawer, .ea-drawer__panel, .ea-sec__chev, .ea-tb__act, .ea-drawer__x{ transition:none; }
}

/* ============================================================
   REDESIGN v23 — FOUNDATION (artboard `redesign/artboard/_tokens.css`)
   ============================================================
   Everything below is the board's component set on the tokens at the top of this file.
   Two kinds of rules:
   (a) NEW board classes (`.btn*`, `.pill`, `.seg`, `.tab`, `.th`/`.td`, `.lbl`/`.cap`/`.u`,
       `.kbd`, `.field-l`, status chips `.chip.ok|caut|fail|info|neu|na` …) — page chips write
       board markup with these names and get the board look in both themes.
   (b) RESTYLES of classes the app already writes (`.card`, `.kpi-*`, `.kpi--hero`, `.pv-kpi`,
       `.ep-kpi`, `.chip`, `.badge`, `.btn-quiet`, `button.primary`, `button.ghost`, `.pv-btn`,
       `.mon-btn`, `.pv-seg`, `input.field`, `table.matrix` heads, EAUI) — every page picks up
       the new look without a page edit.
   Dark mode is a token remap only (see "Redesign v23 — dark tokens"); the few html.dark
   lines here exist because an older, more specific html.dark rule has to be matched.
   ⚠ Tailwind's play-CDN injects its <style> AFTER this file: a Tailwind utility on the same
   node beats a single-class rule here (same specificity, later). Board classes therefore do
   not rely on beating utilities — call sites drop the utility instead.
   ⚠ Status tints are scoped to `.chip.*` on purpose: bare `.ok`/`.fail`/`.info` are already
   modifiers of `.mon-alert` in the app. */

/* --- base -------------------------------------------------------------------------------- */
html body { font-family: var(--font-sans); -webkit-font-smoothing: antialiased; }
html body.bg-slate-50 { background-color: var(--ea-paper); color: var(--ea-ink); }  /* board paper #f7f8fa; dark keeps its !important remap */
.tnum { font-variant-numeric: tabular-nums; font-feature-settings: 'tnum'; }
.u   { font-size: var(--fs-sm); font-weight: 500; color: var(--muted); }          /* unit next to a figure: "246.30 <u>CHF M</u>" */
.cap { font-size: var(--fs-xs); line-height: var(--lh-xs); color: var(--muted); } /* caption */
.lbl { font-size: var(--fs-sm); line-height: 16px; font-weight: 600; color: var(--ea-text-2); } /* label / eyebrow */
.muted { color: var(--muted); }
.num { text-align: right; }
.ea-h1 { margin: 0; font-size: var(--fs-xl); line-height: var(--lh-xl); font-weight: 700; letter-spacing: -.01em; color: var(--ea-ink); }
.ea-h2 { margin: 0; font-size: var(--fs-md); line-height: var(--lh-md); font-weight: 600; color: var(--ea-ink); }
.ea-hero-v { font-size: clamp(var(--fs-xl), 2.9vw, var(--fs-2xl)); line-height: 1.16; font-weight: 800; letter-spacing: -.02em; font-variant-numeric: tabular-nums; font-feature-settings: 'tnum'; }
.ea-kpi-v  { font-size: var(--fs-xl); line-height: var(--lh-xl); font-weight: 600; font-variant-numeric: tabular-nums; font-feature-settings: 'tnum'; }
.row-link { color: var(--ea-ink); font-weight: 600; text-decoration: none; }
.row-link:hover { color: var(--ea-accent); text-decoration: underline; }
.chev { color: var(--muted); font-size: var(--fs-md); }
.sel { background: var(--ea-accent-soft); }
.ico { width: 28px; height: 28px; border-radius: var(--r-md); background: var(--neu-s); color: var(--ea-text-2); font-size: var(--fs-xs); font-weight: 700; display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
mark { background: #fde68a; color: inherit; border-radius: var(--r-sm); padding: 0 1px; }
html.dark mark { background: #5c4a12; }

/* --- page container: board main is 24px 40px on a 1440 canvas --------------------------------- */
.ea-page { max-width: 1440px; margin: 0 auto; padding: 24px 40px; display: flex; flex-direction: column; gap: 16px; min-width: 0; }
.ea-page > * { min-width: 0; }
@media (max-width: 1023px) { .ea-page { padding: 20px 24px; } }
@media (max-width: 767px)  { .ea-page { padding: 16px; } }

/* --- card ------------------------------------------------------------------------------------- */
.card { background: var(--surface); border: 1px solid var(--ea-line); border-radius: var(--r-xl); }
.card-pad { padding: 16px; }
.card-pad.kpi--hero { padding: 20px; }
.sec-card { display: flex; align-items: center; gap: 12px; padding: 12px 16px; }
.panel-head { display: flex; align-items: center; gap: 8px; padding: 14px 16px; border-bottom: 1px solid var(--ea-line); font-size: var(--fs-md); font-weight: 600; color: var(--ea-ink); }

/* --- KPI tile (existing classes, board values) -------------------------------------------------
   Board: label .lbl 12/600 slate-600, value 26/32 600, hero 38/44 800 (fluid below ~1310px,
   see the B0 note on .kpi--hero), sub .cap 11 slate-500, tile padding 16 (hero 20). */
.kpi-label { font-size: var(--fs-sm); line-height: 16px; font-weight: 600; color: var(--ea-text-2); letter-spacing: 0; }
.kpi-value { font-size: var(--fs-xl); line-height: var(--lh-xl); font-weight: 600; color: var(--ea-ink); font-variant-numeric: tabular-nums; font-feature-settings: 'tnum'; }
.kpi-sub { font-size: var(--fs-xs); line-height: var(--lh-xs); color: var(--muted); }
.kpi--hero .kpi-value,
.kpi--hero.pv-kpi .val,
.kpi--hero.ep-kpi .val { font-size: clamp(var(--fs-xl), 2.9vw, var(--fs-2xl)); line-height: 1.16; font-weight: 800; letter-spacing: -.02em; }
.pv-kpi, .ep-kpi { padding: 16px; }
.pv-kpi.kpi--hero, .ep-kpi.kpi--hero { padding: 16px 20px; }
.pv-kpi .lab, .ep-kpi .lab { margin-bottom: 6px; }
.pv-kpi .lab .eyebrow, .ep-kpi .lab .eyebrow, .pv-kpi .eyebrow, .ep-kpi .eyebrow { font-size: var(--fs-sm); line-height: 16px; font-weight: 600; color: var(--ea-text-2); letter-spacing: 0; text-transform: none; }
.ea-kpirow { gap: 16px; }
button.ea-kpi--drill:hover { background: var(--ea-subtle); }
html.dark button.ea-kpi--drill:hover { background: var(--ea-subtle); }

/* --- chips / badges ------------------------------------------------------------------------------
   Board chip: 22px (line-height 20 + 1px border), 0 7px, radius 6, 11/600, 1px border. `.chip` alone = the neutral (`neu`)
   descriptor; status tints are `.chip.ok|caut|fail|info|na` on the six role triplets. */
.chip { display: inline-flex; align-items: center; gap: 4px; min-height: 22px; padding: 0 7px; border-radius: var(--r-md);
  font-size: var(--fs-xs); line-height: 20px; font-weight: 600; border: 1px solid var(--neu-b); background: var(--neu-s); color: var(--neu-t); vertical-align: middle; }
html.dark .chip { background: var(--neu-s); color: var(--neu-t); border-color: var(--neu-b); }
.chip.ok,   html.dark .chip.ok   { color: var(--ok-t);   background: var(--ok-s);   border-color: var(--ok-b); }
.chip.caut, html.dark .chip.caut { color: var(--caut-t); background: var(--caut-s); border-color: var(--caut-b); }
.chip.fail, html.dark .chip.fail { color: var(--fail-t); background: var(--fail-s); border-color: var(--fail-b); }
.chip.info, html.dark .chip.info { color: var(--info-t); background: var(--info-s); border-color: var(--info-b); }
.chip.neu,  html.dark .chip.neu  { color: var(--neu-t);  background: var(--neu-s);  border-color: var(--neu-b); }
.chip.na,   html.dark .chip.na   { color: var(--na-t);   background: var(--na-s);   border-color: var(--na-b); }
.chip-lg { min-height: 28px; padding: 0 10px; font-size: var(--fs-sm); }
.chip.stage { color: var(--ea-accent-ink); background: var(--ea-accent-soft); border-color: var(--ea-accent-line); }
html.dark .ep .chip.stage { color: var(--ea-accent-ink); background: var(--ea-accent-soft); border-color: var(--ea-accent-line); }
.badge { border-radius: var(--r-md); font-weight: 600; padding: 1px 7px; line-height: 16px; }
.prov { border-radius: var(--r-sm); }

/* --- buttons ---------------------------------------------------------------------------------- */
.btn { height: var(--h-ctl); display: inline-flex; align-items: center; justify-content: center; gap: 6px; padding: 0 12px; box-sizing: border-box;
  border: 1px solid var(--ea-line); border-radius: var(--r-lg); background: var(--surface); color: var(--ea-ink);
  font-family: inherit; font-size: var(--fs-sm); font-weight: 500; line-height: 1; white-space: nowrap; text-decoration: none; cursor: pointer;
  transition: background-color .12s ease, border-color .12s ease; }
.btn:hover { background: var(--ea-subtle); text-decoration: none; }
.btn:focus-visible, button.primary:focus-visible, button.ghost:focus-visible, .pv-btn:focus-visible, .mon-btn:focus-visible { outline: 2px solid var(--ea-accent); outline-offset: 2px; }
.btn:disabled, .btn[aria-disabled="true"] { opacity: .4; cursor: default; }
.btn-sm { height: var(--h-ctl-sm); padding: 0 10px; border-radius: var(--r-md); }
.btn.btn-quiet { border-color: transparent; background: transparent; color: var(--ea-accent); font-weight: 600; padding: 0 4px; }
.btn.btn-quiet:hover { background: transparent; text-decoration: underline; }
.btn-primary, button.primary, .pv-btn.primary, .mon-btn.primary,
html.dark .btn-primary, html.dark button.primary, html.dark .pv-btn.primary, html.dark .mon-btn.primary {
  background: var(--btn-primary-bg); border: 1px solid var(--btn-primary-line); color: var(--btn-primary-t); font-weight: 600; }
.btn-primary:hover, button.primary:hover, .pv-btn.primary:hover, .mon-btn.primary:hover,
html.dark .btn-primary:hover, html.dark button.primary:hover, html.dark .pv-btn.primary:hover, html.dark .mon-btn.primary:hover { background: var(--btn-primary-hover); }
/* `.btn-primary` standing alone (one legacy call site) gets the full board button geometry. */
.btn-primary:not(.btn) { height: var(--h-ctl); display: inline-flex; align-items: center; gap: 6px; padding: 0 12px; border-radius: var(--r-lg); font-size: var(--fs-sm); cursor: pointer; }
button.primary { display: inline-flex; align-items: center; justify-content: center; gap: 6px; min-height: var(--h-ctl); padding: 0 12px; border-radius: var(--r-lg); font-size: var(--fs-sm); line-height: 1; }
.btn-danger { background: var(--surface); border-color: var(--fail-b); color: var(--fail-t); font-weight: 600; }
.btn-danger:hover { background: var(--fail-s); }
.btn-icon { width: var(--h-ctl); padding: 0; justify-content: center; }
.btn-sm.btn-icon { width: var(--h-ctl-sm); }
button.ghost { display: inline-flex; align-items: center; justify-content: center; gap: 6px; min-height: var(--h-ctl); padding: 0 12px; border-radius: var(--r-lg);
  background: var(--surface); color: var(--ea-ink); border: 1px solid var(--ea-line); font-size: var(--fs-sm); font-weight: 500; line-height: 1; }
button.ghost:hover { background: var(--ea-subtle); }
.pv-btn, .mon-btn { border-radius: var(--r-lg); font-size: var(--fs-sm); background: var(--surface); border-color: var(--ea-line); }
.pv-btn:hover, .mon-btn:hover { background: var(--ea-subtle); }
/* Board .btn-quiet: accent, 600, underline on hover. Size stays with the call site (inline links). */
.btn-quiet { color: var(--ea-accent); font-weight: 600; border-radius: var(--r-md); }
.btn-quiet:hover { color: var(--ea-accent); text-decoration: underline; }

/* --- pill / segmented control ------------------------------------------------------------------ */
.pill { height: var(--h-ctl-sm); display: inline-flex; align-items: center; gap: 6px; padding: 0 10px; box-sizing: border-box;
  border-radius: var(--r-md); border: 1px solid transparent; background: transparent; color: var(--ea-text-2);
  font-family: inherit; font-size: var(--fs-sm); font-weight: 500; text-decoration: none; white-space: nowrap; cursor: pointer; }
.pill:hover { background: var(--neu-s); color: var(--ea-ink); text-decoration: none; }
.pill.on, .pill.on:hover { background: var(--ea-accent-soft); color: var(--ea-accent-ink); font-weight: 600; border-color: var(--ea-accent-line); }
.pill:focus-visible { outline: 2px solid var(--ea-accent); outline-offset: 2px; }
.seg, .pv-seg { display: inline-flex; flex-wrap: wrap; border: 1px solid var(--ea-line); border-radius: var(--r-lg); background: var(--surface); padding: 2px; gap: 2px; overflow: visible; }
.seg button, .pv-seg button { height: 26px; padding: 0 10px; border: 1px solid transparent; border-radius: var(--r-md); background: transparent;
  font-family: inherit; font-size: var(--fs-sm); font-weight: 500; color: var(--ea-text-2); cursor: pointer; white-space: nowrap; }
.seg button:hover, .pv-seg button:hover { color: var(--ea-ink); background: var(--neu-s); }
.seg button.on, .pv-seg button.on, html.dark .pv-seg button.on { background: var(--ea-accent-soft); color: var(--ea-accent-ink); font-weight: 600; border-color: var(--ea-accent-line); }
.seg button:focus-visible, .pv-seg button:focus-visible { outline: 2px solid var(--ea-accent); outline-offset: 1px; }

/* --- tabs (mandate facet row) ------------------------------------------------------------------ */
.ea-tabs { display: flex; gap: 4px; border-bottom: 1px solid var(--ea-line); overflow-x: auto; overflow-y: hidden; scrollbar-width: none; max-width: 100%; }
.ea-tabs::-webkit-scrollbar { display: none; }
.tab { padding: 10px 12px; font-family: inherit; font-size: var(--fs-md); line-height: var(--lh-md); color: var(--ea-text-2); background: transparent; border: 0;
  border-bottom: 2px solid transparent; margin-bottom: -1px; white-space: nowrap; text-decoration: none; cursor: pointer; flex-shrink: 0; }
.tab:hover { color: var(--ea-ink); text-decoration: none; }
.tab-on, .tab-on:hover { font-weight: 600; color: var(--ea-ink); border-bottom-color: var(--ea-accent); }
.tab:focus-visible { outline: 2px solid var(--ea-accent); outline-offset: -2px; border-radius: var(--r-md); }
/* the ink tab of the older views (.tab-active) follows the board: underline, not fill */
.tab-active { background: transparent; color: var(--ea-ink); box-shadow: inset 0 -2px 0 var(--ea-accent); font-weight: 600; }

/* --- table ------------------------------------------------------------------------------------- */
.th { font-size: var(--fs-xs); font-weight: 600; color: var(--ea-text-2); text-align: left; padding: 8px 12px; border-bottom: 1px solid var(--ea-line); background: var(--ea-subtle); white-space: nowrap; }
.td { font-size: var(--fs-sm); padding: 8px 12px; border-bottom: 1px solid var(--ea-line); white-space: nowrap; }
.th.num, .td.num { text-align: right; }
.grp { padding: 6px 12px; background: var(--ea-subtle); border-bottom: 1px solid var(--ea-line); font-size: var(--fs-xs); font-weight: 600; color: var(--ea-text-2); white-space: nowrap; }
tr.grp { padding: 0; }
table.matrix th { background: var(--ea-subtle); color: var(--ea-text-2); font-size: var(--fs-xs); font-weight: 600; padding: 8px 12px; }
table.matrix td { font-size: var(--fs-sm); padding: 8px 12px; }
table.matrix tr:hover td { background: var(--ea-subtle); }
html.dark table.matrix th { background: var(--ea-subtle); color: var(--ea-text-2); }
/* The board's table head is sentence case, 11/600 slate-600 on slate-50 — no uppercase wall. */
.pv table.matrix th, .ep table.matrix th, .dl-fin th, .ltx-tbl th { text-transform: none; letter-spacing: 0; color: var(--ea-text-2); background: var(--ea-subtle); }
html.dark .pv table.matrix th, html.dark .dl-fin th, html.dark .ltx-tbl th { background: var(--ea-subtle); color: var(--ea-text-2); }
.pv .grp td, html.dark .pv .grp td { background: var(--ea-subtle); color: var(--ea-text-2); }
.pv table.matrix tfoot td, html.dark .pv table.matrix tfoot td { background: var(--ea-subtle); }
.pv-twrap { border-radius: var(--r-xl); }

/* --- kbd / fields -------------------------------------------------------------------------------- */
.kbd { display: inline-flex; align-items: center; height: 18px; padding: 0 5px; border: 1px solid var(--ea-line); border-bottom-width: 2px; border-radius: var(--r-sm);
  font-size: var(--fs-xs); color: var(--muted); background: var(--surface); white-space: nowrap; }
.field { box-sizing: border-box; border: 1px solid var(--ea-line); border-radius: var(--r-lg); font-family: inherit; font-size: var(--fs-sm); color: var(--ea-ink); background: var(--surface); }
input.field, select.field:not([multiple]):not([size]) { height: var(--h-ctl); padding: 0 10px; }
textarea.field { padding: 8px 10px; }
input.field, select.field, textarea.field { font-size: var(--fs-sm); border-radius: var(--r-lg); background: var(--surface); color: var(--ea-ink); }
html.dark input.field, html.dark select.field, html.dark textarea.field { background: var(--surface); color: var(--ea-ink); border-color: var(--ea-line); }
input.field:focus, select.field:focus, textarea.field:focus { border-color: var(--ea-accent); box-shadow: 0 0 0 3px var(--ea-accent-soft); outline: none; }
.field-l { display: flex; flex-direction: column; gap: 4px; font-size: var(--fs-sm); font-weight: 600; color: var(--ea-text-2); }

/* --- bars (board .bar/.track/.fill + textures) --------------------------------------------------- */
.bar { display: grid; grid-template-columns: 168px 1fr 52px; gap: 12px; align-items: center; font-size: var(--fs-sm); }
.track { height: 8px; border-radius: var(--r-sm); background: var(--neu-s); }
.fill { height: 8px; border-radius: var(--r-sm); background: var(--ea-accent); }
.hatch { background: repeating-linear-gradient(135deg, #d97706 0 2px, var(--caut-s) 2px 6px); }
.dots { background-color: var(--caut-s); background-image: radial-gradient(#d97706 1.2px, transparent 1.4px); background-size: 5px 5px; }
.est { background: repeating-linear-gradient(135deg, var(--ea-accent) 0 3px, var(--ea-accent-soft) 3px 7px); }

/* --- states (St*.dc.html): error / empty cards via the shared builders ------------------------- */
.ea-state { padding: 32px; display: flex; flex-direction: column; gap: 12px; }
.ea-state--empty { align-items: center; text-align: center; padding: 48px 24px; }
.ea-state__h { display: flex; align-items: center; gap: 12px; }
.ea-state__ic { width: 32px; height: 32px; padding: 0; justify-content: center; border-radius: var(--r-pill); font-size: 16px; }
.ea-state__t { margin: 0; font-size: var(--fs-lg); line-height: 24px; font-weight: 600; color: var(--ea-ink); }
.ea-state__p { margin: 0; max-width: 760px; font-size: var(--fs-md); line-height: 21px; color: var(--ea-text-2); }
.ea-state__acts { display: flex; gap: 8px; flex-wrap: wrap; }
.ea-state__det { margin-top: 4px; }
.ea-state__det summary { cursor: pointer; }
.ea-state__det pre { margin: 8px 0 0; padding: 12px; background: var(--ea-subtle); border: 1px solid var(--ea-line); border-radius: var(--r-lg);
  font-size: var(--fs-sm); line-height: 18px; color: var(--ea-text-2); white-space: pre-wrap; word-break: break-word; max-height: 240px; overflow: auto; }

/* ============================================================
   SHELL — header 52px + second level 40px (`renderTopNav`, artboard header on every board)
   Level 1 (`.nav-l1`): brand mark "EA" + "EA Cockpit", the three sections with the accent
   underline, right: theme · avatar · sign out. Level 2 (`.nav-l2`): pills of the active
   section; in a mandate the crumb "Mandates › <mandate ▾>" (the switcher). Both bands are
   sticky with FIXED heights — the 53px `top` of level 2 is 52 + the 1px border of level 1.
   Mobile: each `.nav-row` scrolls sideways inside itself (no h-scroll of the body).
   The Ctrl K search field of the board is deferred (new feature).
   ============================================================ */
.nav-l1, .nav-l2 { position: sticky; z-index: 40; background: var(--surface); border-bottom: 1px solid var(--ea-line); }
.nav-l1 { top: 0; }
.nav-l2 { top: 53px; }
/* Header content sits on the page measure (= .ea-page: max 1440, 40px gutters) so it lines up with the body on ultra-wide screens; the band background stays full-width. */
.nav-row { display: flex; align-items: center; gap: 4px; padding: 0 40px; max-width: 1440px; margin: 0 auto; box-sizing: border-box; height: var(--h-header);
  overflow-x: auto; overflow-y: hidden; white-space: nowrap; scrollbar-width: none; }
.nav-row::-webkit-scrollbar { display: none; }
.nav-l1 .nav-row { gap: 32px; }
.nav-l2 .nav-row { height: var(--h-subnav); gap: 4px; }
.nav-brand { display: flex; align-items: center; gap: 10px; flex-shrink: 0; font-size: var(--fs-md); font-weight: 700; color: var(--ea-ink); }
.nav-brand-mark { width: 24px; height: 24px; border-radius: var(--r-md); background: #0b1a2b; color: #fffffe; font-size: var(--fs-xs); font-weight: 800;
  display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; }
html.dark .nav-brand-mark { background: #e8eef5; color: #0b1a2b; }
.nav-brand-mark--lg { width: 36px; height: 36px; border-radius: var(--r-lg); font-size: var(--fs-md); }
.nav-brand-name { font-size: var(--fs-md); font-weight: 700; color: var(--ea-ink); white-space: nowrap; }
.nav-brand-sub { font-size: var(--fs-xs); font-weight: 500; color: var(--muted); }
.nav-secs { display: flex; gap: 24px; align-self: stretch; flex-shrink: 0; }
.nav-sec { position: relative; display: flex; align-items: center; background: transparent; border: 0; cursor: pointer; font-family: inherit;
  font-size: var(--fs-md); font-weight: 500; color: var(--ea-text-2); padding: 0 2px; height: var(--h-header); white-space: nowrap; }
.nav-sec:hover { color: var(--ea-ink); }
.nav-sec.is-active { color: var(--ea-ink); font-weight: 600; }
.nav-sec.is-active::after { content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 2px; background: var(--ea-accent); border-radius: 0; }
.nav-sec:focus-visible { outline: 2px solid var(--ea-accent); outline-offset: -4px; border-radius: var(--r-md); }
.nav-user { margin-left: auto; display: flex; align-items: center; gap: 12px; flex-shrink: 0; padding-left: 12px; }
.nav-avatar { width: 32px; height: 32px; border-radius: var(--r-pill); background: var(--neu-s); color: var(--ea-text-2); font-size: var(--fs-xs); font-weight: 700;
  display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; }
.nav-signout { font-size: var(--fs-sm); }
.nav-theme { width: 32px; height: 32px; border-radius: var(--r-lg); border: 1px solid var(--ea-line); background: var(--surface);
  cursor: pointer; font-size: 14px; line-height: 1; display: inline-flex; align-items: center; justify-content: center; color: var(--ea-ink); flex-shrink: 0; }
.nav-theme:hover { background: var(--ea-subtle); }
.nav-theme:focus-visible { outline: 2px solid var(--ea-accent); outline-offset: 2px; }
.nav-grow { flex-grow: 1; min-width: 12px; }
.nav-crumb-sep { font-size: var(--fs-xs); color: var(--muted); padding: 0; }
.nav-across { margin-right: 4px; }
.nav-cta { flex-shrink: 0; }
/* The level-2 pill is the board `.pill` (both classes are written); the old names stay valid. */
.nav-pill { height: 30px; display: inline-flex; align-items: center; gap: 6px; padding: 0 10px; box-sizing: border-box;
  border-radius: var(--r-md); border: 1px solid transparent; background: transparent; color: var(--ea-text-2);
  font-family: inherit; font-size: var(--fs-sm); font-weight: 500; white-space: nowrap; cursor: pointer; flex-shrink: 0; }
.nav-pill:hover { background: var(--neu-s); color: var(--ea-ink); }
.nav-pill.is-active, .nav-pill.is-active:hover { background: var(--ea-accent-soft); border-color: var(--ea-accent-line); color: var(--ea-accent-ink); font-weight: 600; }
.nav-pill.nav-act { color: var(--ea-text-2); font-weight: 500; }
.nav-pill:focus-visible { outline: 2px solid var(--ea-accent); outline-offset: 2px; }
.nav-badge { font-size: var(--fs-xs); font-weight: 600; color: var(--muted); font-variant-numeric: tabular-nums; }
.nav-badge.is-warn, .nav-pill.is-active .nav-badge.is-warn { color: var(--caut-t); }
@media (max-width: 1023px) { .nav-row { padding: 0 24px; } }
@media (max-width: 767px) {
  .nav-row { padding: 0 16px; }
  .nav-l1 .nav-row { gap: 20px; }
  .nav-secs { gap: 16px; }
  .nav-l2 .nav-row { height: 44px; }
  nav .nav-pill { min-height: 0; }
  .nav-signout, .nav-theme, .nav-sec { min-height: 0; }
  .nav-user { gap: 8px; }
}

/* Phone (<=640px): nothing may be clipped at the right edge. Level 1 wraps into two fixed
   lines - brand + theme/avatar/sign-out (52px), then the three sections (40px) - so level 2's
   sticky `top` stays deterministic (52 + 40 + 1 = 93px). Level 2 wraps its pills onto as many
   lines as needed and is NOT sticky here (a 2-3 line sticky band would eat the phone screen).
   A long mandate name in the switcher ellipsizes instead of pushing past the edge. */
.nav-switch-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@media (max-width: 640px) {
  .nav-l1 .nav-row { flex-wrap: wrap; height: auto; overflow: visible; row-gap: 0; column-gap: 12px; }
  .nav-l1 .nav-brand { order: 1; height: var(--h-header); }
  .nav-l1 .nav-user { order: 2; height: var(--h-header); padding-left: 0; }
  .nav-l1 .nav-secs { order: 3; flex: 0 0 100%; height: var(--h-subnav); gap: 20px; overflow-x: auto; scrollbar-width: none; }
  .nav-l1 .nav-secs::-webkit-scrollbar { display: none; }
  .nav-l1 .nav-sec { height: var(--h-subnav); }
  .nav-l2 { position: static; }
  .nav-l2 .nav-row { flex-wrap: wrap; height: auto; min-height: var(--h-subnav); overflow: visible; white-space: normal; padding: 6px 16px; row-gap: 4px; }
  .nav-l2 .nav-grow { flex-basis: 100%; height: 0; min-width: 0; }
  .nav-switch { max-width: 100%; min-width: 0; }
  .nav-switch-trg { max-width: 100%; }
  nav .nav-cta { min-height: 0; }
}

/* ---- mandate switcher (MandateSwitcher board) — menu is position:fixed, placed after render
   from the trigger rect (`navMandSwitchPlace`): the scrolling .nav-row would clip an absolute child. */
.nav-switch { position: relative; display: inline-flex; flex-shrink: 0; }
.nav-switch-cv { margin-left: 2px; }
.nav-switch-menu { position: fixed; width: 340px; max-width: calc(100vw - 16px); box-sizing: border-box; max-height: 60vh; overflow-y: auto;
  background: var(--surface); border: 1px solid var(--ea-line); border-radius: var(--r-xl); box-shadow: var(--shadow-pop);
  padding: 8px; z-index: 60; white-space: normal; display: flex; flex-direction: column; gap: 2px; }
.nav-switch-h { font-size: var(--fs-xs); font-weight: 600; color: var(--muted); padding: 4px 12px 4px; }
.nav-switch-item { display: flex; align-items: center; gap: 10px; width: 100%; text-align: left; background: transparent; border: 0; cursor: pointer;
  font-family: inherit; font-size: var(--fs-sm); color: var(--ea-ink); padding: 8px 12px; border-radius: var(--r-md); }
.nav-switch-item:hover { background: var(--neu-s); }
.nav-switch-item:focus-visible { outline: 2px solid var(--ea-accent); outline-offset: -2px; }
.nav-switch-item.is-on, html.dark .nav-switch-item.is-on { background: var(--ea-accent-soft); }
.nav-switch-item.is-on .nav-switch-nm { color: var(--ea-accent-ink); }
.nav-switch-tk { width: 14px; flex: 0 0 14px; color: var(--ea-accent); font-weight: 700; }
.nav-switch-lbl { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex-grow: 1; }
.nav-switch-nm { font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.nav-switch-cl { font-size: var(--fs-xs); color: var(--muted); }
.nav-switch-all { border-top: 1px solid var(--ea-line); margin-top: 4px; padding: 8px 4px 2px; display: flex; align-items: center; justify-content: space-between; gap: 8px; }

/* ============================================================
   MANDATE SHELL — header + tabs (`renderMandateDetail`, `renderFxStrip`, rollup foot)
   Board: label line "Mandate · <client>", h1 26/32 700, valuation-date + reporting chips
   right, then the tab row. Below the tabs a context line keeps what the board omits but the
   app has (sleeve switch, counts, estimated NAVs) and the FX strip. Everything wraps at 375.
   ============================================================ */
.mh { display: flex; flex-direction: column; gap: 12px; }
.mh-back { margin-bottom: -4px; }
.mh-top { display: flex; align-items: flex-end; gap: 8px 12px; flex-wrap: wrap; }
.mh-title { flex: 1 1 280px; display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.mh-title .ea-h1 { overflow-wrap: anywhere; }
.mh-chips { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.mh-asof { gap: 6px; }
.mh-asof input { font-family: inherit; font-size: var(--fs-sm); font-weight: 600; color: inherit; background: transparent; border: 0; padding: 0; margin: 0; cursor: pointer; font-variant-numeric: tabular-nums; }
.mh-asof input:focus-visible { outline: 2px solid var(--ea-accent); outline-offset: 2px; border-radius: var(--r-sm); }
html.dark .mh-asof input { color-scheme: dark; }
.mh-ctx { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 4px 0 4px; min-height: 32px; }  /* batch 5 B1: 20px under the tab row (16 gap + 4) */
.mh-ctx > .ea-fx { margin-left: auto; }
/* ^ design gate #6: ONE toolbar line under the tabs - left sleeve switch, counts, estimated NAVs;
   right the FX pairs, stamp and Refresh FX with no card around them. 12px under the tabs, 20px
   to the first content block (16 gap + 4). Wraps on a phone; no h-scroll. */
.mh-body { min-width: 0; }
.ea-fx { display: flex; align-items: center; gap: 6px 10px; flex-wrap: wrap; font-size: var(--fs-sm); min-width: 0; }
.ea-fx.is-stale { }
.ea-fx-pair { display: inline-flex; align-items: baseline; gap: 6px; white-space: nowrap; }
.ea-fx-v { font-weight: 600; color: var(--ea-ink); }
.ea-fx-stale { color: var(--caut-t); font-weight: 600; }
.ea-fx-miss { font-size: var(--fs-xs); color: var(--fail-t); }
/* FIX 19: the CHF rollup row is a subtle total row in bold ink (was a dark foot). */
.ea-rollup-foot td { background: var(--ea-subtle); color: var(--ea-ink); font-weight: 700; border-top: 1px solid var(--ea-line); }
.ea-rollup-foot td .cap { font-weight: 400; }
.ea-rollup-foot .ea-foot-note { font-size: var(--fs-xs); font-weight: 400; white-space: normal; }
.ea-rollup-foot .ea-foot-note--quiet { color: var(--muted); }
.ea-rollup-foot .ea-foot-note.r-caut { color: var(--caut-t); background: var(--caut-s); }
.ea-rollup-foot .ea-foot-note.r-fail { color: var(--fail-t); background: var(--fail-s); }
.ea-ccy-table th, .ea-ccy-table td { white-space: nowrap; }
@media (max-width: 767px) {
  .mh-top { align-items: flex-start; }
  .ea-state { padding: 20px; }
  .tab { padding: 10px; }
}

/* ============================================================
   FIX 17 (design gate batch 4) — shared primitives, app-wide
   ============================================================ */
/* table rows: header 31px, chip-less row 32px */
.th { line-height: 14px; }
.td { line-height: 15px; }
/* mandate tab row 39px */
.tab { line-height: var(--lh-sm); }
/* top bar: sections without side padding; the theme toggle is a quiet 16px monochrome glyph */
.nav-sec { padding: 0; }
.nav-theme { border: 0; background: transparent; color: var(--ea-text-2); border-radius: var(--r-lg); }
.nav-theme:hover { background: var(--neu-s); color: var(--ea-ink); }
.nav-theme svg { display: block; }
/* mandate header: controls 30px, level with the h1; date input borderless, the calendar icon
   shows on hover / focus only (the input stays focusable and opens with the keyboard) */
.mh-chips .chip-lg { min-height: 30px; }
.mh-chips .btn-sm { height: 30px; }
.mh-chips { margin-bottom: 1px; }
.mh-asof input { border: 0; outline-offset: 2px; }
.mh-asof input::-webkit-calendar-picker-indicator { opacity: 0; cursor: pointer; margin-left: 2px; transition: opacity .12s ease; }
.mh-asof:hover input::-webkit-calendar-picker-indicator,
.mh-asof input:focus::-webkit-calendar-picker-indicator,
.mh-asof input:focus-visible::-webkit-calendar-picker-indicator { opacity: 1; }
/* EAUI.targetBar — board Open-items band: radius 12, 12px 16px, no dot, label = white chip in
   the state tone, message in ink with bold ink lead-ins, points inline, neutral btn-sm action */
.ea-tb { border-radius: var(--r-xl); padding: 12px 16px; align-items: center; }
.ea-tb.ea-tb--ok, .ea-tb.ea-tb--warn, .ea-tb.ea-tb--breach { color: var(--ea-ink); }
.ea-tb--ok .ea-tb__bar { color: var(--ok-t); }
.ea-tb--warn .ea-tb__bar { color: var(--caut-t); }
.ea-tb--breach .ea-tb__bar { color: var(--fail-t); }
.ea-tb__txt { align-items: center; gap: 8px; }
html .ea-tb .ea-tb__label.chip { background: var(--surface); font-weight: 600; }
.ea-tb__msg { color: var(--ea-ink); font-size: var(--fs-sm); line-height: 18px; }
.ea-tb__msg b, .ea-tb__msg strong { font-weight: 700; color: var(--ea-ink); }
.ea-tb .ea-tb__act, html.dark .ea-tb .ea-tb__act { opacity: 1; height: var(--h-ctl-sm); padding: 0 10px; border: 1px solid var(--ea-line); border-radius: var(--r-md);
  background: var(--surface); color: var(--ea-ink); font-weight: 500; font-size: var(--fs-sm); text-decoration: none; }
.ea-tb .ea-tb__act:hover, html.dark .ea-tb .ea-tb__act:hover { background: var(--ea-subtle); }
/* EAUI.section — 48px head, count as chip.neu, muted chevron, one-line rollup, headRight slot */
.ea-sec__toggle { padding: 12px 16px; }
.ea-sec__chev { color: var(--muted); }
.ea-sec__count { display: inline-flex; align-items: center; min-height: 20px; padding: 0 7px; border-radius: var(--r-md); line-height: 18px;
  font-size: var(--fs-xs); font-weight: 600; color: var(--neu-t); background: var(--neu-s); border: 1px solid var(--neu-b); }
.ea-sec__meta { padding: 8px 16px 8px 0; }
.ea-sec__roll { align-items: center; gap: 8px; }
.ea-sec__rollitem + .ea-sec__rollitem::before { content: '\00B7'; color: var(--muted); margin-right: 4px; }
.ea-sec__rollitem { flex-direction: row; align-items: baseline; gap: 4px; }
.ea-sec__rolllab { font-size: var(--fs-sm); font-weight: 400; color: var(--ea-text-2); }
.ea-sec__rollval { font-size: var(--fs-sm); font-weight: 700; color: var(--ea-ink); }
.ea-sec__rollchip b { font-weight: 700; color: var(--ea-ink); }
.ea-sec__right { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding: 8px 16px 8px 0; min-width: 0; }
/* EAUI.kpi drill: board ">" in the label colour, no dotted underline under the value */
.ea-kpi__arrow { color: inherit; font-weight: inherit; }
button.ea-kpi--drill:hover .ea-kpi__arrow { color: inherit; }
.ea-kpi--drill .kpi-value { text-decoration: none; }
/* filterDropdown trigger (Registry, Calendar, Compare) — a btn btn-sm, auto width */
.ea-fd-trg { gap: 6px; }
.ea-fd-val { font-weight: 600; }
.ea-fd-cv { color: var(--muted); flex-shrink: 0; transition: transform .15s ease; }
.ea-fd-cv.is-open { transform: rotate(180deg); }
@media (prefers-reduced-motion: reduce) { .ea-fd-cv { transition: none; } }
/* Batch 5 B1 — the valuation-date chip ends ~10px after the date: the input is sized to its
   content (fallback 11ch) and the hidden picker icon reserves no width until hover / focus.
   The input stays a real <input type=date>: focusable, keyboard-operable, picker on click. */
.mh-asof input { width: 12ch; min-width: 0; position: relative; padding-right: 0; box-sizing: content-box; }
.mh-asof input::-webkit-calendar-picker-indicator { position: absolute; right: 0; top: 50%; transform: translateY(-50%); width: 12px; height: 12px; margin: 0; padding: 0; }
.mh-asof:hover input, .mh-asof input:focus { padding-right: 16px; }  /* room for the icon while it shows */

/* ROW standard (DESIGN.md §4.5) — every board table (.td) gets the full-row hover that
   table.matrix already has; `tr.row-open` rows open their primary link from anywhere in the
   row (one delegated handler, `installRowOpen` in app.js). Token-driven: dark = #16212e. */
tbody tr:hover > td.td { background: var(--ea-subtle); }
tr.row-open > td { cursor: pointer; }

/* ============================================================
   Micro-Interaktionen (assets/ui-motion.js) — DESIGN.md §4.13
   Bewegung meldet einen ZUSTANDSWECHSEL, nie Dekoration. 120–200 ms, nur Tokens, und jede
   Animation hat fill-mode:none und einen Startwert, der auch EINGEFROREN lesbar ist
   (Deckkraft >= .6, Versatz <= 4 px) — kein Zustand haengt an einer laufenden Animation.
   Kein eigener html.dark-Block: jede Farbe hier ist ein Token, das §8 schon remappt.
   ============================================================ */

/* §1 Toast — top-right, --fs-sm, shadow-pop (DESIGN.md §4.6); die Rolle als linke Kante */
.ea-toast-host { position: fixed; top: 16px; right: 16px; z-index: 100; display: flex; flex-direction: column;
  gap: 8px; pointer-events: none; width: max-content; max-width: min(380px, calc(100vw - 32px)); }
.ea-toast { pointer-events: auto; display: flex; align-items: flex-start; gap: 10px; padding: 9px 10px 9px 12px;
  background: var(--surface); color: var(--ea-ink); border: 1px solid var(--ea-line); border-left-width: 3px;
  border-radius: var(--r-lg); box-shadow: var(--shadow-pop); font-size: var(--fs-sm); line-height: var(--lh-sm);
  animation: ea-toast-in .16s ease-out; transition: opacity .16s ease, transform .16s ease; }
.ea-toast.is-leaving { opacity: 0; transform: translateX(8px); }
.ea-toast--info { border-left-color: var(--neu-t); }
.ea-toast--ok   { border-left-color: var(--ok-t); }
.ea-toast--caut { border-left-color: var(--caut-t); }
.ea-toast--fail { background: var(--fail-s); border-color: var(--fail-b); border-left-color: var(--fail-t); color: var(--fail-t); }
.ea-toast__msg { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; }
.ea-toast__act { flex: none; background: none; border: 0; padding: 0 2px; font: inherit; font-weight: 600;
  color: var(--ea-accent); cursor: pointer; text-decoration: underline; text-underline-offset: 2px; }
.ea-toast__x { flex: none; background: none; border: 0; padding: 0 2px; margin-top: -1px; font-size: 16px; line-height: 1;
  color: var(--muted); cursor: pointer; border-radius: var(--r-sm); }
.ea-toast__x:hover { color: var(--ea-ink); }
.ea-toast__act:focus-visible, .ea-toast__x:focus-visible { outline: 2px solid var(--ea-accent); outline-offset: 2px; }
@keyframes ea-toast-in { from { opacity: .6; transform: translateY(-4px); } to { opacity: 1; transform: none; } }

/* §2 Dialog-Eintritt fuer die handgebauten Overlays — Host blendet, Panel hebt sich (Modal)
   bzw. schiebt (Drawer, `justify-end`). Klasse nur fuer den Eintritt, danach wieder weg. */
.ea-ov-in { animation: ea-ov-fade .14s ease-out; }
.ea-ov-in > .ea-ov-pop { animation: ea-ov-pop .16s ease-out; }
.ea-ov-in > .ea-ov-slide { animation: ea-ov-slide .18s ease-out; }
@keyframes ea-ov-fade { from { opacity: .6; } to { opacity: 1; } }
@keyframes ea-ov-pop { from { transform: translateY(4px) scale(.99); } to { transform: none; } }
@keyframes ea-ov-slide { from { transform: translateX(4px); } to { transform: none; } }

/* §3 Reduced motion — EINE Regel fuer die ganze App (DESIGN.md §10), auch fuer alles, was die
   einzelnen Komponenten-Bloecke vergessen haben: Shimmer, Chip-/Aktions-Uebergaenge, die
   Micro-Interaktionen. Nicht 0 s, sondern .001 ms — so feuern animationend/transitionend
   weiterhin, falls je ein Code darauf wartet. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .001ms !important; animation-iteration-count: 1 !important;
    transition-duration: .001ms !important; scroll-behavior: auto !important; }
  .skel { animation: none !important; }
}

/* §4 Fokus-Ring als Rueckfall (DESIGN.md §10) — :where() haelt die Spezifitaet bei 0, jeder
   bestehende :focus-visible-Stil (btn, pill, tab, nav, drill, EAUI …) gewinnt weiterhin. Gedeckt
   werden damit die Tailwind-gestylten Knoepfe, Links und Zeilen-Links ohne eigenen Ring.
   ⚠ Felder (input/textarea) sind bewusst NICHT drin — .field traegt seinen Fokus-Rahmen selbst. */
:where(button, a[href], [role="button"], summary, select, [tabindex]:not([tabindex="-1"])):focus-visible {
  outline: 2px solid var(--ea-accent); outline-offset: 2px; }

/* §5 Change-Flash — eine Kennzahl, die sich seit dem letzten Render derselben Ansicht bewegt
   hat. Akzent-Hauch, der ausklingt; der Endzustand ist transparent (nichts bleibt haengen). */
.ea-changed { border-radius: var(--r-sm); animation: ea-changed 1.2s ease-out; }
@keyframes ea-changed { 0%, 35% { background-color: var(--ea-accent-soft); box-shadow: 0 0 0 3px var(--ea-accent-soft); }
  100% { background-color: transparent; box-shadow: 0 0 0 3px transparent; } }

/* §6 Click-to-copy — Kennzahl-Kacheln ohne eigene Aktion; Bestaetigung kurz im OK-Ton */
.ea-copy { cursor: copy; }
.ea-copy:hover { text-decoration: underline dotted var(--muted-2); text-underline-offset: 4px; }
.ea-copied { color: var(--ok-t) !important; transition: color .12s ease; }

/* §8 Sortierbarer Spaltenkopf — der Knopf erbt Schrift und Farbe des .th, der Pfeil steht
   gedaempft daneben und wird im aktiven Kopf zur Akzentfarbe. */
.ea-th-sort { display: inline-flex; align-items: center; gap: 4px; background: none; border: 0; padding: 0; margin: 0;
  font: inherit; color: inherit; letter-spacing: inherit; text-transform: inherit; cursor: pointer; border-radius: var(--r-sm); }
.ea-th-sort:hover { color: var(--ea-ink); }
.ea-th-sort__ar { font-size: 9px; line-height: 1; color: var(--muted-2); opacity: 0; transition: opacity .12s ease; }
.ea-th-sort:hover .ea-th-sort__ar, .ea-th-sort:focus-visible .ea-th-sort__ar { opacity: 1; }
.ea-th-sort.is-on { color: var(--ea-ink); }
.ea-th-sort.is-on .ea-th-sort__ar { opacity: 1; color: var(--ea-accent); }
.ea-th-sort:focus-visible { outline: 2px solid var(--ea-accent); outline-offset: 2px; }

/* §10 Armed confirm — der Knopf selbst traegt die Rueckfrage und den Countdown (Caution-Ton) */
.ea-armed { background: var(--caut-s) !important; color: var(--caut-t) !important; border-color: var(--caut-b) !important; }
.ea-armed__n { display: inline-block; min-width: 1ch; margin-left: 4px; opacity: .8; }

/* §11 View-Enter — Wechsel von Ansicht, Mandat oder Reiter (180 ms; eingefroren noch lesbar) */
.ea-view-enter { animation: ea-view-enter .18s ease-out; }
@keyframes ea-view-enter { from { opacity: .85; transform: translateY(3px); } to { opacity: 1; transform: none; } }

/* §12 Tastenkuerzel-Liste (im EAUI-Drawer) */
.ea-keys { width: 100%; border-collapse: collapse; font-size: var(--fs-sm); }
.ea-keys td { padding: 7px 0; border-bottom: 1px solid var(--ea-line); vertical-align: middle; color: var(--ea-ink); }
.ea-keys td:first-child { white-space: nowrap; padding-right: 16px; width: 1%; }
.ea-keys__note { margin-top: 12px; font-size: var(--fs-xs); color: var(--muted); }
.ea-kbd { display: inline-block; min-width: 1.6em; padding: 1px 6px; font: 600 var(--fs-xs)/var(--lh-xs) var(--font-sans);
  text-align: center; color: var(--ea-ink); background: var(--ea-subtle); border: 1px solid var(--ea-line);
  border-bottom-width: 2px; border-radius: var(--r-sm); }

/* §14 Such-Feedback — duenne Akzent-Linie unter dem Feld, solange der Debounce wartet;
   Treffer im Namen im Caution-Hauch markiert (Text behaelt seine Farbe) */
input.ea-pending { background-image: linear-gradient(90deg, transparent 0%, var(--ea-accent) 50%, transparent 100%);
  background-size: 200% 2px; background-repeat: no-repeat; background-position: 100% 100%; animation: ea-pending .9s linear infinite; }
@keyframes ea-pending { to { background-position: -100% 100%; } }
@media (prefers-reduced-motion: reduce) { input.ea-pending { animation: none; background-position: 50% 100%; } }
mark.ea-hl { background: var(--caut-s); color: inherit; box-shadow: 0 0 0 1px var(--caut-b); border-radius: 2px; padding: 0 1px; }

/* Batch 12 #2 — section head to the board: (a) the chevron is the text glyph ▸/▾, 14px, --muted,
   8px from the title (the toggle's gap) instead of the CSS caret; aria-expanded stays on the button.
   (b) a head that carries right-hand controls (headRight) is 61px: 14px 16px, the controls
   padded to match; plain heads keep 12px 16px. (c) select.field reads at 400 like the board. */
.ea-sec__chev, .ea-sec.is-open .ea-sec__chev { width: auto; height: auto; border: 0; transform: none; transition: none;
  font-size: 14px; line-height: 1; font-weight: 600; color: var(--muted); }
.ea-sec__chev::before { content: '\25B8'; }
.ea-sec.is-open .ea-sec__chev::before { content: '\25BE'; }
.ea-sec__head:has(> .ea-sec__right) > .ea-sec__toggle { padding: 14px 16px; }
.ea-sec__head:has(> .ea-sec__right) > .ea-sec__right { padding: 14px 16px 14px 0; }
select.field { font-weight: 400; }

/* §15 Hinzufuegen — Geist vom Universum zur neuen Holdings-Zeile, dann Zeilen-Hauch */
.ea-fly { position: fixed; z-index: 90; pointer-events: none; padding: 8px 12px; border-radius: var(--r-lg);
  background: var(--surface); color: var(--ea-ink); border: 1px solid var(--ea-accent-line); box-shadow: var(--shadow-pop);
  font-size: var(--fs-sm); font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
tr.ea-added > td { animation: ea-added 1.4s ease-out; }
@keyframes ea-added { 0%, 30% { background-color: var(--ea-accent-soft); } 100% { background-color: transparent; } }
