/* ---- Space Grotesk: die Schrift der Banner-Überschrift ---------------------------------------
   LOKAL ausgeliefert, nicht über Google Fonts. Dieselbe Hausregel wie bei den Symbolschriften:
   Eine Anlage beim Kunden steht oft ohne Weg nach draußen, und ein Aufruf an einen fremden Server
   bei jedem Seitenaufbau ist in einem System mit Personaldaten nichts, was man nebenbei einführt.
   Die Dateien liegen unter `lib/space-grotesk` (SIL Open Font License, siehe OFL.txt dort).

   EINE variable Datei je Zeichensatz deckt alle Stärken von 300 bis 700 ab - getrennte Schnitte
   wären fünf Dateien statt einer. */
@font-face {
    font-family: 'Space Grotesk';
    font-style: normal;
    font-weight: 300 700;
    font-display: swap;
    src: url('../lib/space-grotesk/space-grotesk-latin.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304,
        U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
    font-family: 'Space Grotesk';
    font-style: normal;
    font-weight: 300 700;
    font-display: swap;
    src: url('../lib/space-grotesk/space-grotesk-latin-ext.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308,
        U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113,
        U+2C60-2C7F, U+A720-A7FF;
}

:root {
    /* =====================================================================
       ZENTRALE DESIGN-TOKENS – einzige Quelle der Wahrheit für Farben.
       Niemals Hex-Werte in Razor/Scoped-CSS duplizieren, immer hierauf
       referenzieren (var(--tri-…)). Auch scoped .razor.css erbt diese.
       ===================================================================== */

    /* Markengrün. Dunkler seit 2.0.631 (vorher #2e8b3d / #277a35 / #1f5e28): Auf einer gefüllten
       Schaltfläche wirkte das alte Grün hell und die weiße Schrift darauf flau; als Textfarbe hatte es
       gegen Weiß zu wenig Kontrast. Beides hängt an DIESEM Token – Schaltflächen und grüne Texte ziehen
       deshalb gemeinsam nach. */
    --tri-green: #246c30;          /* Standard (Buttons, Links, Akzente) */
    --tri-green-hover: #1e5c28;
    --tri-green-active: #184a20;
    --tri-green-dark: #14532d;     /* dunkler Akzent: Hover-Text, Links */
    --tri-green-soft: #cdeacf;     /* heller Akzent: weiche Ränder/Unterstriche */
    --tri-green-bg: #ebf6ed;       /* sehr heller Grün-Hintergrund (Hover-Flächen) */
    --tri-green-bg-active: #e1f1e4;/* aktiver Grün-Hintergrund (Sidebar active) */
    /* Dieselbe Farbe als Zahlentripel. Gebraucht ueberall dort, wo eine DURCHSICHTIGE Variante noetig
       ist - `rgba(var(--tri-green-rgb), .15)`. Ein Hex-Token taugt dafuer nicht. Die Branding-Umschaltung
       setzt dieses Token mit; ohne das blieben Fokusringe und Schatten gruen. */
    --tri-green-rgb: 36, 108, 48;
    /* Die Grundfarbe des SCHWEBENDEN Kopfes. Er liegt durchscheinend ueber dem hellen Zeichenblatt
       (#fafbfc) und wirkte dadurch heller als jeder andere Banner. Diese Farbe ist so weit
       abgedunkelt, dass sie bei 85 % Deckkraft ueber dem Blatt wieder genau --tri-green ergibt:
       0,85 x (0,83,12) + 0,15 x (250,251,252) = (38,108,48).
       MEHR Durchsicht geht nicht: Grün ist dunkler als das Blatt, und ab etwa 15 % Durchsicht
       reicht selbst reines Schwarz als Grundfarbe nicht mehr an den Zielton heran. */
    --tri-green-schwebend-rgb: 0, 83, 12;
    /* Dieselbe Rechnung fuer eine DUNKLE Szene (3D-Ansicht mit „Dark Mode"): Dort zieht die
       Durchsicht die Farbe nach unten statt nach oben, die Grundfarbe muss also heller sein.
       0,85 x (42,127,56) + 0,15 x (0,0,0) = (36,108,48) - wieder genau --tri-green. */
    --tri-green-schwebend-dunkel-rgb: 42, 127, 56;

    /* Grau & Text */
    --tri-text: #33373d;           /* Standard-Textfarbe */
    --tri-muted: #6c757d;          /* gedämpfter Text, Formular-Labels */
    --tri-muted-2: #4b5159;        /* etwas dunkler (Sekundärinfo, Nav-Text) */
    --tri-subtle: #495057;         /* Hinweis-Grau (z. B. „bearbeiten") */
    --tri-faint: #9aa0a6;          /* sehr blass (Abschnittstitel, Carets) */
    --tri-border: #e7e9ec;         /* Standard-Rahmen */
    --tri-surface: #f3f4f6;        /* Seiten-Hintergrund */
    --tri-ink: #1f2227;            /* schwarzer Sidebar-Kopf / mobiler Menü-Knopf */
    /* Der Haus-Schatten fuer eine aufliegende Flaeche (Liste, Karte, Gespraechsfenster, Kachel):
       ein kurzer Kontaktschatten und ein weicher darunter. An EINER Stelle, damit alle Flaechen
       gleich hoch ueber dem Grund liegen. */
    --tri-shadow-flaeche: 0 1px 2px rgba(20, 50, 25, .10), 0 6px 14px -6px rgba(20, 50, 25, .22);
    /* Schatten der Knoten im Designer – Karten UND Trabanten (Kreise, Pillen, Werkzeug-Karten) tragen
       denselben, sonst wirken die Werkzeuge flacher als die Agenten und liegen scheinbar in einer
       anderen Ebene. Zwei Lagen: eine weite, weiche fuer die Hoehe, eine enge fuer die Kante. */
    /* VERSUCH (2026-10-17): deutlich kraeftiger, damit die Elemente ueber dem Blatt zu schweben scheinen.
       Drei Lagen: eine sehr weite, weiche fuer die Hoehe, eine mittlere fuer den Koerper, eine enge
       fuer die Kante. Die vorherigen, zurueckhaltenden Werte stehen darunter zum Zurueckschalten.
       --wfd-shadow:       0 6px 16px rgba(0, 0, 0, .12), 0 1px 3px rgba(0, 0, 0, .10);
       --wfd-shadow-hover: 0 10px 26px rgba(0, 0, 0, .18), 0 2px 5px rgba(0, 0, 0, .12); */
    /* LICHT VON OBEN RECHTS: Der Schatten faellt nach unten LINKS. Der waagerechte Versatz ist halb so
       gross wie der senkrechte (-11 zu 22) – das entspricht einem Lichteinfall von etwa 60 Grad und
       bleibt ruhig; bei gleichem Mass (45 Grad) kippt das Bild optisch zur Seite. Dieselbe Richtung
       gilt fuer ALLE Schatten im Designer, sonst kaeme das Licht je Element aus einer anderen Ecke. */
    --wfd-shadow: -11px 22px 44px -14px rgba(16, 24, 40, .38), -5px 10px 20px -10px rgba(16, 24, 40, .28), -1px 1px 3px rgba(16, 24, 40, .14);
    --wfd-shadow-hover: -16px 32px 60px -14px rgba(16, 24, 40, .46), -7px 14px 26px -10px rgba(16, 24, 40, .32), -2px 2px 5px rgba(16, 24, 40, .16);
    /* Schatten der VERBINDUNGSLINIEN: Er wird als EIGENE, weichgezeichnete Linienebene gezeichnet
       (.wfd-lines-shadow) und nicht als drop-shadow – an einer 1,5 px duennen Linie bleibt von einem
       weichgezeichneten Schlagschatten praktisch nichts uebrig. `--wfd-line-lift` ist die Flughoehe und
       entspricht dem Versatz der Knoten-Schatten (22 px); die Farbe traegt die Dichte. */
    --wfd-line-lift: 22px;
    /* Waagerechter Versatz der Linien-Schattenebene – dieselbe Lichtrichtung wie oben (halbes Mass). */
    --wfd-line-drift: -11px;
    --wfd-line-shadow-color: rgba(16, 24, 40, .09);
    /* KLEINE Elemente (Kreis-Trabanten, Pille) brauchen eigene Werte, obwohl sie auf DERSELBEN Hoehe
       schweben: Der negative Spread der Karten-Werte (-14 px) frisst bei einem 40-px-Kreis fast die
       ganze Schattenflaeche auf (40 - 2x14 = 12 px Kern) – die Kreise sahen deshalb flach aus, waehrend
       die Karten schwebten. Gleicher Versatz nach unten, kleinerer Spread, etwas engerer Weichzeichner. */
    --wfd-shadow-sat: -11px 22px 26px -10px rgba(16, 24, 40, .32), -4px 8px 12px -6px rgba(16, 24, 40, .24), -1px 1px 2px rgba(16, 24, 40, .12);
    --wfd-shadow-sat-hover: -15px 30px 34px -10px rgba(16, 24, 40, .40), -6px 12px 16px -6px rgba(16, 24, 40, .28), -2px 2px 4px rgba(16, 24, 40, .14);

    /* Akzentfarben */
    --tri-dialog: #e8590c;         /* „Nur im Dialog startbar"-Badge */
    --tri-secondary: #6c757d;      /* neutrale Sekundär-Pille (Kritiker-Badge) */
    --tri-red: #c0392b;            /* Gatekeeper (Security): Badge/Knoten */
    --tri-red-dark: #962d22;       /* dunkler Rot-Akzent (Gatekeeper-Knoten-Verlauf) */
    /* Die Rot-Familie der FEHLERMELDUNG. Eine Meldung ist eine Flaeche, kein Akzent - sie braucht
       einen Grund, einen Rand und eine Textfarbe, die auf diesem Grund noch ruhig wirkt. Deshalb
       eigene Toene statt --tri-red mit Durchsicht: Durchsichtiges Rot auf wechselndem Untergrund
       (Karte, Dialog, Zeichenblatt) ergibt jedes Mal eine andere Farbe. */
    --tri-red-bg: #fef7f5;         /* heller Grund der Fehlermeldung */
    --tri-red-soft: #f9e4e1;       /* Hof um das Sinnbild */
    --tri-red-border: #eecbc6;     /* Rand der Fehlermeldung */
    --tri-red-text: #98483f;       /* Fließtext in der Fehlermeldung */

    --bs-primary: var(--tri-green);
    --bs-primary-rgb: var(--tri-green-rgb);
    --bs-success: var(--tri-green);
    --bs-success-rgb: var(--tri-green-rgb);
    --bs-link-color: var(--tri-green);
    --bs-link-color-rgb: var(--tri-green-rgb);
    --bs-link-hover-color: var(--tri-green-dark);
}

html, body {
    font-family: 'Segoe UI', 'Helvetica Neue', Helvetica, Arial, sans-serif;
    background-color: var(--tri-surface);
    color: var(--tri-text);
}

/* Grün-Buttons (primary UND success) nutzen denselben zentralen Grünton. */
.btn-primary, .btn-success {
    --bs-btn-color: #fff;
    --bs-btn-bg: var(--tri-green);
    --bs-btn-border-color: var(--tri-green);
    --bs-btn-hover-color: #fff;
    --bs-btn-hover-bg: var(--tri-green-hover);
    --bs-btn-hover-border-color: var(--tri-green-hover);
    --bs-btn-active-color: #fff;
    --bs-btn-active-bg: var(--tri-green-active);
    --bs-btn-active-border-color: var(--tri-green-active);
    --bs-btn-disabled-bg: var(--tri-green);
    --bs-btn-disabled-border-color: var(--tri-green);
}

.btn-outline-primary, .btn-outline-success {
    --bs-btn-color: var(--tri-green);
    --bs-btn-border-color: var(--tri-green);
    --bs-btn-hover-color: #fff;
    --bs-btn-hover-bg: var(--tri-green);
    --bs-btn-hover-border-color: var(--tri-green);
    --bs-btn-active-bg: var(--tri-green);
    --bs-btn-active-border-color: var(--tri-green);
    /* Auch der AUSGEGRAUTE Zustand: Bootstrap belegt ihn mit eigenen Variablen, die der Override
       darüber nicht erreicht - eine deaktivierte Schaltfläche blieb deshalb überall in der Anwendung
       blau (Bootstrap-#0d6efd), obwohl sie aktiv grün ist. Aufgefallen am „PDF erstellen" im
       Datenschutz, das ohne gewählten Benutzer deaktiviert startet. */
    --bs-btn-disabled-color: var(--tri-green);
    --bs-btn-disabled-border-color: var(--tri-green);
}

.text-primary, .text-success { color: var(--tri-green) !important; }
.bg-primary, .bg-success { background-color: var(--tri-green) !important; }
.text-bg-primary, .text-bg-success { background-color: var(--tri-green) !important; color: #fff !important; }

/* Einheitliche Bezeichnungsfelder (Formular-Labels): fett und dunkelgrau – überall gleich. */
.form-label {
    font-weight: 600 !important;
    color: var(--tri-muted) !important;
}

/* Klammer-/Zusatzhinweise im Label nicht fett (z. B. „(Markdown)", „(optional)"). */
.form-label .text-muted,
.form-label .small {
    font-weight: 400 !important;
}

/* Dashboard stat cards */
.stat-card {
    border: none;
    border-left: 0.3rem solid var(--accent, var(--tri-green));
    border-radius: 0.6rem;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
}

.stat-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 3rem;
    height: 3rem;
    border-radius: 50%;
    font-size: 1.3rem;
    color: #fff;
    background-color: var(--accent, var(--tri-green));
}

.feature-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 3rem;
    height: 3rem;
    border-radius: 0.75rem;
    font-size: 1.5rem;
}

/* Tag-Bubbles */
.tag-pill {
    background-color: var(--tri-green);
    color: #fff;
    font-weight: 500;
    padding: 0.4em 0.7em;
}

.tag-pill .tag-x {
    font-size: 0.55rem;
    padding: 0.25em;
    opacity: 0.85;
}

.tag-pill .tag-x:hover {
    opacity: 1;
}

.tag-x-btn {
    border: none;
    background: none;
    padding: 0;
    line-height: 1;
    font-size: 0.7rem;
    opacity: 0.85;
    cursor: pointer;
}

.tag-x-btn:hover { opacity: 1; }

/* Tag-Auswahlliste (Picker) */
.tag-picker {
    position: absolute;
    z-index: 1056;            /* über dem tag-pop-backdrop (1055), damit Einträge klickbar bleiben */
    top: calc(100% + 4px);
    left: 0;
    min-width: 220px;
    max-height: 260px;
    overflow-y: auto;
    background: #fff;
    border: 1px solid #e2e4e8;
    border-radius: 0.6rem;
    padding: 0.35rem;
    box-shadow: 0 10px 28px rgba(16, 24, 40, 0.16);
}

/* Kopfzeile des Auswahl-Popups (MCP/Tool/Skill hinzufügen). */
.tag-picker-head {
    font-size: 0.75rem;
    font-weight: 600;
    color: #9aa0a6;
    text-transform: uppercase;
    letter-spacing: 0.02em;
    padding: 0.3rem 0.6rem 0.4rem;
}

.tag-picker-item {
    display: flex;
    align-items: center;
    width: 100%;
    border: none;
    background: none;
    text-align: left;
    padding: 0.45rem 0.6rem;
    border-radius: 0.4rem;
    font-size: 0.9rem;
    color: #33373d;
}

.tag-picker-item:hover {
    background-color: var(--tri-green-bg);
    color: var(--tri-green);
}

/* Farb-Swatches (Tag-Verwaltung) */
.swatch {
    width: 26px;
    height: 26px;
    border-radius: 50%;
    border: 2px solid #fff;
    box-shadow: 0 0 0 1px #d0d3d8;
    cursor: pointer;
    padding: 0;
}

.swatch-active {
    box-shadow: 0 0 0 2px #212529;
}

/* Tag mit rundem Entfernen-Symbol (Detailansicht) */
.tag-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.4em;
    padding: 0.35em 0.75em;
    border-radius: 999px;
    font-size: 0.8rem;
    font-weight: 500;
}

.tag-chip .tag-remove {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: none;
    background: none;
    color: inherit;
    opacity: 0.8;
    padding: 0;
    line-height: 1;
    cursor: pointer;
}

.tag-chip .tag-remove:hover { opacity: 1; }
.tag-chip .tag-remove i { font-size: 1rem; }

/* Weißes "+"-Tag, das das Popover öffnet */
.tag-add {
    display: inline-flex;
    align-items: center;
    gap: 0.35em;
    padding: 0.3em 0.7em;
    border-radius: 999px;
    font-size: 0.8rem;
    font-weight: 500;
    background: #fff;
    color: #495057;
    border: 1px dashed #adb5bd;
    cursor: pointer;
}

.tag-add:hover { border-color: var(--tri-green); color: var(--tri-green); }

/* Popover zum Zuordnen/Anlegen von Tags */
.tag-pop-backdrop {
    position: fixed;
    inset: 0;
    z-index: 1055;
    background: transparent;
}

.btn-close-sm {
    width: 0.6rem;
    height: 0.6rem;
    padding: 0.25rem;
}

.tag-pop {
    position: absolute;
    z-index: 1060;
    top: calc(100% + 6px);
    left: 0;
    width: 280px;
    max-height: 360px;
    overflow-y: auto;
    background: #fff;
    border: 1px solid #e2e4e8;
    border-radius: 0.6rem;
    box-shadow: 0 8px 24px rgba(0,0,0,0.12);
    padding: 0.6rem;
}

.tag-pop-item {
    display: flex;
    align-items: center;
    gap: 0.5em;
    width: 100%;
    padding: 0.35rem 0.4rem;
    border-radius: 0.4rem;
    cursor: pointer;
    font-size: 0.88rem;
}

.tag-pop-item:hover { background-color: #f3f5f7; }
.tag-pop-item input[type="checkbox"] { width: 1.25rem; height: 1.25rem; flex: 0 0 auto; cursor: pointer; }
/* GLOBAL: Beim Ziehen ziehbarer Elemente (native HTML5-DnD, `draggable="true"`) darf KEIN Text markiert werden –
   sonst „färbt" das Ziehen die Inhalte blau ein (gilt für Ordnerbaum, Paletten, Agentenliste, Formular-Toolbox …).
   Eingabefelder innerhalb ziehbarer Elemente bleiben ausdrücklich markierbar. Pointer-basierte Drags (Agent-Designer)
   sind separat über `.wfd-canvas` abgedeckt. */
[draggable="true"], [draggable="true"] * { user-select: none; -webkit-user-select: none; }
[draggable="true"] input, [draggable="true"] textarea, [draggable="true"] [contenteditable="true"] { user-select: text; -webkit-user-select: text; }
/* Zusätzlich für Ordnerbaum-/Paletten-Zeilen unabhängig vom draggable-Zustand (robust „überall"). */
.folder-agent-leaf, .folder-agent-leaf *, .folder-agent-row, .folder-agent-row * { user-select: none; -webkit-user-select: none; }
/* FolderTreeView: Schrift/Icons EXAKT wie die Menüpunkte (.nav-link 0.92rem / .nav-icon 1.05rem). */
.ftv .folder-node { font-size: 0.92rem; }
.ftv .folder-name { font-size: 0.92rem; font-weight: 400; }
.ftv .folder-agent-leaf { font-size: 0.92rem; padding-top: .25rem; padding-bottom: .25rem; }
.ftv .folder-agent-leaf-name { font-size: 0.92rem; font-weight: 400; color: #33373d; }
.ftv .folder-agent-leaf-num { font-size: 0.92rem; }
.ftv .folder-agent-leaf-icon { font-size: 1.05rem; }
.ftv input[type="checkbox"] { width: 1.2rem; height: 1.2rem; flex: 0 0 auto; cursor: pointer; }
.ftv .folder-icon { font-size: 1.05rem; }

/* Kompakte Variante (z. B. im Tool-Einstellungen-Dialog): Schrift so groß wie der Erklärungstext darüber. */
.ftv-compact .ftv .folder-node,
.ftv-compact .ftv .folder-name,
.ftv-compact .ftv .folder-agent-leaf,
.ftv-compact .ftv .folder-agent-leaf-name,
.ftv-compact .ftv .folder-agent-leaf-num { font-size: .8rem; }
.ftv-compact .ftv .folder-agent-leaf-icon,
.ftv-compact .ftv .folder-icon { font-size: .9rem; }
.ftv-compact .ftv input[type="checkbox"] { width: 1rem; height: 1rem; }

/* Knowledge-Zuordnung (Liste + Hinzufügen-Popover): Schrift wie der Erklärungstext (.form-text). */
.kb-list, .kb-list .list-group-item, .kb-list label { font-size: .875rem; }
.kb-list .bi { font-size: 1rem; }
.kb-list label { cursor: pointer; margin: 0; }

.tag-dot {
    width: 12px;
    height: 12px;
    border-radius: 50%;
    flex: 0 0 auto;
}

/* Zurück-Button auf gleiche Höhe wie die große Agenten-Nummer */
.btn-back {
    height: 3.2rem;
    width: 3.2rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 1.2rem;
    flex-shrink: 0;
}

/* Große Agenten-Nummer in der Detailansicht */
.agent-id-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 3.2rem;
    height: 3.2rem;
    padding: 0 0.6rem;
    border-radius: 0.75rem;
    background: var(--tri-green);
    color: #fff;
    font-size: 1.4rem;
    font-weight: 700;
    box-shadow: 0 2px 6px rgba(var(--tri-green-rgb),0.3);
}

/* Tag-Filter (Agentenliste): aufklappbares Popup mit mehrfach wählbaren Bubbles */
.tag-filter-pop {
    position: absolute;
    top: calc(100% + 4px);
    left: 0;
    right: 0;
    z-index: 1056;
    background: #fff;
    border: 1px solid #e6e8ea;
    border-radius: 0.6rem;
    padding: 0.6rem;
    max-height: 320px;
    overflow-y: auto;
}

.tag-filter-pill {
    border: 0;
    cursor: pointer;
    padding: 0.42em 0.75em;
    font-size: 0.82rem;
    opacity: 0.45;
    transition: opacity 0.12s ease, box-shadow 0.12s ease;
}

.tag-filter-pill:hover {
    opacity: 0.8;
}

.tag-filter-pill.tag-filter-pill-on {
    opacity: 1;
    box-shadow: 0 0 0 2px rgba(16, 24, 40, 0.22);
}

/* Kritiker-Agenten: graue Nummer statt grün */
.agent-id-badge.agent-id-badge-critic {
    background: #6f757d;
    box-shadow: 0 2px 6px rgba(111,117,125,0.3);
}

/* ---------- Kanban-Dashboard ---------- */

/* Kartenbewegungen werden per FLIP (Web Animations API) animiert – siehe index.html. */

/* Runder Benutzer-Avatar (Bild oder Symbol-Fallback) */
.user-avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    overflow: hidden;
    background-color: #e7e9ec;
    color: #8a9099;
    flex-shrink: 0;
}

.user-avatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

/* Runder Agenten-Avatar (hochgeladenes Bild oder Icon-Fallback) – überall statt des Agenten-Icons */
.agent-avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    overflow: hidden;
    background-color: #e7e9ec;
    color: var(--tri-green);
    flex-shrink: 0;
    vertical-align: middle;
}
.agent-avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* Liegt ein BILD im Avatar, ist nur das Bild zu sehen - nichts darunter. Der helle Grund (#e7e9ec)
   ist der Platzhalter fuer den Fall OHNE Bild; mit Bild blitzte er an der weichgezeichneten Kante des
   runden Zuschnitts als heller Saum durch. Auf weissem Grund faellt das nicht auf, auf dem gruenen
   Band des Seitenkopfs sah es aus wie ein weisser Rahmen um jeden Avatar. */
.agent-avatar:has(> img) { background-color: transparent; }
/* Kritiker-Avatare in Graustufe kenntlich machen */
.agent-avatar.agent-head-critic { filter: grayscale(1); color: #6c757d; }
/* Agenten-Avatar in der Chat-Nachricht (grüner Fallback-Hintergrund wie bisher) */
.agent-avatar.chat-msg-avatar { background: var(--tri-green); color: #fff; font-size: 1.15rem; }

/* „Der Agent arbeitet": Der Avatar pulsiert im Sekundentakt – er wird dabei periodisch ABGEDUNKELT und
   atmet in der Größe leicht mit. Das sagt nur, dass etwas geschieht; den Fortschritt beschreibt der Text
   daneben. Derselbe Takt wie beim Sinnbild der KI im Gespräch (ki-atmet), aber umgekehrt herum: Dort wird
   der Wirbel im Scheitel HELLER, hier wird der Kopf DUNKLER – ein Bild eines Menschen oder einer Figur
   wirkt beim Aufhellen ausgewaschen, beim Abdunkeln dagegen wie ein Lidschlag.

   `filter` und `transform` liegen zusammen auf DEMSELBEN Element, weil beide Eigenschaften hier aus
   derselben Animation kommen – zwei Animationen auf einem Element überschrieben einander (die zuletzt
   gestartete gewinnt). Bei „prefers-reduced-motion" steht das Bild still. */
.agent-avatar.is-working { animation: agent-arbeitet 1s ease-in-out infinite; }
@keyframes agent-arbeitet {
    0%, 100% { transform: scale(1);    filter: brightness(1); }
    50%      { transform: scale(1.07); filter: brightness(0.55); }
}
@media (prefers-reduced-motion: reduce) {
    .agent-avatar.is-working { animation: none; }
}
/* Avatar-Zuschneide-Dialog – muss über dem Designer-Eigenschaften-Dialog (z-index 1100) liegen */
.avatar-crop-backdrop { z-index: 1190; }
.avatar-crop-dialog { z-index: 1200; }
.avatar-crop-stage { display: flex; justify-content: center; }
.avatar-crop-canvas { width: 256px; height: 256px; border-radius: 50%; touch-action: none; cursor: grab; background: #1113; }
.avatar-crop-canvas:active { cursor: grabbing; }
.avatar-crop-zoom { display: flex; align-items: center; gap: 0.6rem; margin: 0.9rem 0 0.3rem; }
.avatar-crop-zoom .form-range { flex: 1 1 auto; }
.wfd-avatar-tab .agent-avatar { background-color: #e7e9ec; }
/* „Avatar eines anderen Agenten übernehmen" – Liste der Agenten mit Avatar */
.wfd-avatar-reuse-grid { display: flex; flex-wrap: wrap; gap: 0.5rem; max-height: 12rem; overflow-y: auto; }
.wfd-avatar-reuse-item {
    display: flex; align-items: center; gap: 0.5rem; padding: 0.3rem 0.6rem 0.3rem 0.3rem;
    border: 1px solid var(--tri-border, #dee2e6); border-radius: 2rem; background: #fff; cursor: pointer;
    max-width: 100%;
}
.wfd-avatar-reuse-item:hover:not(:disabled) { border-color: var(--tri-green); background: var(--tri-green-bg-active); }
.wfd-avatar-reuse-item:disabled { opacity: 0.6; cursor: default; }
.wfd-avatar-reuse-name { font-size: 0.85rem; color: var(--tri-text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 12rem; }
/* Agentenliste: Avatar links, Name/Beschreibung rechts – Avatar über zwei Zeilen zentriert */
.agentlist-name-flex { display: flex; align-items: center; gap: 0.6rem; }
.agentlist-name-main { min-width: 0; }
.agentlist-avatar { flex: 0 0 auto; }
/* Fallback-Icon (kein Avatar) in der Agentenliste größer – überschreibt den Inline-font-size der Komponente */
.agentlist-avatar i { font-size: 1.9rem !important; }

/* ===== Kompakte Ordneransicht (Master-Detail): links Ordnerbaum, rechts Agenten des markierten Ordners =====
   Volle Resthöhe; Baum und Agentenliste scrollen UNABHÄNGIG (je eigenes overflow in der Grid-Zelle). */
/* Die Höhe folgt dem KOPF, nicht einer geschätzten Zahl: `--rbh-sticky-h` ist die Unterkante des
   klebenden Kopfes im Fenster (js/sticky-banner.js), 1,5 rem ist das untere Polster der Seite. Mit
   den festen 11 rem von früher ragte der Kasten unter den Fensterrand, sobald der Kopf wuchs. */
.agentfolders-split { display: grid; grid-template-columns: minmax(220px, 320px) minmax(0, 1fr); height: calc(100vh - var(--rbh-sticky-h, 11rem) - 1.5rem); }
.agentfolders-tree { border-right: 1px solid var(--tri-border); display: flex; flex-direction: column; min-height: 0; }
.agentfolders-tree-scroll { padding: .5rem; overflow-y: auto; min-height: 0; flex: 1 1 auto; }
/* Der Fuß trägt nur noch das Pluszeichen – linksbündig, damit es zur Ordnerspalte darüber fluchtet. */
.agentfolders-tree-foot { border-top: 1px solid var(--tri-border); padding: .3rem .35rem; flex: 0 0 auto; display: flex; }
.agentfolders-agents { padding: .35rem .25rem; overflow-y: auto; min-height: 0; }
/* Hover-„+" je Ordner zum Anlegen eines Unterordners. */
.agentfolders-addsub { flex: 0 0 auto; width: 1.35rem; height: 1.35rem; margin-left: .25rem; padding: 0; border: none; background: transparent; color: var(--tri-green); border-radius: .3rem; line-height: 1; opacity: 0; transition: opacity .12s; }
.agentfolders-folder:hover .agentfolders-addsub { opacity: 1; }
.agentfolders-addsub:hover { background: #d9efdd; }
/* Tags in der kompakten Agentenzeile (nur bei „Tags anzeigen"). */
.agentfolders-tags { display: flex; flex-wrap: wrap; gap: .2rem; margin-left: .4rem; min-width: 0; overflow: hidden; }
.agentfolders-folder { display: flex; align-items: center; padding: .32rem .4rem; border-radius: .45rem; cursor: pointer; user-select: none; }
.agentfolders-folder:hover { background: #f1f3f5; }
.agentfolders-folder.active { background: var(--tri-green-bg); }
.agentfolders-folder.drag-over { background: #d9efdd; outline: 2px dashed var(--tri-green); }
.agentfolders-caret { width: 1.1rem; flex: 0 0 auto; text-align: center; color: var(--tri-muted); font-size: .8rem; }
.agentfolders-folder-ic { color: var(--tri-green); margin-right: .35rem; flex: 0 0 auto; }
.agentfolders-folder-name { font-weight: 400; font-size: .875rem; color: var(--tri-text); flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Die Anzahl je Ordner in Hausgrün statt Grau: Der Baum ist grün (Ordnersymbole, Auswahl), und ein
   graues Abzeichen daneben sah aus wie ein fremdes Element. */
.agentfolders-count { flex: 0 0 auto; font-size: .68rem; font-weight: 700; color: #fff; background: var(--tri-green); border-radius: 1rem; padding: .02rem .45rem; margin-left: .4rem; }
/* „Neuer Ordner" am Fuß des Baumes: ein stilles Pluszeichen, kein breiter Knopf. */
.agentfolders-newfolder {
    display: inline-flex; align-items: center; justify-content: center;
    width: 1.9rem; height: 1.9rem; border: 0; border-radius: .5rem;
    background: transparent; color: var(--tri-green); font-size: 1rem; cursor: pointer;
}
.agentfolders-newfolder:hover { background: var(--tri-green-bg); }

/* Leerer Ordner: eine Mitte statt einer grauen Zeile – Sinnbild, Name des Ordners, ein Satz dazu und
   der nächste Schritt als Schaltfläche. */
.agentfolders-empty {
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: .55rem; padding: 3.5rem 2rem; text-align: center; min-height: 18rem;
}
.agentfolders-empty-ic {
    width: 3.4rem; height: 3.4rem; border-radius: .9rem; margin-bottom: .35rem;
    display: inline-flex; align-items: center; justify-content: center;
    background: var(--tri-green-bg); color: var(--tri-green); font-size: 1.5rem;
}
.agentfolders-empty-title { font-size: 1.1rem; font-weight: 700; color: var(--tri-text); }
.agentfolders-empty-text { font-size: .92rem; color: var(--tri-muted); max-width: 32rem; line-height: 1.5; }
.agentfolders-empty .btn { margin-top: .6rem; }

.agentfolders-agentrow { display: flex; align-items: center; gap: .55rem; padding: .32rem .5rem; border-bottom: 1px solid #f0f1f3; }
.agentfolders-agentrow:hover { background: #f8f9fa; }
.agentfolders-avatar { flex: 0 0 auto; border-radius: 50%; }
.agentfolders-avatar i { font-size: 1.05rem !important; }
.agentfolders-agent-name { min-width: 0; }
@media (max-width: 700px) {
    .agentfolders-split { grid-template-columns: 1fr; grid-template-rows: minmax(6rem, 38vh) 1fr; height: calc(100vh - var(--rbh-sticky-h, 10rem) - 1.5rem); }
    .agentfolders-tree { border-right: none; border-bottom: 1px solid var(--tri-border); }
}
/* Agentennummer als Teil des Namens: echter Inline-Text (kein eigenes Box-Element) mit hellgrünem
   Hintergrund – dadurch liegt die Baseline automatisch bündig zum Agentennamen. */
.agent-num-inline {
    background: var(--tri-green-bg-active); color: var(--tri-green);
    border-radius: 0.3rem; padding: 0.02em 0.4em; margin-right: 0.25rem; font-weight: 700;
}
.agent-num-inline-critic { background: #e9ecef; color: #6c757d; }
/* In BAUM- UND LISTENZEILEN bekommt die Nummer eine feste Mindestbreite. Sonst beginnt jeder Name an
   einer anderen Stelle - „#50" ist schmaler als „#1027" -, und eine Spalte, deren Text ausfranst,
   liest sich als Reihe nur mit Mühe. Die Zahl steht darin mittig, die Namen stehen bündig. */
.folder-agent-leaf-name .agent-num-inline {
    display: inline-block;
    min-width: 3.2rem;
    text-align: center;
}
/* Ruhiges Abzeichen für eine Nebenangabe (Aufbewahrungsdauer, Datenklasse, Anzahl). Bootstraps blosses
   `.badge` hat WEISSE Schrift ohne Fläche und ist damit auf hellem Grund unsichtbar; `.sec-badge-muted`
   sah richtig aus, ist aber auf AgentSecurityView.razor begrenzt (scoped CSS) und wirkt woanders nicht. */
.tri-badge-muted {
    background: var(--tri-surface); color: var(--tri-muted);
    border-radius: 0.3rem; padding: 0.15em 0.5em; font-size: 0.78rem; font-weight: 600;
    white-space: nowrap;
}
/* Tag-Zeile je Agent (Option „Tags anzeigen"): einzeilig, bei Überlänge horizontal scrollbar */
.agentlist-tags { display: flex; gap: 0.3rem; flex-wrap: nowrap; overflow-x: auto; margin-top: 0.25rem; }
.agentlist-tag { flex: 0 0 auto; font-size: 0.65rem; line-height: 1.3; font-weight: 600; color: #fff;
    background: var(--tg, var(--tri-green)); border-radius: 0.8rem; padding: 0.05rem 0.45rem; white-space: nowrap; }
/* Gehirn-Icon im Menüpunkt „LLM-Provider": global (scoped .nav-icon greift nicht auf das Kind-Komponenten-SVG).
   Layout-Breite = 1,25rem wie die übrigen Menü-Icons (Text bleibt bündig); optische Vergrößerung per transform
   (verändert die Layout-Box nicht) und minimale Anhebung, da die Zeichnung leicht unterhalb der viewBox-Mitte liegt. */
.nav-brain { width: 1.25rem; height: 1.25rem; flex: 0 0 auto; overflow: visible; transform: scale(1.4) translateY(-0.8px); transform-origin: center; }
/* Gehirn-Icon im Seitenkopf „LLM-Provider" (grün, an .page-head-icon angeglichen) */
.page-head-brain { width: 1.9rem; height: 1.9rem; color: var(--tri-green); align-self: flex-start; flex: 0 0 auto; }
/* Nach-Nummer-sortieren-Umschalter im Namensspaltenkopf */
.agentlist-sort-num { margin-left: 0.5rem; color: var(--tri-muted, #8a9099); font-weight: 700; opacity: 0.6; }
.agentlist-sort-num.active { color: var(--tri-green); opacity: 1; }
.agentlist-sort-num:hover { opacity: 1; }
/* Kopf der Namensspalte um die Avatar-Breite (46px) + Abstand einrücken, damit „# Name" über den
   Zellinhalt „#id Agentenname" fällt statt über den Avatar. Erste Sortiermarke ohne Vorabstand. */
.agentlist-head-name { padding-left: calc(46px + 0.6rem + 0.5rem) !important; }
.agentlist-head-name .agentlist-sort-num { margin-left: 0; }

/* Avatar mit Kamera-Button (Foto wählen) in Dialogen */
.avatar-edit {
    position: relative;
    flex-shrink: 0;
}

.avatar-edit-btn {
    position: absolute;
    right: -2px;
    bottom: -2px;
    width: 1.4rem;
    height: 1.4rem;
    border-radius: 50%;
    background-color: var(--tri-green);
    color: #fff;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 0.7rem;
    cursor: pointer;
    border: 2px solid #fff;
}

.avatar-edit-btn:hover { background-color: #256e31; }
/* Foto entfernen: zweiter Knopf AM Bild (oben rechts), damit die Aktion sichtbar zum Foto gehoert.
   Als Muelleimer weit rechts in der Kopfzeile las er sich wie „Profil loeschen". */
.avatar-del-btn { top: -2px; bottom: auto; background-color: #b02a37; border: 0; padding: 0; }
.avatar-del-btn:hover { background-color: #8f222c; }
.avatar-del-btn:disabled { opacity: .6; }

.kanban-board {
    display: grid;
    /* Alle Spalten dynamisch gleich breit in EINER Reihe (unabhängig von der Spaltenanzahl). */
    grid-auto-flow: column;
    grid-auto-columns: minmax(0, 1fr);
    gap: 1rem;
    align-items: start;
}

@media (max-width: 1200px) {
    .kanban-board { grid-auto-flow: row; grid-auto-columns: auto; grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 576px) {
    .kanban-board { grid-template-columns: 1fr; }
}

.kanban-col {
    background: var(--col-bg, #f4f5f7);
    border: 1px solid rgba(0, 0, 0, 0.05);
    border-radius: 0.9rem;
    padding: 0.75rem;
    min-height: 200px;
}

.kanban-col-head {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.25rem 0.4rem 0.75rem;
}

.kanban-col-title {
    font-weight: 700;
    font-size: 0.95rem;
    color: var(--col-accent, #6c757d);
}

.kanban-col-count {
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--col-accent, #6c757d);
    background: #fff;
    border: 1px solid rgba(0, 0, 0, 0.08);
    border-radius: 0.4rem;
    padding: 0.05rem 0.45rem;
}

/* Laufzeitanzeige in der Spalte "In Arbeit" */
.kanban-runtime { color: #80868b; }
.kanban-runtime-over { color: #dc3545; font-weight: 700; }

/* Stop-Button auf wartenden/laufenden Karten */
.kanban-stop-btn {
    border: none;
    background: none;
    color: #dc3545;
    font-size: 1rem;
    line-height: 1;
    padding: 0.1rem 0.25rem;
    border-radius: 0.35rem;
    opacity: 0.7;
}
.kanban-stop-btn:hover { opacity: 1; background: #fdecea; }

/* Icon-Button zum Archivieren im Spaltenkopf */
.kanban-archive-btn {
    border: none;
    background: none;
    color: var(--col-accent, #6c757d);
    font-size: 0.95rem;
    line-height: 1;
    padding: 0.2rem 0.35rem;
    border-radius: 0.35rem;
    opacity: 0.65;
}
.kanban-archive-btn:hover {
    opacity: 1;
    background: rgba(0, 0, 0, 0.06);
}

.kanban-col-body {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}

.kanban-empty {
    color: #9aa0a6;
    font-size: 0.85rem;
    text-align: center;
    padding: 1.25rem 0;
}

.kanban-col-foot {
    text-align: center;
    font-size: 0.75rem;
    color: #9aa0a6;
    padding: 0.6rem 0.4rem 0.1rem;
}

/* "Weitere laden" steht unter der Zahl, nicht daneben: Die Zahl sagt, was fehlt, der Verweis
   holt es. Eigene Zeile, damit er in einer schmalen Spalte nicht mit der Zahl verschmilzt. */
.kanban-col-more {
    display: block;
    margin-top: 0.25rem;
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--tri-green);
    cursor: pointer;
    text-decoration: none;
}

.kanban-col-more:hover { text-decoration: underline; }

.kanban-card {
    position: relative;
    background: #fff;
    border: 1px solid #e8eaed;
    border-radius: 0.7rem;
    padding: 0.75rem 0.85rem;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
    transition: box-shadow 0.15s, transform 0.15s;
    display: flex;
    flex-direction: column;
    min-height: 7rem;   /* Karten etwas höher */
}
/* Kopfzeile: Agentennummer + Name (ohne Symbol). */
.kanban-card-head-row { display: flex; align-items: flex-start; gap: 0.4rem; flex-wrap: nowrap; margin-bottom: 0.35rem; }
/* Titel als Text-Block; die #-Nummer sitzt inline als erster Teil des Namens → umgebrochene Zeilen beginnen
   linksbündig unter dem Chip (kein Einzug). */
.kanban-card-head-row .kanban-card-title { display: flex; align-items: flex-start; gap: 0.5rem; flex: 1 1 auto; min-width: 0; margin-bottom: 0; }
/* Titeltext schrumpfbar + ellipsis, damit die Prioritäts-/Dialog-Badge daneben nicht den Namen überlappt. */
.kanban-card-head-row .kanban-card-titletext { overflow: hidden; text-overflow: ellipsis; }
.kanban-card-head-row .kanban-priority { flex: 0 0 auto; align-self: flex-start; }
/* Nummer + Name als eine Inline-Zeile (ein Flex-Item), damit die Baselines bündig sind; Avatar bleibt separates Item. */
.kanban-card-titletext { min-width: 0; }
.kanban-card-title .agent-id-chip {
    display: inline-block; height: auto; min-width: 0;
    padding: 0.05rem 0.35rem; margin-right: .25rem;
    vertical-align: baseline; line-height: 1.2;
}
/* Payload-Kurzanzeige (Details-Button). */
.kanban-card-payload {
    margin-top: 0.45rem; padding-top: 0.45rem; border-top: 1px dashed var(--tri-border);
    font-size: 0.72rem; color: var(--tri-muted); line-height: 1.3; word-break: break-word;
}
.kanban-card-payload-label { font-weight: 700; color: #9aa0a6; margin-right: 0.35rem; text-transform: uppercase; font-size: 0.62rem; letter-spacing: 0.03em; }
/* Fuß-Buttonleiste: RUN, Designer, Stopp, Details – als kleine Buttons unten. */
.kanban-card-actions { display: flex; align-items: center; gap: 0.35rem; margin-top: auto; padding-top: 0.6rem; flex-wrap: wrap; border-top: 1px solid #e8eaed; }
.kanban-mini-btn {
    display: inline-flex; align-items: center; gap: 0.25rem; height: 1.6rem; padding: 0 0.5rem;
    border-radius: 0.4rem; border: 1px solid var(--tri-border); background: #fff; color: var(--tri-muted);
    font-size: 0.72rem; font-weight: 600; text-decoration: none; cursor: pointer;
}
.kanban-mini-btn:hover { color: var(--tri-green); border-color: var(--tri-green); }
.kanban-mini-btn.is-active { color: var(--tri-green); border-color: var(--tri-green); background: var(--tri-green-bg); }
.kanban-mini-btn-stop { color: #d9534f; }
/* „Rückfrage öffnen"-Button auf Karten in der Spalte „Wartet auf Eingabe" (bernsteinfarben, wie die Spalte). */
.kanban-mini-btn-answer { color: #b8860b; border-color: #f2d9a8; background: #fdf9ef; }
.kanban-mini-btn-answer:hover { color: #8a6608; border-color: #e0a94a; background: #fbf1d9; }
/* Sub-Lauf-/Task-Marker in der Pipeline: eigene (bernsteinfarbene) Kennzeichnung + Verweis auf den Parent-Lauf. */
.kanban-mini-sub { color: #b45309; border-color: #f2d9a8; background: #fdf6e9; }
.kanban-mini-sub:hover { color: #92400e; border-color: #e0a94a; }
/* Task-/Sub-Lauf-Liste auf der Pipeline-Karte: je Zeile ein Status-Punkt + gekürzter Titel, Klick → Lauf-Detail. */
/* Task-Liste in der Pipeline-Karte: exakt an den Kopf-Meta-Zeilen (.kanban-card-times) ausgerichtet –
   gleiche Schriftgröße (.74rem) und Farbe (#80868b), Icon wie dort (bi-Icon in Textgröße + .25rem Abstand,
   1em Vorschub → Text fluchtet mit Kopf-Icons/-Texten), linksbündig ohne Extra-Padding. */
.kanban-card-tasks { display: flex; flex-direction: column; margin: .35rem 0 .15rem; }
/* Baseline-Ausrichtung: Agentennummer-Chip und Titel teilen die Schrift-Grundlinie; nur das Status-Icon bleibt mittig. */
.kanban-task-row { display: flex; align-items: baseline; text-decoration: none; color: #80868b; font-size: .74rem; line-height: 1.5; }
.kanban-task-row:hover { color: var(--tri-green); }
.kanban-task-title { flex: 1 1 auto; min-width: 0; }
.kanban-task-ic { flex: 0 0 auto; align-self: center; margin-right: .25rem; font-size: 1em; text-align: center; }
/* Agentennummer eines echten Sub-Agenten (start_agent) in der Task-Liste: Standard-Chip `agent-num-inline`
   (hellgrün hinterlegt), Schriftgröße erbt von der Zeile (.74rem) – Status-Icon/Titel bleiben unverändert. */
.kanban-task-more { display: block; font-size: .74rem; color: var(--tri-green); text-decoration: none; margin-top: .1rem; }
.kanban-task-more:hover { text-decoration: underline; }
/* Agentenläufe-Liste: delegierte Sub-Läufe leicht hinterlegt (stehen eingerückt unter dem Parent). */
.run-delegated-row > td { background: #fafbfa; }
.kanban-mini-btn-stop:hover { color: #b52b27; border-color: #d9534f; background: #fdecea; }
.kanban-card-designer {
    position: absolute; right: .5rem; bottom: .45rem;
    width: 1.7rem; height: 1.7rem; border-radius: .4rem;
    display: inline-flex; align-items: center; justify-content: center;
    color: var(--tri-muted); border: 1px solid var(--tri-border); background: #fff;
    font-size: .85rem; text-decoration: none;
}
.kanban-card-designer:hover { color: var(--tri-green); border-color: var(--tri-green); }

.kanban-card:hover {
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
    transform: translateY(-1px);
}

.kanban-card-id {
    font-size: 0.72rem;
    letter-spacing: 0.03em;
    color: #9aa0a6;
    margin-bottom: 0.25rem;
}

.kanban-card-run-link {
    color: inherit;
    text-decoration: none;
    font-weight: 700;
}

.kanban-card-title {
    display: flex;
    align-items: flex-start;   /* Agentenkopf oben am (mehrzeiligen) Text, nicht mittig */
    gap: 0.4rem;
    font-weight: 600;
    font-size: 0.85rem;
    color: var(--tri-muted-2);
    text-decoration: none;
    margin-bottom: 0.45rem;
}

/* Statusfarbenes Agenten-Symbol (bi-robot, wie im Menü) auf der Karte – fett, Farbe je Status inline gesetzt. */
.kanban-card-icon {
    font-size: 20px;
    line-height: 1;
    flex-shrink: 0;
    font-weight: bold;
    -webkit-text-stroke: 0.4px currentColor;   /* Icon-Font kennt keine Schriftstärke → Glyph kräftiger zeichnen */
}

/* … und in der Lauf-Detailansicht (so hoch wie Titel + Unterzeile) */
.run-detail-icon {
    height: 72px;
    width: auto;
}

/* Einstellungen: Abschnitte */
/* ---- Einstellungen: eine Karte, Gruppen als kleine Überschrift, je Einstellung EINE Zeile ----
   Beschriftung mit (i) links, Bedienelement rechts. Vorbild ist die Datenschutz-Seite. Die Erklärungen
   standen bis 2.0.632 als Absatz unter jedem Feld; sechs Einstellungen füllten damit zwei
   Bildschirmhöhen. Sie stehen jetzt im (i) – siehe `InfoHint`. */
.set-card {
    background: #fff; border: 1px solid var(--tri-border); border-radius: .9rem;
    padding: .25rem 1.4rem 1rem; overflow: visible;
}
/* Zwischenüberschriften gibt es nicht mehr: Bei einer Einstellung je Gruppe stand über jeder Zeile eine
   Überschrift, die nur den Text der Zeile wiederholte. Die Zeilen trennt jetzt allein die dünne Linie. */
/* ZWEI SPALTEN mit fester Kante statt „links Text, rechts außen das Feld": Rechtsbündig stand jedes
   Bedienelement woanders – mal am Kartenrand, mal weit davor –, und zwischen Beschriftung und Feld lag
   eine handbreite Lücke. Jetzt beginnen alle Felder auf derselben Linie, dicht an den Beschriftungen. */
.set-row {
    display: grid; grid-template-columns: minmax(0, 24rem) minmax(0, 1fr); align-items: center; gap: 1.5rem;
    padding: .85rem 0; border-top: 1px solid var(--tri-border);
}
.set-row:first-child { border-top: 0; }
/* Die Beschriftung steht in normaler Stärke: In einer Liste aus zwanzig Zeilen war jede fett, und fett
   hebt dann nichts mehr hervor. Betont wird, was man ändert – das Feld daneben. */
.set-row-label {
    display: flex; align-items: center; gap: .5rem; flex-wrap: wrap;
    min-width: 0; color: var(--tri-text);
}
.set-row-control { display: flex; align-items: center; justify-content: flex-start; min-width: 0; }
/* Für Adressen und Pfade: Das Feld nimmt, was die Zeile übrig lässt – ein Pfad in 26 rem war nach einem
   Drittel abgeschnitten. */
.set-row-control.is-wide .form-control { width: 100%; max-width: 38rem; }
.set-row-warn { font-size: .82rem; font-weight: 400; color: #8a6508; }
/* Eine Angabe, die man NICHT einstellen kann (etwa fest vorgegebene Passwortregeln): Sie steht an der
   Stelle des Bedienelements, damit die Zeile wie jede andere aussieht – nur eben ohne Schalter. */
.set-row-fixed { font-size: .85rem; font-weight: 400; color: var(--tri-faint); }

/* ---- Das (i) neben einer Beschriftung ----
   Die Blase erscheint beim Zeigen UND wenn der Knopf den Fokus hat; so ist sie auch auf einem Tastfeld
   und mit der Tastatur erreichbar. `pointer-events: none` an der Blase selbst: Sie darf dem Zeiger nie
   in den Weg geraten, sonst flackert sie an ihrer eigenen Kante. */
.info-hint { position: relative; display: inline-flex; align-items: center; }
.info-hint-btn {
    display: inline-flex; align-items: center; justify-content: center;
    width: 1.15rem; height: 1.15rem; padding: 0; border: 0; border-radius: 50%;
    background: transparent; color: var(--tri-faint); font-size: .95rem; line-height: 1; cursor: pointer;
}
.info-hint-btn:hover, .info-hint:focus-within .info-hint-btn { color: var(--tri-green); }
.info-hint-pop {
    position: absolute; left: 0; top: calc(100% + .45rem); z-index: 20;
    display: none; width: max-content; max-width: 30rem;
    padding: .65rem .85rem; border-radius: .6rem;
    background: #1b1c1d; color: #f1f3f5; font-size: .82rem; font-weight: 400; line-height: 1.5;
    box-shadow: 0 10px 28px rgba(16, 24, 40, .22); pointer-events: none;
}
.info-hint-pop strong { color: #fff; }
.info-hint-pop code { color: #cdeacf; background: rgba(255,255,255,.08); border-radius: .25rem; padding: 0 .25rem; }
.info-hint:hover .info-hint-pop, .info-hint:focus-within .info-hint-pop { display: block; }
/* Am rechten Rand würde die Blase sonst aus der Karte laufen. */
.info-hint.is-right .info-hint-pop { left: auto; right: 0; }

.settings-section {
    padding-bottom: 1.25rem;
    margin-bottom: 1.25rem;
    border-bottom: 1px solid #eceef0;
}

.settings-section:last-child {
    padding-bottom: 0;
    margin-bottom: 0;
    border-bottom: none;
}

.settings-section-title {
    font-size: 0.95rem;
    font-weight: 700;
    color: #2b2f36;
    margin-bottom: 0.75rem;
}

/* Lauf-Detail: grüne Icon-Kachel im Kopf */
.run-detail-tile {
    width: 3rem;
    height: 3rem;
    border-radius: 0.8rem;
    background-color: var(--tri-green);
    color: #fff;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 1.5rem;
    flex: 0 0 auto;
}

/* Audit-Zeitstrahl */
.run-timeline-item {
    position: relative;
    padding-left: 1.4rem;
    padding-bottom: 0.85rem;
}

.run-timeline-item::before {
    content: "";
    position: absolute;
    left: 4px;
    top: 4px;
    bottom: 0;
    width: 2px;
    background-color: #d7e3da;
}

.run-timeline-item:last-child {
    padding-bottom: 0;
}

.run-timeline-item:last-child::before {
    bottom: auto;
    height: 9px;
}

.run-timeline-item::after {
    content: "";
    position: absolute;
    left: 0;
    top: 2px;
    width: 11px;
    height: 11px;
    border-radius: 50%;
    background-color: #fff;
    border: 2px solid var(--tri-green);
}

.run-timeline-head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.35rem;
    margin-bottom: 0.15rem;
}

.run-timeline-time {
    font-size: 0.75rem;
    color: #8a9099;
}

/* Benachrichtigungs-Karten im Lauf-Detail */
.run-notif-card {
    border: 1px solid #e7e9ec;
    border-radius: 0.65rem;
    padding: 0.6rem 0.75rem;
    margin-bottom: 0.6rem;
}

.run-notif-card:last-child {
    margin-bottom: 0;
}

.run-notif-hitl {
    background-color: #f6f7f9;
}


.kanban-card-tags {
    display: flex;
    flex-wrap: wrap;
    gap: 0.3rem;
    margin-bottom: 0.55rem;
}

.kanban-card-times {
    font-size: 0.74rem;
    color: #80868b;
    margin-bottom: 0.5rem;
}

.kanban-card-error {
    font-size: 0.78rem;
    color: #b02a37;
    background: #fdf0f1;
    border-left: 3px solid #dc3545;
    border-radius: 0.3rem;
    padding: 0.3rem 0.5rem;
    margin-bottom: 0.5rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.kanban-priority {
    font-size: 0.66rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    border-radius: 0.3rem;
    padding: 0.1rem 0.35rem;
    margin-left: 0.4rem;
}
.kanban-priority-low { background: #eceff1; color: #607d8b; }
.kanban-priority-high { background: #fff3e0; color: #e65100; }
.kanban-priority-immediate { background: #fdecea; color: #c62828; }
.kanban-priority-dialog { background: var(--tri-green-bg-active); color: var(--tri-green-active); }

.kanban-card-foot {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    border-top: 1px solid #f1f3f4;
    padding-top: 0.55rem;
}

.kanban-card-foot .agent-id-chip {
    min-width: 1.6rem;
    height: 1.3rem;
    font-size: 0.72rem;
    border-radius: 0.35rem;
}

.kanban-card-agent {
    font-size: 0.8rem;
    color: #5f6368;
}

.kanban-card-link {
    color: #9aa0a6;
    font-size: 0.85rem;
    text-decoration: none;
}

.kanban-card-link:hover { color: var(--tri-green-dark); }

/* Modernes Benutzer-Modal */
/* Modal-Overlay fängt Scrollen ein: verhindert, dass das Scrollen (auch über Kopf/Fuß/Backdrop) an die Seite
   dahinter durchschlägt („Hintergrund scrollt statt Popup-Inhalt"). */
.modal.d-block { overscroll-behavior: contain; }

/* Solange ein Dialog offen ist, scrollt die SEITE nicht mit.
   Die Anwendung baut ihre Dialoge selbst (kein Bootstrap-JS), also setzt auch niemand `modal-open` auf den
   Body – Bootstraps Sperre greift damit nie. Sichtbar wurde das beim Rollen in einem Dialog mit langer
   Liste: Der Zeiger verlässt beim Rollen kurz den Scrollbereich, und ab da bewegte sich der Hintergrund.
   `overscroll-behavior: contain` allein genügt nicht – es verhindert nur die Weitergabe AM RAND des
   Scrollbereichs, nicht das Rollen daneben. Zentral über :has(), damit es für JEDEN Dialog gilt und nicht
   je Dialog nachgezogen werden muss. */
body:has(.modal.d-block) { overflow: hidden; }

.user-modal {
    border-radius: 1.1rem;
    /* KEIN eigener Grund. Das Fenster ist weiss, sein Kopf gruen - und zwischen beiden liegt bei
       manchen Dialogen noch ein <form> (EditForm), das die Rundung nicht mitbringt. Dort schaute
       das Weiss des Fensters oben um die gruene Ecke herum: ein heller Rand links und rechts oben.
       Beschneiden (`overflow: hidden`) scheidet aus - es schnitte die Aufklappmenues im Dialog ab.
       Das Weiss kommt deshalb aus Koerper und Fuss, die ihre Ecken selbst runden. */
    background-color: transparent;
    /* Kein overflow:hidden – sonst werden Popover/Menüs (z. B. „Tags zuordnen") am Modalrand abgeschnitten.
       Die runden Ecken werden stattdessen an Kopf/Fuß bzw. dem letzten Body einzeln gesetzt. */
    /* DREI Lagen, damit der Schatten auf dem abgedunkelten Grund überhaupt zu sehen ist: Ein
       dunkler Schatten auf einem halbdunklen Schirm verschwindet darin. Die feine helle Kante
       zeichnet die Form nach, der kurze Kontaktschatten setzt den Dialog auf, der weite gibt ihm
       Tiefe. Dieselbe Bauart wie beim Banner. */
    /* KEINE helle Kante mehr: Als 1-px-Ring um den Dialog zeichnete sie sich an den runden Ecken
       als weisser Schnipsel ab - ein Ring folgt der Rundung mit eigener Rasterung und passt dort
       nie genau auf die Kante darunter. Die beiden Schattenlagen genuegen. */
    box-shadow:
        0 2px 6px rgba(0, 0, 0, .35),
        0 28px 70px rgba(0, 0, 0, .55);
}
/* HAUSSTANDARD Dialogkopf: dunkles Band, weiße Schrift, kein Trennstrich. Gilt für ALLE `user-modal`,
   damit Zuordnungs-, Designer- und Verwaltungsdialoge denselben Kopf tragen. */
.user-modal-head {
    display: flex;
    align-items: center;
    gap: 0.85rem;
    padding: 1.1rem 1.5rem;
    /* Dieselbe Fläche wie der Seitenkopf: Dialog und Banner sind dasselbe Haus. Mit Branding gilt
       die Signature-Farbe des Kunden (`--wl-signature`, von js/branding-boot.js auf :root gesetzt), ohne Branding das
       Marken-Grün. Vorher war das Band fast schwarz - eine dritte Farbe neben Grün und Grau. */
    background: var(--wl-signature, var(--tri-green));
    color: #fff;
    border-bottom: 0;
    border-top-left-radius: 1.1rem;
    border-top-right-radius: 1.1rem;
}
.user-modal-head h5, .user-modal-head h6, .user-modal-head .modal-title { color: #fff; }
/* Bootstrap-Hilfsklassen für Untertitel sind auf hellen Grund gemünzt – auf dem dunklen Band aufhellen. */
.user-modal-head .text-muted, .user-modal-head .text-secondary { color: rgba(255, 255, 255, .78) !important; }
/* REIN WEISSES ✕ auf einer hellen, durchscheinenden Kachel - dieselbe Bauart wie die Knöpfe im Banner.
   Bootstraps `.btn-close` bringt ein SCHWARZES Bild mit; ein `filter: invert(1)` hätte die Fläche
   mitgedreht (der Knopf wurde weiß). Deshalb wird das Bild ersetzt, nicht gefiltert. Das frühere
   dunkelgraue Feld stammt aus der Zeit des fast schwarzen Kopfbandes und lag auf dem Grün als
   einziger dunkler Fleck. */
.user-modal-head .btn-close {
    flex: 0 0 auto; opacity: 1; width: 2.1rem; height: 2.1rem; padding: 0;
    border-radius: .6rem; background-color: rgba(255, 255, 255, .18); background-size: .85rem; background-position: center;
    background-repeat: no-repeat;
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23ffffff'%3e%3cpath d='M.293.293a1 1 0 0 1 1.414 0L8 6.586 14.293.293a1 1 0 1 1 1.414 1.414L9.414 8l6.293 6.293a1 1 0 0 1-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 0 1-1.414-1.414L6.586 8 .293 1.707a1 1 0 0 1 0-1.414z'/%3e%3c/svg%3e");
}
.user-modal-head .btn-close:hover { background-color: rgba(255, 255, 255, .3); }
/* HAUSSTANDARD Agententitel im Dialogkopf: Avatar · Zweckzeile (Kicker) · „#Nr Name" als Überschrift.
   Gilt für jeden Dialog, der sich auf EINEN Agenten bezieht – ein generisches Icon plus Zweck als
   Überschrift verwechselt der Benutzer sonst mit einer Funktion statt eines Agenten. */
.user-modal-kicker { font-size: .66rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: rgba(255, 255, 255, .72); }
.user-modal-title { font-size: 1.05rem; font-weight: 700; color: #fff; display: flex; align-items: baseline; gap: .5rem; min-width: 0; }
/* Der abzukürzende Teil ist ein FLEX-ELEMENT, und ein Flex-Element wird ohne `min-width: 0` nie kleiner
   als sein Inhalt (Vorgabe `min-width: auto`). Ohne die Angabe griff `text-overflow: ellipsis` nicht: Ein
   langer Titel wuchs aus dem Kopfband heraus und schob das Schließen-Kreuz aus dem Dialog. */
.user-modal-title > span:last-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
/* Zweites Netz: Auch ein Titel ohne die span-Struktur (nur Text im Element) darf das Band nicht sprengen. */
.user-modal-head { overflow: hidden; }
.user-modal-agentavatar { flex: 0 0 auto; border-radius: 50%; box-shadow: 0 0 0 2px rgba(255, 255, 255, .35); }
/* Die Agentennummer bleibt hellgrün wie überall und steht in der Größe des Namens davor. */
.user-modal-head .agent-num-inline { font-size: inherit; margin-right: 0; }
.user-modal-foot {
    background: #fff;
    border-bottom-left-radius: 1.1rem;
    border-bottom-right-radius: 1.1rem;
}
/* Dialoge, die Bootstraps eigenen Koerper verwenden, brauchen das Weiss ebenso. */
.user-modal > .modal-body,
.user-modal > form > .modal-body { background: #fff; }
/* Dialoge ohne Fußzeile (z. B. Typ-Auswahl): unteren Body abrunden. */
.user-modal > .modal-body:last-child {
    border-bottom-left-radius: 1.1rem;
    border-bottom-right-radius: 1.1rem;
}
.user-modal-avatar {
    width: 3rem;
    height: 3rem;
    flex-shrink: 0;
    border-radius: 50%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 1.4rem;
    color: #fff;
    /* Hell und durchscheinend statt grünem Verlauf: Auf dem grünen Band wäre ein grüner Kreis
       nur an seinem Schatten zu erkennen. Warnung und Löschen behalten ihre Farbe (siehe unten) -
       dort IST die Farbe die Aussage. */
    background: rgba(255, 255, 255, .18);
    box-shadow: 0 0 0 1px rgba(255, 255, 255, .25);
}
/* Warn-/Löschdialoge: gleiche runde Kachel, nur in Rot bzw. Gelb. Bootstraps `bg-danger` reicht nicht –
   `.user-modal-avatar` setzt einen Verlauf als background-image, der die Hintergrundfarbe verdeckt. */
.user-modal-avatar.is-danger { background: linear-gradient(135deg, #dc3545, #a71d2a); box-shadow: 0 4px 10px rgba(220,53,69,.35); }
.user-modal-avatar.is-warning { background: linear-gradient(135deg, #f0ad4e, #d98c1a); box-shadow: 0 4px 10px rgba(240,173,78,.35); }

/* Kennzeichen einer VERWEIS-Zeile in der Memory-Inhaltsliste: Das Kettensymbol steht vor dem Namen und
   sagt, dass der Eintrag nicht in diesem Ordner liegt, sondern dass der Ordner auf ihn zeigt.
   Bewusst GEDÄMPFT statt `text-primary`: Das Marken-Primär ist hier Grün, und ein grünes Symbol direkt vor
   einem grünen Namen verschwand darin - als Kennzeichen taugt nur, was sich vom Namen absetzt. */
.mem-link-mark { color: var(--tri-muted); font-size: 1.05em; vertical-align: -.06em; }

.user-modal-body { padding: 1.5rem; background: #fff; }
/* Modal, bei dem der INHALT scrollt statt das Fenster zu wachsen: feste Maximalhöhe, Kopf/Fuß bleiben,
   nur der Body scrollt. Robust auch in Safari (kein verlässliches max-height:Xvh auf zentrierten Flex-Bodys). */
.user-modal.user-modal-scroll { display: flex; flex-direction: column; max-height: calc(100vh - 3rem); overflow: hidden; }
/* Falls ein <EditForm>/<form> Kopf/Body/Fuß umschließt: es muss selbst die Flex-Spalte weiterreichen. */
.user-modal.user-modal-scroll > form { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; }
/* Descendant-Selektoren (nicht „>"), damit es mit UND ohne Form-Wrapper funktioniert. */
.user-modal.user-modal-scroll .user-modal-head,
.user-modal.user-modal-scroll .user-modal-foot { flex: 0 0 auto; }
/* Body füllt den Rest und scrollt. Höhe übernimmt der Flex (passt sich Kopf-/Fußhöhe automatisch an);
   Voraussetzung ist modal-no-lock, sonst friert modal-height-lock.js die min-height ein. */
.user-modal.user-modal-scroll .user-modal-body { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; }
/* STANDARD für größere/tab-basierte Dialoge: KONSTANTE (feste) Höhe. Das Popup öffnet immer gleich groß und
   springt beim Tab-Wechsel NICHT; der Body (bzw. der aktive Tab) scrollt intern. Bei vielen Feldern Tabs
   (trinidat-tabs) verwenden. Pflicht-Kombi: `user-modal user-modal-fixed modal-no-lock` (modal-no-lock, sonst
   friert modal-height-lock.js die min-height ein). Funktioniert mit UND ohne <EditForm>/<form>-Wrapper. */
.user-modal.user-modal-fixed { display: flex; flex-direction: column; height: min(780px, 94vh); overflow: hidden; }
.user-modal.user-modal-fixed > form { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; }
.user-modal.user-modal-fixed .user-modal-head,
.user-modal.user-modal-fixed .user-modal-foot { flex: 0 0 auto; }
.user-modal.user-modal-fixed .user-modal-body { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; }
/* Nutzungsbedingungen: Der TEXT scrollt in einem eigenen Kasten, nicht der ganze Körper. Nur so bleibt
   der Hinweis „bitte bis zum Ende lesen" darunter stehen, während gelesen wird – und nur so lässt sich
   messen, ob der Leser unten angekommen ist (die Freigabe von „Bestätigen" hängt daran). */
.user-modal-body.terms-body { display: flex; flex-direction: column; overflow: hidden; }
.terms-scroll { overflow-y: auto; overscroll-behavior: contain; padding-right: .5rem; }
/* Das Schlusszeichen am Ende des Textes: unsichtbar, aber vorhanden – der Beobachter braucht etwas
   zum Ansehen. Ein Element ohne Höhe meldet in keinem Browser verlässlich „ist zu sehen". */
.terms-end { height: 1px; }
/* Sprachwahl im dunklen Kopf: kleine, flache Schalter, die sich vom Band abheben, ohne es zu zerreißen. */
.terms-lang { flex: 0 0 auto; align-self: flex-start; }
.terms-lang .btn { --bs-btn-padding-y: .15rem; --bs-btn-padding-x: .5rem; font-weight: 600; letter-spacing: .03em; }

/* Dieses eine Fenster nimmt, was der Bildschirm hergibt — anders als jeder andere Dialog im Haus.
   Grund: Es ist kein Formular, sondern ein langer Text, der GELESEN werden soll, und die Schaltfläche
   „Bestätigen" wird erst am Ende frei. Je mehr auf einmal dasteht, desto weniger Rollen, desto eher
   wird wirklich gelesen. Die feste Höhe aus `user-modal-fixed` (780 px) wird dafür überschrieben.

   `dvh` statt `vh`: Auf dem Telefon zählt `vh` die eingeblendete Adressleiste mit — der Fuß mit den
   beiden Schaltflächen läge dann darunter und wäre nicht erreichbar. */
.modal-dialog.terms-dialog {
    max-width: min(1180px, calc(100vw - 2rem));
    width: 100%;
    margin: 1rem auto;
}
.user-modal.user-modal-fixed.terms-modal { height: calc(100dvh - 2rem); max-height: none; }

/* Telefon: Rand auf ein Minimum, Inhalt enger gesetzt, und der Fuß darf umbrechen — drei Schaltflächen
   nebeneinander passen auf 360 px nicht. „Als PDF laden" landet dann in der ersten Zeile, die
   Entscheidung („Abmelden · Bestätigen") in der zweiten. */
@media (max-width: 575.98px) {
    .modal-dialog.terms-dialog { max-width: calc(100vw - .75rem); margin: .375rem auto; }
    .user-modal.user-modal-fixed.terms-modal { height: calc(100dvh - .75rem); }
    .user-modal.terms-modal .user-modal-head { padding-left: 1rem; padding-right: 1rem; }
    .user-modal.terms-modal .user-modal-body { padding: 1rem; }
    /* Drei Schaltflächen passen auf 360 px nicht nebeneinander. Statt sie irgendwie umbrechen zu lassen:
       „Als PDF laden" bekommt die erste Zeile für sich, die ENTSCHEIDUNG („Abmelden · Bestätigen") steht
       darunter zusammen – so liegen die beiden Ausgänge nebeneinander, wo man sie sucht. */
    .user-modal.terms-modal .user-modal-foot { flex-wrap: wrap; padding-left: 1rem; padding-right: 1rem; }
    .user-modal.terms-modal .user-modal-foot > .btn:first-child { flex: 1 0 100%; margin-right: 0 !important; }
    .user-modal.terms-modal .user-modal-foot > .btn:not(:first-child) { flex: 1 1 0; }
}

/* Register, die den Dialog AUSFÜLLEN: Der Körper wird zur Flex-Spalte, der Registerkörper wächst in den
   Rest. Die feste Höhe kommt dann vom Dialog selbst – das Popup springt beim Registerwechsel genauso
   wenig wie mit einer festen Registerhöhe, lässt aber unten nichts leer stehen. */
.user-modal.user-modal-fixed .user-modal-body.user-modal-body-tabs {
    display: flex; flex-direction: column; overflow: hidden;
}
.user-modal-body-tabs > .ws-tab-body { height: auto; flex: 1 1 auto; min-height: 0; }
/* Trigger-Dialog mit Tabs: KONSTANTE (feste) Höhe als Flex-Spalte, damit das Popup beim Tab-Wechsel nicht
   springt. Der aktive Tab füllt den Platz; lange Inhalte scrollen intern. */
.trigger-modal-body { display: flex; flex-direction: column; height: min(36rem, 76vh); overflow: hidden; }
.trigger-tab-scroll { flex: 1 1 auto; min-height: 0; overflow-y: auto; align-content: flex-start; }
.trigger-tab-fill { flex: 1 1 auto; min-height: 0; }
/* HAUSSTANDARD Dialogfuß: ohne graue Fläche, ohne Trennstrich, Schaltflächen rechts. */
.user-modal-foot {
    display: flex;
    justify-content: flex-end;
    gap: 0.5rem;
    padding: .4rem 1.5rem 1rem;
    /* WEISS, nicht `transparent`. Das `transparent` stammt aus der Zeit, als das Fenster selbst
       weiss war - der Fuss sollte damals nur keine eigene graue Flaeche haben (Hausstandard).
       Seit das Fenster keinen Grund mehr traegt (damit die gruene Ecke oben sauber bleibt), muss
       der Fuss sein Weiss selbst mitbringen; sonst schaut der abgedunkelte Schirm hindurch. */
    background: #fff;
    border-top: 0;
}
.role-toggle {
    display: flex;
    gap: 0.5rem;
}
.role-option {
    flex: 1;
    padding: 0.35rem 0.6rem;
    border: 1.5px solid #dde1e5;
    border-radius: 0.6rem;
    background: #fff;
    color: #6c757d;
    font-weight: 600;
    font-size: 0.85rem;
    transition: all 0.15s;
}
.role-option:hover { border-color: var(--tri-green); color: var(--tri-green); }
.role-option.active {
    border-color: var(--tri-green);
    background: var(--tri-green-bg-active);
    color: var(--tri-green-active);
}

/* Sortierbare Tabellen-Überschriften */
th.sortable {
    cursor: pointer;
    user-select: none;
    white-space: nowrap;
}
th.sortable:hover { background-color: #e9ecef; }

/* Kleine Agenten-Nummer für Listen/Überschriften */
.agent-id-chip {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 1.65rem;
    height: 1.3rem;
    padding: 0 0.4rem;
    border-radius: 0.35rem;
    /* Helles Marken-Grün wie das aktive Menü (branding-fähig: leitet sich bei aktivem Branding
       automatisch aus der Signature-Farbe ab – dieselben Tokens wie die Sidebar). */
    background: var(--tri-green-bg-active);
    color: var(--tri-green);
    font-size: 0.72rem;
    font-weight: 700;
    line-height: 1;
}

/* Agentenkopf-Symbol in der Liste (grün; Kritiker grau via Graustufenfilter).
   Höhe an den zweizeiligen Textblock (Name + Beschreibung) rechts angeglichen. */
.agent-head {
    height: 2.4rem;
    width: auto;
    flex: 0 0 auto;
    display: block;
}

/* Etwas größere Nummern-Variante für die Agentenliste (Worker grün, Kritiker grau). */
/* Zeile "Nummer + Name" in Auswahllisten: Die Nummern sind unterschiedlich breit (#60 vs. #105) und
   schoben die Namen jeweils an eine andere Stelle. Feste Chip-Breite -> alle Namen beginnen gleich. */
.agent-pick-row { display: flex; align-items: center; gap: .5rem; min-width: 0; }
.agent-pick-row > .agent-id-chip { flex: 0 0 auto; min-width: 3.1rem; }
.agent-pick-row > span:last-child { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.agent-id-chip-lg {
    min-width: 2.3rem;
    height: 1.95rem;
    padding: 0 0.55rem;
    border-radius: 0.5rem;
    font-size: 0.95rem;
}

/* In Titel/Namen integrierte Agentennummer: dunkelgrau, gleiche Schriftart wie der Name. */
/* Agentennummer (z. B. „#32") vor dem Namen: IMMER fett + grau, mit Abstand zum Namen. */
.agent-num {
    color: var(--tri-subtle);
    font-weight: 600;
    margin-right: .35rem;
}

/* Run-Detail-Kopf: EINZEILIG – Nummer-Badge, Agentenname (kürzt via Ellipsis) und RUN-Nummer nebeneinander (Links → Designer mit Lauf). */
/* Alle drei Elemente (Nummer-Badge, Agentenname, RUN-Nummer) als flache, an der Grundlinie ausgerichtete Zeile –
   so teilen Name und „RUN-…" exakt dieselbe Textbasislinie (früher lag der Name in einem verschachtelten Flex-Container,
   dessen synthetische Baseline die RUN-Nummer nach oben versetzte). */
.run-title-block { display: flex; flex-direction: row; align-items: baseline; gap: 0.5rem; min-width: 0; }
/* Agentennummer, Agentenname und Laufnummer im Lauf-Kopf: EINHEITLICHE Schriftgröße (= Titelgröße, per inherit) und
   gleiche line-height, damit sie über align-items:baseline sauber auf EINER Baseline sitzen. */
.agent-num-badge {
    flex: 0 0 auto; font-weight: 700; font-size: inherit; line-height: 1.2; color: var(--tri-green-dark);
    background: var(--tri-green-bg); border: 1px solid var(--tri-green-soft);
    border-radius: 0.5rem; padding: 0 0.45rem; text-decoration: none;
}
.agent-num-badge:hover { background: var(--tri-green-bg-active); color: var(--tri-green-dark); }
.run-title-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; line-height: 1.2; }
.run-num-link { flex: 0 0 auto; white-space: nowrap; font-size: inherit; line-height: 1.2; font-weight: 600; color: var(--tri-muted, #6b7280); text-decoration: none; }
.run-num-link:hover { color: var(--tri-green); text-decoration: underline; }
.run-num-sub { color: var(--tri-green); }
.run-num-sub:hover { color: var(--tri-green-dark); text-decoration: underline; }

/* Agentenname im Seitentitel: Markengrün. */
.agent-name-title {
    color: var(--tri-green);
}

.agent-head-critic {
    filter: grayscale(1) brightness(1.05);
}

/* Größerer Kopf für Detail-/Kopfbereiche (passt zur Höhe des Nummern-Badges). */
.agent-head-lg {
    height: 3.2rem;
}

/* Kritiker-Agenten: helles Grau (analog zum hellen Grün der Worker-Nummer). */
.agent-id-chip-critic {
    background: #eceef0;
    color: #6f757d;
}

/* Drag&Drop-Tabelle für Skills (vorangestellte Prompts) */
.skill-order-table tbody tr {
    cursor: grab;
}

.skill-order-table tbody tr.skill-row-dragging {
    opacity: 0.5;
    background: var(--tri-green-bg);
}

.skill-order-table .bi-grip-vertical {
    cursor: grab;
}

/* Aktionen-Menü (Kebab) in der Agentenliste. */
/* Aktionsmenü darf aus dem Tabellen-Container herausragen (sonst wird das Popup bei den
   unteren Zeilen abgeschnitten). */
.agents-table-wrap,
.triggers-table-wrap,
.bucket-table-wrap {
    overflow: visible;
}

/* Tabellen-Wrapper mit Zeilen-Aktionsmenü (agent-actions-menu) sichtbar lassen, damit das absolut
   positionierte Menü nicht vom horizontalen Scroll-Container (table-responsive) abgeschnitten wird. */
.memory-table-wrap,
.db-table-wrap { overflow: visible; }

.agent-actions-menu {
    position: absolute;
    top: calc(100% + 4px);
    right: 0;
    z-index: 1056;
    min-width: 210px;
    background: #fff;
    border: 1px solid #e2e4e8;
    border-radius: 0.6rem;
    padding: 0.35rem;
    text-align: left;
}

/* Bei den unteren Zeilen nach oben öffnen, damit das Menü im sichtbaren Bereich bleibt. */
.agent-actions-menu-up {
    top: auto;
    bottom: calc(100% + 4px);
}

.agent-actions-item {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    width: 100%;
    border: none;
    background: none;
    text-align: left;
    padding: 0.45rem 0.6rem;
    border-radius: 0.4rem;
    font-size: 0.9rem;
    color: #33373d;
}

.agent-actions-item:hover {
    background-color: var(--tri-green-bg);
}

/* Gefährliche Aktion (z. B. Löschen): roter Hover statt grün. */
.agent-actions-item.text-danger:hover {
    background-color: #fdecec;
}

/* Trenner zwischen Aktionsgruppen im Zeilen-Menü. */
.agent-actions-sep {
    height: 1px;
    background: #e2e4e8;
    margin: 0.3rem 0.25rem;
}

/* ---------- Ordner-TreeView ---------- */
.folder-tree {
    user-select: none;
}

/* Ordner-Auswahl als Popup (z. B. Filter in der Agentenliste). */
.folder-filter-pop {
    position: absolute;
    top: calc(100% + 4px);
    left: 0;
    right: 0;
    z-index: 1056;
    background: #fff;
    border: 1px solid #e2e4e8;
    border-radius: 0.6rem;
    padding: 0.4rem;
    max-height: 22rem;
    overflow: auto;
    user-select: none;
}

.folder-node {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.3rem 0.5rem;
    border-radius: 0.5rem;
    cursor: pointer;
    font-size: 0.82rem;       /* gleiche Größe wie die Agenten-Blätter */
    transition: background 0.12s, box-shadow 0.12s;
}

.folder-node:hover {
    background: #f1f5f2;
}

.folder-node.selected {
    background: var(--tri-green-bg-active);
}

/* Ordner, der direkt oder in einem Unterordner (rekursiv) einen markierten Bucket enthält: deutlich hervorgehoben. */
.folder-node.folder-has-selected {
    background: #eaf6ee;
    box-shadow: inset 3px 0 0 var(--tri-green);
}
.folder-node.folder-has-selected .folder-name { color: var(--tri-green-dark); font-weight: 600; }
.folder-node.folder-has-selected .folder-icon { color: var(--tri-green-dark); }

/* Hervorhebung beim Darüberziehen eines Agenten (Drop-Ziel). */
.folder-node.drag-over {
    background: #d7efdc;
    box-shadow: 0 0 0 2px var(--tri-green) inset;
}

.folder-caret {
    width: 1rem;
    display: inline-flex;
    justify-content: center;
    color: #8a9099;
    font-size: 0.8rem;
    flex: 0 0 auto;
}

.folder-icon {
    color: var(--tri-green);   /* TriniDat-Grün */
    font-size: 1.25rem;        /* etwas größer */
    flex: 0 0 auto;
    /* Ein Pixel nach unten. Die Zeile richtet mittig aus (align-items: center), das Symbol ist aber mit
       1.25rem deutlich größer als der Text (0.82rem) - und bei den Bootstrap-Icons liegt die sichtbare
       Fläche innerhalb des Zeichens etwas über der Mitte. Mathematisch mittig sah deshalb zu hoch aus.
       Über `position: relative` verschoben, damit die Zeilenhöhe unberührt bleibt. */
    position: relative;
    top: 1px;
}

/* Pausierte Trigger-Zeile dezent ausgrauen (Bezeichnung/Aktionen bleiben bedienbar). */
.trigger-paused td:not(:last-child) {
    opacity: 0.55;
}

.folder-name {
    flex: 1 1 auto;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.folder-count {
    flex: 0 0 auto;
    min-width: 1.4rem;
    text-align: center;
    background: #e9ecef;
    color: #495057;
    border-radius: 1rem;
    font-size: 0.72rem;
    font-weight: 600;
    padding: 0.05rem 0.45rem;
}

/* Aktions-Buttons je Knoten: erst beim Hovern sichtbar – und reservieren vorher KEINEN Platz
   (Breite 0), damit der Ordnername die volle Breite nutzen kann und nur beim Hovern gekürzt wird. */
.folder-actions {
    display: inline-flex;
    gap: 0.15rem;
    opacity: 0;
    width: 0;
    overflow: hidden;
    transition: opacity 0.12s;
    flex: 0 0 auto;
}

.folder-node:hover .folder-actions {
    opacity: 1;
    width: auto;
}

.folder-actions button {
    border: none;
    background: transparent;
    color: #6c757d;
    padding: 0.1rem 0.3rem;
    border-radius: 0.35rem;
    line-height: 1;
}

.folder-actions button:hover {
    background: #ffffff;
    color: var(--tri-green);
}

/* Agenten-Blatt im Baum (unter einem Ordner) – kompakt, dezent. */
.folder-agent-leaf {
    display: flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.12rem 0.5rem;
    border-radius: 0.5rem;
    cursor: grab;
    font-size: 0.82rem;
}

.folder-agent-leaf:hover {
    background: #f1f5f2;
}

/* Klickbarer Agent (z. B. im Designer-Baum) + aktuell geöffneter Agent */
.folder-agent-leaf.is-clickable { cursor: pointer; }
.folder-agent-leaf.is-clickable .folder-agent-leaf-name { cursor: pointer; }
.folder-agent-leaf.active { background: #e7f4ea; }
.folder-agent-leaf.active .folder-agent-leaf-name { color: var(--tri-green-hover); font-weight: 600; }

.folder-agent-leaf:active {
    cursor: grabbing;
}

.folder-agent-leaf-icon {
    color: #9aa0a6;
    font-size: 0.8rem;
    flex: 0 0 auto;
}

/* Agentennummer: fett, dunkelgrau, mit Abstand zum Namen (#106782). */
.folder-agent-leaf-num {
    color: #495057;
    font-weight: 700;
    margin-right: 0.4rem;
}

/* Agentenname: normal (nicht fett), dezente Farbe, beim Hovern grün. */
.folder-agent-leaf-name {
    flex: 1 1 auto;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: #33373d;
    font-weight: 400;
    text-decoration: none;
}

.folder-agent-leaf-name:hover {
    color: var(--tri-green);
}

.folder-agent-leaf-remove {
    border: none;
    background: transparent;
    color: #adb5bd;
    padding: 0.05rem 0.3rem;
    border-radius: 0.35rem;
    line-height: 1;
    opacity: 0;
    transition: opacity 0.12s;
    flex: 0 0 auto;
}

.folder-agent-leaf:hover .folder-agent-leaf-remove {
    opacity: 1;
}

.folder-agent-leaf-remove:hover {
    background: #fff;
    color: #dc3545;
}

/* Farbiger Tag-Punkt am Ordnerknoten. */
.folder-tag-dot {
    width: 0.55rem;
    height: 0.55rem;
    border-radius: 50%;
    flex: 0 0 auto;
}

/* Agenten-Zeile (rechts), per Drag&Drop einem Ordner zuweisbar – kompakt. */
.folder-agent-row {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.18rem 0.5rem;
    border: 1px solid #eceef1;
    border-radius: 0.5rem;
    margin-bottom: 0.2rem;
    background: #fff;
    cursor: grab;
    font-size: 0.92rem;
}
.folder-agent-row .folder-agent-leaf-name { font-weight: 400; color: #33373d; font-size: 0.92rem; }
.folder-agent-row .folder-agent-leaf-num { font-size: 0.92rem; }
.folder-agent-row .folder-agent-leaf-icon { font-size: 1.05rem; }
/* Ressourcen-Icons (Memory/Workspace/Datenbank/Konnektor/Tool) in Zeilen & Baum immer GRÜN. */
.folder-row-ic-green { color: var(--tri-green); font-size: 1.05rem; flex: 0 0 auto; }

.folder-agent-row:hover {
    border-color: #cfe6d5;
    background: #fafdfb;
}

.folder-agent-row:active {
    cursor: grabbing;
}

/* Topbar: angemeldeter Benutzer */
.topbar-user {
    color: #cfd2d6;
    font-size: 0.9rem;
    margin-left: 0.5rem;
}

/* Klickbarer Benutzername in der Topbar (öffnet das Profil) */
.topbar-user-btn {
    align-items: center;
    background: none;
    border: none;
    color: #cfd2d6;
    font-size: 0.9rem;
    margin-left: 0.5rem;
    padding: 0.35rem 0.6rem;
    border-radius: 6px;
    cursor: pointer;
}
.topbar-user-btn:hover {
    background-color: rgba(255, 255, 255, 0.08);
    color: #fff;
}

/* API-Token-Liste in Profil-/Benutzer-Dialogen */
.token-list {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}
.token-item {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.5rem 0.7rem;
    border: 1px solid #e6e8ea;
    border-radius: 0.5rem;
    background: #f8f9fa;
}
.token-value {
    display: block;
    font-size: 0.75rem;
    color: #4b5159;
    word-break: break-all;
}

/* Lauf-Historie */
.list-group-item-action.active-run {
    background-color: var(--tri-green-bg-active);
    border-left: 3px solid var(--tri-green);
}

.chat-bubble {
    max-width: 85%;
    border-radius: 0.75rem;
    padding: 0.6rem 0.85rem;
    font-size: 0.9rem;
}

.chat-out {
    background-color: var(--tri-green-bg-active);
    border: 1px solid var(--tri-green-soft);
}

.chat-in {
    background-color: #f1f3f5;
    border: 1px solid #e6e8ea;
}

/* Volle-Breite-Chatnachrichten (Claude-Desktop-Stil) */
.chat-msg {
    width: 100%;
    border-radius: 0.6rem;
    padding: 0.75rem 1rem;
    margin-bottom: 0.75rem;
}

.chat-msg-out {
    background-color: #fff;
    border: 1px solid var(--tri-border);
}

/* Payload/JSON als Chat-Nachricht: eingerückt, umbrechend statt horizontalem Scroll */
.chat-json {
    white-space: pre-wrap;
    word-break: break-word;
    overflow-wrap: anywhere;
    margin-top: 0.25rem;
}

.chat-msg-in {
    background-color: #f7f8fa;
    border: 1px solid #e6e8ea;
}

.chat-msg-critic {
    background-color: #fff4e3;
    border: 1px solid #ffd9a0;
}

/* Finale, vom Lauf übernommene Antwort: schlichtes graues Rechteck mit runden Ecken. */
.chat-msg-final {
    border: 2px solid var(--tri-green);
    border-radius: 0.6rem;
    box-shadow: none;
}

.chat-msg-critic .chat-msg-head {
    color: #b45e09;
}

/* Finale Antwort eines Sub-Agenten (delegierter Lauf): neutraler Block wie eine normale Nachricht;
   die Kennzeichnung übernimmt das grüne „Finale Antwort Sub-Agent"-Badge im Kopf (kein grüner Hintergrund/Streifen). */
.chat-msg-deleg {
    background-color: #fff;
    border: 1px solid var(--tri-border);
}
/* Kopf des Delegations-Blocks an der TEXT-Baseline ausrichten (nicht mittig): so sitzt das „Finale Antwort
   Sub-Agent"-Badge auf derselben Grundlinie wie der Agentenname/RUN-Link daneben. */
.chat-msg-deleg > .chat-msg-head { align-items: baseline; }

/* Agentenläufe-Übersicht: Agentenname + Aufgaben-Titel EINZEILIG mit Ellipsis (kein Umbruch, Kürzung nach Breite).
   Die Breite gibt die SPALTE vor (siehe AgentRunsOverview.razor.css), nicht mehr ein fester Wert: 26 rem
   schoben die Tabelle in einem schmalen Fenster über den rechten Rand hinaus. */
.run-agent-name {
    display: inline-block;
    max-width: 100%;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    vertical-align: bottom;
}
.run-agent-ref {
    display: block;
    max-width: 100%;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.chat-msg-head {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.25rem;
    font-size: 0.8rem;
    font-weight: 600;
    color: #4b5159;
    margin-bottom: 0.35rem;
}

.chat-tokens {
    font-size: 0.7rem;
    font-weight: 400;
    color: #9aa0a6;
    margin-left: 0.4rem;
}

.chat-copy {
    border: none;
    background: none;
    color: #9aa0a6;
    padding: 0 0.25rem;
    line-height: 1;
    cursor: pointer;
    font-size: 0.9rem;
}

.chat-copy:hover { color: var(--tri-green); }

.chat-activity > summary {
    cursor: pointer;
    list-style: none;
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    padding: 0.35rem 0.85rem;
    background: #f3f4f6;
    border: none;
    border-radius: 999px;
    color: var(--tri-text);
    font-size: 0.85rem;
    font-weight: 600;
}
.chat-activity > summary::-webkit-details-marker { display: none; }
.chat-activity > summary:hover { background: #eceef1; }
.chat-activity-bulb { color: var(--tri-green); font-size: 0.92rem; }
.chat-activity-caret-end { margin-left: 0.4rem; color: #6a7078; font-size: 0.78rem; transition: transform 0.15s; }
.chat-activity[open] > summary .chat-activity-caret-end { transform: rotate(180deg); }

/* Schritt-Timeline (Denk- & Tool-Schritte) */
.chat-activity-body.chat-steps { background: transparent; border-left: 2px solid #eceef1; padding: 0 0 0 0.5rem; margin-top: 0.5rem; font-size: inherit; }
.chat-step { display: flex; gap: 0.5rem; padding: 0.35rem 0 0.35rem 0.5rem; }
.chat-step-icon { color: #6a7078; font-size: 0.82rem; margin-top: 0.15rem; flex: 0 0 auto; }
.chat-step-main { min-width: 0; }
.chat-step-title { font-weight: 700; color: var(--tri-text); font-size: 0.82rem; }
.chat-step-detail { color: var(--tri-muted, #8a9099); font-size: 0.76rem; overflow-wrap: anywhere; }

.chat-activity-body {
    margin-top: 0.4rem;
    padding: 0.5rem 0.75rem;
    background: #f6f8f9;
    border-left: 3px solid #c9d3cb;
    border-radius: 0.35rem;
    font-size: 0.82rem;
}

/* Immer sichtbare Abschnitte im Chat-Verlauf (Denkprozess, Tool-/MCP-Aufrufe) – kein Ein-/Ausklappen. */
.chat-section-head {
    font-size: 0.78rem;
    font-weight: 600;
    color: #6c757d;
    margin-bottom: 0.1rem;
}

.chat-section-body {
    margin-top: 0.25rem;
    padding: 0.5rem 0.75rem;
    background: #f6f8f9;
    border-left: 3px solid #c9d3cb;
    border-radius: 0.35rem;
    font-size: 0.82rem;
}

/* Vollständiges LLM-Protokoll: bei sehr langen Verläufen begrenzen + scrollen, statt die Seite zu sprengen. */
.chat-protocol-scroll {
    max-height: 32rem;
    overflow-y: auto;
}

/* Strukturiertes LLM-Protokoll: jeder Tool-Aufruf in eigenem Rahmen; finale Antwort (nach dem letzten Tool) hervor. */
.run-tool-card {
    border: 1px solid var(--tri-border, #d7ddd9);
    border-radius: 0.5rem;
    padding: 0.55rem 0.75rem;
    margin: 0.6rem 0;
    background: #fbfcfc;
}
.run-tool-card-head { font-weight: 600; margin-bottom: 0.25rem; }
.run-tool-card-label {
    font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.03em;
    color: var(--tri-muted, #6b7770); margin: 0.45rem 0 0.1rem;
}
/* Parameter/Ergebnis: helles Grau mit schwarzem Text (nicht schwarz hinterlegt); lange Zeilen umbrechen. */
.run-tool-code {
    background: #f1f4f5;
    color: #1a1f1c;
    border: 1px solid var(--tri-border, #d7ddd9);
    border-radius: 0.4rem;
    padding: 0.5rem 0.7rem;
    margin: 0.1rem 0 0;
    font-size: 0.8rem;
    white-space: pre-wrap;
    word-break: break-word;
    overflow-x: auto;
}
.run-tool-code code { color: inherit; background: none; padding: 0; }
.run-final-answer {
    border: 1px solid var(--tri-green);
    border-radius: 0.5rem;
    padding: 0.55rem 0.85rem;
    margin: 0.7rem 0 0.3rem;
    background: #fff;
}
.run-proto-meta { border-top: 1px dashed var(--tri-border, #d7ddd9); padding-top: 0.4rem; margin-top: 0.5rem; }

/* Tool-Aktivitäten: Tabelle mit aufklappbaren Zeilen (Parameter + Ergebnis). */
.run-toolcall-name {
    font-weight: 600;
    color: var(--bs-emphasis-color, #212529);
}
.run-toolcall-detail > td {
    background: #f6f8f9;
}

/* Live mitlaufender Text auf der Lauf-Detailseite – in voller Länge, Zeilenumbrüche erhalten, KEIN Scroll-Bereich
   (eigene Klasse, damit die scrollbare .chat-live-text aus Chat/Test-Dialog hier nicht greift). */
.run-live-text {
    white-space: pre-wrap;
    line-height: 1.4;
    font-size: 0.82rem;
    margin-top: 0.35rem;
}

.progress-history {
    border-top: 1px solid #dde0e4;
    margin-top: 0.6rem;
    padding-top: 0.6rem;
    max-height: 55vh;
    overflow-y: auto;
}

.progress-activity-log {
    background: #f0f4f1;
    border-left: 3px solid var(--tri-green);
    border-radius: 0.4rem;
    padding: 0.4rem 0.75rem;
}

.progress-activity-item {
    font-size: 0.82rem;
    color: #3a4a3d;
    padding: 0.1rem 0;
}

/* Composer: Eingabefeld mit +-Button (Anhänge) und grünem Senden-Button */
.composer {
    border: 1px solid #e3e6ea;
    border-radius: 0.9rem;
    background: #fff;
    padding: 0.7rem 0.85rem 0.6rem;
    /* Eine eigene Flaeche unter dem Gespraech - sie liegt genauso auf wie dieses. */
    box-shadow: var(--tri-shadow-flaeche);
    transition: border-color 0.15s, box-shadow 0.15s;
}

/* Dezenter, neutraler Fokus – kein grüner Rahmen/Glow (Design-Vorgabe) */
.composer:focus-within {
    border-color: #cfd4da;
    box-shadow: none;
}

.composer-text {
    display: block;
    width: 100%;
    border: none;
    outline: none;
    /* Deutlich höheres Eingabefeld; vom Nutzer vertikal vergrößerbar (#106823). */
    resize: vertical;
    min-height: 5.5rem;
    background: transparent;
    font: inherit;
    line-height: 1.45;
}

.composer-bar {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    margin-top: 0.35rem;
}

.composer-add {
    width: 2.1rem;
    height: 2.1rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 0.55rem;
    color: #4b5159;
    font-size: 1.1rem;
    cursor: pointer;
    margin-bottom: 0;
}

.composer-add:hover { background: #eef0f3; }
.composer-add.disabled { opacity: 0.4; pointer-events: none; }

.composer-send {
    width: 2.3rem;
    height: 2.3rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: none;
    border-radius: 0.65rem;
    background: var(--tri-green);
    color: #fff;
    font-size: 1.05rem;
    transition: background 0.15s;
}

.composer-send:hover:not(:disabled) { background: var(--tri-green-active); }
.composer-send:disabled { opacity: 0.45; }

/* Datei-Drop auf den Composer: Rahmen hervorheben + Overlay-Hinweis (nur beim Ziehen sichtbar). */
.composer.composer-dragover { border-color: var(--tri-green); box-shadow: 0 0 0 2px rgba(var(--tri-green-rgb),.18); }
.composer-drophint {
    display: none; position: absolute; inset: 0; z-index: 3;
    align-items: center; justify-content: center;
    border-radius: 0.9rem; background: rgba(var(--tri-green-rgb),.06);
    border: 2px dashed var(--tri-green); color: var(--tri-green); font-weight: 600; font-size: 0.9rem;
    pointer-events: none;
}
.composer.composer-dragover .composer-drophint { display: flex; }

/* Datenbank-Browser: Primärschlüssel-Zelle als Link (öffnet Popup referenzierender Tabellen). */
.db-pk-link { color: var(--tri-green); font-weight: 600; cursor: pointer; text-decoration: none; border-bottom: 1px dotted var(--tri-green); }
.db-pk-link:hover { color: var(--tri-green-dark); border-bottom-style: solid; }

/* ===== Modernes Chat-Fenster (AgentChatPanel): flach, Avatar + Name/Zeit + Text (kein Sprechblasen-Stil) ===== */
.chat-conv { display: flex; flex-direction: column; height: 100%; min-height: 0; }
.chat-conv > .chat-thread {
    flex: 1 1 auto; min-height: 0; overflow-y: auto;
    background: #fff; padding: 0.25rem 0.25rem 0.5rem;
}
.chat-conv > .chat-composer { flex: 0 0 auto; padding: 0.85rem 1rem 1rem; border-top: 1px solid #eef0f2; }

.chat-msg { display: flex; gap: 0.75rem; align-items: flex-start; padding: 0.85rem 0.75rem; border-bottom: 1px solid #f0f1f3; }
.chat-msg:last-child { border-bottom: none; }
/* Finale Antwort: allseitiger grauer Rahmen auch als last-child (sonst nimmt .chat-msg:last-child die Unterkante weg). */
.chat-msg.chat-msg-final { border: 2px solid var(--tri-green); border-radius: 0.6rem; box-shadow: none; }
/* Run-Kontext-Nachrichten (RunDetail/AgentRuns/AgentTest) als gestapelter Block: Meta-Kopf OBEN (horizontal über die
   volle Breite), Inhalt + Anhänge darunter – NICHT links daneben. Gilt nicht für den Chat-Dialog (.chat-msg.user/.agent).
   Muss nach der .chat-msg{display:flex}-Regel stehen, um deren Flex-Spalten-Layout zu überschreiben. */
.chat-msg-out, .chat-msg-in, .chat-msg-critic, .chat-msg-deleg { display: block; }
/* Meta-Kopf über die Breite verteilt (Name, Badge, Uhrzeit, Tokens nebeneinander). */
.chat-msg-out > .chat-msg-head, .chat-msg-in > .chat-msg-head, .chat-msg-critic > .chat-msg-head, .chat-msg-deleg > .chat-msg-head {
    width: 100%; margin-bottom: 0.5rem; column-gap: 0.75rem;
}
.chat-msg-body { min-width: 0; }
/* Datei-Anhang-Karten (Icon + Name + Größe), unter dem Textblock. */
.run-att-list { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 0.6rem; }
.run-att-card {
    display: inline-flex; align-items: center; gap: 0.55rem;
    min-width: 11rem; max-width: 16rem; padding: 0.45rem 0.6rem;
    border: 1px solid var(--tri-border); border-radius: 0.6rem; background: #fff;
    text-align: left; cursor: pointer; transition: border-color 0.12s, box-shadow 0.12s;
}
.run-att-card:hover { border-color: var(--tri-green); box-shadow: 0 2px 8px rgba(0,0,0,0.08); }
.run-att-icon { flex: 0 0 auto; font-size: 1.6rem; line-height: 1; display: inline-flex; }
.run-att-info { display: flex; flex-direction: column; min-width: 0; flex: 1 1 auto; }
.run-att-name { font-size: 0.82rem; font-weight: 600; color: var(--tri-text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.run-att-size { font-size: 0.72rem; color: var(--tri-muted); }
.run-att-dl { flex: 0 0 auto; color: var(--tri-muted); font-size: 0.9rem; }
.run-att-card:hover .run-att-dl { color: var(--tri-green); }

/* Register „Ergebnis": Karten der gesendeten Mails */
.erg-mail-card { border: 1px solid var(--bs-border-color, #dee2e6); border-radius: 0.6rem; padding: 0.75rem 0.9rem; background: var(--bs-body-bg, #fff); }
.erg-mail-head { display: flex; align-items: center; gap: 0.15rem; }
.erg-mail-fields { margin-top: 0.5rem; display: grid; gap: 0.15rem; }
.erg-mf-row { display: grid; grid-template-columns: 4.5rem 1fr; gap: 0.5rem; font-size: 0.9rem; }
.erg-mf-label { color: var(--bs-secondary-color, #6c757d); font-weight: 600; }
.erg-mf-val { color: var(--bs-body-color); overflow-wrap: anywhere; }
.erg-mail-body { border-top: 1px solid var(--bs-border-color, #eee); padding-top: 0.5rem; margin-top: 0.5rem; }

/* Datei-Vorschau-Dialog (FilePreviewDialog): liegt ÜBER allem anderen. Sie wird meist aus einem anderen
   Dialog heraus geöffnet (Lauf-Ergebnis im Designer, Memory, Chat); mit der Bootstrap-Standardhöhe (1055)
   erschien sie hinter den Designer-Dialogen (1100) - der Klick sah dann wirkungslos aus. Über dem
   Avatar-Zuschnitt (1190/1200), weil beides nie zugleich offen ist und die Vorschau der letzte Aufruf ist. */
/* Mehrere Selektoren, und der letzte ist der entscheidende. Gegen Bootstraps `.modal` (0,1,0) genuegte
   eine Klasse nicht; gemessen kam 1055 heraus. Der eigentliche Gegner steht weiter unten in DIESER Datei:
   `.page-content > .modal.modal { z-index: 1055 }` (0,3,0, der Opt-out fuer seitenfuellende Dialoge).
   Die Vorschau wird aus solchen Seiten heraus geoeffnet und lag deshalb HINTER dem Dialog, aus dem der
   Klick kam – der Klick sah wirkungslos aus. Deshalb hier dieselbe Spezifitaet (0,3,0) und zusaetzlich die
   Form mit `.page-content >`, damit es unabhaengig von der Reihenfolge der Regeln stimmt. */
.modal-backdrop.file-preview-backdrop,
.page-content > .modal-backdrop.file-preview-backdrop { z-index: 1210; }
.modal.modal.file-preview-modal,
.page-content > .modal.file-preview-modal { z-index: 1220; }

/* Datei-Vorschau-Dialog (FilePreviewDialog): angenehm groß, aber nicht bildschirmfüllend. */
.file-preview-dialog { max-width: min(860px, 92vw); width: auto; margin: 1.75rem auto; }
.file-preview-body { max-height: 70vh; min-height: 32vh; overflow: auto; }
/* Der Rahmen für PDF/Bild füllt den Rumpf ohne Rand. Seit 2.0.548 zeichnet PDF.js das PDF selbst
   (.file-preview-pdf); .file-preview-frame bleibt für den Fall, dass wieder etwas eingebettet wird. */
.file-preview-body:has(.file-preview-frame), .file-preview-body:has(.file-preview-pdf) { padding: 0; overflow: hidden; }
.file-preview-frame { width: 100%; height: 70vh; border: 0; display: block; }
/* PDF-Vorschau: die Seiten liegen untereinander und werden mitgerollt. Grauer Grund, damit die weißen
   Seiten als Blätter zu erkennen sind. */
.file-preview-pdf { width: 100%; height: 70vh; overflow: auto; background: #4a4f55; padding: .6rem; }
.file-preview-pdf .pdf-page {
    display: block; margin: 0 auto .6rem; background: #fff;
    box-shadow: 0 1px 6px rgba(0,0,0,.45); max-width: 100%;
}
.file-preview-pdf .pdf-page:last-child { margin-bottom: 0; }
.file-preview-img { display: block; max-width: 100%; height: auto; margin: 0 auto; }
.chat-avatar {
    flex: 0 0 auto; width: 2.4rem; height: 2.4rem;
    display: inline-flex; align-items: center; justify-content: center;
    font-size: 0.85rem; font-weight: 700; color: #fff;
    background: var(--tri-green);
}
.chat-avatar.user  { border-radius: 50%; }
/* Rund wie die Benutzer-Avatare: Im Gespräch stehen zwei Gesprächspartner nebeneinander, und zwei
   verschiedene Formen ließen den einen wie eine Schaltfläche aussehen. */
.chat-avatar.agent { border-radius: 50%; font-size: 1.15rem; }

/* „Die KI überlegt": Der Avatar pulsiert im Sekundentakt von Hell- nach Dunkelgrün, das Symbol atmet
   leicht mit. Das ersetzt keinen Text – es sagt nur, dass etwas geschieht, während der Denkprozess
   darunter noch leer ist. Bei „prefers-reduced-motion" steht beides still. */
.chat-avatar.is-thinking { animation: ki-denkt 1s ease-in-out infinite; }
.chat-avatar.is-thinking > i { display: inline-block; animation: ki-denkt-symbol 1s ease-in-out infinite; }
@keyframes ki-denkt {
    0%, 100% { background: #7cc38c; }
    50%      { background: #1e6b33; }
}
@keyframes ki-denkt-symbol {
    0%, 100% { transform: scale(1); }
    50%      { transform: scale(1.14); }
}
@media (prefers-reduced-motion: reduce) {
    .chat-avatar.is-thinking,
    .chat-avatar.is-thinking > i { animation: none; }
}

/* Die KI im Gespräch trägt ein Bild statt eines Symbols (KiAvatar): der grüne Wirbel, rund
   ausgeschnitten. Der Kreis selbst bringt seine Farbe mit – der grüne Grund würde nur hinter dem
   Bild liegen und beim Pulsieren an den weichen Rändern durchscheinen. */
.chat-avatar.agent:has(> img) { background: transparent; overflow: hidden; }
.chat-avatar.agent > img { width: 100%; height: 100%; object-fit: cover; border-radius: 50%; display: block; }
/* „Die KI arbeitet": Der Wirbel ATMET und DREHT sich zugleich – das Atmen im Sekundentakt (Größe und
   Helligkeit), die Drehung gemächlich mit einer Umdrehung alle 4 Sekunden, gleichmäßig (linear, sonst
   ruckelte jede Runde am Übergang).

   Beides liegt bewusst auf ZWEI Elementen: Atmen (scale) und Drehen (rotate) sind beide `transform`, und
   zwei Animationen auf demselben Element überschreiben einander – die zuletzt gestartete gewinnt, die
   andere verschwindet spurlos. Der Kreis trägt deshalb das Atmen, das Bild darin die Drehung. Weil der
   Kreis das Bild beschneidet, skaliert er es mit, und die Helligkeit des Elternteils färbt ohnehin durch. */
.chat-avatar.agent.is-thinking:has(> img) { animation: ki-atmet 1s ease-in-out infinite; }
.chat-avatar.agent.is-thinking > img { animation: ki-dreht 4s linear infinite; }
@keyframes ki-atmet {
    0%, 100% { transform: scale(1);    filter: brightness(0.82); }
    50%      { transform: scale(1.08); filter: brightness(1.25); }
}
@keyframes ki-dreht {
    from { transform: rotate(0deg); }
    to   { transform: rotate(360deg); }
}
@media (prefers-reduced-motion: reduce) {
    .chat-avatar.agent.is-thinking:has(> img),
    .chat-avatar.agent.is-thinking > img { animation: none; }
}

/* Dasselbe Sinnbild außerhalb des Gesprächs: im Menüpunkt und in der Seiten-Kopfzeile. Die Größe kommt
   von der Komponente (Size), hier steht nur die Ausrichtung in der jeweiligen Zeile. */
/* Der Kreis belegt GENAU die Box eines Menü-Symbols (.nav-icon: 1,25 rem breit, kein Rand rechts –
   den Abstand macht das Leerzeichen im Markup). Sonst beginnt die Beschriftung weiter rechts als in
   allen anderen Zeilen. */
.nav-ki-avatar { width: 1.25rem; height: 1.25rem; flex: 0 0 1.25rem; overflow: visible; }
/* Der Kreis selbst darf 5 % über seine Box hinausragen – er wirkt sonst kleiner als die Strichsymbole
   daneben. Die Box bleibt 1,25 rem, damit die Beschriftung an derselben Stelle beginnt wie überall.

   Er dreht sich dauerhaft, aber sehr gemächlich: eine Umdrehung in 20 Sekunden. Das ist langsam genug, um
   beim Lesen der Menüzeilen nicht abzulenken, und schnell genug, dass das Sinnbild lebendig wirkt statt
   wie ein Symbol. Im Gespräch dreht derselbe Wirbel fünfmal so schnell (4 s) – dort heißt die Bewegung
   „ich arbeite gerade", hier nur „ich bin da". */
.nav-ki-avatar > img { width: 1.3125rem; height: 1.3125rem; animation: ki-dreht 20s linear infinite; }
@media (prefers-reduced-motion: reduce) {
    .nav-ki-avatar > img { animation: none; }
}
.page-head-ki-avatar { align-self: flex-start; margin-top: 0.1rem; }
.chat-msg-main { flex: 1 1 auto; min-width: 0; }
/* Name und Text gehören zusammen: enge Zeile (die Standard-Zeilenhöhe polstert den Namen oben und
   unten aus). Ein Hauch Abstand darunter bleibt - ohne ihn klebte der Name an der Zeile mit Uhrzeit und
   Schrittzahl, die unmittelbar folgt. */
.chat-msg-head { display: flex; align-items: baseline; gap: 0.5rem; margin-bottom: 0.15rem; line-height: 1.2; }

/* Spaltenbreiten in Verwaltungs-Listen: EINE Spalte nimmt den Rest, alle anderen genau so viel, wie ihr
   Inhalt braucht. „width:100%" auf der wachsenden und „width:1%" auf den festen ist der übliche Weg, dem
   Tabellen-Algorithmus das beizubringen - er verteilt sonst gleichmäßig, und die Beschreibung bräche
   mitten in der Zeile um, während neben zwei Status-Chips die halbe Breite leer bliebe. */
th.col-grow, td.col-grow { width: 100%; }
th.col-fit,  td.col-fit  { width: 1%; white-space: nowrap; }

/* Der Knopf mit der Funktionszahl in den Listen der Werkzeuge und Konnektoren. Er ersetzt seit 2026.9.504
   die Spalte, in der alle Funktionsnamen standen: Die Namen sagten beim Überfliegen wenig, brauchten aber
   die halbe Zeilenbreite. Die Zahl beantwortet, was man dort suchte („hat es überhaupt etwas, und wie
   viel?"), der Klick zeigt alles samt Beschreibungen. Feste Mindestbreite, damit ein- und zweistellige
   Zahlen die Knopfreihe nicht gegeneinander verschieben. */
.fn-count { min-width: 3.4rem; font-variant-numeric: tabular-nums; }

/* Abgegrenzter Geltungsbereich in den Einstellungen: Was nur unter einer Bedingung wirkt (bisher nur der
   Demo-Modus), steht in einem eigenen Kasten mit Kopfzeile. Ohne die Abgrenzung landeten Einstellungen, die
   IMMER gelten, unter derselben Ueberschrift - und wer den Demo-Modus ausschaltete, hielt sie fuer mit
   abgeschaltet. */
.scope-box {
    border: 1px solid var(--tri-border, #e6e8ea); border-left: 3px solid var(--tri-green);
    border-radius: .5rem; padding: .75rem 1rem 1rem;
}
.scope-head {
    font-size: .78rem; font-weight: 600; letter-spacing: .02em; text-transform: uppercase;
    color: var(--tri-green); margin-bottom: .6rem;
}

/* Anlagen direkt unter einer Rückfrage (RunResultView FilesOnly): etwas Luft zur Frage-Karte darüber. */
.run-read-files { margin-top: .75rem; }

/* Absenderliste im Mail-Werkzeug: zwei schmale Spalten (primär, auch erlaubt) und die Adresse daneben.
   Eine Tabelle waere hier zu schwer - es sind zwei Haken je Zeile, keine Daten. */
.sender-list { display: flex; flex-direction: column; }
.sender-row { display: grid; grid-template-columns: 4.5rem 5.5rem 1fr; align-items: center; gap: .25rem; padding: .25rem 0; }
.sender-head { font-size: .78rem; color: var(--tri-muted, #8a9099); padding-bottom: .15rem; }
.sender-head .sender-col { justify-content: flex-start; }
.sender-col { display: flex; justify-content: center; }
.sender-addr { margin: 0; cursor: pointer; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Datei-Auswahl („Bild wählen", Anhang anhängen, Avatar tauschen …): Das Eingabefeld liegt UNSICHTBAR
   über seiner Schaltfläche, statt mit display:none aus dem Layout genommen zu werden.

   Mit display:none gibt es kein anklickbares Feld; der Klick trifft das umgebende <label> und wird von
   dort an das Feld weitergereicht. Safari öffnet den System-Dialog in diesem Fall gelegentlich HINTER dem
   Browserfenster - er ist dann scheinbar „kaputt" (gemeldet am 14.09.2026 am Agenten-Avatar). Liegt das
   Feld selbst unter dem Zeiger, ist der Klick ein echter Klick darauf, und der Dialog kommt nach vorn.
   Dasselbe Muster benutzen die Ablegezonen (.memory-drop-input, .aad-drop-input) seit jeher. */
label:has(> .file-pick-input) { position: relative; }
.file-pick-input {
    position: absolute; inset: 0; width: 100%; height: 100%;
    opacity: 0; cursor: pointer; font-size: 0;
}
.file-pick-input:disabled { cursor: default; }

/* Personen-Auswahl in Werkzeug-Dialogen (Outlook-Kalender): eine Liste, keine Knopfsammlung.
   Vorher lag der ganze Bereich auf grauem Grund (.bg-light) und jede Zeile war zusaetzlich ein graues
   btn-light - zwei Grautoene uebereinander, in denen die Namen untergingen. Jetzt: weisser Grund wie im
   uebrigen Dialog, Trennlinien statt Kaesten, und die Liste nimmt sich die Hoehe, die der Dialog hergibt
   (vorher 14 rem, darunter blieb der halbe Dialog leer). */
.pick-panel { background: #fff; }
.pick-list { min-height: 16rem; max-height: 30rem; overflow: auto; }
.pick-row {
    display: flex; align-items: center; gap: .6rem; width: 100%; text-align: left;
    background: transparent; border: 0; border-bottom: 1px solid var(--tri-border, #e6e8ea);
    padding: .4rem .35rem; color: inherit;
}
.pick-row:last-child { border-bottom: 0; }
.pick-row:hover:not(:disabled) { background: var(--tri-green-bg-active); }
.pick-row:disabled { opacity: .55; cursor: default; }
.pick-text { display: flex; flex-direction: column; min-width: 0; flex: 1 1 auto; }
.pick-name { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pick-mail { font-size: .8rem; color: var(--tri-muted, #8a9099); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pick-done { color: var(--tri-green); font-size: 1.1rem; flex: 0 0 auto; }

/* Lauf-Detail, Register „Kontext": Der Inhalt einer Nachricht steht in der Standard-Chat-Komponente,
   die farbige Kennzeichnung (an das LLM, vom Agenten, Kritiker, Sub-Agent) traegt jetzt dieser innere
   Block statt einer eigenen Nachrichten-Optik. */
.run-ctx{min-width:0}
.run-ctx-head{display:flex;align-items:baseline;flex-wrap:wrap;gap:.35rem;margin-bottom:.25rem;font-size:.82rem;color:var(--tri-muted)}
.run-ctx-head:empty{display:none}
/* Die Nachricht VOM Modell ist ein Kasten (Fläche + Rahmen ringsum, siehe `.chat-msg-in`) und braucht
   deshalb Luft auf ALLEN Seiten - die Geschwister hier sind nur ein Strich links und kommen mit
   `padding-left` aus. Ohne diese Regel klebte der Text direkt am Rahmen. */
.run-ctx.chat-msg-in{padding:.7rem;border-radius:.5rem}
.run-ctx.chat-msg-out{border-left:3px solid var(--tri-green-soft);padding-left:.7rem}
.run-ctx.chat-msg-critic{border-left:3px solid #f0c36d;padding-left:.7rem}
.run-ctx.chat-msg-deleg{border-left:3px solid var(--tri-green);padding-left:.7rem}
/* Runder Avatar wie im Chat (AgentAvatar bringt seine eigene Form mit). */
.chat-avatar-round{border-radius:50%;overflow:hidden}

/* Tabler-Symbole in Schaltflaechen etwas kleiner als Bootstrap-Symbole: Tabler zeichnet bis an den Rand
   des Schriftquadrats, Bootstrap laesst innen Luft. Bei gleicher Schriftgroesse wirkt ein Tabler-Symbol
   dadurch deutlich groesser als seine Nachbarn in derselben Knopfleiste. */
.btn .ti { font-size: .88em; vertical-align: -.06em; }
.chat-msg-name { font-weight: 700; color: var(--tri-text); }
.chat-msg-time { font-size: 0.72rem; font-weight: 400; color: #9aa0a6; }

/* Sub-Agenten-Antwort im Chat: sichtbar getrennter, leicht eingerückter Block mit hellgrünem Akzent (links),
   eigenem Icon-Avatar und einer „#Nr Name"-Kennung im Kopf. */
.chat-avatar.subagent { border-radius: 0.6rem; font-size: 1.05rem; background: var(--tri-green-bg-active); color: var(--tri-green); }
.chat-msg.subagent { background: color-mix(in srgb, var(--tri-green) 5%, transparent); border-left: 3px solid var(--tri-green-soft); }
.chat-msg.subagent .chat-msg-name { color: var(--tri-green); font-weight: 600; }
.chat-subagent-tag { display: inline-flex; align-items: baseline; font-weight: 600; color: var(--tri-text); }

/* Aktionszeile unter dem Nachrichtentext – erscheint beim Hovern über die Nachricht (Copy usw.) */
.chat-msg-actions { display: flex; gap: 0.25rem; margin-top: 0.4rem; opacity: 0; transition: opacity 0.12s; }
.chat-msg:hover .chat-msg-actions { opacity: 1; }
.chat-action-btn {
    border: none; background: transparent; color: #9aa0a6; cursor: pointer;
    padding: 0.2rem 0.4rem; border-radius: 0.45rem; font-size: 0.95rem; line-height: 1;
    transition: color 0.12s, background 0.12s;
}
.chat-action-btn:hover { color: var(--tri-green); background: #f0f2f4; }
.chat-msg-body { line-height: 1.5; color: var(--tri-text); overflow-wrap: anywhere; }
.chat-msg-body > :last-child { margin-bottom: 0; }

/* Benutzer-Nachrichten: rechtsbündig als hellgraue Bubble (Avatar rechts), Name/Zeit ausgeblendet */
.chat-msg.user { flex-direction: row-reverse; }
.chat-msg.user .chat-msg-main { display: flex; flex-direction: column; align-items: flex-end; }
.chat-msg.user .chat-msg-head { display: none; }
.chat-msg.user .chat-msg-body {
    background: #f0f1f3;
    border-radius: 1.1rem;
    padding: 0.6rem 0.95rem;
    max-width: 85%;
}
.chat-msg.user .chat-msg-actions { justify-content: flex-end; }

/* Composer: „+" oben rechts, „Senden ↑" als beschrifteter Button unten rechts */
.composer { position: relative; }
/* Das Plus sitzt OBEN RECHTS in der Eingabe; `.composer-text` haelt mit `padding-right` den Platz frei.
   Der Selektor ist bewusst zweiteilig: `label:has(> .file-pick-input)` (weiter oben, Safari-Korrektur fuer
   den Datei-Dialog) setzt `position: relative` und hat mit (0,1,1) die hoehere Spezifitaet als eine einzelne
   Klasse. Damit gewann dort `relative`, `top`/`right` wirkten als Verschiebung aus der Textlage heraus - und
   das Plus stand links ueber dem Platzhaltertext statt in der Ecke. */
.composer .composer-add-top {
    position: absolute; top: 0.55rem; right: 0.7rem; z-index: 1;
    width: 2rem; height: 2rem; display: inline-flex; align-items: center; justify-content: center;
    border-radius: 0.5rem; color: #6a7078; font-size: 1.15rem; cursor: pointer; margin: 0;
}
.composer-add-top:hover { background: #eef0f3; }
.composer-add-top.disabled { opacity: 0.4; pointer-events: none; }
.composer-text { padding-right: 2.4rem; }
.composer-send {
    width: auto; height: auto; padding: 0.5rem 1.15rem; border-radius: 0.75rem;
    font-size: 0.95rem; font-weight: 600; gap: 0.3rem;
}

/* Datei-Anhang-Button: Dateityp-Icon in Typ-Farbe; Download-Symbol erscheint beim Hover */
.chat-file-btn .chat-file-dl { opacity: 0; transition: opacity 0.12s; }
.chat-file-btn:hover .chat-file-dl { opacity: 1; }

/* Chat-Layout mit fixierter Eingabeleiste */
/* ============================================================================
   VOLL-HÖHE-LAYOUT – dauerhafte Lösung gegen „Seite/Panel nutzt die Fensterhöhe nicht aus".

   Wiederkehrende Ursache: Eine Spalte soll die volle (Rest-)Höhe einnehmen und nur EIN innerer Bereich
   soll scrollen. Das gelingt nur, wenn die GESAMTE Flex-Kette vom voll-hohen Vorfahren bis zum Scroll-
   bereich konsistent ist:
     • jeder Flex-Container in der Kette:  display:flex; flex-direction:column; min-height:0;
     • der füllende (wachsende) Bereich:   flex:1 1 auto; min-height:0;
     • der Scrollbereich zusätzlich:        overflow:auto;
   Fehlt irgendwo `min-height:0` oder `flex:1`, kollabiert der Bereich auf Inhaltshöhe (→ Lücke unten)
   ODER überläuft den Viewport (→ Inhalt unten unerreichbar). Genau dieser Fehler trat wiederholt auf.

   REGEL: Für „füllt die Höhe + scrollt intern" IMMER diese Utilities verwenden, statt feste vh-/calc-
   Höhen zu raten. Voraussetzung ist nur, dass ein Vorfahre eine definierte Höhe hat (z. B. 100vh oder
   selbst .fill-grow in einer .fill-col-Kette).
   ============================================================================ */
.fill-col    { display: flex; flex-direction: column; min-height: 0; }
.fill-grow   { flex: 1 1 auto; min-height: 0; }
.fill-scroll { flex: 1 1 auto; min-height: 0; overflow: auto; }

/* Seite füllt exakt die Fensterhöhe: page-content wird zur Flex-Spalte (Kopfband bleibt erstes Kind),
   der mit .page-fill markierte Inhalt nimmt die Resthöhe (kein geratenes calc, kein Rest unten). */
.page-content:has(> .page-fill) { display: flex; flex-direction: column; height: 100vh; }
.page-fill { flex: 1 1 auto; min-height: 0; }

/* Test-Dialog (/agents/{id}/test): Konfig + Chat füllen die Fensterhöhe.
   .test-fill nimmt mind. die Resthöhe unter dem Kopfband; der Chat wächst per Flex, intern scrollt nur
   .chat-scroll. min-height (statt height) → bei aufgeklappter Konfiguration darf der Block wachsen und die
   Seite normal scrollen. page-content bleibt unangetastet (sonst würde der Bleed des Kopfbands abgeschnitten). */
.test-fill {
    display: flex;
    flex-direction: column;
    min-height: calc(100vh - 11rem);
}

.chat-card {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 18rem;
}

.chat-scroll {
    flex: 1;
    overflow-y: auto;
    min-height: 0;
}

.chat-input {
    border-top: 1px solid #e6e8ea;
    padding: 0.75rem 1rem;
    background: #fff;
    border-bottom-left-radius: var(--bs-card-border-radius, .375rem);
    border-bottom-right-radius: var(--bs-card-border-radius, .375rem);
}

/* Markdown-Darstellung */
.markdown-body { font-size: 0.95rem; }
.markdown-body > :first-child { margin-top: 0; }
.markdown-body > :last-child { margin-bottom: 0; }
.markdown-body p { margin: 0 0 0.6rem; }
.markdown-body h1, .markdown-body h2, .markdown-body h3, .markdown-body h4, .markdown-body h5, .markdown-body h6 {
    margin: 0.8rem 0 0.5rem;
    font-weight: 600;
    line-height: 1.25;
    color: var(--tri-green);   /* Markdown-Überschriften einheitlich in TriniDat-Grün */
}
.markdown-body h1 { font-size: 1.2rem; }
.markdown-body h2 { font-size: 1.05rem; }
.markdown-body h3 { font-size: 0.95rem; }
.markdown-body h4, .markdown-body h5, .markdown-body h6 { font-size: 0.9rem; }
.markdown-body ul, .markdown-body ol { margin: 0 0 0.6rem 1.25rem; }
.markdown-body code {
    background: #eceef1;
    padding: 0.1rem 0.3rem;
    border-radius: 4px;
    font-size: 0.875em;
    color: #b3306f;
}
.markdown-body pre {
    background: #1f2227;
    color: #e6e8ea;
    padding: 0.75rem 1rem;
    border-radius: 8px;
    /* Lange Zeilen (z. B. Tool-Parameter/Ergebnis-JSON) umbrechen statt horizontal scrollen. */
    white-space: pre-wrap;
    overflow-wrap: anywhere;
    word-break: break-word;
}
.markdown-body pre code { background: none; color: inherit; padding: 0; white-space: inherit; }
/* Eingebettete Bilder (u. a. vom Agenten generierte SVG) proportional einpassen. */
.markdown-body img { max-width: 100%; height: auto; }
.markdown-body img[src^="data:image/svg"] {
    display: block;
    max-height: 32rem;
    margin: 0.5rem 0;
    border: 1px solid var(--border, #dee2e6);
    border-radius: 8px;
    background: #fff;
    padding: 0.25rem;
}
.markdown-body table {
    border-collapse: collapse;
    width: auto;
    margin: 0 0 0.6rem;
    font-size: 0.9rem;
}
.markdown-body th, .markdown-body td {
    border: 1px solid #d7dade;
    padding: 0.35rem 0.6rem;
    text-align: left;
}
.markdown-body th { background: #f1f3f5; }
.markdown-body blockquote {
    border-left: 3px solid var(--tri-green-soft);
    margin: 0 0 0.6rem;
    padding: 0.2rem 0.8rem;
    color: #5b6b73;
}
.markdown-body a { color: var(--tri-green); }

/* JSON-Editor / -Vorschau */
.json-preview {
    background: #1f2227;
    color: #e6e8ea;
    padding: 0.75rem 1rem;
    border-radius: 8px;
    font-size: 0.85rem;
    line-height: 1.4;
    max-height: 240px;
    overflow: auto;
    white-space: pre;
}
.json-preview .json-key { color: #79c0ff; }
.json-preview .json-string { color: #7ee787; }
.json-preview .json-number { color: #ffa657; }
.json-preview .json-bool { color: #d2a8ff; }
.json-preview .json-null { color: #8b949e; }

/* Agent-Detail */
/* Alle Links zentral: Logo-Grün. Beim HOVERN (Maus drüber, vor dem Klick)
   deutlich dunkleres Grün + fett + Zeigefinger → signalisiert Klickbarkeit.
   Kein Unterstreichen. !important schlägt Bootstrap. */
a,
.agent-name-link,
.kanban-card-title,
.kanban-card-run-link {
    color: var(--tri-green);
}

/* Namen in Listen/Karten durchgängig fett hervorheben. */
.agent-name-link,
.kanban-card-title {
    font-weight: 600;
}

/* Audit-Protokoll: farbiger Kategorie-Punkt vor dem Label. */
.audit-cat { display: inline-flex; align-items: center; white-space: nowrap; font-weight: 400; }
.audit-dot {
    flex: 0 0 auto;
    width: .5rem;
    height: .5rem;
    border-radius: 50%;
    margin-right: .4rem;
}
.bg-purple { background-color: #7c4dff !important; }
.bg-teal { background-color: #0d9488 !important; }
.bg-pink { background-color: #d63384 !important; }

a:hover,
.agent-name-link:hover,
.kanban-card-title:hover,
.kanban-card-run-link:hover {
    color: var(--tri-green-dark) !important;
    text-decoration: none !important;
    cursor: pointer;
}

/* AUSNAHME fuer das gruene Kopfband: Dort faerbte die Regel darueber jeden Link beim Ueberfahren
   dunkelgruen - auf dem Gruen gelesen fast schwarz, und der Rueckweg war kaum noch zu erkennen.
   Im weissen Anbau darunter gilt die Hausfarbe weiter; dort steht sie auf hellem Grund richtig.
   `!important` ist hier kein Uebermut, sondern Notwehr: Die Regel darueber traegt es selbst. */
.rbh-body a:hover,
.rbh-body a:focus {
    color: #fff !important;
    text-decoration: underline !important;
}

/* Buttons/Chips/Badges/Picker bleiben beim Hovern normal (kein Fett).
   NICHT .nav-link aufnehmen: `inherit` zieht 400 vom Elternelement und würde
   das Zustands-Gewicht der Tabs (aktiv 700 / inaktiv 600) beim Hover auf 400
   stürzen lassen. Die Tab-Gewichte regelt allein der .trinidat-tabs-Block. */
a.btn:hover,
a.agent-id-chip:hover,
a.agent-id-badge:hover,
.trigger-agent-item:hover,
.tag-picker-item:hover {
    font-weight: inherit !important;
}

/* Anklickbare große Agentennummer-Badge (führt zur Detailseite) */
a.agent-id-badge {
    text-decoration: none;
    color: #fff;
    transition: background 0.15s;
}
a.agent-id-badge:hover {
    background: var(--tri-green-dark);
    color: #fff !important;
    text-shadow: none;
}

/* Anklickbarer Agentennummer-Chip (führt zur Detailseite) */
a.agent-id-chip {
    text-decoration: none;
    transition: background 0.15s;
}
a.agent-id-chip:hover {
    background: var(--tri-green-dark);
    color: #fff !important;
    text-shadow: none;
}

.legend-dot {
    display: inline-block;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    vertical-align: middle;
}

/* Interaktives Struktur-Diagramm */
.diagram-scroll {
    overflow-x: auto;
}

.diagram {
    position: relative;
    margin: 0 auto;
}

.diagram-lines {
    position: absolute;
    inset: 0;
    z-index: 0;
}

.diag-node {
    position: absolute;
    z-index: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    border-radius: 16px;
    box-sizing: border-box;
    padding: 8px 12px 8px 16px;
    background: #fff;
    cursor: pointer;
    user-select: none;
    border: 1px solid #e7e9ee;
    box-shadow: 0 4px 12px rgba(16, 24, 40, 0.10), 0 1px 3px rgba(16, 24, 40, 0.06);
    transition: box-shadow 0.18s ease, transform 0.18s ease, border-color 0.18s ease;
}

/* Farbiger Akzentstreifen links */
.diag-node::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: 5px;
    border-radius: 16px 0 0 16px;
}

.diag-mcp::before {
    background: linear-gradient(180deg, #f3c66b 0%, #e0a51f 100%);
}

.diag-tool::before {
    background: linear-gradient(180deg, #8ed8cd 0%, #1f9e8d 100%);
}

.diag-text {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    font-size: 12px;
    line-height: 1.2;
    font-weight: 500;
    color: #33373d;
    word-break: break-word;
}

.diag-node-body {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    width: 100%;
}

.diag-node-kind {
    display: block;
    font-size: 9px;
    font-weight: 700;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    margin-bottom: 2px;
}

/* Ketten-/Orchestrierungs-Node im Designer-Look: Avatar + Kicker + Name + Beschreibung, linksbündig, keine Buttons. */
.diag-run { justify-content: flex-start; align-items: flex-start; text-align: left; }
/* Avatar links, Text in der Mitte, Tokenring rechts – alle drei oben ausgerichtet, damit die Kachel
   flach bleibt. Bis 2.0.621 standen Avatar und Ring UNTEREINANDER in einer eigenen Spalte; das gab der
   Kachel ihre Höhe, und bei einem Team mit sechs Läufen passte kaum die Hälfte auf den Schirm. */
/* Kopfzeile wie .wfd-node-head: Avatar, Text und Ring auf EINER Mittellinie, Abstand .6rem. */
.diag-run-card { display: flex; align-items: center; gap: .6rem; width: 100%; min-width: 0; }
.diag-run-avatar { flex: 0 0 auto; line-height: 0; }
.diag-run-gauge { flex: 0 0 auto; display: block; }
/* Avatar exakt wie im Designer (.wfd-node-avatar): runder Kreis, 2,7 rem, ohne eigene Fläche. */
.diag-run-avatar .agent-avatar { width: 2.7rem; height: 2.7rem; border-radius: 50%; }
.diag-run-main { min-width: 0; flex: 1 1 auto; display: flex; flex-direction: column; }
.diag-run-kicker { font-size: 9px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--tri-green); margin-bottom: 1px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Zwei Zeilen, seit die Art und die Nummern im Schild über der Kachel stehen: Der Platz daneben ist
   frei geworden, und viele Agentennamen sind ganze Sätze. */
/* Schriftgrad, Stärke und Farbe wie .wfd-node-title im Designer. */
.diag-run-name {
    font-size: .92rem; font-weight: 700; color: var(--tri-green); line-height: 1.2;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
    overflow: hidden; overflow-wrap: anywhere;
}

/* Das Schild über der Kachel – dieselbe Bauart wie im Designer (.wfd-node-kind): Lasche auf der
   Oberkante, unten gerade, etwas nach rechts eingerückt, damit die runde Kartenecke sichtbar bleibt.
   `bottom: 100%` statt eines gerechneten Abstands: So sitzt die Unterkante immer genau auf der
   Kartenkante, gleich wie hoch das Schild gerade ist. */
.diag-run-kind {
    position: absolute; bottom: 100%; left: .6rem; z-index: 2; max-width: 100%;
    padding: .18rem .6rem; border-radius: .5rem .5rem 0 0;
    background: var(--diag-kind-accent, var(--tri-faint)); color: #fff;
    font-size: .66rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
    line-height: 1.15;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* Dieselben Akzentfarben wie im Designer: Worker grün, Kritiker grau, Gatekeeper rot. */
.diag-kind-worker { --diag-kind-accent: var(--tri-green); }
.diag-kind-critic { --diag-kind-accent: #7a869a; }
.diag-kind-gatekeeper { --diag-kind-accent: var(--tri-red); }
.diag-run-desc { font-size: 11px; color: #8a9099; line-height: 1.3; margin-top: 1px; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
/* LLM-Provider je Knoten: eine Spur kleiner als der Name, damit er die Kachel nicht dominiert - aber
   dunkler als die Beschreibung, weil er eine Tatsache ist und keine Prosa. */
.diag-run-provider { font-size: 10px; color: #6b7178; line-height: 1.3; margin-top: 2px; }

.diag-mcp {
    border-color: #f0d49a;
    background: linear-gradient(160deg, #fffdf8 0%, #fff4dc 100%);
}

.diag-mcp .diag-node-kind {
    color: #c98a00;
}

.diag-tool {
    border-color: #aee0d8;
    background: linear-gradient(160deg, #f7fcfb 0%, #e3f5f1 100%);
}

.diag-tool .diag-node-kind {
    color: #1f9e8d;
}

.diag-skill::before {
    background: linear-gradient(180deg, #8fb3f7 0%, #5b8def 100%);
}

.diag-skill {
    border-color: #b9cdf7;
    background: linear-gradient(160deg, #f7faff 0%, #e6eefb 100%);
}

.diag-skill .diag-node-kind {
    color: #3f6fd0;
}

/* Sub-Agenten von „Agent starten" – grau, unter dem Agenten */
.diag-subagent::before {
    background: linear-gradient(180deg, #b9bfc7 0%, #8a9099 100%);
}
.diag-subagent {
    border-color: #d3d7dd;
    background: linear-gradient(160deg, #f4f5f7 0%, #e7e9ed 100%);
    cursor: pointer;
}
.diag-subagent .diag-node-kind {
    color: #6c757d;
}

/* Lauf-Kette (Run-Knoten) */
.diag-run::before {
    background: linear-gradient(180deg, #b9c0c9 0%, #8a9099 100%);
}

.diag-run {
    border-color: #dfe3e8;
    background: linear-gradient(160deg, #fbfcfd 0%, #eef1f4 100%);
}

.diag-run .diag-node-kind {
    color: #5b6470;
}

.diag-run-user {
    font-size: 10px;
    color: #6b7280;
    margin-top: 1px;
}

.diag-run.diag-run-ok::before {
    background: linear-gradient(180deg, #6cc47c 0%, var(--tri-green) 100%);
}

.diag-run.diag-run-ok .diag-node-kind {
    color: var(--tri-green);
}

.diag-run.diag-run-error::before {
    background: linear-gradient(180deg, #e88a8a 0%, #d64545 100%);
}

.diag-run.diag-run-error .diag-node-kind {
    color: #d64545;
}

.diag-run.diag-run-active::before {
    background: linear-gradient(180deg, #8fb3f7 0%, #3f6fd0 100%);
}

/* --- Ketten-/Orchestrierungs-Node exakt im Designer-Node-Look: weiße Karte, farbiger OBERRAND je Status,
   sauberer Schatten, KEIN Links-Streifen (überschreibt die alte diag-node/diag-run-Optik). --- */
.diag-run {
    background: #fff;
    /* Rundum derselbe dünne Rahmen wie im Designer. Der farbige OBERRAND, den die Kachel bis 2.0.630
       trug, stand als grüner Strich zwischen Schild und Namen – im Designer gibt es ihn nicht, und die
       Farbe trägt ohnehin das Schild darüber. */
    border: 1px solid var(--tri-border, #e5e7eb);
    border-radius: .7rem;
    box-shadow: 0 6px 16px rgba(0,0,0,.12), 0 1px 3px rgba(0,0,0,.10);
    padding: .7rem .85rem;
}
.diag-run::before { display: none; }
.diag-run:hover { box-shadow: 0 10px 26px rgba(0,0,0,.18), 0 2px 5px rgba(0,0,0,.12); }
/* Aktueller Lauf hervorgehoben (grüner Ring wie im Designer). */
.diag-run.diag-run-current {
    border-color: var(--tri-green);
    box-shadow: 0 0 0 3px rgba(var(--tri-green-rgb), 0.18), 0 8px 20px rgba(16, 24, 40, 0.10);
}

/* Kritiker: wie der Worker dargestellt, aber in Grau.
   Doppelte Klasse erhöht die Spezifität, damit der graue Hintergrund den grünen
   von .diag-agent überschreibt, unabhängig von der Reihenfolge im Stylesheet. */
.diag-agent.diag-agent-critic {
    background: linear-gradient(150deg, #9aa0a8 0%, #7c828b 55%, #61666e 100%);
    box-shadow: 0 8px 22px rgba(60, 64, 70, 0.30), inset 0 1px 0 rgba(255, 255, 255, 0.18);
    cursor: pointer;
}

.diag-agent.diag-agent-critic .diag-agent-label {
    color: #e7e9ec;
}

/* Gatekeeper: wie der Worker dargestellt, aber in Rot (Security). */
.diag-agent.diag-agent-gatekeeper {
    background: linear-gradient(150deg, #d65f50 0%, var(--tri-red) 55%, var(--tri-red-dark) 100%);
    box-shadow: 0 8px 22px rgba(150, 45, 34, 0.32), inset 0 1px 0 rgba(255, 255, 255, 0.18);
    cursor: pointer;
}
.diag-agent.diag-agent-gatekeeper .diag-agent-label {
    color: #ffe3df;
}

.diag-node-kind i {
    font-size: 10px;
    margin-right: 2px;
}

.diag-node:hover {
    box-shadow: 0 10px 22px rgba(16, 24, 40, 0.16), 0 2px 6px rgba(16, 24, 40, 0.08);
    transform: translateY(-2px);
}

.diag-node.open {
    border-color: var(--tri-green);
    box-shadow: 0 0 0 3px rgba(var(--tri-green-rgb), 0.22), 0 10px 22px rgba(16, 24, 40, 0.16);
    /* Über das Klick-Backdrop (z-index 1055) heben, sonst fangen es die Popup-Buttons nicht. */
    z-index: 1056;
}

.diag-agent {
    z-index: 2;
    background: linear-gradient(150deg, #34a14a 0%, var(--tri-green) 55%, #246e31 100%);
    border: none;
    border-radius: 20px;
    flex-direction: row;
    align-items: center;
    justify-content: flex-start;
    gap: 10px;
    padding: 8px 14px;
    cursor: default;
    box-shadow: 0 8px 22px rgba(36, 110, 49, 0.32), inset 0 1px 0 rgba(255, 255, 255, 0.18);
}

.diag-agent-figure {
    height: 88%;
    width: auto;
    flex: 0 0 auto;
    object-fit: contain;
    filter: grayscale(1) brightness(1.35) contrast(0.85)
            drop-shadow(0 2px 4px rgba(0, 0, 0, 0.25));
    opacity: 0.92;
}

/* Gatekeeper-Knoten: Schild-Icon anstelle der Roboter-Figur. */
.diag-gatekeeper-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 2.6rem;
    font-size: 2rem;
    color: #fff;
    opacity: 0.95;
    filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.25));
}

.diag-agent-text {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    text-align: left;
    min-width: 0;
    flex: 1 1 auto;
}

.diag-agent-label {
    font-size: 9px;
    font-weight: 700;
    letter-spacing: 0.14em;
    color: #d6f0d9;
}

.diag-agent-name {
    font-size: 14px;
    font-weight: 700;
    color: #fff;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
    line-height: 1.15;
    /* Lange Namen (z. B. „Rechtschreibprüfung Word") umbrechen statt aus dem Kasten laufen. */
    overflow-wrap: anywhere;
    word-break: break-word;
}

.diag-pop {
    position: absolute;
    top: calc(100% + 6px);
    left: 50%;
    transform: translateX(-50%);
    z-index: 1056;
    background: #fff;
    border: 1px solid #e2e4e8;
    border-radius: 8px;
    padding: 6px;
    white-space: nowrap;
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.15);
}

h1:focus {
    outline: none;
}

.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {
    box-shadow: 0 0 0 0.1rem white, 0 0 0 0.2rem rgba(var(--tri-green-rgb), 0.35);
}

.form-control:focus, .form-select:focus {
    border-color: #8fd39b;
    box-shadow: 0 0 0 0.2rem rgba(var(--tri-green-rgb), 0.18);
}

.form-check-input:checked {
    background-color: var(--tri-green);
    border-color: var(--tri-green);
}

/* Rahmen unmarkierter Checkboxen/Radios dunkler, damit die Kästchen klar erkennbar sind. */
.form-check-input:not(:checked) { border-color: #8a9099; }

.valid.modified:not([type=checkbox]) {
    outline: 1px solid #26b050;
}

.invalid {
    outline: 1px solid red;
}

.validation-message {
    color: red;
}

#blazor-error-ui {
    color-scheme: light only;
    background: lightyellow;
    bottom: 0;
    box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
    box-sizing: border-box;
    display: none;
    left: 0;
    padding: 0.6rem 1.25rem 0.7rem 1.25rem;
    position: fixed;
    width: 100%;
    z-index: 1000;
}

    #blazor-error-ui .dismiss {
        cursor: pointer;
        position: absolute;
        right: 0.75rem;
        top: 0.5rem;
    }

.blazor-error-boundary {
    background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
    padding: 1rem 1rem 1rem 3.7rem;
    color: white;
}

    .blazor-error-boundary::after {
        content: "An error has occurred."
    }

.loading-progress {
    position: absolute;
    display: block;
    width: 8rem;
    height: 8rem;
    inset: 20vh 0 auto 0;
    margin: 0 auto 0 auto;
}

    .loading-progress circle {
        fill: none;
        stroke: #e0e0e0;
        stroke-width: 0.6rem;
        transform-origin: 50% 50%;
        transform: rotate(-90deg);
    }

        .loading-progress circle:last-child {
            stroke: var(--tri-green);
            stroke-dasharray: calc(3.141 * var(--blazor-load-percentage, 0%) * 0.8), 500%;
            transition: stroke-dasharray 0.05s ease-in-out;
        }

.loading-progress-text {
    position: absolute;
    text-align: center;
    font-weight: bold;
    inset: calc(20vh + 3.25rem) 0 auto 0.2rem;
}

    .loading-progress-text:after {
        content: var(--blazor-load-percentage-text, "Loading");
    }

code {
    color: #c02d76;
}

.form-floating > .form-control-plaintext::placeholder, .form-floating > .form-control::placeholder {
    color: var(--bs-secondary-color);
    text-align: end;
}

.form-floating > .form-control-plaintext:focus::placeholder, .form-floating > .form-control:focus::placeholder {
    text-align: start;
}
/* Durchsuchbare Agentenauswahl im Trigger-Dialog */
.trigger-agent-list {
    position: absolute;
    z-index: 1080;
    top: calc(100% + 4px);
    left: 0;
    right: 0;
    max-height: 260px;
    overflow-y: auto;
    background: #fff;
    border: 1px solid #e2e4e8;
    border-radius: 0.5rem;
    padding: 0.3rem;
}
.trigger-agent-item {
    display: flex;
    align-items: center;
    width: 100%;
    border: none;
    background: none;
    text-align: left;
    padding: 0.45rem 0.6rem;
    border-radius: 0.4rem;
    font-size: 0.9rem;
    color: #33373d;
}
.trigger-agent-item:hover { background-color: var(--tri-green-bg); color: var(--tri-green-dark); }

/* Einzel-Agent-Auswahl (AgentPickerDialog): klickbare Zeilen. */
.agent-pick-row { display:flex; align-items:center; gap:.5rem; width:100%; border:0; background:transparent;
    border-bottom:1px solid #eef0f2; padding:.5rem .65rem; cursor:pointer; color:inherit; }
.agent-pick-row:last-child { border-bottom:0; }
.agent-pick-row:hover { background:var(--tri-green-bg); }
.agent-pick-row.active { background:var(--tri-green-bg-active); }

/* Tab-Register (Bootstrap nav-tabs) in Logo-Grün.
   WICHTIG: Hover ändert NIEMALS das Schriftgewicht – nur Farbe/Unterstrich.
   Sonst „springt" der aktive (700) Tab beim Hovern auf das Hover-Gewicht
   zurück und wirkt dünner. Gewicht hängt allein am Zustand inaktiv/aktiv. */
.trinidat-tabs .nav-link {
    border: none;
    background: none;
    color: var(--tri-muted);
    font-weight: 600;            /* inaktiv: solide, nie „dünn" */
    border-bottom: 2px solid transparent;
}
.trinidat-tabs .nav-link:hover {
    color: var(--tri-green-dark);
    border-bottom-color: var(--tri-green-soft);
}
.trinidat-tabs .nav-link.active {
    color: var(--tri-green);
    font-weight: 700;            /* aktiv: fett – unabhängig von Hover/Focus */
    background: none;
    border-bottom: 2px solid var(--tri-green);
}
/* Zähler-Badges in den Registern in hellerem Grau. */
.trinidat-tabs .nav-link .badge {
    background-color: #ced4da !important;
    color: var(--tri-subtle) !important;
}
/* Tab-Inhalt im Workspace-Dialog: feste Mindesthöhe, damit der Dialog beim
   Wechsel der Register nicht in der Höhe springt (Tab-Standard). */
/* Feste Höhe + Scroll: das Popup ändert die Höhe NICHT bei Tab-Wechsel oder langem Suchergebnis. */
.ws-tab-body { height: 24rem; overflow-y: auto; }

/* Ein Register, das seine Höhe ausfüllt: Der letzte Block darin (Beschreibung, Editor) wächst in den
   verbleibenden Platz, statt ihn leer zu lassen. `overflow: hidden` hält das Wachsen im Kasten. */
.ws-tab-body > .fill-col { height: 100%; min-height: 0; overflow: hidden; }

/* Entitäts-ID in Verwaltungstabellen (Knowledge-Buckets, Workspaces …): grün & fett. */
.entity-id { color: var(--tri-green); font-weight: 700; }

/* Der Schlüssel eines Second Brains in der Liste. Er ist technischer Natur – er steckt in den
   Funktionsnamen, die das Modell sieht – und tritt deshalb zurück: klein, grau, dicktengleich. */
.brain-key {
    font-family: var(--bs-font-monospace);
    font-size: .75rem;
    color: var(--tri-muted);
    background: var(--tri-surface);
    border-radius: .25rem;
    padding: .05rem .35rem;
}

/* =====================================================================
   Wiederverwendbare Komponenten-Klassen – statt inline-style in Razor.
   ===================================================================== */

/* Art-/Status-Pillen am Seitenkopf (Worker / Kritiker / „Nur im Dialog"). */
.badge-kind {
    font-size: .7rem;
    font-weight: 600;
    vertical-align: middle;
}
/* Helle Badges (Hintergrund hell + farbiger Text), analog zu den Agentennummern-Chips.
   Grün-Varianten sind branding-fähig (Tokens leiten sich bei aktivem Branding aus der Signature-Farbe ab). */
.badge-worker { background-color: var(--tri-green-bg-active) !important; color: var(--tri-green) !important; }
.badge-critic { background-color: #eceef0 !important; color: var(--tri-secondary) !important; }
.badge-gatekeeper { background-color: color-mix(in srgb, var(--tri-red) 14%, white) !important; color: var(--tri-red) !important; }
.badge-dialog { background-color: var(--tri-green-bg-active) !important; color: var(--tri-green) !important; }
.badge-system { background-color: var(--tri-green-bg-active) !important; color: var(--tri-green) !important; }
/* Kleinere Inline-Variante (in Listen/Karten neben dem Agentennamen). */
.badge-dialog-sm { font-size: .65em; vertical-align: 2px; }

/* Grauer Zusatz im Editor-Titel (z. B. „bearbeiten"). */
.editor-subtitle { color: var(--tri-subtle); font-weight: 400; }

/* Text-Utilities auf Basis der zentralen Grautöne (statt inline-Farben). */
.text-muted-2 { color: var(--tri-muted-2) !important; }

/* Chat-Vollbild (?fullscreen): Menü + Kopfzeile ausblenden, nur der Chat bleibt sichtbar.
   Global (nicht scoped), damit die Layout-Struktur (.sidebar/.content-area/.page-content) getroffen wird. */
body.chat-fullscreen .sidebar,
body.chat-fullscreen .mobile-menu-toggle { display: none !important; }
body.chat-fullscreen .content-area { flex: 1 1 100% !important; }
body.chat-fullscreen .page-content { padding: 0 !important; }
body.chat-fullscreen .page-content > .chat-page.chat-page { height: 100vh !important; }
/* Schlanke Kopfleiste im Vollbild mit dem Agentennamen (der normale PageHeader ist ausgeblendet). */
.chat-fullscreen-bar {
    flex: 0 0 auto; display: flex; align-items: center; min-width: 0;
    padding: 0.6rem 1rem; background: #fff; border-bottom: 1px solid var(--tri-border);
    color: var(--tri-green); font-size: 1.05rem;
}

/* ===== Chat-Seite ===== */
/* Chat-Seite füllt die volle Höhe. Opt-out vom Standard-Kopfband (.page-content > :first-child),
   stattdessen eigenes Kopfband (.chat-topbar) und eine flex-füllende Chat-Fläche.
   Klasse doppelt notiert → höhere Spezifität als `.page-content > :first-child` (sonst gewinnt dessen
   `align-items:center !important` per Source-Order und die Kopfzeile würde zentriert/schmal). */
.page-content > .chat-page.chat-page {
    display:flex !important; flex-direction:column; align-items:stretch !important;
    position:static !important; min-height:0 !important; border-bottom:none !important;
    background:transparent !important; margin:0 !important; padding:0 !important;
    /* KEIN overflow:hidden – sonst wird der negative Rand (Bleed) des Kopfbands abgeschnitten → Lücke zur Sidebar.
       Die feste Höhe + flex-Chain (chat-thread scrollt intern) hält den Inhalt im Rahmen. */
    height: calc(100vh - 1.5rem); overflow:visible;
}
/* Eigenes Kopfband, das den Standard nachbildet (weiß, grüne Unterkante, randbündig). */
/* Exakt wie das Standard-Kopfband (.page-content > :first-child): weiß, grüne Unterkante, 64px, randbündig. */
.chat-topbar { display:flex; align-items:center; min-height:64px; background:#fff; border-bottom:1px solid var(--tri-border);
    margin:0 -1rem 1.5rem -1rem; padding:0 1rem; }
/* Ab 992px hat der Inhaltsbereich 1.5rem Polster (px-lg-4). Bliebe der Bleed bei 1rem, stuende links
   neben dem Titel eine 8px-Luecke zur Sidebar - das Standard-Kopfband zieht dort ebenfalls auf 1.5rem. */
@media (min-width: 992px) {
    .chat-topbar { margin-left: -1.5rem; margin-right: -1.5rem; padding-left: 1.5rem; padding-right: 1.5rem; }
}
/* Kopf-Buttons (Details/Verlauf/Neuer Chat) einzeilig, nicht schrumpfen – der Agent-Bereich schrumpft stattdessen. */
.chat-topbar .btn { white-space:nowrap; flex-shrink:0; }
.chat-topbar .chat-history-wrap { flex-shrink:0; }
/* Titel & Icon im Chat-/KI-Kopfband kommen jetzt aus der zentralen PageHeader-Komponente
   (.page-head-title / .page-head-icon); frühere .chat-head-icon/.chat-head-name-Regeln entfernt. */
@media (min-width:992px){ .chat-topbar { margin-left:-1.5rem; margin-right:-1.5rem; padding-left:1.5rem; padding-right:1.5rem; } }
.chat-shell { display:flex; gap:1rem; flex:1 1 auto; min-height: 0; width:100%; }
/* KI-Assistent: Tab-Körper füllt die Resthöhe; nur der innere Bereich scrollt (wie die übrigen Voll-Höhe-Seiten). */
.kiv-tabbody { flex:1 1 auto; min-height:0; display:flex; flex-direction:column; }
.kiv-tab-scroll { flex:1 1 auto; min-height:0; overflow:auto; }
/* Verlauf-Popup im Kopf (ersetzt die frühere linke Sidebar) */
.chat-history-wrap { position:relative; display:inline-block; }
.chat-pop-backdrop { position:fixed; inset:0; z-index:1040; background:transparent; }
.chat-history-pop {
    position:absolute; top:calc(100% + .4rem); right:0; left:auto; z-index:1050;
    width:340px; max-width:90vw; max-height:70vh; display:flex; flex-direction:column;
    background:#fff; border:1px solid #eef0f2; border-radius:.75rem;
    box-shadow:0 .5rem 1.5rem rgba(0,0,0,.18); overflow:hidden;
    /* AUSDRUECKLICH DUNKEL. Das Fenster haengt an der Schaltflaeche „Verlauf" und die steht im
       GRUENEN BAND des Kopfes - von dort erbte es `color: #fff`. Auf der weissen Flaeche waren
       Ueberschrift und Gespraechstitel dadurch unsichtbar; zu sehen blieb nur die graue Zeile
       darunter, und zwischen den Eintraegen klafften die Luecken der unsichtbaren Zeilen. */
    color: var(--tri-text);
}
.chat-history-head { display:flex; align-items:center; justify-content:space-between; gap:.5rem; padding:.6rem .8rem; border-bottom:1px solid #eef0f2; }
.chat-list { overflow:auto; padding:.4rem; flex:1 1 auto; }
.chat-list-item {
    display:block; width:100%; text-align:left; border:0; background:transparent;
    border-radius:.6rem; padding:.55rem .65rem; margin-bottom:.15rem; cursor:pointer; color:inherit;
}
.chat-list-item:hover { background:#f3f5f7; }
.chat-list-item.active { background:#e7f3ea; }
.chat-list-title { font-weight:600; font-size:.9rem; line-height:1.2; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; }
.chat-list-meta { font-size:.75rem; color:#8a9099; margin-top:.15rem; }
/* Antwort-Dialog der Tabellenansicht: beide Register in einem Container mit fester Mindesthöhe
   (kein Größensprung beim Wechseln); das Chat-Fenster füllt die Höhe. */
.qa-tab-body { min-height: 26rem; display: flex; flex-direction: column; }
.qa-question { flex: 1 1 auto; min-height: 26rem; display: flex; flex-direction: column; }
.cursor-pointer { cursor: pointer; }

/* Mail-Vorschau: gerendertes Mail-HTML in einem abgeschotteten iframe (Höhe setzt js/mail-preview.js) */
.mail-preview-frame { width:100%; border:0; background:#fff; height:14rem; display:block; }

/* Leseansicht „Bisheriges Ergebnis" (RunResultDialog): schlichte Abschnitte statt Chat-Blasen */
.run-read-label { font-size:.78rem; font-weight:600; text-transform:uppercase; letter-spacing:.03em;
    color:var(--tri-faint); margin-bottom:.35rem; }
.run-read-block { background:var(--tri-surface); border:1px solid var(--tri-border); border-radius:.5rem;
    padding:.6rem .75rem; }
.run-read-entry { border-top:1px solid var(--tri-border); padding:.6rem 0; }
.run-read-entry:first-of-type { border-top:0; padding-top:.2rem; }
.run-read-time { font-size:.75rem; color:var(--tri-faint); margin-bottom:.25rem; }

/* Kopfzeile eines Rückfragen-Eintrags: Agent einzeilig, bei Platzmangel gekürzt (…) */
.chat-list-agent { display:flex; align-items:center; gap:.3rem; min-width:0; margin-bottom:.2rem;
    font-size:.78rem; color:var(--tri-muted-2); }
.chat-list-agent-name { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }

/* Empfänger einer Rückfrage – eigene Zeile unter dem Titel */
.chat-list-to { font-size:.78rem; color:var(--tri-muted-2); margin-top:.2rem;
    display:flex; align-items:center; gap:.3rem; min-width:0; }
.chat-list-to > span { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.chat-pager { display:flex; align-items:center; justify-content:space-between; gap:.5rem; padding:.5rem .6rem; border-top:1px solid #eef0f2; }

.chat-main { flex:1 1 auto; min-width:0; display:flex; flex-direction:column;
    background:#fff; border-radius:.75rem; box-shadow: var(--tri-shadow-flaeche); overflow:hidden; }
/* Linke Liste (z. B. Rückfragen) als weiße Karte – gleiche Optik wie der rechte Bereich */
.chat-sidebar { flex:0 0 20rem; min-width:0; display:flex; flex-direction:column;
    background:#fff; border-radius:.75rem; box-shadow: var(--tri-shadow-flaeche); overflow:hidden; }
.chat-sidebar-head { padding:.85rem 1rem; border-bottom:1px solid #eef0f2; }
.chat-sidebar .chat-list { flex:1 1 auto; overflow-y:auto; padding:.4rem; }
.chat-main-head { padding:.85rem 1rem; border-bottom:1px solid #eef0f2; display:flex; align-items:center; gap:.6rem; }
/* Agentname im Chat-Kopf: groß und einzeilig (Tools/Prompt sind über „Details" erreichbar). */
.chat-info { padding:.7rem 1rem; border:1px solid #eef0f2; border-radius:.75rem; background:#fff;
    box-shadow:0 .125rem .25rem rgba(0,0,0,.06); max-height:16rem; overflow:auto; }
.chat-info a { cursor:pointer; }
/* Sub-Agenten-Zeile im Chat-Details-Bereich: einzeilig, bei Überlänge horizontal scrollbar; jede Nummer hellgrün. */
.chat-subagents { display:flex; align-items:center; gap:.4rem; white-space:nowrap; overflow-x:auto; }
.chat-subagents > strong { flex:0 0 auto; }
.chat-subagent-list { display:inline-flex; align-items:center; gap:.7rem; min-width:0; }
.chat-subagent-item { display:inline-flex; align-items:center; flex:0 0 auto; }
.chat-thread { flex:1 1 auto; overflow:auto; padding:1.1rem 1.2rem; background:#fafbfc; }
.chat-row { display:flex; margin-bottom:.7rem; }
.chat-row.user { justify-content:flex-end; }
/* Wrapper um Blase + Copy-Symbol: begrenzt den Hover-Bereich auf Blase + Symbolzeile (#106828). */
.chat-bubble-wrap { position:relative; display:inline-block; max-width:78%; padding-bottom:1.2rem; }
.chat-copy { position:absolute; left:.15rem; bottom:-.05rem; border:none; background:transparent; color:#9aa0a6; padding:.1rem .25rem; font-size:.85rem; line-height:1; cursor:pointer; opacity:0; transition:opacity .12s, color .12s; }
.chat-bubble-wrap:hover .chat-copy { opacity:1; }
.chat-copy:hover { color:var(--tri-green); }
.chat-bubble { max-width:100%; padding:.55rem .85rem; border-radius:1rem; font-size:.92rem; }
.chat-bubble :last-child { margin-bottom:0; }
.chat-bubble.user { background:var(--tri-green); color:#fff; border-bottom-right-radius:.3rem; }
.chat-bubble.agent { background:#eef1f4; color:#212529; border-bottom-left-radius:.3rem; }
.chat-bubble.user a { color:#dff3e4; }
/* Ohne seitliches Polster: Der Einzug stammte vom fruehreren pulsierenden Punkt davor. Ohne ihn stand
   „KI denkt nach" einen Tick weiter rechts als die Zeile mit Dauer/Schritten und der Denkprozess-Kasten
   darunter - drei Zeilen, drei Anfaenge. */
/* „KI denkt nach …": linksbündig (kein seitlicher Rand) und ohne senkrechte Polsterung – sie schob
   die Zahlenzeile darunter sichtbar weg. */
.chat-typing { color:#6c757d; font-size:.85rem; padding:0; line-height:1.3; }
.chat-composer { padding:.75rem; border-top:1px solid #eef0f2; }
.chat-empty { flex:1 1 auto; display:flex; align-items:center; justify-content:center; color:#8a9099; text-align:center; padding:2rem; }
.chat-agent-pick { width:100%; }
/* System-Prompt-Editor: etwas kleinerer Font + Vollbild-Modus */
.agent-prompt-area { font-size: .82rem; line-height: 1.45; }
/* Gerenderte Markdown-Vorschau des System-Prompts (z. B. Test-/Dialogseite) – etwas kleiner. */
.agent-prompt-md, .agent-prompt-md .markdown-body { font-size: .85rem; }
.agent-prompt-sidebar { font-size: .9rem; }
.prompt-fs {
    position: fixed;
    inset: 0;
    z-index: 1060;
    background: #fff;
    padding: 1rem 1.25rem;
    overflow: auto;
    display: flex;
    flex-direction: column;
}
.prompt-fs .agent-prompt-row { flex: 1 1 auto; min-height: 0; }
.prompt-fs .agent-prompt-area { height: calc(100vh - 11rem) !important; resize: none; }
.prompt-fs .agent-prompt-preview { max-height: calc(100vh - 8rem) !important; }
.prompt-fs .agent-prompt-sidebar { max-height: calc(100vh - 11rem) !important; }

.chat-agent-item { display:flex; align-items:center; gap:.6rem; width:100%; text-align:left; border:1px solid #e6e8eb; background:#fff; border-radius:.6rem; padding:.6rem .75rem; margin-bottom:.4rem; cursor:pointer; }
.chat-agent-item:hover { border-color:var(--tri-green); background:#f6fbf7; }

/* Agenten-Auswahl als Kachel-Grid (ganze Kachel klickbar). */
/* ===== Agent Desk: Konfigurationsdialog (Bildvorschau, Auswahl-Listen, Startart) ===== */
.adk-bg-preview { width:8rem; height:4.6rem; object-fit:cover; border-radius:.6rem; border:1px solid var(--tri-border); }
.adk-bg-empty { display:flex; align-items:center; justify-content:center; color:var(--tri-faint); font-size:1.4rem; background:var(--tri-surface); }
.adk-picklist { border:1px solid var(--tri-border); border-radius:.6rem; max-height:15rem; overflow:auto; background:#fff; }
.adk-pick { display:flex; align-items:center; gap:.5rem; padding:.3rem .55rem; font-size:.85rem; cursor:pointer; margin:0; }
.adk-pick:hover { background:var(--tri-green-bg); }
.adk-choice { display:flex; align-items:flex-start; gap:.6rem; border:1px solid var(--tri-border); border-radius:.6rem; padding:.55rem .7rem; cursor:pointer; margin:0; }
/* Der Knopf sitzt auf der Mitte der ERSTEN Zeile, nicht an deren Oberkante. Ohne diesen Versatz
   steht er sichtbar zu hoch neben der fetten Ueberschrift - `align-items:flex-start` richtet nach
   dem Kasten aus, das Auge aber nach der Schrift. */
.adk-choice > input[type="radio"] { flex: 0 0 auto; margin-top: .3rem; }
.adk-choice:hover { border-color:var(--tri-green); }
.adk-choice.is-disabled { opacity:.6; cursor:not-allowed; }

.chat-agent-grid { display:grid; grid-template-columns:repeat(auto-fill, minmax(340px, 1fr)); gap:1rem; }
.chat-agent-tile { display:flex; flex-direction:row; align-items:flex-start; gap:1rem; text-align:left; background:#fff; border:1px solid #e6e8eb; border-radius:.85rem; padding:1.1rem 1.15rem; cursor:pointer; min-height:8rem; transition:box-shadow .15s, transform .15s, border-color .15s; }
.chat-agent-tile:hover { border-color:var(--tri-green); box-shadow:0 4px 12px rgba(0,0,0,.1); transform:translateY(-1px); }
/* Agentenbeschreibung im Chat-Kopf (klein, grau, einzeilig) – kürzt erst am Spaltenrand (vor den Aktionen) */
.chat-head-desc { font-size:.82rem; font-weight:400; color:var(--tri-muted, #8a9099); display:block; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; max-width:100%; }
/* Die Lauf-Nummer unter dem Agentennamen: in Markenfarbe und halbfett, weil sie ein Verweis ist und
   nicht Prosa – die Beschreibung daneben bleibt grau. Rechts ein Abstand, sonst klebt sie am Text. */
/* Rueckfallebene, wenn Markdig einen Text nicht umsetzen kann (siehe MarkdownView): unformatiert, aber
   lesbar und umbrechend – eine waagerechte Rollleiste quer ueber die Seite waere schlimmer als kein Satz. */
.markdown-plain { white-space: pre-wrap; word-break: break-word; font-family: inherit; font-size: inherit; margin: 0; }
.chat-head-run { color: var(--tri-green); font-weight: 600; margin-right: .4rem; }
.chat-head-run:hover { color: var(--tri-green-hover); text-decoration: underline !important; }
.chat-topbar.page-head { flex-wrap:nowrap; }
.chat-topbar .page-head-main { flex:1 1 auto; min-width:0; }
.chat-topbar .page-head-text { flex:1 1 auto; min-width:0; }
/* Aktionsleiste bleibt fix auf EINER Zeile; die Beschreibung (min-width:0) kürzt stattdessen */
.chat-topbar .page-head-actions { flex:0 0 auto; flex-wrap:nowrap; }
.chat-agent-tile-avatar { flex:0 0 auto; }
.chat-agent-tile-avatar i { font-size:2.4rem !important; }   /* größeres Fallback-Icon, wenn kein Avatar */
.chat-agent-tile-body { min-width:0; display:flex; flex-direction:column; gap:.2rem; }
.chat-agent-tile-head { display:flex; align-items:center; gap:.4rem; flex-wrap:wrap; }
.chat-agent-tile-kicker { font-size:.68rem; text-transform:uppercase; letter-spacing:.05em; font-weight:700; color:var(--tri-green); }
.chat-agent-tile-name { font-weight:700; font-size:.98rem; color:var(--tri-text, #33373d); line-height:1.2; }
.chat-agent-tile-desc { color:var(--tri-muted, #6c757d); font-size:.8rem; line-height:1.35; margin-top:.1rem; display:-webkit-box; -webkit-line-clamp:5; -webkit-box-orient:vertical; overflow:hidden; }

/* ===== Agentenbeschreibung als Markdown – überall in der bestehenden (grauen, kleinen) Schrift; alle
   Überschriften werden auf die aktuelle Schriftgröße verkleinert (keine großen H1/H2 in Kacheln/Kopf/Liste). ===== */
/* Chat-Auswahlkachel (mehrzeilig, per line-clamp begrenzt): markdown-body verschwindet (display:contents),
   damit das -webkit-line-clamp die Block-Kinder (p/Überschriften) direkt begrenzt. */
.chat-agent-tile-desc .markdown-body { display: contents; }
.chat-agent-tile-desc :is(h1,h2,h3,h4,h5,h6),
.chat-agent-tile-desc p, .chat-agent-tile-desc ul, .chat-agent-tile-desc ol, .chat-agent-tile-desc li, .chat-agent-tile-desc code {
    font-size: inherit; line-height: inherit; color: inherit;
}
.chat-agent-tile-desc :is(h1,h2,h3,h4,h5,h6) { font-weight: 700; margin: 0; }
.chat-agent-tile-desc p { margin: 0; }
.chat-agent-tile-desc ul, .chat-agent-tile-desc ol { margin: 0; padding-left: 1.1em; }

/* Einzeilige Kontexte (Chat-Kopf, Agentenliste): Markdown inline, damit Ellipsis/nowrap greifen. */
.chat-head-desc .markdown-body, .chat-head-desc .markdown-body p, .chat-head-desc :is(h1,h2,h3,h4,h5,h6),
.agentlist-desc-md .markdown-body, .agentlist-desc-md .markdown-body p, .agentlist-desc-md :is(h1,h2,h3,h4,h5,h6) {
    display: inline; font-size: inherit; line-height: inherit; color: inherit; font-weight: inherit; margin: 0;
}

/* Interaktive Rückfragen (Multiple-Choice) in der Agent-Bubble */
/* Interaktive Rückfragen (```ask-Block) – Triagen-Design */
.chat-questions { margin:.4rem 0; font-size:.9rem; }
/* Entscheidungsgrundlage: KEINE Überschrift mehr, sondern ein Sachverhalt - normale Schriftstärke,
   eigene ruhige Fläche, Abstand. Fett und grün war richtig, solange dort ein Einleitungssatz stand;
   für eine Tabelle mit Empfänger und Betrag ist es falsch. */
.chat-questions .cq-intro-toggle { display:inline-flex; align-items:center; gap:.35rem; margin:0 0 .5rem;
    padding:0; border:0; background:none; color:var(--tri-green-dark); font-size:.85rem; font-weight:600; }
.chat-questions .cq-intro-toggle:hover { text-decoration:underline; }
.chat-questions .cq-intro-toggle i { font-size:.8em; }
.chat-questions .cq-intro { margin-bottom:.75rem; padding:.6rem .8rem; border-radius:.5rem;
    background:var(--tri-surface); border:1px solid var(--tri-border); }
.chat-questions .cq-intro .markdown-body > *:first-child { margin-top:0; }
.chat-questions .cq-intro .markdown-body > *:last-child { margin-bottom:0; }
.chat-questions .cq-intro table { font-size:.9em; margin:.35rem 0; }
/* Frage-Karte: Kopf (Fragetext) mit Trennlinie, darunter die Antwortoptionen */
.chat-questions .cq-card { border:1px solid var(--tri-border); border-radius:.75rem; background:#fff;
    margin-bottom:.75rem; box-shadow:0 1px 3px rgba(0,0,0,.04); overflow:hidden; }
.chat-questions .cq-card-head { display:flex; align-items:baseline; gap:.5rem; flex-wrap:wrap;
    padding:.8rem 1rem; border-bottom:1px solid var(--tri-border); }
.chat-questions .cq-qnum { font-size:.72rem; font-weight:600; letter-spacing:.02em; text-transform:uppercase; color:var(--tri-faint); }
.chat-questions .cq-q { font-weight:700; color:var(--tri-text); line-height:1.35; }
.chat-questions .cq-card-body { padding:.85rem 1rem; }
/* Antwortoption als anklickbare Karte; ausgewählt = grün */
.chat-questions .cq-option { display:flex; align-items:center; gap:.7rem; padding:.6rem .8rem; margin-bottom:.5rem; cursor:pointer;
    border:1px solid var(--tri-border); border-radius:.6rem; background:#fff;
    transition:background .12s ease, border-color .12s ease; }
.chat-questions .cq-option:last-child { margin-bottom:0; }
.chat-questions .cq-option:hover { background:var(--tri-green-bg); border-color:var(--tri-green-soft); }
.chat-questions .cq-option.sel { background:var(--tri-green-bg); border-color:var(--tri-green); }
.chat-questions .cq-option input { width:1.15rem; height:1.15rem; flex:0 0 auto; margin:0; cursor:pointer; accent-color:var(--tri-green); }
.chat-questions .cq-option span { font-size:inherit; }
.chat-questions .cq-option input:disabled, .chat-questions .cq-option input:disabled ~ span { cursor:default; }
/* „Andere Antwort": Option + (bei Auswahl) eingerücktes Freitextfeld mit Zeichenzähler */
.chat-questions .cq-option-other { display:block; }
.chat-questions .cq-option-lead { display:flex; align-items:center; gap:.7rem; cursor:pointer; }
.chat-questions .cq-free .cq-other-wrap { margin:0; }
.chat-questions .cq-free .cq-count { margin-left:0; }
.chat-questions .cq-other-wrap { position:relative; margin:.6rem 0 0 1.85rem; }
.chat-questions .cq-other { min-height:5.5rem; resize:vertical; padding-right:2.1rem; font-size:inherit; line-height:1.45; border-radius:.55rem; background:#fff; }
.chat-questions .cq-count { margin:.3rem 0 0 1.85rem; text-align:right; font-size:.78rem; color:var(--tri-faint); }
.chat-questions .cq-zoom-btn { position:absolute; top:.4rem; right:.4rem; width:1.65rem; height:1.65rem;
    display:inline-flex; align-items:center; justify-content:center; padding:0; font-size:.78rem; line-height:1;
    border:1px solid var(--tri-green-soft); border-radius:.4rem; background:#fff; color:var(--tri-green); cursor:pointer; transition:background .12s, color .12s; }
.chat-questions .cq-zoom-btn:hover { background:var(--tri-green); color:#fff; }
.chat-questions .cq-zoom-btn:disabled { opacity:.45; cursor:default; background:#fff; color:var(--tri-green); }
/* Aktionszeile: Senden-Button + Hinweis, warum noch nicht gesendet werden kann */
.chat-questions .cq-actions { display:flex; align-items:center; gap:.9rem; flex-wrap:wrap; }
.chat-questions .cq-submit { border-radius:.55rem; font-weight:600; padding:.5rem 1.1rem; }
.chat-questions .cq-submit:disabled { background:var(--tri-surface); border-color:var(--tri-border); color:var(--tri-faint); opacity:1; }
.chat-questions .cq-hint { font-size:.86rem; color:var(--tri-muted); }
.chat-questions .cq-done { display:inline-flex; align-items:center; font-size:.86rem; font-weight:600; color:var(--tri-green); }
/* Benutzergruppen: Mitglieder-Chips */
.ug-members { display:flex; flex-wrap:wrap; gap:.4rem; max-height:min(42vh,320px); overflow-y:auto; padding:.15rem; }
.ug-member { display:inline-flex; align-items:center; gap:.4rem; padding:.2rem .3rem .2rem .25rem;
    border:1px solid #d0e5d8; border-radius:1rem; background:#fff; font-size:.85rem; max-width:100%; }
.ug-member-name { white-space:nowrap; overflow:hidden; text-overflow:ellipsis; max-width:12rem; }
.ug-member-x { display:inline-flex; align-items:center; justify-content:center; width:1.2rem; height:1.2rem;
    border:none; border-radius:50%; background:transparent; color:#98a2b3; cursor:pointer; padding:0; font-size:.7rem; flex:0 0 auto; }
.ug-member-x:hover { background:#f2dede; color:#c0392b; }
/* Benutzergruppen: Ankreuz-Liste im Benutzer-Editor */
.ug-checklist { display:flex; flex-direction:column; gap:.1rem; max-height:min(42vh,300px); overflow-y:auto;
    border:1px solid #e2ece6; border-radius:.5rem; padding:.35rem .5rem; background:#fff; }
.ug-check { display:flex; align-items:baseline; gap:.55rem; padding:.3rem .15rem; cursor:pointer; border-radius:.3rem; }
.ug-check:hover { background:#f5faf6; }
.ug-check input { width:1.05rem; height:1.05rem; flex:0 0 auto; margin:0; align-self:center; cursor:pointer; accent-color:var(--tri-green); }
.ug-check-name { font-weight:500; }
.ug-check-desc { color:#8a97a0; font-size:.82rem; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
/* Großes Eingabefeld (Zoom) für lange Freitext-Antworten einer Rückfrage */
/* „Antwort vergrößern": seit 2026.9.471 im Popup-Hausstandard (user-modal mit dunklem Kopf, Abbrechen · OK).
   Eigene Regeln gibt es nur noch für das große Eingabefeld - Kopf, Rumpf und Fuß kommen aus .user-modal. */
.cq-zoom-area { width:100%; min-height:min(60vh,26rem); resize:vertical; font-size:.95rem; line-height:1.5; }

/* ---------- Einheitlich abgerundete Karten ----------
   Alle Karten erhalten einen deutlicheren, einheitlichen Radius. Karten, die eine
   Tabelle enthalten, beschneiden ihren Inhalt an den runden Ecken (sonst füllt die
   Tabelle die Ecken eckig aus). */
.card {
    --bs-card-border-radius: 0.75rem;
    --bs-card-inner-border-radius: 0.7rem;
    border-radius: 0.75rem;
}

.card:has(> .table-responsive),
.card:has(> table) {
    overflow: hidden;
}

/* Agenten-/Trigger-/Datenbank-Liste: Karte NICHT clippen, sonst wird das Zeilen-Aktionsmenü („…") am Rand abgeschnitten. */
.card:has(> .agents-table-wrap),
.card:has(> .triggers-table-wrap),
.card:has(> .db-table-wrap) {
    overflow: visible;
}

/* Einheitliche Tabellen: etwas kleinere Schrift, Kopfzeilen in Grau (nicht schwarz/fett). */
.table {
    font-size: 0.875rem;
}
.table > thead th {
    color: var(--tri-muted);
    font-weight: 600;
    font-size: 0.9rem;
}

/* JSON-Editor: kompaktere Schrift */
.json-editor textarea {
    font-size: 0.8rem;
    line-height: 1.4;
}

/* Tool-Call-Popover (Agent-Editor, über dem Tools-Symbol in der Formatierungsleiste) */
.toolcalls-backdrop {
    position: fixed;
    inset: 0;
    z-index: 1040;
}

.toolcalls-pop {
    position: absolute;
    top: calc(100% + 0.35rem);
    right: 0;
    z-index: 1050;
    width: 24rem;
    max-width: 90vw;
    max-height: 26rem;
    overflow: auto;
    background: #fff;
    border: 1px solid #e5e7eb;
    border-radius: 0.6rem;
    box-shadow: 0 10px 28px rgba(0, 0, 0, 0.14);
    padding: 0.7rem 0.8rem;
}

/* ---------- Einheitliches Seiten-Kopfband ----------
   Die Überschrift jeder Seite (erstes Element des Inhalts) bildet ein weißes Band
   in Höhe der schwarzen Sidebar-Kopfzeile (64px) mit hellgrüner Unterkante. Die Linie
   liegt damit bündig auf 64px; die Überschrift steht im weißen Band darüber, der
   restliche (graue) Seiteninhalt folgt darunter – ohne Überlappung. Volle Breite per
   negativer Ränder, die das horizontale Padding des Inhaltsbereichs ausgleichen.

   Die Ausnahme für Dialoge steht als EIGENE Regel weiter unten – NICHT als `:not(.modal)` an diesem
   Selektor. Ein `:not()` hier erhöht die Spezifität auf (0,4,0) und schlägt damit die Opt-outs anderer
   Seiten (`.page-content > .chat-page.chat-page`, (0,3,0)); Chat und KI-Assistent wurden dadurch am
   11.09.2026 schmal und mittig statt über die volle Breite. */
.page-content > :first-child {
    display: flex !important;
    align-items: center !important;
    min-height: 64px;
    background-color: #fff;
    /* Grau und 1 px wie jede andere Trennlinie – siehe .sidebar-header::after, mit dem diese Kante
       durchgehend fluchtet. */
    border-bottom: 1px solid var(--tri-border);
    margin: 0 -1rem 1.5rem -1rem !important;
    padding: 0 1rem;
    /* Titelzeile bleibt beim Scrollen oben fixiert (gilt für alle Seiten,
       da jede Seite dieses Kopfband als erstes Element rendert). Das Fenster
       scrollt, daher genügt sticky top:0; z-index über den Inhaltskarten. */
    position: sticky;
    top: 0;
    z-index: 30;
}

/* Opt-out für Dialoge: Rendert eine Seite STATT des Kopfbands einen Dialog (so sperrt der Demo-Modus die
   Verwaltungsseiten), wäre er das erste Element und bekäme Kopfband-Aussehen, `position: sticky` und
   `z-index: 30` – er stand dann oben links statt mittig, und das Backdrop (fest, z-index 1050) lag ÜBER
   ihm, sodass „Schließen" keinen Klick mehr annahm. Klasse doppelt notiert, damit die Spezifität (0,3,0)
   der des Kopfbands entspricht und die spätere Stelle entscheidet – genau wie beim Chat-Opt-out. */
.page-content > .modal.modal {
    display: block !important;
    align-items: stretch !important;
    position: fixed;
    top: 0;
    margin: 0 !important;
    padding: 0;
    min-height: 0;
    background-color: transparent;
    border-bottom: 0;
    z-index: 1055;
}
/* Opt-out für das grüne Lauf-Banner (RunBannerHeader, Versuch ab 2.0.636): Es IST das Kopfband und
   bringt sein eigenes Aussehen mit – weisse Fläche, Trennlinie und `align-items: center` der Regel oben
   zerlegten es (die drei Zeilen standen mittig statt über die volle Breite, gemessen: Pfadzeile bei
   x = 774 statt am linken Rand). Sticky bleibt es NICHT: Ein 200 px hohes Banner, das beim Scrollen
   stehen bliebe, nähme ein Drittel des Fensters. Klasse doppelt notiert (0,3,0) wie bei Chat und Dialog,
   damit diese spätere Stelle entscheidet. */
.page-content .rbh.rbh {
    align-items: stretch !important;
    min-height: 0;
    /* OHNE eigenen Grund: Kopf und Anbau bringen ihren mit. Stand hier Weiss, blitzte es in den
       Rundungen als heller Keil zwischen grünem Kopf und dem Band dahinter durch – beim Scrollen,
       wenn der Anbau zugeklappt ist, war das als Ecke am unteren Rand zu sehen. (Grün darf hier
       erst recht nicht stehen: Es färbte früher den Anbau mit.) */
    background-color: transparent;
    /* KEINE Kante. Die Regel `.page-content > :first-child` zieht unter dem ersten Element der Seite
       einen Trennstrich über die volle Breite; das Banner braucht ihn nicht - es grenzt sich durch
       seine Fläche und seinen Schatten ab. Eine einzelne Linie unter einem rahmenlosen Kasten sähe
       aus wie ein halber Rahmen. */
    border-bottom: 0;
    /* Das Kopfband der Regel oben trägt seitlich 1 rem Polster, damit sein Inhalt über dem Seiteninhalt
       fluchtet. Die Karte braucht keines: Ihr Polster sitzt im grünen Kopf und in den Spalten des
       Streifens – mit dem geerbten stand alles 24 px zu weit innen (gemessen gegen die Vorlage). */
    padding: 0;
    margin: 1rem 0 1rem 0 !important;
    /* RELATIVE, nicht `static`: Das Kopfband der Regel oben ist `sticky`, und das soll das Banner nicht
       sein. Mit `static` verlöre es aber auch den Bezugsrahmen für seine absolut gesetzten Kinder – die
       Schmuckbalken rutschten dann an den unteren Rand des Fensters und waren nicht mehr zu sehen. */
    position: relative;
}
/* Der Behälter um die Karte. Als ERSTES Element der Seite bekäme er sonst das weisse Kopfband der
   Regel weiter oben – er soll aber gar nichts sein ausser einem Block. */
.page-content > .rbh-sticky.rbh-sticky {
    display: block !important;
    align-items: initial !important;
    /* NICHT schrumpfen: Auf Seiten mit `.page-fill` ist der Seitenbereich eine Flex-Spalte fester
       Höhe. Ohne diese Zeile staucht sie den Behälter, und die Karte darin ragt über ihn hinaus –
       auf der Lauf-Detailseite legte sich das Banner dadurch über die Zeitleiste. */
    flex: 0 0 auto;
    position: static;
    min-height: 0;
    margin: 0 !important;
    padding: 0;
    background: transparent;
    border-bottom: 0;
}

/* Mit `StickyCompact` trägt er das Kleben – und den Rand oben wie unten als ECHTE Fläche in der
   Seitenfarbe. Vorher taten das zwei Schlagschatten an der Karte; die nahmen deren Rundung mit und
   standen beim Scrollen als Kerbe am linken Rand. */
.page-content > .rbh-sticky.rbh-sticky.is-on {
    position: sticky;
    top: 0;
    z-index: 30;
    /* ÜBER die Seitenränder hinaus (wie das Kopfband der Hausregel): Die Karte darunter wirft einen
       Schatten, der seitlich in das Polster der Seite reicht. Endete das Band an der Kartenkante,
       blieb dieser Schatten daneben stehen und lief beim Scrollen als feine senkrechte Linie links
       und rechts am Band hoch. Mit dem Überstand deckt das Band ihn mit ab. */
    margin: 0 -1rem !important;
    padding: 1rem 1rem .75rem;
    background: var(--tri-surface);
}
@media (min-width: 992px) {
    .page-content > .rbh-sticky.rbh-sticky.is-on {
        margin: 0 -1.5rem !important;
        padding-inline: 1.5rem;
        padding-top: 1.5rem;
    }
}

/* ---- Der Abstand nach OBEN ist so gross wie der nach links und rechts ----
   Seitlich polstert der Inhaltsbereich selbst (px-3 / px-lg-4, also 1 bzw. 1,5 rem). Oben kamen
   bisher ZWEI Abstände zusammen: das Polster des klebenden Behälters UND der Rand der Karte darin -
   zusammen 2 rem, also doppelt so viel Luft wie an den Seiten.

   Er kommt jetzt aus EINER Quelle: Beim klebenden Kopf aus dem Polster des Behälters (es muss dort
   sitzen, weil dessen Fläche beim Scrollen die durchlaufenden Tabellenzeilen abdeckt - ein Rand
   wäre durchsichtig), bei jedem anderen aus dem Rand der Karte selbst.

   Der SCHWEBENDE Kopf bleibt aussen vor: Er liegt über einer Szene und hält seinen eigenen, bewusst
   knapperen Abstand zur oberen Kante. */
.page-content > .rbh-sticky.is-on > .rbh.rbh { margin-top: 0 !important; }
@media (min-width: 992px) {
    .page-content .rbh.rbh:not(.rbh-floating) { margin-top: 1.5rem !important; }
    .page-content > .rbh-sticky.is-on > .rbh.rbh { margin-top: 0 !important; }
}
/* Die Überschrift gehört dem Banner: Die Regel `.page-content > :first-child h1` färbt sie sonst
   schwarz und setzt sie auf 1,45 rem – auf Grün war sie dadurch kaum zu lesen. */
.page-content .rbh.rbh h1 {
    color: #fff;
    /* Die Hausschrift der Ueberschrift. Nur HIER - der uebrige Text bleibt bei der Systemschrift,
       sonst waere es keine Auszeichnung mehr, sondern die neue Grundschrift. */
    font-family: 'Space Grotesk', 'Segoe UI', 'Helvetica Neue', Helvetica, Arial, sans-serif;
    /* Ohne diese Zeilen setzt `.page-content > :first-child h1` die Überschrift auf 1,45 rem und
       halbfett. Die Werte sind die der Vorlage: 32 px in leichter Stärke. */
    font-size: 32px;
    font-weight: 300;
}
/* Der VOLLE Kopf (Lauf-Detail) trägt sie noch einmal ein Viertel kleiner: Dort stehen Abzeichen,
   Überschrift, zwei Pillenzeilen und vier Schaltflächen übereinander – die Überschrift muss die
   Zeile anführen, nicht füllen. */
.page-content .rbh.rbh .rbh-body.is-tall h1 { font-size: 1.32rem; }

/* AUSNAHME von der Regel darueber: die Datei-Vorschau. Sie wird aus einem solchen Dialog heraus geoeffnet
   und muss darueber liegen. Vier Klassen (0,4,0) – mit drei Klassen hatte die Regel oben dieselbe
   Spezifitaet, und weil DIESE Stelle spaeter steht, gewann sie: Die Vorschau lag hinter dem Dialog, aus dem
   der Klick kam, und der Klick sah wirkungslos aus (gemessen 1055 statt 1220). */
.page-content > .modal.modal.file-preview-modal { z-index: 1220; }
.page-content > .modal-backdrop.modal-backdrop.file-preview-backdrop { z-index: 1210; }

.page-content > .modal-backdrop.modal-backdrop {
    display: block !important;
    align-items: stretch !important;
    position: fixed;
    top: 0;
    margin: 0 !important;
    padding: 0;
    min-height: 0;
    background-color: #000;
    border-bottom: 0;
    z-index: 1050;
}

/* Seitenüberschriften einheitlich etwas kleiner und in Schwarz/Standardtextfarbe.
   Links (z. B. Agentennamen via .agent-name-link, Run-Badges) und Agentennummern
   behalten ihre eigene Farbe über ihre spezifischeren Regeln. */
.page-content > :first-child h1 {
    color: var(--tri-text);
    font-size: 1.45rem;
    font-weight: 700;
    margin-bottom: 0;
}
/* Überschriften in Chat-Nachrichten folgen IMMER dem Markdown-Stil (grün, moderat) – die obige Seiten-Titel-Regel
   „.page-content > :first-child h1" würde sonst eine `#`-Überschrift des Agenten als große schwarze h1 rendern
   (während `###` grün bleibt). Höhere Spezifität + spätere Position → gewinnt. */
.chat-msg-body .markdown-body :is(h1, h2, h3, h4, h5, h6) { color: var(--tri-green); font-weight: 600; }
.chat-msg-body .markdown-body h1 { font-size: 1.2rem; margin-bottom: 0.5rem; }

/* Führendes Icon jeder Seitenüberschrift als grüne Kachel mit weißem Glyph
   (wie auf der Lauf-Detailseite). Das Glyph je Seite bleibt erhalten; Badge-Icons
   (in <span>) und der Agenten-Avatar (Bild) sind nicht betroffen. */
.page-content > :first-child h1 > i.bi {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 3rem;
    height: 3rem;
    margin-right: 0.7rem !important;
    border-radius: 0.8rem;
    background-color: var(--tri-green);
    color: #fff;
    font-size: 1.5rem;
    vertical-align: middle;
}

@media (min-width: 992px) {
    .page-content > :first-child {
        margin-left: -1.5rem !important;
        margin-right: -1.5rem !important;
        padding-left: 1.5rem;
        padding-right: 1.5rem;
    }
}

/* ---------- Kompakte Agent-Typ-Auswahl (Neuanlage) ---------- */
.kindpick { border-radius: .8rem; }
.kindpick-card {
    display: flex; align-items: center; gap: .8rem; width: 100%; text-align: left;
    border: 1.5px solid var(--tri-border); border-radius: .7rem; background: #fff;
    padding: .7rem .85rem; cursor: pointer; transition: border-color .12s, box-shadow .12s, background .12s;
}
/* Live mitlaufender Generierungstext (Denkprozess/Antwort) in Chat- und Test-Dialog. */
.chat-live-text {
    white-space: pre-wrap;
    font-size: .8rem;
    line-height: 1.35;
    color: #33373d;
    background: #f4f5f7;
    border: 1px solid var(--tri-border);
    border-radius: .5rem;
    padding: .5rem .65rem;
    max-height: 16rem;
    overflow-y: auto;
}

/* Live mitlaufender Denkprozess im Chat – beschriftete, scrollbare Box (statt roher 🧠-Zeile). */
/* Hellgrau statt gruen: Der Denkprozess ist Beiwerk zur Antwort, kein Ergebnis. In Markenfarbe zog er
   den Blick auf sich, obwohl darunter das steht, worauf der Benutzer wartet. */
.chat-think-live {
    border: 1px solid var(--tri-line, #e6e8e7);
    border-radius: .5rem;
    background: #f5f6f7;
    overflow: hidden;
}
.chat-think-live-head {
    font-size: .72rem;
    font-weight: 600;
    color: #5b6168;
    padding: .35rem .65rem;
    border-bottom: 1px solid var(--tri-line, #e6e8e7);
    display: flex;
    align-items: center;
    gap: .4rem;
}
/* Auf-/Zuklappen des Denkprozesses – sitzt rechts in der Kopfzeile, nicht als eigene Zeile darunter. */
.chat-think-toggle {
    margin-left: auto;
    border: 0;
    background: transparent;
    color: inherit;
    padding: 0 .15rem;
    line-height: 1;
    cursor: pointer;
}
.chat-think-toggle:hover { color: var(--tri-text, #1f2a24); }
/* ---------- Denkprozess als Schrittliste (ThinkingSteps) ----------
   Je Schritt eine ruhige, graue Zeile; Einzelheiten erscheinen erst auf Klick. Die Liste ist das
   Protokoll einer Arbeit, keine Erzählung: Sie soll überflogen werden können, und nur dort, wo jemand
   nachsieht, steht der volle Befehl samt Ausgabe. */
.think-steps {
    border: 1px solid var(--tri-line, #e6e8e7);
    border-radius: .55rem;
    overflow: hidden;
    background: #fff;
}
.think-step + .think-step { border-top: 1px solid var(--tri-line, #e6e8e7); }
.think-step-head {
    display: flex;
    align-items: center;
    gap: .5rem;
    width: 100%;
    text-align: left;
    background: transparent;
    border: 0;
    padding: .5rem .7rem;
    font-size: .82rem;
    color: #6b7570;
    cursor: pointer;
}
.think-step-head.is-static { cursor: default; }
button.think-step-head:hover { background: #f6f8f9; }
.think-step-title {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
/* Fehlgeschlagen steht IN der Zeile, nicht als Symbol daneben: Wer die Liste überfliegt, soll den
   Fehlschlag lesen können, ohne eine Farbe deuten zu müssen. */
.think-step-failed { color: #a4262c; font-weight: 600; flex: 0 0 auto; }
.think-step-caret { flex: 0 0 auto; font-size: .75rem; opacity: .7; }
.think-step-detail {
    padding: .1rem .7rem .6rem 1.4rem;
    background: #fbfcfc;
}
.think-step-detail-label { font-size: .72rem; color: #8a918c; margin-bottom: .2rem; }
.think-step-detail pre {
    margin: 0;
    font-size: .74rem;
    line-height: 1.45;
    white-space: pre-wrap;
    word-break: break-word;
    max-height: 18rem;
    overflow: auto;
    color: #46504a;
}
/* Die laufende Zeile: dezent hervorgehoben, mit pulsierendem Punkt - das Streaming soll sichtbar sein. */
.think-step.is-live .think-step-head { color: var(--tri-green-dark); }
.think-step-dot {
    flex: 0 0 auto;
    width: .45rem;
    height: .45rem;
    border-radius: 50%;
    background: var(--tri-green);
    animation: think-dot 1s ease-in-out infinite;
}
@keyframes think-dot { 0%, 100% { opacity: .25; } 50% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .think-step-dot { animation: none; opacity: .8; } }

/* Zugeklappt: genau EINE Zeile, der Rest wird abgeschnitten. Ohne die feste Zeile waechst der Kasten
   waehrend des Wartens weiter und schiebt Verlauf und Eingabe aus dem Bild. */
.chat-think-live-last {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Hinweis in der laufenden Antwort-Blase, wenn das Nachladen der Lauf-Details mehrfach scheitert.
   Die Live-Abfrage laeuft weiter – der Nutzer soll nur wissen, dass die Anzeige gerade haengt. */
.chat-poll-warn {
    font-size: .74rem;
    color: var(--tri-warn, #a8501b);
}

/* Token-Rate unter einer Antwort – nur fuer Administratoren sichtbar (Betriebskennzahl, kein Nutzerinhalt). */
.chat-rate {
    font-size: .72rem;
    color: var(--tri-text-muted, #6b7570);
    font-variant-numeric: tabular-nums;
}
.chat-think-live-body {
    font-size: .78rem;
    line-height: 1.4;
    color: #5b6168;
    padding: .5rem .65rem;
    /* Vollständig anzeigen (kein eigener Scrollbalken); bei Bedarf scrollt der gesamte Chat-Thread. */
}

/* Keine gelbe Hervorhebung im Denkbereich. Der Denkprozess ist Rohtext des Modells; darin stehen
   Abschnittsmarken wie `==FRAGEN==` oder `==PROMPT==`. Markdown liest `==…==` als Hervorhebung und malt
   den Rest der Zeile gelb – gemeint war eine Trennlinie, zu sehen war ein Textmarker quer durch den
   Absatz. Im Denkbereich deshalb neutral darstellen; in den ANTWORTEN bleibt die Hervorhebung erhalten,
   dort ist sie gewollt. */
.chat-think-live-body mark,
.chat-section-body mark {
    background: transparent;
    color: inherit;
    padding: 0;
}

/* Markdown im Live-Denkprozess kompakt halten (kleine Überschriften/Abstände, damit der gesamte Verlauf reinpasst). */
.chat-think-live-body :is(h1, h2, h3, h4, h5, h6) { font-size: .82rem; font-weight: 600; margin: .35rem 0 .15rem; }
.chat-think-live-body p,
.chat-think-live-body ul,
.chat-think-live-body ol { margin: .15rem 0; }
.chat-think-live-body pre { margin: .25rem 0; font-size: .74rem; }
.chat-think-live-body :first-child { margin-top: 0; }

.kindpick-card:hover { box-shadow: 0 3px 10px rgba(0,0,0,.08); }
.kindpick-card.selected { border-color: var(--tri-green); background: var(--tri-green-bg); box-shadow: 0 0 0 2px rgba(var(--tri-green-rgb),.15); }
.kindpick-card img { height: 1.9rem; width: auto; flex: 0 0 auto; }
.kindpick-card > i { font-size: 1.6rem; width: 1.9rem; text-align: center; flex: 0 0 auto; }
.kindpick-text { display: flex; flex-direction: column; line-height: 1.25; min-width: 0; }
.kindpick-title { font-weight: 700; font-size: .95rem; }
.kindpick-desc { font-size: .78rem; color: var(--tri-muted); }
.kindpick-worker:hover { border-color: var(--tri-green); background: var(--tri-green-bg); }
.kindpick-worker .kindpick-title { color: var(--tri-green); }
.kindpick-critic:hover { border-color: var(--tri-secondary); background: var(--tri-surface); }
.kindpick-critic .kindpick-title { color: var(--tri-secondary, #6c757d); }
.kindpick-gatekeeper:hover { border-color: var(--tri-red); background: #fcf3f2; }
.kindpick-gatekeeper > i { color: var(--tri-red); }
.kindpick-gatekeeper .kindpick-title { color: var(--tri-red); }

/* ===== Wiederverwendbare Agentenauswahl (AgentPicker) – Suche/Typeahead, NIE DropDown ===== */
/* AgentListPicker: gefilterte, seitenweise Liste mit Einzel-Markierung. */
.agent-lp { display: flex; flex-direction: column; gap: .5rem; }
.agent-lp-search { position: relative; display: flex; align-items: center; }
.agent-lp-ic { position: absolute; left: .7rem; color: var(--tri-faint); font-size: .9rem; pointer-events: none; }
.agent-lp-input {
    width: 100%; padding: .5rem .7rem .5rem 2rem; border: 1px solid var(--tri-border);
    border-radius: .5rem; font-size: .92rem; outline: none;
}
.agent-lp-input:focus { border-color: var(--tri-green); box-shadow: 0 0 0 2px rgba(var(--tri-green-rgb),.15); }
.agent-lp-list {
    display: flex; flex-direction: column; gap: .2rem;
    max-height: 60vh; min-height: 18rem; overflow-y: auto; padding-right: .15rem;
}
.agent-lp-empty { color: var(--tri-muted); font-size: .9rem; padding: .6rem; text-align: center; }
.agent-lp-item {
    display: flex; align-items: center; gap: .55rem; width: 100%; text-align: left;
    border: 1px solid var(--tri-border); background: #fff; border-radius: .5rem; padding: .45rem .6rem;
    font-size: .9rem; color: #4b5159; cursor: pointer;
}
.agent-lp-item:hover { border-color: var(--tri-green); background: var(--tri-surface); }
.agent-lp-item.selected { border-color: var(--tri-green); background: var(--tri-green-bg); }
.agent-lp-radio { color: var(--tri-faint); font-size: 1rem; flex: 0 0 auto; }
.agent-lp-item.selected .agent-lp-radio { color: var(--tri-green); }
/* Agentennummer im Listen-Picker: hellgrüner Chip wie der Standard (.agent-num-inline), nicht faint-grau. */
.agent-lp-id { flex: 0 0 auto; font-size: .78rem; font-weight: 700; background: var(--tri-green-bg-active); color: var(--tri-green); border-radius: .3rem; padding: .02em .4em; }
.agent-lp-name { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; }
.agent-lp-kind { color: var(--tri-muted); font-size: .76rem; flex: 0 0 auto; }
.agent-lp-pager { display: flex; align-items: center; justify-content: center; gap: .6rem; }
.agent-lp-pageinfo { color: var(--tri-muted); font-size: .8rem; }

/* Provider-Auswahl (Designer „Provider ändern"): Karten mit Logo + Beschreibung, eine auswählbar. */
.wfd-prov-list { display: flex; flex-direction: column; gap: .5rem; max-height: 52vh; overflow-y: auto; padding: .15rem; }
.wfd-prov-card { display: flex; align-items: center; gap: .75rem; width: 100%; text-align: left;
    background: #fff; border: 1.5px solid var(--tri-border, #dee2e6); border-radius: .6rem; padding: .6rem .8rem;
    cursor: pointer; transition: border-color .12s, background .12s, box-shadow .12s; }
.wfd-prov-card:hover { border-color: var(--tri-green); background: var(--tri-green-bg-active); }
.wfd-prov-card.sel { border-color: var(--tri-green); background: var(--tri-green-bg-active);
    box-shadow: 0 0 0 2px rgba(var(--tri-green-rgb),.15); }
.wfd-prov-logo { flex: 0 0 auto; width: 34px; height: 34px; object-fit: contain; border-radius: 6px; background: #fff; }
.wfd-prov-logo-fb { display: inline-flex; align-items: center; justify-content: center; color: var(--tri-muted);
    font-size: 1.1rem; border: 1px solid var(--tri-border, #dee2e6); }
.wfd-prov-main { display: flex; flex-direction: column; gap: .1rem; min-width: 0; flex: 1 1 auto; }
.wfd-prov-name { font-weight: 700; font-size: .95rem; display: flex; align-items: center; gap: .4rem; }
.wfd-prov-badge { font-size: .62rem; font-weight: 700; text-transform: uppercase; letter-spacing: .03em;
    color: var(--tri-green); background: var(--tri-green-bg-active); border-radius: .3rem; padding: .05em .4em; }
.wfd-prov-model { font-size: .78rem; color: var(--tri-muted); }
.wfd-prov-desc { font-size: .8rem; color: var(--tri-muted); line-height: 1.25;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.wfd-prov-check { flex: 0 0 auto; font-size: 1.15rem; color: var(--tri-green); }
.wfd-prov-card:not(.sel) .wfd-prov-check { color: #c7cdc9; }
.agent-lp-pagebtn {
    border: 1px solid var(--tri-border); background: #fff; border-radius: .4rem;
    width: 1.7rem; height: 1.7rem; display: inline-flex; align-items: center; justify-content: center;
    color: var(--tri-muted); cursor: pointer;
}
.agent-lp-pagebtn:disabled { opacity: .4; cursor: not-allowed; }
.agent-lp-pagebtn:hover:not(:disabled) { border-color: var(--tri-green); color: var(--tri-green); }

.agent-picker { position: relative; }
.agent-picker-field { position: relative; display: flex; align-items: center; }
.agent-picker-ic { position: absolute; left: .7rem; color: var(--tri-faint); font-size: .9rem; pointer-events: none; }
.agent-picker-input {
    width: 100%; border: 1px solid var(--tri-border); border-radius: .6rem;
    padding: .55rem .75rem .55rem 2.1rem; font-size: .92rem; color: var(--tri-text); background: #fff;
}
.agent-picker-input:focus { outline: none; border-color: var(--tri-green); box-shadow: 0 0 0 3px rgba(var(--tri-green-rgb),.18); }
.agent-picker-chosen {
    display: flex; align-items: center; gap: .5rem; border: 1px solid var(--tri-green);
    border-radius: .6rem; padding: .5rem .55rem .5rem .6rem; background: var(--tri-surface);
}
.agent-picker-chosen .agent-picker-name { font-weight: 600; color: var(--tri-text); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.agent-picker-clear {
    margin-left: auto; flex: 0 0 auto; border: none; background: transparent; color: var(--tri-muted);
    cursor: pointer; font-size: .8rem; line-height: 1; padding: .25rem .3rem; border-radius: .35rem;
}
.agent-picker-clear:hover { color: var(--tri-red); background: rgba(192,57,43,.1); }
.agent-picker-id {
    flex: 0 0 auto; font-size: .72rem; font-weight: 700; color: #fff; background: var(--tri-green);
    border-radius: .35rem; padding: .1rem .4rem; line-height: 1.3;
}
.agent-picker-kind { flex: 0 0 auto; margin-left: auto; font-size: .72rem; color: var(--tri-faint); }
.agent-picker-list {
    position: absolute; z-index: 20; left: 0; right: 0; top: calc(100% + 4px);
    background: #fff; border: 1px solid var(--tri-border); border-radius: .6rem;
    box-shadow: 0 12px 30px rgba(0,0,0,.16); max-height: 16rem; overflow-y: auto; padding: .3rem;
}
.agent-picker-item {
    display: flex; align-items: center; gap: .55rem; width: 100%; text-align: left;
    border: none; background: transparent; border-radius: .45rem; padding: .45rem .55rem; cursor: pointer;
}
.agent-picker-item .agent-picker-name { font-size: .9rem; color: var(--tri-text); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.agent-picker-item:hover, .agent-picker-item.active { background: var(--tri-surface); }
.agent-picker-empty { padding: .6rem .55rem; color: var(--tri-muted); font-size: .88rem; }

/* SharePoint-Browser: Breadcrumb-Überschrift („Websites") größer/grau, Einträge kompakt */
.sp-crumbs { font-size: 1rem; color: var(--tri-muted); }
.sp-crumbs > i { color: var(--tri-muted); }
.sp-crumb { color: var(--tri-muted); font-weight: 600; }
.sp-crumb:hover { color: var(--tri-text); }

/* SharePoint-Zuordnung: links der Baum, rechts die zugeordneten Pfade.
   Beide Spalten haben dieselbe feste Höhe und scrollen für sich – der Dialog selbst springt dadurch beim
   Aufklappen des Baums nicht, und die rechte Spalte bleibt beim Zuordnen an ihrem Platz. */
/* Höhe der beiden Spalten: so hoch wie der Dialog es zulässt, aber gedeckelt – sonst stand unter den
   Spalten ein Streifen Leerraum, während die Liste daneben scrollte. */
/* Beide Spalten füllen die HÖHE DES DIALOGS (er hat mit user-modal-fixed eine konstante Höhe). Eine
   eigene Zahl (vorher min(58vh, 34rem)) ließ unten einen Streifen Leerraum stehen. */
.sp-assign { --sp-indent: 1.1rem; height: 100%; }
/* Feste Höhe, nicht min-height: Mit min-height wächst die Spalte mit ihrem Inhalt, der innere
   Scrollbereich kommt nie zum Tragen – und es scrollte der ganze Dialog statt jeder Liste für sich. */
.sp-assign > [class*="col-"] { height: 100%; min-height: 0; }
.sp-tree { display: flex; flex-direction: column; min-height: 0; flex: 1 1 auto; }
.sp-tree-body {
    flex: 1 1 auto; min-height: 0; overflow: auto;
    border: 1px solid var(--tri-border); border-radius: var(--tri-radius);
    padding: .35rem .25rem; background: #fff;
}
.sp-tree-row { display: flex; align-items: center; gap: .3rem; padding: .12rem 0; font-size: .88rem; }
.sp-tree-row:hover { background: var(--tri-green-bg); }
.sp-tree-toggle { width: 1.1rem; flex: 0 0 1.1rem; color: var(--tri-muted); text-align: center; }
.sp-tree-icon { color: var(--tri-muted); flex: 0 0 auto; }
.sp-tree-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sp-tree-badge { margin-left: auto; flex: 0 0 auto; font-weight: 500; }
/* Der „+"-Knopf steht rechts und erscheint erst beim Überfahren der Zeile: Sonst ist der Baum eine Wand
   aus Knöpfen, und man sieht die Struktur nicht mehr. */
.sp-tree-add { margin-left: auto; flex: 0 0 auto; padding: 0 .3rem; line-height: 1.3; visibility: hidden; }
.sp-tree-row:hover .sp-tree-add, .sp-tree-add:focus-visible { visibility: visible; }
.sp-assign-list {
    flex: 1 1 auto; min-height: 0; overflow: auto;
    border: 1px solid var(--tri-border); border-radius: var(--tri-radius);
    padding: .4rem; background: #fff;
}
.sp-assign-row { border: 1px solid var(--tri-border); border-radius: var(--tri-radius); padding: .4rem; background: #fff; }
.sp-assign-row + .sp-assign-row { margin-top: .4rem; }
/* Kopfzeile einer Zuordnung: Sinnbild, Pfad (nur Anzeige, gekürzt) und das Entfernen-Kreuz rechts. */
.sp-assign-head { display: flex; align-items: center; gap: .4rem; }
.sp-assign-head > i { color: var(--tri-muted); flex: 0 0 auto; }
.sp-assign-path {
    /* Kein Monospace: Der Pfad ist hier Beschriftung, kein Code – er soll wie der übrige Text aussehen. */
    font-size: .85rem;
    color: var(--tri-text); direction: rtl; text-align: left;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 1 1 auto; min-width: 0;
}
/* Gekürzt wird VORNE: „…/sites/DataCenter/Marketing" sagt etwas, „https://trinidat.sharepo…" nichts.
   direction: rtl schneidet am Anfang ab; die Zeichen selbst bleiben in ihrer Reihenfolge, weil eine URL
   keine bidirektionalen Anteile hat. */
.sp-assign-del { flex: 0 0 auto; padding: 0 .35rem; line-height: 1.4; }
.sp-assign-rights { margin: .3rem 0 0 .15rem; }
/* „inkl. Unterordner" ist Reichweite, kein Recht – etwas abgesetzt, damit die drei Rechte zusammenbleiben. */
.sp-assign-scope { margin-left: auto; }
.sp-assign-scope .form-check-label { color: var(--tri-muted); }

/* Auswahl „Welche Art von Tool?": kompakte Zeilen – Sinnbild links, Name und Zweck rechts gestapelt.
   Vorher war jede Zeile ein Knopf mit py-3 und dreizeilig umbrechender Beschreibung; sieben Einträge
   füllten damit zwei Bildschirmhöhen, obwohl man sie vergleichen will. */
.tool-type-row { display: flex; align-items: flex-start; gap: .55rem; text-align: left; padding: .5rem .7rem; }
.tool-type-row > i { font-size: 1.05rem; line-height: 1.35; flex: 0 0 1.2rem; }
.tool-type-row .tool-type-text { min-width: 0; }
.tool-type-row .tool-type-name { font-weight: 600; line-height: 1.3; }
.tool-type-desc { font-size: .82rem; line-height: 1.3; margin-top: .05rem; }

/* ===== Prompt-Engineering-Dialog (wiederverwendbar) ===== */
.pe-backdrop { position: fixed; inset: 0; z-index: 1200; background: rgba(0,0,0,.35); display: flex; align-items: center; justify-content: center; padding: 1rem; }
.pe-modal { background: #fff; border-radius: 1rem; box-shadow: 0 2px 6px rgba(0,0,0,.35), 0 28px 70px rgba(0,0,0,.55); width: min(1100px, 96vw); height: min(86vh, 900px); display: flex; flex-direction: column; overflow: hidden; }
/* Prompt-Engineering/Diagnose-Fenster tragen denselben dunklen Kopf wie jeder andere Dialog. */
.pe-head { display: flex; align-items: center; gap: .75rem; padding: 1rem 1.25rem; background: var(--wl-signature, var(--tri-green)); border-bottom: 0; }
.pe-head .btn-close {
    flex: 0 0 auto; opacity: 1; width: 2.1rem; height: 2.1rem; padding: 0;
    border-radius: .6rem; background-color: rgba(255, 255, 255, .18); background-size: .85rem; background-position: center;
    background-repeat: no-repeat;
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23ffffff'%3e%3cpath d='M.293.293a1 1 0 0 1 1.414 0L8 6.586 14.293.293a1 1 0 1 1 1.414 1.414L9.414 8l6.293 6.293a1 1 0 0 1-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 0 1-1.414-1.414L6.586 8 .293 1.707a1 1 0 0 1 0-1.414z'/%3e%3c/svg%3e");
}
.pe-head .btn-close:hover { background-color: rgba(255, 255, 255, .3); }
.pe-head .agent-num-inline { font-size: inherit; margin-right: 0; }
.pe-ic { flex: 0 0 auto; width: 2.4rem; height: 2.4rem; border-radius: .7rem; display: inline-flex; align-items: center; justify-content: center; background: var(--tri-surface); color: var(--tri-green); font-size: 1.2rem; }
.pe-kicker { font-size: .66rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: rgba(255, 255, 255, .72); }
.pe-title { font-size: 1.05rem; font-weight: 700; color: #fff; display: flex; align-items: baseline; gap: .5rem; min-width: 0; }
/* minmax(0,1fr) statt 1fr: verhindert, dass eine Spalte mit langen, nicht umbrechbaren Inhalten (z. B. eine lange
   URL im Editor) über ihre min-content-Breite ausbricht und die andere Spalte zusammenquetscht. */
.pe-body { flex: 1 1 auto; display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); min-height: 0; }
.pe-left { display: flex; flex-direction: column; min-width: 0; min-height: 0; border-right: 1px solid var(--tri-border); }
/* Prompt-Engineering nutzt die einheitliche Chat-Optik (chat-conv/chat-thread/composer) → Kette füllt die Spalte. */
.pe-left > .chat-conv { flex: 1 1 auto; min-height: 0; }
.pe-chat { flex: 1 1 auto; overflow-y: auto; padding: 1rem; display: flex; flex-direction: column; gap: .6rem; }
.pe-hint { color: var(--tri-muted); font-size: .9rem; background: var(--tri-surface); border-radius: .6rem; padding: .7rem .8rem; }
/* An die moderne Chat-Optik angeglichen: Benutzer = rechte hellgraue Bubble, KI = flach linksbündig. */
.pe-msg { max-width: 92%; padding: 0; }
.pe-msg.user { align-self: flex-end; background: #f0f1f3; border: none; border-radius: 1.1rem; padding: .6rem .95rem; max-width: 85%; }
.pe-msg.user .pe-msg-role { display: none; }
.pe-msg.ai { align-self: stretch; background: transparent; border: none; padding: .1rem 0; }
.pe-msg-role { font-size: .78rem; font-weight: 700; color: var(--tri-text); margin-bottom: .15rem; }
.pe-msg-text { font-size: .9rem; color: var(--tri-text); white-space: pre-wrap; word-break: break-word; }
/* Prompt-Engineering-Editor-Spalte: Flex-Wrapper, damit die <PromptEditor>-Komponente die Höhe füllt.
   Die Editor-Optik (Überschriften, Toolbar) liegt jetzt in der Komponente (PromptEditor.razor.css). */
.pe-draft-editor { display: flex; flex-direction: column; min-height: 0; }

/* Moderner Composer: dezenter grauer Rahmen, kein grüner Kasten; Textfeld randlos, kompakter Senden-Button. */
.pe-compose { display: flex; gap: .5rem; margin: .6rem .75rem .75rem; padding: .5rem .6rem; border: 1px solid #e3e6ea; border-radius: .9rem; align-items: flex-end; }
.pe-compose:focus-within { border-color: #cfd4da; }
.pe-compose textarea { resize: vertical; min-height: 6rem; max-height: 45vh; border: none; box-shadow: none; background: transparent; padding: .25rem .35rem; }
.pe-compose textarea:focus { border: none; box-shadow: none; outline: none; }
.pe-compose #pe-send { align-self: flex-end; width: 2.6rem; height: 2.6rem; border-radius: .7rem; flex: 0 0 auto; }

/* Multiple-Choice-Rückfragen im Prompt-Engineer-Dialog */
.pe-qa { display: flex; flex-direction: column; gap: .8rem; border: 1px solid var(--tri-border); border-radius: .6rem; padding: .8rem; background: #fff; }
.pe-q { display: flex; flex-direction: column; gap: .45rem; }
.pe-q-text { font-weight: 600; font-size: .9rem; }
.pe-q-multi { font-weight: 400; color: var(--tri-muted); font-size: .8rem; }
.pe-opts { display: flex; flex-wrap: wrap; gap: .4rem; }
.pe-opt { border: 1px solid var(--tri-border); background: #fff; color: var(--tri-ink); border-radius: 999px; padding: .3rem .8rem; font-size: .85rem; cursor: pointer; transition: all .12s ease; }
.pe-opt:hover { border-color: var(--tri-green); }
.pe-opt.sel { background: var(--tri-green); border-color: var(--tri-green); color: #fff; }
.pe-free { max-width: 100%; }
.pe-qa-send { align-self: flex-start; }
.pe-right { position: relative; display: flex; flex-direction: column; min-width: 0; min-height: 0; }
.pe-right-head { display: flex; align-items: center; min-height: 2.1rem; font-size: .8rem; font-weight: 700; color: var(--tri-muted); padding: .5rem 1rem .25rem; }
.pe-right .prompt-find-input { max-width: 15rem; }
/* „Das hat die KI geaendert": gelb hinterlegte Zeilen im erzeugten Prompt (siehe js/prompt-diff.js und
   Shared/Agents/PromptDiff.cs). Die Antwort liefert immer den GANZEN Prompt zurueck, nie nur die
   Aenderung - ohne diese Farbe sieht man nur, dass sich etwas getan hat, nicht was.
   Die Regel braucht `.CodeMirror` davor: EasyMDE faerbt seine Zeilen selbst, und eine blosse Klasse
   verlieren sich dagegen. */
.CodeMirror .CodeMirror-line.pe-diff,
.CodeMirror .pe-diff { background: #fff6cc; }
/* Der Hinweis in der Kopfzeile des rechten Bereichs – mit demselben Gelb als Punkt davor, damit die
   Farbe erklaert ist, ohne dass ein Satz sie beschreiben muss. */
.pe-diff-hint { display: inline-flex; align-items: center; gap: .35rem; margin-left: auto; font-weight: 500; text-transform: none; }
.pe-diff-dot { width: .7rem; height: .7rem; border-radius: .2rem; background: #fff6cc; border: 1px solid #e8d48a; }
/* width:auto + box-sizing: sonst überschreibt Bootstraps .form-control (width:100%) die seitlichen Ränder
   und das Textfeld ragt rechts über den Dialogrand hinaus (#106824). */
.pe-draft { flex: 1 1 auto; width: auto; box-sizing: border-box; margin: 0 1rem 1rem; resize: none; font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: .85rem; }
.pe-draft-md { flex: 1 1 auto; margin: 0 1rem 1rem; overflow-y: auto; border: 1px solid var(--tri-border); border-radius: .5rem; padding: .6rem .8rem; font-family: inherit; font-size: .92rem; background: #fff; }
/* Fuß wie ueberall: ohne graue Flaeche und ohne Trennstrich, Schaltflaechen rechts. */
.pe-foot { display: flex; align-items: center; gap: .5rem; padding: .4rem 1.25rem 1rem; border-top: 0; background: transparent; }
@media (max-width: 800px) { .pe-body { grid-template-columns: 1fr; } .pe-left { border-right: none; border-bottom: 1px solid var(--tri-border); } }

/* ===== Agenten-Graph (Force-Directed) ===== */
/* Agentenwolke eingebettet in die Agentenseite (Inline-Umschalter): randlos, weiß, randbündig.
   Die Höhe (bis zum unteren Viewport-Rand) setzt das JS exakt per Pixel (spinalcordGraph), damit die SVG
   eine definite Höhe hat und der Graph die volle Fläche nutzt. */
.ag-cloud-embed { display: flex; flex-direction: column; min-height: 24rem;
    margin: -1.5rem -1rem -1.5rem -1rem; background: #fff; overflow: hidden; }
@media (min-width: 992px) { .ag-cloud-embed { margin-left: -1.5rem; margin-right: -1.5rem; } }
.ag-canvas { flex: 1 1 auto; min-height: 0; width: 100%; position: relative; background: #fff; overflow: hidden; }
.ag-svg { display: block; width: 100%; height: 100%; touch-action: none; }
.ag-svg text { user-select: none; pointer-events: none; }
.ag-density {
    position: absolute; right: 1rem; bottom: 1rem; z-index: 5;
    display: flex; align-items: center; gap: .5rem;
    background: rgba(255,255,255,.92); border: 1px solid var(--tri-border); border-radius: 1rem;
    padding: .4rem .8rem; box-shadow: 0 4px 14px rgba(0,0,0,.1); color: var(--tri-muted);
}
.ag-density input[type=range] { width: 9rem; accent-color: var(--tri-green); cursor: pointer; }
/* Trenner und Drehen-Schalter in derselben Leiste unten rechts. */
.ag-density-sep { width: 1px; height: 1.1rem; background: var(--tri-border); flex: 0 0 auto; }
.ag-density-check { display: flex; align-items: center; gap: .35rem; margin: 0; cursor: pointer;
    font-size: .82rem; white-space: nowrap; user-select: none; }
.ag-density-check input { margin: 0; cursor: pointer; }
canvas.ag-svg { touch-action: none; cursor: grab; }
/* Hinweis-Textfeld des markierten Agenten (Triagen-Design, hell). Unten links, damit es die Dichte-Regelung
   (unten rechts) nicht überdeckt. Erscheint beim Anklicken eines Agenten. */
.ag-desc {
    position: absolute; left: 1rem; bottom: 1rem; max-width: min(360px, 72%); z-index: 5;
    background: #fff; border: 1px solid var(--tri-border); border-radius: .7rem; padding: .7rem .9rem;
    box-shadow: 0 10px 28px rgba(20,70,36,.14); font-size: .85rem; line-height: 1.45; color: #2b3138;
    pointer-events: none; opacity: 0; transform: translateY(6px); transition: opacity .18s, transform .18s;
}
.ag-desc.is-visible { opacity: 1; transform: none; }
.ag-desc-title { display: flex; align-items: baseline; gap: .4rem; font-weight: 700; color: var(--tri-green); margin-bottom: .3rem; }
.ag-desc-text { color: var(--tri-muted); }
.ag-desc-empty { font-style: italic; opacity: .8; }

/* Bucket-interne Ordnerstruktur: nutzt die Klassen des Agenten-Ordnerbaums (.folder-tree/.folder-node …).
   Der Baum wird scrollbar gehalten; das Verschieben-Popover ist eigenständig. */
.folder-tree.ftv { max-height: 28rem; overflow: auto; }
/* In .ftv-compact-Kontexten bringt der umgebende Wrapper IMMER seine eigene Höhe + overflow:auto mit
   (Designer-Panel, /folders-Kartenkörper, Auswahl-Dialoge). Die 28rem-Kappung der bloßen Variante darf
   hier NICHT zusätzlich greifen – sonst endet der Baum vorzeitig (halbe Höhe). Der Wrapper scrollt. */
.ftv-compact .folder-tree.ftv { max-height: none; overflow: visible; }
/* Ordner-Seite (/folders): der Kartenkörper füllt die volle Höhe und scrollt selbst (overflow-y:auto). Die
   28rem-Kappung der inneren .ftv darf hier NICHT greifen – sonst endet der Baum vorzeitig mit leerem Raum
   darunter. Anders als .ftv-compact bleibt die normale (große) Schrift erhalten. */
.ftv-fill-host > .folder-tree.ftv { max-height: none; overflow: visible; }
/* Ziehbare Einträge (z. B. Bucket → auf Agenten ziehen) erhalten einen Greif-Cursor. */
.folder-agent-leaf.is-draggable { cursor: grab; }
.folder-agent-leaf.is-draggable:active { cursor: grabbing; }

/* Breadcrumb-Pfad auf der Bucket-Inhaltsseite (graue Pfeile als Trennzeichen) */
.bucket-breadcrumb { display: flex; flex-wrap: wrap; align-items: center; gap: .3rem; }
.bucket-breadcrumb .bc-seg { color: var(--tri-muted); text-decoration: none; cursor: pointer; }
.bucket-breadcrumb .bc-seg:hover { color: var(--tri-green); }
.bucket-breadcrumb .bc-seg.current { color: var(--tri-text); font-weight: 600; cursor: default; }
.bucket-breadcrumb .bc-sep { color: var(--tri-subtle, #b6bcc4); font-size: .7rem; }

/* Bucket-Ordnerbaum: Schrift exakt wie die Sidebar-Menüpunkte (~0.9rem), unabhängig von .ftv/.ftv-compact. */
.btree-sm .folder-node,
.btree-sm .folder-name { font-size: 0.9rem !important; line-height: 1.2; }
.btree-sm .folder-icon { font-size: 1rem !important; }
.btree-sm .folder-caret { font-size: 0.7rem !important; }
.btree-sm .folder-node { padding-top: 0.2rem; padding-bottom: 0.2rem; }

/* Trigger-Kalender (Monatsraster) */
.cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 6px; }
.cal-dow-row { margin-bottom: 6px; }
.cal-dow { text-align: center; font-size: .75rem; font-weight: 600; color: var(--tri-muted); padding: .15rem 0; }
.cal-cell {
    min-height: 6.5rem; background: #fff; border: 1px solid var(--tri-border);
    border-radius: .55rem; padding: .3rem; display: flex; flex-direction: column; gap: .25rem; overflow: hidden;
}
.cal-cell-clickable { cursor: pointer; transition: background-color .12s, box-shadow .12s; }
.cal-cell-clickable:hover { background: var(--tri-surface, #f3f7f4); box-shadow: inset 0 0 0 1px var(--tri-green); }
.cal-cell-other { background: #f6f7f9; color: var(--tri-muted); }
.cal-cell-other .cal-daynum { color: var(--tri-subtle, #aeb4bc); }
.cal-cell-today { border-color: var(--tri-green); box-shadow: inset 0 0 0 1px var(--tri-green); }
.cal-daynum { font-size: .8rem; font-weight: 600; color: var(--tri-text); align-self: flex-end; line-height: 1; }
.cal-cell-today .cal-daynum {
    background: var(--tri-green); color: #fff; border-radius: 999px;
    width: 1.4rem; height: 1.4rem; display: inline-flex; align-items: center; justify-content: center; align-self: flex-end;
}
.cal-events { display: flex; flex-direction: column; gap: 3px; overflow: auto; }
.cal-event {
    display: flex; align-items: baseline; gap: .3rem; width: 100%; text-align: left;
    border: none; border-radius: .35rem; padding: .12rem .35rem; cursor: pointer;
    font-size: .72rem; line-height: 1.2; color: var(--tri-green-dark); background: var(--tri-green-bg-active);
    border-left: 3px solid var(--tri-green); overflow: hidden;
}
.cal-event:hover { filter: brightness(.97); }
.cal-event-rec { color: #1e3a8a; background: #e6eefc; border-left-color: #3b82f6; }
.cal-event-muted { opacity: .5; text-decoration: line-through; }
.cal-event-time { font-weight: 700; flex: 0 0 auto; }
.cal-event-name { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cal-dot { display: inline-block; width: .7rem; height: .7rem; border-radius: 3px; vertical-align: middle; margin-right: .15rem; }
.cal-dot-once { background: var(--tri-green); }
.cal-dot-rec { background: #3b82f6; }

/* Icon-Auswahl für MCP-Server (Admin-Formular) */
.mcp-icon-grid { display: flex; flex-wrap: wrap; gap: .4rem; }
.mcp-icon-choice {
    width: 2.2rem; height: 2.2rem; display: inline-flex; align-items: center; justify-content: center;
    border: 1px solid var(--tri-border); background: #fff; border-radius: .5rem; cursor: pointer;
    color: var(--tri-text); font-size: 1.1rem;
}
.mcp-icon-choice:hover { border-color: var(--tri-green); color: var(--tri-green); }
.mcp-icon-choice.active { background: var(--tri-green); color: #fff; border-color: var(--tri-green); }

/* Abschnittsüberschrift im Designer-Tree-Panel (z. B. „Workspaces"). */
.wfd-tree-section { padding: .5rem .5rem .15rem; font-size: .72rem; font-weight: 700; color: var(--tri-faint); text-transform: uppercase; letter-spacing: .03em; }

/* ---- Kostenbericht: modernes, animiertes Balkendiagramm (grün) ---- */
.costchart { display: grid; grid-template-columns: auto 1fr; gap: .5rem; }
.costchart-yaxis {
    display: flex; flex-direction: column; justify-content: space-between;
    height: 320px; padding-bottom: 1.6rem; /* Platz für X-Labels unten */
    font-size: .7rem; color: var(--tri-faint); text-align: right; white-space: nowrap;
}
.costchart-plot { position: relative; }
.costchart-grid {
    position: absolute; inset: 0 0 1.6rem 0; display: flex; flex-direction: column; justify-content: space-between;
    pointer-events: none;
}
.costchart-grid span { border-top: 1px dashed var(--tri-border); height: 0; }
.costchart-bars {
    position: relative; display: flex; align-items: flex-end; gap: clamp(2px, 0.5%, 10px);
    height: 320px; padding-bottom: 1.6rem;
}
.costchart-col { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; align-items: center; height: 100%; }
.costchart-track { flex: 1 1 auto; width: 100%; display: flex; align-items: flex-end; }
.costchart-bar {
    position: relative; width: 100%; height: var(--h); min-height: 2px;
    background: linear-gradient(180deg, var(--tri-green) 0%, var(--tri-green-active) 100%);
    border-radius: 6px 6px 0 0;
    transform: scaleY(0); transform-origin: bottom;
    animation: costbar-grow .6s cubic-bezier(.22,1,.36,1) forwards;
    transition: filter .15s ease;
}
.costchart-bar.is-zero { background: var(--tri-green-soft); }
.costchart-bar:hover { filter: brightness(1.08); }
.costchart-bar .costchart-val {
    position: absolute; top: -1.15rem; left: 50%; transform: translateX(-50%);
    font-size: .68rem; font-weight: 600; color: var(--tri-green-dark); white-space: nowrap;
    opacity: 0; transition: opacity .15s ease; pointer-events: none;
}
.costchart-bar:hover .costchart-val { opacity: 1; }
.costchart-xlabel {
    margin-top: .35rem; height: 1.25rem; font-size: .68rem; color: var(--tri-muted);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; text-align: center;
}
@keyframes costbar-grow { from { transform: scaleY(0); } to { transform: scaleY(1); } }

/* Ein-/Ausklapp-Link für lange Funktionslisten (MCP-Server / Tools) – kleinere Schrift */
.fn-toggle { font-size: .72rem; }

/* Zentrale Seiten-Kopfzeile (PageHeader-Komponente) – einheitliches Layout & Abstände */
.page-head {
    display: flex;
    flex-wrap: nowrap;             /* Titel + Aktionen bleiben IMMER in EINER Zeile (nie zweizeilig) */
    justify-content: flex-start;   /* der wachsende Titelbereich (page-head-main) schiebt die Aktionen nach rechts */
    align-items: center;
    gap: 0.75rem;
    margin-bottom: 1.5rem;
}
.page-head-main {
    display: flex;
    align-items: center;       /* Leading/Avatar mittig zur Überschrift */
    gap: 0.75rem;              /* Abstand Icon ↔ Titeltext */
    min-width: 0;            /* erlaubt Text-Truncation im Titel */
    flex: 1 1 auto;         /* Titelbereich schrumpft → Titel wird gekürzt, statt die Buttons zu verdrängen */
}
.page-head-icon {
    font-size: 1.45rem;
    /* Zeilenhöhe = erste Titelzeile (1.45rem × 1.25); zusammen mit align-self:flex-start
       sitzt das Icon mittig auf der ERSTEN Titelzeile (auch bei zweizeiligen Köpfen),
       statt zur Blockmitte zu rutschen. */
    line-height: 1.8rem;
    align-self: flex-start;
    color: var(--tri-green);
    flex-shrink: 0;
}
.page-head-text { min-width: 0; flex: 1 1 auto; }
.page-head-title {
    margin: 0;
    font-size: 1.45rem;
    font-weight: 700;
    color: var(--tri-text);   /* schwarzer Titel; Links (Agentennamen, Runs) behalten ihre Farbe */
    line-height: 1.25;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: nowrap;      /* Titelzeile bricht NIE um */
    min-width: 0;
    overflow: hidden;       /* Grundlage für die Ellipsis-Kürzung des Titeltexts */
}
/* Einfacher Titeltext (String-Titel): bei Platzmangel mit … gekürzt statt Umbruch. */
.page-head-title-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.page-head-title.h4 { font-size: 1.3rem; }
.page-head-title.h5 { font-size: 1.1rem; }
/* Einzeiliger Kopftitel: nicht umbrechen; ein langer (Agenten-)Name wird mit … gekürzt, die #Nr bleibt sichtbar. */
.page-head-title.is-single-line { flex-wrap: nowrap; min-width: 0; }
.page-head-title.is-single-line .agent-num { flex-shrink: 0; }
.page-head-title.is-single-line .agent-name-link {
    min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* RUN-Nummer inline hinter dem Namen: einzeilig, kleiner, bricht nicht um. */
.page-head-title.is-single-line .run-num-inline {
    flex-shrink: 0; white-space: nowrap;
    font-size: 0.8rem; font-weight: 500; margin-left: 0.15rem;
}
/* Einzeilige Kopfzeile: Titel und Aktionsbuttons bleiben in EINER Zeile (kein Umbruch der Buttons unter den
   Titel). Der Titelbereich schrumpft und kürzt den Agentennamen bei Platzmangel (siehe is-single-line). */
.page-head-1line { flex-wrap: nowrap; }
.page-head-1line .page-head-main { flex: 1 1 auto; min-width: 0; }
.page-head-1line .page-head-actions { flex: 0 0 auto; flex-wrap: nowrap; }
.page-head-sub {
    margin-top: 0.15rem;
    font-size: 0.85rem;
    color: var(--tri-muted, #6c757d);
}
.page-head-actions {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: nowrap;      /* Aktionsbuttons bleiben nebeneinander (kein Umbruch unter den Titel) */
    flex: 0 0 auto;
}
/* Die Beschriftung der Kopf-Schaltflächen eine Spur kleiner als Fließtext: Sie stehen neben einem Titel
   in 1,45 rem und wirkten in voller Größe wie eine zweite Überschrift. Das Symbol behält seine Größe –
   gekürzt wird die Schrift, nicht der Knopf. Gilt NICHT im Symbol-Modus (.ph-compact), dort steht die
   Schriftgröße auf 0. */
.page-head-actions .btn { font-size: .88rem; }
.page-head.ph-compact .page-head-actions .btn:not(.btn-keep-text) { font-size: 0; }
/* Platz im Kopf knapp (Titel würde gekürzt) → Aktionsbuttons nur noch als Symbol (Text ausgeblendet, Icon
   behält Größe). Die Klasse .ph-compact wird von der PageHeader-Komponente per JS gesetzt, sobald der Titel
   nicht mehr vollständig passt (spinalcordHeaderFit). Trick: font-size:0 lässt den Textknoten kollabieren;
   das <i>-Icon bekommt seine Größe zurück. Ausnahme: .btn-keep-text behält seinen Text. */
.page-head.ph-compact .page-head-actions .btn:not(.btn-keep-text) { font-size: 0; }
/* Zeilenhoehe ausdruecklich: Mit font-size:0 am Knopf bestimmt allein das Icon die Hoehe der Zeilenbox.
   Bootstrap-Icons (bi) erben dafuer 1,5, Tabler-Icons (ti) bringen ihre eigene Zeilenhoehe 1 mit – der
   Knopf mit dem Gehirn war dadurch 30 statt 38 Pixel hoch und stand sichtbar niedriger als seine
   Nachbarn. Der feste Wert macht alle Symbol-Knoepfe gleich hoch, unabhaengig von der Icon-Familie. */
.page-head.ph-compact .page-head-actions .btn:not(.btn-keep-text) > i { font-size: 1rem; line-height: 1.5; margin: 0 !important; }
/* DER WARTEKREISEL BRAUCHT DIESELBE BEHANDLUNG WIE DAS ICON – und zwar aus zwei Gruenden.
   (1) Bootstrap gibt ihm `border-width: .2em`. Bei `font-size: 0` am Knopf ist das NULL: Der Ring war
       unsichtbar, der Knopf sah nach dem Klick leer aus.
   (2) Seine Hoehe ist mit 1rem fest, waehrend das Icon aus 1rem x Zeilenhoehe 1,5 auf 24px kommt. Ohne
       Ausgleich schrumpfte der Knopf beim Klick um 8 Pixel und stand niedriger als seine Nachbarn.
   4px Luft oben und unten stellen die 24px wieder her. */
.page-head.ph-compact .page-head-actions .btn:not(.btn-keep-text) > .spinner-border {
    font-size: 1rem; width: 1rem; height: 1rem; border-width: 2px;
    margin: 4px 0 !important; vertical-align: top;
}

/* Memory-Inhalt: Datei-Upload per Drag&Drop (Overlay + Zonen-Hervorhebung) */
.memory-dropzone { position: relative; }
.memory-dropzone.dragging { outline: 2px dashed var(--tri-green); outline-offset: -6px; border-radius: .5rem; }
.memory-drop-overlay {
    position: absolute; inset: 0; z-index: 30; border-radius: .5rem;
    display: flex; align-items: center; justify-content: center;
    background: var(--tri-green-bg); /* leichtes Grün */
}
.memory-drop-input { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; cursor: copy; }
.memory-drop-hint {
    pointer-events: none; display: inline-flex; align-items: center;
    font-weight: 600; color: var(--tri-green-dark);
    background: #fff; border: 1px solid var(--tri-green-soft); border-radius: .5rem;
    padding: .6rem 1rem; box-shadow: 0 4px 14px rgba(0,0,0,.10);
}

/* Benachrichtigungen: gerendertes Markdown kompakt halten (kleine Überschriften/Abstände) */
.notif-md .markdown-body { font-size: .82rem; color: var(--tri-muted, #6b7280); }
.notif-md .markdown-body :is(h1,h2,h3,h4,h5,h6) { font-size: .92rem; font-weight: 600; margin: .35rem 0 .2rem; }
.notif-md .markdown-body p { margin: .2rem 0; }
.notif-md .markdown-body ul, .notif-md .markdown-body ol { margin: .2rem 0; padding-left: 1.15rem; }
.notif-md .markdown-body table { font-size: .8rem; }

/* Prompt-Editor: In-Editor-Suche. Geoeffnet wird ueber die LUPE IN DER WERKZEUGLEISTE des Editors; die
   Leiste legt sich dann rechts ueber dieselbe Zeile. Absolut positioniert, damit sie keine Zeile beansprucht:
   Sonst rutschte der Editor beim Oeffnen nach unten (Hoehensprung), und geschlossen bliebe eine leere Zeile. */
.prompt-editor { position: relative; }
.prompt-find {
    position: absolute; top: .3rem; right: .4rem; z-index: 3;
    display: flex; justify-content: flex-end; align-items: center; gap: .25rem; min-height: 1.9rem;
    background: #fff; padding-left: .6rem; border-radius: .5rem;
    box-shadow: -10px 0 10px -8px rgba(0,0,0,.12);
}
.prompt-find-input {
    width: 16rem; max-width: 60%; height: 1.9rem; padding: .1rem .5rem;
    border: 1px solid var(--tri-green-soft); border-radius: .375rem; font-size: .85rem; outline: none;
}
.prompt-find-input:focus { border-color: var(--tri-green); box-shadow: 0 0 0 .15rem rgba(var(--tri-green-rgb),.15); }
.prompt-find-count { font-size: .78rem; color: var(--tri-muted, #6b7280); min-width: 2.5rem; text-align: right; }
.prompt-find-btn {
    display: inline-flex; align-items: center; justify-content: center; width: 1.9rem; height: 1.9rem;
    border: 1px solid var(--tri-green-soft); background: #fff; border-radius: .375rem;
    color: var(--tri-green-dark); cursor: pointer;
}
.prompt-find-btn:hover:not(:disabled) { background: var(--tri-green-bg); }
.prompt-find-btn:disabled { opacity: .4; cursor: default; }
.prompt-find-ic { color: var(--tri-muted, #6b7280); margin-right: .1rem; }
/* Treffer-Hervorhebung innerhalb des CodeMirror-Editors (global, da von EasyMDE gerendert). */
.CodeMirror .ps-hit { background: rgba(253, 224, 71, .55); border-radius: 2px; }

/* ============================================================================================
   Memory-Verweise (MemoryLinks) und die Landkarte
   ============================================================================================ */
/* Eine Mindesthöhe, damit der Dialog beim ersten Verweis nicht sichtbar wächst - und eine Obergrenze,
   ab der die Liste selbst rollt statt den Dialog über den Bildschirm hinauszuschieben. */
.memlink-list { min-height: 7rem; max-height: 44vh; overflow-y: auto; }
.memlink-row {
    display: flex; align-items: flex-start; gap: .55rem;
    padding: .45rem .1rem; border-bottom: 1px solid var(--tri-border, #e7e9ec);
}
.memlink-row:last-child { border-bottom: 0; }
.memlink-ic { color: var(--tri-green); width: 1.2rem; text-align: center; flex: 0 0 1.2rem; padding-top: .1rem; }
.memlink-target { font-weight: 600; word-break: break-word; }
/* Ein Verweis, den jemand von der Gegenseite gelegt hat: Sein Anlass ist aus deren Sicht formuliert -
   das muss man sehen, sonst liest man ihn falsch herum. */
.memlink-back {
    margin-left: .4rem; font-size: .72rem; font-weight: 500; color: var(--tri-muted, #6b7280);
    border: 1px solid var(--tri-border, #e7e9ec); border-radius: 1rem; padding: 0 .4rem;
}
.memlink-add { border-top: 1px solid var(--tri-border, #e7e9ec); padding-top: .75rem; }

.memory-map { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; position: relative; }
.memory-map-bar { display: flex; align-items: center; gap: .5rem; margin-bottom: .4rem; }

/* Die Bedienleiste über der Landkarte. EINE Schriftgröße für alles – Eingabe, Knöpfe, Zähler –,
   damit die Zeile nicht nach Flickwerk aussieht. Die Knöpfe bringen ihre Höhe über `btn-sm` mit. */
.memory-map-bar { font-size: .8125rem; }
.memory-map-bar .btn, .memory-map-bar .form-control, .memory-map-bar .input-group-text { font-size: .8125rem; }
.map-bar-suche { max-width: 15rem; width: 15rem; }
.map-bar-label { color: var(--tri-muted); white-space: nowrap; }
/* Die Schalter sitzen auf derselben Grundlinie wie Eingabe und Knöpfe. Bootstraps `form-check` bringt
   einen linken Einzug und eine eigene Zeilenhöhe mit – in einer Leiste, in der alles auf einer Linie
   steht, sieht das aus wie verrutscht. */
.memory-map-bar .form-check { display: flex; align-items: center; gap: .35rem; padding: 0; margin: 0; min-height: 0; }
.memory-map-bar .form-check .form-check-input { margin: 0; float: none; }
.memory-map-bar .form-check .form-check-label { line-height: 1.2; }
.map-bar-info { color: var(--tri-muted); white-space: nowrap; }

/* Aufklappliste (Typen, Themengebiete). Sie hängt unter ihrem Knopf und schließt über die unsichtbare
   Fläche `.map-bar-schirm`, die währenddessen über der Seite liegt. */
.map-bar-pop { position: relative; }
/* Die Aufklapp-Knöpfe bleiben EINZEILIG: Bricht „5 Themengebiete" um, wächst die ganze Leiste in die
   Höhe und die Karte verliert Platz. */
.map-bar-pop .btn { white-space: nowrap; }
.map-bar-liste {
    position: absolute; left: 0; top: calc(100% + .25rem); z-index: 30;
    min-width: 16rem; max-width: 26rem; max-height: 22rem; overflow-y: auto;
    padding: .35rem; background: #fff; border: 1px solid var(--tri-border); border-radius: .4rem;
    box-shadow: 0 .5rem 1.5rem rgba(0,0,0,.18);
}
.map-bar-zeile {
    display: flex; align-items: center; gap: .5rem; margin: 0;
    padding: .28rem .45rem; border-radius: .25rem; cursor: default;
}
label.map-bar-zeile { cursor: pointer; }
label.map-bar-zeile:hover { background: var(--tri-surface); }
.map-bar-punkt { flex: 0 0 auto; width: .7rem; height: .7rem; border-radius: 50%; }
.map-bar-name { flex: 1 1 auto; color: var(--tri-text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.map-bar-zahl { flex: 0 0 auto; color: var(--tri-muted); font-variant-numeric: tabular-nums; }

/* Hinweis in der Kartenleiste, wenn die Karte NICHT jedes Dokument zeigt (zusammengefasst oder gekürzt).
   Er steht direkt neben den Filtern und nicht als Banner darüber: Eine Karte, die etwas anderes zeigt
   als sonst, muss das dort sagen, wo man ohnehin hinsieht. */
.map-bar-hinweis {
    flex: 0 0 auto;
    font-size: .8125rem;
    color: var(--tri-muted);
    white-space: nowrap;
    cursor: help;
}
.map-bar-trenner { height: 1px; background: var(--tri-border); margin: .3rem .25rem; }
.map-bar-schirm { position: fixed; inset: 0; z-index: 25; }

/* Im Vollbild hat der Kasten keinen Seitenhintergrund mehr hinter sich – er bringt ihn selbst mit,
   sonst steht die helle Bedienleiste auf Schwarz. */
.memory-map:fullscreen { background: #fff; padding: .6rem; }
.memory-map:fullscreen .memory-map-canvas { border-radius: .4rem; }

/* Feste Spaltenaufteilung: Die Namensspalte steht auf 100 % und bekommt damit alles, was die schmalen
   Spalten übrig lassen. Ohne `table-layout: fixed` verhandelt der Tabellensatz die Breiten am Inhalt –
   dann hungerte die Typspalte auf „R…" aus, während der Titel alles nahm. */
.sbc-tabelle { table-layout: fixed; }
/* Eine Zeile je Dokument: abgeschnitten statt umgebrochen. Ein zweizeiliges Themengebiet machte die
   ganze Zeile doppelt hoch. */
.sbc-titel, .sbc-eng { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* Ein <a> OHNE href erbt die Textfarbe - die Verweislisten im Dokument sahen damit aus wie eine
   Aufzählung. Diese Klasse gibt ihnen die Markenfarbe, den Zeiger und den Unterstrich beim Überfahren. */
.sbc-link { color: var(--tri-green); cursor: pointer; text-decoration: none; }
.sbc-link:hover { color: var(--tri-green-dark); text-decoration: underline; }

/* Die Zahl der Verweise ist die Schaltfläche - als Knopf gerahmt wäre die Tabelle voller Kästchen. */
.sbc-zahl { color: var(--tri-green); font-weight: 600; text-decoration: none; vertical-align: baseline; }
.sbc-zahl:hover { color: var(--tri-green-dark); text-decoration: underline; }

/* Das aufgeklappte Feld mit den Titeln. FESTE Position, weil die Dokumentliste rollt: in der Zelle
   verankert würde es am Rand des Rollbereichs abgeschnitten, bei der letzten Zeile immer. */
.sbc-pop-backdrop { position: fixed; inset: 0; z-index: 1080; }
.sbc-pop {
    position: fixed; z-index: 1081; width: 20rem; max-height: 22rem; overflow-y: auto;
    background: var(--bs-body-bg); border: 1px solid var(--tri-green-soft); border-radius: .5rem;
    box-shadow: 0 .5rem 1.5rem rgba(0, 0, 0, .18); padding: .25rem 0;
    /* Die Spalten stehen rechtsbündig; ohne diese Zeile erbt das Feld die Ausrichtung der Zelle und
       die Titel klebten am rechten Rand. */
    text-align: left;
}
.sbc-pop-kopf {
    font-size: .75rem; font-weight: 700; text-transform: uppercase; letter-spacing: .03em;
    color: var(--bs-secondary-color); padding: .35rem .75rem .25rem;
}
.sbc-pop-liste { list-style: none; margin: 0; padding: 0; }
.sbc-pop-liste li { padding: .2rem .75rem; font-size: .875rem; }
.sbc-pop-liste li:hover { background: var(--tri-green-bg); }
/* Der Canvas füllt, was die Seite ihm lässt - eine geratene vh-Höhe säße auf jedem Bildschirm anders. */
/* Schwarzer Grund: Die Kugeln und ihr Schein stehen darauf plastisch, die gestrichelten Verweise heben
   sich vom Gewirr der Zugehörigkeitslinien ab. Auf Weiß wirkte dieselbe Karte flach und grau. Der Grund
   wird ZUSÄTZLICH im Canvas gezeichnet - das Element selbst ist nur für den Moment vor dem ersten Bild. */
/* Der Entzerr-Regler liegt AUF der Karte, unten rechts: Er wirkt auf das Bild, also gehört er dorthin,
   wo man hinsieht, während man ihn bewegt. Dunkel gehalten, damit er auf schwarzem Grund nicht blendet. */
.memory-map-regler {
    position: absolute; right: .75rem; bottom: .75rem; z-index: 5;
    display: flex; align-items: center; gap: .5rem;
    padding: .3rem .6rem; border-radius: 1.2rem;
    background: rgba(18, 22, 24, .78); border: 1px solid #2c3236; color: #cdd6dc;
}
.memory-map-regler input[type=range] { width: 8rem; accent-color: var(--tri-green); }
/* Der Zahlenwert neben dem Gewichts-Regler. Feste Breite, damit die Leiste beim Schieben nicht
   zuckt - sie steht in der Ecke der Karte und wandert sonst bei jedem Schritt. */
.memory-map-reglerwert { font-size: .78rem; min-width: 2.6rem; text-align: right; }

/* ---- Die Lesekarte der Strukturkarte -----------------------------------------------------------
   Sie steht VOR dem Betrachter, rechts über der Karte: Als Flaeche im Raum konnte sie weder rollen
   noch Verweise tragen. Rechts und nicht mittig, damit die markierte Kugel links sichtbar bleibt. */
/* Die Flaeche, an der die Lesekarte haengt: Leinwand plus Karte, ohne die Werkzeugleiste darueber. */
.sbm-kartenflaeche { position: relative; flex: 1 1 auto; min-height: 24rem; display: flex; }
.sbm-kartenflaeche > .memory-map-canvas { flex: 1 1 auto; min-height: 0; }

/* Sie beginnt UNTER den schwebenden Knoepfen rechts oben (.map-ecke-schwebend, z-Wert 8) und liegt
   davor. Vorher lag sie auf derselben Hoehe und darunter - die Knoepfe schienen durch ihren Kopf. */
.sbm-lesekarte {
    position: absolute; right: .75rem; top: 3.5rem; bottom: 3.6rem; z-index: 9;
    width: min(26rem, 42%); display: flex; flex-direction: column;
    background: rgba(14, 18, 20, .94); border: 1px solid #2c3236; border-radius: .6rem;
    box-shadow: 0 .6rem 2rem rgba(0, 0, 0, .55); color: #d7dee4;
}
.sbm-lk-kopf {
    display: flex; align-items: center; gap: .5rem;
    padding: .5rem .75rem .25rem; border-bottom: 1px solid #23282b;
}
.sbm-lk-meta { display: flex; align-items: baseline; gap: .6rem; flex: 1 1 auto; min-width: 0; }
.sbm-lk-typ {
    font-size: .72rem; text-transform: uppercase; letter-spacing: .04em;
    color: var(--tri-green); font-weight: 700;
}
.sbm-lk-datum { font-size: .72rem; color: #8a959d; }
.sbm-lk-zu { background: none; border: 0; color: #8a959d; line-height: 1; cursor: pointer; padding: 0 .1rem; }
.sbm-lk-zu:hover { color: #fff; }
.sbm-lk-titel { padding: .35rem .75rem .5rem; font-weight: 700; font-size: 1rem; color: #fff; }
/* DAS ROLLEN IST DER PUNKT: `min-height: 0` ist die Bedingung dafuer, dass ein Flex-Kind ueberhaupt
   kleiner werden darf als sein Inhalt - ohne das waechst der Kasten und rollt nie. */
.sbm-lk-inhalt {
    flex: 1 1 auto; min-height: 0; overflow-y: auto;
    padding: 0 .75rem .5rem; font-size: .84rem; line-height: 1.5;
}
.sbm-lk-summary { color: #aeb9c2; font-style: italic; margin-bottom: .6rem; }
.sbm-lk-inhalt .markdown-body { color: #d7dee4; }
.sbm-lk-inhalt .markdown-body h1,
.sbm-lk-inhalt .markdown-body h2,
.sbm-lk-inhalt .markdown-body h3 { color: #fff; font-size: .95rem; margin-top: .8rem; }
.sbm-lk-inhalt .markdown-body a { color: var(--tri-green); }
.sbm-lk-inhalt .markdown-body table { font-size: .78rem; }
.sbm-lk-fuss {
    border-top: 1px solid #23282b; padding: .45rem .75rem;
    max-height: 11rem; overflow-y: auto; flex: 0 0 auto;
}
.sbm-lk-fusstitel {
    font-size: .7rem; text-transform: uppercase; letter-spacing: .04em; color: #8a959d;
    margin: .2rem 0 .25rem;
}
.sbm-lk-verweise { display: flex; flex-wrap: wrap; gap: .3rem; }
.sbm-lk-verweis {
    background: rgba(var(--tri-green-rgb), .14); border: 1px solid rgba(var(--tri-green-rgb), .45);
    color: #7ed08c; border-radius: .8rem; padding: .1rem .5rem; font-size: .76rem;
    cursor: pointer; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.sbm-lk-verweis:hover { background: rgba(var(--tri-green-rgb), .3); color: #fff; }
.sbm-lk-knopf { padding: .5rem .75rem; border-top: 1px solid #23282b; text-align: right; }
.memory-map-regler button {
    background: none; border: 0; color: #cdd6dc; padding: 0 .15rem; line-height: 1; cursor: pointer;
}
.memory-map-regler button:hover { color: #fff; }

/* HELLE FASSUNG der Reglerleiste – gilt in der 3D-Wolke, solange „Dark Mode" aus ist. Auf heller
   Szene war die fast schwarze Kapsel der einzige dunkle Fleck im ganzen Bild und sah aus wie ein
   vergessenes Stück aus der dunklen Ansicht. Sie bekommt deshalb dieselbe Gestalt wie die
   schwebenden Kapseln im Designer (Zoom, „Am Raster ausrichten"): milchiges Weiß mit leichter
   Weichzeichnung, Hausrahmen, gedämpfte Schrift. Was darunter liegt, bleibt zu erkennen.
   Die dunkle Fassung oben bleibt die Vorgabe: Brain- und Strukturkarte stehen immer auf Schwarz. */
.memory-map-regler.is-light {
    background: rgba(255, 255, 255, .5);
    -webkit-backdrop-filter: blur(4px);
    backdrop-filter: blur(4px);
    border-color: var(--tri-border);
    color: var(--tri-text);
    box-shadow: 0 1px 4px rgba(0, 0, 0, .08);
}
.memory-map-regler.is-light > i { color: var(--tri-muted); }
.memory-map-regler.is-light button { color: var(--tri-muted); }
.memory-map-regler.is-light button:hover { color: var(--tri-text); }

.memory-map-canvas {
    flex: 1 1 auto; min-height: 24rem; width: 100%;
    /* Dieselbe Rundung wie jede Karte im Haus (.75rem) - die Strukturkarte ist eine Kachel unter
       dem Register und soll nicht als einzige Flaeche aus der Reihe fallen. */
    border: 1px solid #23282b; border-radius: .75rem;
    background: #0b0d0c; touch-action: none; cursor: grab;
}

/* In einer Voll-Hoehe-Seite bestimmt die Flex-Kette die Hoehe, nicht eine geratene Mindesthoehe:
   24rem schoben die Kachel bei kleinem Fenster unter den Fensterrand. */
.memory-map.page-fill .sbm-kartenflaeche,
.memory-map.page-fill .memory-map-canvas { min-height: 0; }

/* Tool-Typ-Auswahl (Popup „Neues Tool"): Beschreibung je Eintrag auf max. 2 Zeilen begrenzen. */
.tool-type-desc {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* Aufgaben-Register auf der Lauf-Detailseite: je Aufgabe eine Karte mit Feldern (Instructions, Ergebnis …). */
/* ---- Register „Aufgaben": je Aufgabe EINE Zeile, keine Kachel ----
   Links der Nummernkreis, rechts Titel mit Zustand, darunter Herkunft und Ergebnis. Prompt und
   vollständiges Ergebnis stehen NEBENEINANDER, nicht untereinander: Sie gehören zusammen, und so
   sieht man Auftrag und Antwort in einem Blick. Schriftgrade bleiben wie zuvor. */
.tsk-hinweis { color: var(--tri-muted); font-size: .82rem; margin-bottom: .9rem; }
.tsk { display: flex; flex-direction: column; }
.tsk-row { display: flex; gap: .85rem; padding: 1rem .25rem; border-bottom: 1px solid var(--tri-border); }
.tsk-row:last-child { border-bottom: 0; }
.tsk-num {
    flex: 0 0 auto; width: 1.7rem; height: 1.7rem; border-radius: 50%;
    display: inline-flex; align-items: center; justify-content: center;
    background: var(--tri-surface); color: var(--tri-muted); font-size: .8rem; font-weight: 700;
}
.tsk-num.is-ok { background: var(--tri-green-bg); color: var(--tri-green); }
.tsk-num.is-err { background: #fdeceb; color: #8d2b22; }
.tsk-main { min-width: 0; flex: 1 1 auto; }
.tsk-head { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; }
.tsk-title { font-weight: 600; font-size: 1rem; color: var(--tri-text); }
.tsk-modell { font-size: .76rem; color: var(--tri-muted); background: var(--tri-surface); border-radius: .4rem; padding: .05rem .45rem; }
/* Der Verweis auf den Sub-Lauf steht rechts außen – `margin-left: auto` statt eines Platzhalters. */
.tsk-runlink {
    margin-left: auto; flex: 0 0 auto; font-size: .82rem; color: var(--tri-muted); text-decoration: none;
    border: 1px solid var(--tri-border); border-radius: .5rem; padding: .15rem .55rem; white-space: nowrap;
}
.tsk-runlink:hover { color: var(--tri-green); border-color: var(--tri-green); }
.tsk-meta { color: var(--tri-muted); font-size: .78rem; margin: .25rem 0 .55rem; }
.tsk-id { font-weight: 600; }
.tsk-ergebnis { display: flex; align-items: baseline; gap: .7rem; background: var(--tri-surface); border-radius: .5rem; padding: .5rem .75rem; }
.tsk-ergebnis.is-error { background: #fdeceb; color: #8d2b22; }
.tsk-ergebnis-label { flex: 0 0 auto; font-size: .78rem; color: var(--tri-muted); }
.tsk-ergebnis-text { min-width: 0; font-size: .9rem; }
.tsk-ergebnis-text .markdown-body { font-size: .9rem; }
/* Zwei Spalten ab mittlerer Breite, darunter untereinander – gezwungen nebeneinander würde beides zu schmal. */
.tsk-spalten { display: grid; grid-template-columns: repeat(auto-fit, minmax(22rem, 1fr)); gap: 1rem; margin-top: .75rem; }
.tsk-feld { min-width: 0; }
.tsk-feld-label { font-size: .78rem; color: var(--tri-muted); margin-bottom: .25rem; }
.tsk-box { background: var(--tri-surface); border-radius: .5rem; padding: .6rem .8rem; font-size: .9rem; }
.tsk-box.is-ok { background: var(--tri-green-bg); }
.tsk-box .markdown-body { font-size: .9rem; }
.tsk-schalter { background: none; border: 0; padding: 0; margin-top: .6rem; font-size: .88rem; color: var(--tri-green); cursor: pointer; }
.tsk-schalter:hover { text-decoration: underline; }
.tsk-schalter:disabled { color: var(--tri-faint); cursor: default; text-decoration: none; }

/* ---------- Hinweisbänder am unteren Rand (Wartung, Budget, Plattenplatz) ----------
   Alle Bänder liegen in EINEM Behälter (.app-banners) als letztes Element des Inhaltsbereichs.
   Der Behälter klebt am Fensterrand (position: sticky), steht dabei aber im normalen Fluss und
   belegt echten Platz. Deshalb kann er nichts dauerhaft verdecken: Wer bis ans Seitenende scrollt,
   sieht die letzte Schaltfläche (z. B. „Speichern") vollständig über dem Band.

   Vorher hing jedes Band einzeln `position: fixed` über dem Inhalt, und der reservierte Platz war
   ein fester Wert (3rem). Bei zwei Bändern oder umbrechendem Text reichte er nicht – die letzte
   Schaltfläche einer Seite lag unerreichbar darunter. Das war der Grund für die Umstellung.

   Weil der Behälter im Inhaltsbereich sitzt, entfällt auch das Einrücken um die Sidebar-Breite
   samt der Sonderfälle für schmale Sidebar und Mobilgeräte. Ersetzt NICHT das Seiten-Kopfband. */
.app-banners {
    position: sticky;
    bottom: 0;
    z-index: 1050;
    display: flex;
    flex-direction: column;
    /* Schiebt die Bänder auf einer kurzen Seite an den unteren Fensterrand. `sticky` allein genügt
       dafür nicht: Es hält ein Element nur INNERHALB des Flusses fest, hebt es aber nie über seine
       natürliche Stelle hinaus. Endete der Inhalt auf halber Höhe, hing das Band genau dort. */
    margin-top: auto;
}
/* DUNKLES BAND, WEISSE SCHRIFT - derselbe Hausstandard wie der Kopf jedes Dialogs (`user-modal-head`).
   Vorher trug jedes Band seine eigene helle Flaeche (Gelb, Rot, Gruen) mit dunkler Schrift. Auf einer
   hellen Seite verschwimmt so ein Band mit dem Inhalt; genau das soll es nicht. Die Art der Meldung sagt
   jetzt das SYMBOL-ABZEICHEN in seiner Farbe, nicht die ganze Flaeche - die Aussage bleibt, das Geschrei
   entfaellt. */
.maintenance-footer {
    display: flex;
    align-items: center;
    gap: 0.7rem;
    margin: 0 .75rem .75rem;
    padding: 0.6rem 1rem;
    background-color: #1b1c1d;
    color: #e6ecf2;
    border: 0;
    border-radius: 0.85rem;
    font-size: 0.9rem;
    box-shadow: 0 .4rem 1.2rem rgba(0, 0, 0, 0.25);
}
/* Der fette Anfang ist die Ueberschrift des Bandes - sie steht in Weiss, der Rest etwas zurueckgenommen.
   So liest man zuerst, WAS los ist, und danach die Erlaeuterung. */
.maintenance-footer strong { color: #fff; margin-right: .35rem; }
/* Das Symbol sitzt in einem runden Abzeichen; seine Farbe traegt die Bedeutung. */
.maintenance-footer .bi {
    flex: 0 0 auto;
    font-size: 1rem;
    width: 1.9rem;
    height: 1.9rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    background: rgba(224, 168, 0, .18);
    color: #e0a800;
}
/* Knapper Plattenplatz: hier droht Datenverlust, nicht bloss eine Wartepause - deshalb Rot am Abzeichen.
   Steht im Stapel ganz oben, er ist der dringendere Hinweis. */
.maintenance-footer.lowdisk-footer .bi { background: rgba(220, 53, 69, .20); color: #ff8b8b; }
/* Aufgebrauchtes Budget: kein Fehler, sondern eine Grenze mit Ausweg - deshalb der Markenton statt Rot,
   und der Weg zur Erweiterung steht als Schaltflaeche mitten im Satz. */
.maintenance-footer.budget-footer .bi { background: rgba(var(--tri-green-rgb), .22); color: #85bb8e; }
.maintenance-footer.budget-footer .budget-more {
    color: #85bb8e;
    font-weight: 600;
    text-decoration: underline;
}
.maintenance-footer.budget-footer .budget-more:hover { color: #a8d4af; }

/* --- Designer-Panel: Register Browser | KI-Assistent ------------------------------------ */
/* Register im Panel-Kopf: beide Reiter teilen die Breite, damit nichts aus dem schmalen Panel laeuft.
   Die Andock-Symbole sitzen rechtsbuendig und zaehlen nicht zur Breitenaufteilung. */
.wfd-tree-tabs { flex: 0 0 auto; margin: 0; flex-wrap: nowrap; align-items: center; }
.wfd-tree-tabs .nav-item { flex: 1 1 0; min-width: 0; }
.wfd-tree-tabs .nav-item.wfd-tree-pin { flex: 0 0 auto; margin-left: auto; display: flex; gap: .1rem;
    padding: 0 .35rem; }
/* Durchgehend dunkelgrau; der aktive Zustand wird durch eine dezente Flaeche gezeigt, nicht durch Farbe. */
.wfd-dockbtn { border: 0; background: none; padding: .2rem .3rem; border-radius: .3rem; line-height: 1;
    color: var(--tri-muted-2); cursor: pointer; }
.wfd-dockbtn:hover { background: var(--tri-green-bg); color: var(--tri-text); }
.wfd-dockbtn.on { background: var(--tri-border); color: var(--tri-text); }
/* Kein eigenes Icon fuer "unten angedockt" - das Leisten-Symbol um 90 Grad gedreht zeigt es. */
.wfd-dockbtn-rot > i { display: inline-block; transform: rotate(90deg); }
.wfd-tree-tabs .nav-link { width: 100%; font-size: .78rem; padding: .45rem .3rem;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Der KI-Bereich fuellt die Panel-Hoehe und scrollt innen (fill-col/fill-grow-Muster). */
.wfd-tree-ai { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
.aip { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; background: #fff; }
.aip-thread { flex: 1 1 auto; min-height: 0; overflow-y: auto; padding: .5rem .6rem; }
/* Kopfzeile des KI-Assistenten: links der Agent im Dialog, rechts die beiden Neuanfaenge. */
.aip-head { flex: 0 0 auto; display: flex; align-items: center; gap: .35rem;
    padding: .4rem .6rem; border-bottom: 1px solid var(--tri-border); background: #fff; }
.aip-head-who { flex: 1 1 auto; min-width: 0; display: flex; align-items: center; gap: .35rem;
    font-size: .82rem; overflow: hidden; }
.aip-head-name { font-weight: 600; color: var(--tri-green-dark);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.aip-head-none { color: var(--tri-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.aip-head .btn { flex: 0 0 auto; white-space: nowrap; font-size: .74rem; padding: .15rem .4rem; }
/* Was die KI gerade geaendert hat, waehrend sie noch arbeitet. */
.aip-progress { margin-top: .25rem; font-size: .74rem; color: var(--tri-green-dark); font-style: italic; }
.aip-hint { font-size: .82rem; color: var(--tri-muted); padding: .6rem .2rem; }
.aip-hint-title { font-weight: 600; color: var(--tri-text); margin-bottom: .35rem; }
.aip-draft { flex: 0 0 auto; border-top: 1px solid var(--tri-border); background: var(--tri-green-bg); }
.aip-draft-head { display: flex; align-items: center; gap: .4rem; width: 100%; border: 0; background: none;
    padding: .45rem .6rem; font-size: .8rem; font-weight: 600; color: var(--tri-green-dark); cursor: pointer; }
.aip-draft-len { margin-left: auto; font-weight: 400; color: var(--tri-muted); font-variant-numeric: tabular-nums; }
.aip-draft-body { padding: 0 .6rem .4rem; background: #fff; }
.aip-draft-foot { padding: 0 .6rem .5rem; }
.aip-composer { flex: 0 0 auto; border-top: 1px solid var(--tri-border); padding: .5rem .6rem .6rem; background: #fff; }

/* "Neuer Chat" und die Anzahl der Beitraege stehen in der Sende-Leiste, linksbuendig zu den
   Sprechblasen; der Sende-Knopf bleibt per ms-auto rechts. */
.aip-bar-info { font-size: .76rem; color: var(--tri-muted); font-variant-numeric: tabular-nums; }

/* „Verlauf der Bearbeitung" der KI-Assistenten: die Werkzeuge, die die KI gerade aufruft. Bewusst schlicht
   und schmal - er soll beim Warten Auskunft geben, nicht die Antwort verdrängen. */
/* ---- Wartezustand der KI-Assistenten (AiLiveProgress) ---------------------------------------------
   Ohne Balken und ohne Punkt: „Es laeuft" sagt der pulsierende Avatar, „wie weit" sagen die Zahlen
   (Dauer, Schritte, Zeichen). Drei Bewegungen nebeneinander machten aus dem Warten ein Flimmern. */
.ai-live { margin-top: 0; }
.ai-live-meta {
    display: flex;
    gap: .5rem;
    margin-top: 0;
    /* Enge Zeile: Die Zahlen gehören zur Zeile „KI denkt nach …" darüber und sollen wie deren
       Unterzeile wirken, nicht wie ein eigener Absatz. */
    line-height: 1.15;
    font-size: .72rem;
    color: var(--tri-muted);
    font-variant-numeric: tabular-nums;
}
.ai-live-meta > span + span::before { content: "· "; }

.ai-steps {
    list-style: none;
    margin: 0.4rem 0 0;
    padding: 0;
    font-size: 0.78rem;
    max-height: 9rem;
    overflow-y: auto;
}
.ai-steps li {
    color: var(--bs-secondary-color, #6c757d);
    padding: 0.05rem 0;
    /* Bündig mit dem „KI denkt nach …" darüber - der Pfeil hing vorher davor und schob die Zeile ein. */
    margin: 0;
    text-align: left;
}
.ai-steps li::after {
    content: " …";
    opacity: 0.6;
}

/* ---- Spracheingabe (VoiceInputButton) --------------------------------------------------------------
   Der Ring um den Knopf folgt der Aussteuerung: voice-input.js schreibt --voice-level (0…1) auf das
   Element. Der Anwender muss sehen, DASS zugehört wird - eine stumme Aufnahme merkt man sonst erst am
   leeren Ergebnis. */
.voice-wrap { position: relative; display: inline-flex; }

.voice-btn {
    width: 2.3rem;
    height: 2.3rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.3rem;
    border: 1px solid var(--tri-border);
    border-radius: 0.65rem;
    background: var(--tri-surface);
    color: var(--tri-muted);
    font-size: 1.05rem;
    transition: background 0.15s, color 0.15s, border-color 0.15s;
}

/* Grün beim Überfahren nur im Ruhezustand - während der Aufnahme muss der Knopf rot bleiben, sonst wird
   der Stopp-Knopf unter dem Mauszeiger grün und sieht aus wie „starten". */
.voice-btn:hover:not(:disabled):not(.voice-btn-rec) { color: var(--tri-green); border-color: var(--tri-green); }
.voice-btn:disabled { opacity: 0.45; }

/* Während der Aufnahme: rot, breiter (die Laufzeit steht daneben) und mit dem Pegelring. */
.voice-btn-rec {
    width: auto;
    padding: 0 0.6rem;
    background: rgba(192, 57, 43, 0.10);
    border-color: var(--tri-red);
    color: var(--tri-red);
    box-shadow: 0 0 0 calc(var(--voice-level, 0) * 0.45rem) rgba(192, 57, 43, 0.22);
}

.voice-btn-rec:hover { background: rgba(192, 57, 43, 0.16); }

.voice-time { font-size: 0.78rem; font-weight: 600; font-variant-numeric: tabular-nums; }

/* Hinweis (kein Mikrofon, nichts zu hören, …): schwebt über dem Knopf, damit die Eingabezeile beim
   Erscheinen nicht springt. */
.voice-hint {
    position: absolute;
    bottom: calc(100% + 0.35rem);
    right: 0;
    z-index: 5;
    max-width: 17rem;
    width: max-content;
    padding: 0.3rem 0.5rem;
    border-radius: 0.4rem;
    background: var(--tri-ink);
    color: #fff;
    font-size: 0.75rem;
    line-height: 1.25;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.18);
}

/* Rückfragen: Dringlichkeit und verstrichene Frist. Farbe kommt aus den zentralen Tokens. */
.q-urgent { color: var(--tri-red); }
.q-overdue { color: var(--tri-red); font-weight: 600; }

/* ---- Rückfragen als Arbeitsliste ------------------------------------------------------------------
   Kein Datengitter: großzügige Karten, die Frage als Hauptzeile, das Beiwerk gedämpft darunter, rechts
   die Frist. Was oben steht, ist dran. */

/* Werkzeugleiste: Suche + Chips mit Zählern - man sieht, wie viel hinter einem Filter steckt, bevor
   man ihn setzt. */
.q-toolbar { display:flex; align-items:center; flex-wrap:wrap; gap:.6rem; margin-bottom:1.1rem; }
.q-search { position:relative; flex:1 1 22rem; max-width:34rem; }
.q-search > .bi-search { position:absolute; left:.9rem; top:50%; transform:translateY(-50%);
    color:var(--tri-faint); font-size:.85rem; pointer-events:none; }
.q-search .form-control { border-radius:2rem; padding:.6rem 2.4rem .6rem 2.5rem; border-color:var(--tri-border);
    background:#fff; font-size:.95rem; }
.q-search .form-control:focus { border-color:var(--tri-green); box-shadow:0 0 0 .18rem rgba(var(--tri-green-rgb),.12); }
.q-search-clear { position:absolute; right:.7rem; top:50%; transform:translateY(-50%); border:0;
    background:transparent; color:var(--tri-faint); font-size:.8rem; line-height:1; padding:.2rem; }
.q-search-clear:hover { color:var(--tri-text); }

/* Sortierung: zwei Möglichkeiten, mehr braucht eine Arbeitsliste nicht. Als Segmentschalter statt
   Auswahlfeld - man sieht beide Zustände und trifft mit einem Klick. */
/* Rechtsbündig (margin-left:auto) und exakt so hoch wie das Suchfeld daneben (align-self:stretch):
   Die Knöpfe füllen die Höhe und zentrieren ihren Text, statt mit eigener Polsterung eine Höhe zu
   raten, die dann doch ein paar Pixel neben dem Suchfeld liegt. */
.q-sort { display:inline-flex; border:1px solid var(--tri-border); border-radius:2rem; overflow:hidden;
    background:#fff; margin-left:auto; align-self:stretch; }
.q-sort button { border:0; background:transparent; color:var(--tri-muted); font-size:.9rem;
    padding:0 1rem; line-height:1; display:inline-flex; align-items:center;
    transition:background .12s, color .12s; }
.q-sort button + button { border-left:1px solid var(--tri-border); }
.q-sort button:hover { color:var(--tri-green-dark); }
.q-sort button.on { background:var(--tri-green-bg); color:var(--tri-green-dark); font-weight:600; }

/* Gruppenkopf: leise Zwischenzeile mit auslaufender Linie, kein fetter Balken. */
.q-group-head { display:flex; align-items:center; gap:.6rem; margin:1.6rem 0 .6rem;
    font-size:.78rem; font-weight:700; letter-spacing:.06em; text-transform:uppercase; color:var(--tri-muted); }
.q-group-head:first-child { margin-top:.2rem; }
.q-group-count { display:inline-block; min-width:1.4rem; padding:.05rem .4rem; border-radius:1rem;
    background:var(--tri-surface); color:var(--tri-muted); font-size:.78rem; font-weight:700; text-align:center; }
.q-group-rule { flex:1 1 auto; height:1px; background:var(--tri-border); }

.q-item { border:1px solid var(--tri-border); border-radius:.9rem; margin-bottom:.7rem;
    background:#fff; transition:border-color .12s, box-shadow .12s; }
.q-item:hover { border-color:var(--tri-green-soft); box-shadow:0 2px 8px rgba(0,0,0,.05); }
.q-item-open { border-color:var(--tri-green); box-shadow:0 2px 10px rgba(0,0,0,.07); }

.q-item-head { display:flex; align-items:center; gap:.9rem; padding:1rem 1.1rem; cursor:pointer; }

/* Marker: kurzer Balken INNEN mit Abstand zur Kante. Als Rahmen wirkte er an der Rundung wie ein Klecks. */
.q-marker { flex:0 0 auto; width:4px; align-self:stretch; min-height:2.4rem; border-radius:2px;
    background:var(--tri-green-soft); }
.q-marker-urgent { background:var(--tri-red); }

.q-item-body { flex:1 1 auto; min-width:0; }
.q-item-title { font-size:.95rem; font-weight:400; color:var(--tri-text); line-height:1.35;
    overflow:hidden; text-overflow:ellipsis; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; }
.q-item-meta { font-size:.88rem; color:var(--tri-muted); margin-top:.4rem;
    display:flex; align-items:center; flex-wrap:wrap; gap:.1rem; }
.q-meta-strong { color:var(--tri-muted-2); }
.q-sep { color:var(--tri-faint); margin:0 .45rem; }
.q-agent-num { display:inline-block; margin-right:.5rem; padding:.12rem .45rem; border-radius:.4rem;
    background:var(--tri-green-bg); color:var(--tri-green); font-weight:700; font-size:.85rem; }

/* „DRINGEND" ist das EINZIGE Dringlichkeitssignal im Text - dazu der rote Marker links. */
.q-badge-urgent { display:inline-block; margin-left:.55rem; padding:.12rem .45rem; border-radius:.35rem;
    background:rgba(192,57,43,.09); color:var(--tri-red); font-size:.72rem; font-weight:700;
    letter-spacing:.06em; text-transform:uppercase; vertical-align:.12em; white-space:nowrap; }

/* Frist nur, wenn sie drängt: rotes Badge in der Machart von „DRINGEND". */
.q-due-badge { flex:0 0 auto; display:inline-flex; align-items:center; padding:.2rem .55rem; border-radius:.35rem;
    background:rgba(192,57,43,.09); color:var(--tri-red); font-size:.8rem; font-weight:600;
    white-space:nowrap; font-variant-numeric:tabular-nums; }

/* Standard-Button (btn btn-sm btn-primary) – hier nur: nicht schrumpfen, nicht umbrechen. */
.q-answer { flex:0 0 auto; white-space:nowrap; }

.q-item-detail { border-top:1px solid var(--tri-border); padding:1rem 1.1rem; }

@media (max-width: 760px) {
    .q-item-head { flex-wrap:wrap; }
}

/* Mehrere Empfänger: kleiner Hinweis, dass die erste Antwort für alle gilt. */
.q-first-wins { margin-left:.45rem; padding:.05rem .35rem; border-radius:.35rem;
    background:var(--tri-green-bg); color:var(--tri-green-dark); font-size:.72rem; font-weight:600; }


/* ============================================================================
   MEMORY-VERLAUF: Name einzeilig mit „…", Pfad klein darunter.
   Ein Titel wie „Klärung Risikoteilung Abrechenbarkeits-Staffel / Zielvereinbarung Joachim Lemke" brach
   sonst über zwei Zeilen und schob die Tabelle auseinander. Die Breitenangabe ist nötig, weil
   text-overflow in einer Tabellenzelle ohne begrenzte Breite nicht greift.
   ============================================================================ */
.mc-hist-table { table-layout: fixed; width: 100%; }
.mc-hist-cell { min-width: 0; }
/* Sinnbild und Name in EINER Zeile; min-width:0 ist die Bedingung dafür, dass ein Flex-Kind
   überhaupt schrumpfen darf - ohne das wächst es über die Spalte hinaus. */
.mc-hist-line { display: flex; align-items: baseline; gap: .35rem; min-width: 0; }
.mc-hist-name {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.mc-hist-path {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
/* Art des Eintrags („Word", „PDF", „Text") vor dem Pfad – ruhig, aber unterscheidbar. */
.mc-hist-type {
    display: inline-block;
    padding: 0 .3rem;
    margin-right: .35rem;
    border: 1px solid var(--bs-border-color, #dee2e6);
    border-radius: .25rem;
    font-size: .78em;
    color: var(--bs-secondary-color, #6c757d);
    background: var(--bs-tertiary-bg, #f8f9fa);
}
/* Die Registerfläche der Änderungsansicht: feste Höhe, damit der Dialog beim Wechseln zwischen
   „Ansicht" und „Änderungen" nicht springt; gerollt wird nur hier drin. */
.mc-diff-pane {
    height: 52vh;
    overflow: auto;
}


/* Suche im Register „System-Prompt" (Lauf-Detailseite): alle Fundstellen markiert, die aktuelle
   hervorgehoben – dieselbe Lesart wie in einem Editor, damit die Pfeiltasten sichtbar wirken. */
mark.prompt-hit-current {
    background: var(--tri-green);
    color: #fff;
}

/* ---------------------------------------------------------------------------------------------
   Gescheiterter Start (js/boot-lang.js)

   Greift, BEVOR Blazor lebt – also ohne Komponenten, ohne Ressourcen, ohne Farbschema aus dem
   Benutzerprofil. Deshalb ausschliesslich die zentralen Token und nichts, was die Anwendung selbst
   erst setzen wuerde. Die Alternative waere ein ewiger Spinner ohne Text; genau das war der Fehler.
   --------------------------------------------------------------------------------------------- */
.boot-failed {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 100vh;
    padding: 16px;
}

.boot-failed-box {
    max-width: 34rem;
    text-align: center;
}

.boot-failed-title {
    font-size: 1.35rem;
    font-weight: 600;
    margin-bottom: .75rem;
}

.boot-failed-text {
    color: var(--tri-muted, #6c757d);
    margin-bottom: 1.25rem;
}

.boot-failed-detail {
    margin-top: 1.25rem;
    font-size: .8rem;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    color: var(--tri-muted, #6c757d);
    word-break: break-word;
}

/* ---------------------------------------------------------------------------------------------
   QR-Scanner (Components/QrScanDialog.razor)

   Die Buehne hat eine FESTE Hoehe. Sie an das Kamerabild zu koppeln waere der naheliegende Fehler:
   Der Dialog spraenge in dem Moment auf, in dem die Kamera ihre Aufloesung meldet – und das ist
   genau das, was der Popup-Hausstandard verbietet.
   --------------------------------------------------------------------------------------------- */
.qr-scan-stage {
    position: relative;
    width: 100%;
    height: 17rem;
    border-radius: .5rem;
    overflow: hidden;
    background: #1b1c1d;
}

.qr-scan-video {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

/* Zielmarke: nur die vier Ecken. Ein voller Rahmen sieht aus wie ein Bildrand und sagt nicht,
   wohin man halten soll. */
.qr-scan-frame {
    position: absolute;
    inset: 15% 20%;
    border: 2px solid rgba(255, 255, 255, .9);
    border-radius: .35rem;
    box-shadow: 0 0 0 100vmax rgba(0, 0, 0, .35);
    pointer-events: none;
}

/* Der Lizenzschlüssel steht über die volle Breite: Er ist lang, und umbrochene Gruppen lassen sich
   schlechter mit dem Lieferschein vergleichen. */
.lic-key-input {
    font-variant-ligatures: none;
    letter-spacing: .02em;
}

/* ---------------------------------------------------------------------------------------------
   Lizenzzertifikat (Components/LicenseCertificateCard.razor)

   Eine gruene Urkunde statt einer Feldliste: Eine Lizenz ist ein Beleg, und sie soll aussehen wie
   einer. Weisse Schrift auf Gruen traegt keine Ampelfarben – der Hinweis auf eine knappe
   Restlaufzeit steckt deshalb in einem Abzeichen neben dem Datum, nicht in der Textfarbe.
   --------------------------------------------------------------------------------------------- */
.lic-cert {
    max-width: 46rem;
    border-radius: 1rem;
    overflow: hidden;
    background: var(--tri-green);
    color: #fff;
    box-shadow: 0 10px 24px rgba(0, 0, 0, .12);
}

.lic-cert-head {
    display: flex;
    align-items: center;
    gap: .9rem;
    padding: 1.4rem 2rem 1.1rem;
    font-size: 1.7rem;
    font-weight: 700;
    border-bottom: 2px solid rgba(255, 255, 255, .35);
}
.lic-cert-head .bi { font-size: 1.7rem; }

.lic-cert-body { padding: 1.5rem 2rem 1.75rem; }

/* Zwei Spalten; auf schmalem Schirm untereinander. */
.lic-cert-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0 2.5rem;
    padding-bottom: .85rem;
    margin-bottom: .85rem;
    border-bottom: 1px solid rgba(255, 255, 255, .22);
}
.lic-cert-cell { display: flex; align-items: baseline; gap: 1.25rem; }
.lic-cert-cell-wide { grid-column: 1 / -1; }

.lic-cert-label {
    flex: 0 0 8.5rem;
    font-size: .7rem;
    font-weight: 600;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, .82);
}
.lic-cert-value { font-size: 1.05rem; font-weight: 700; }

@media (max-width: 575.98px) {
    .lic-cert-row { grid-template-columns: 1fr; gap: .6rem 0; }
    .lic-cert-cell { flex-direction: column; gap: .1rem; }
    .lic-cert-label { flex: none; }
}

.lic-cert-key {
    margin: 1.1rem 0 1.25rem;
    padding: .9rem 1.1rem;
    border: 1px solid rgba(255, 255, 255, .35);
    border-radius: .65rem;
    background: rgba(255, 255, 255, .08);
}
.lic-cert-key .lic-cert-label { display: block; flex: none; margin-bottom: .4rem; }
.lic-cert-key-value {
    display: block;
    color: #fff;
    font-size: 1rem;
    letter-spacing: .04em;
    word-break: break-all;
}

.lic-cert-foot {
    display: flex;
    align-items: center;
    padding-top: .9rem;
    border-top: 1px solid rgba(255, 255, 255, .22);
    font-size: .95rem;
}

/* ---- Assistent (Components/LicenseWizardDialog.razor) ---- */
.lic-steps {
    display: flex; gap: 1.5rem; flex-wrap: wrap;
    list-style: none; padding: 0; margin: 0 0 1.25rem;
}
.lic-step { display: flex; align-items: center; gap: .5rem; color: var(--tri-muted, #6c757d); }
.lic-step-num {
    display: inline-flex; align-items: center; justify-content: center;
    width: 1.6rem; height: 1.6rem; border-radius: 50%;
    background: #e9ecef; font-size: .8rem; font-weight: 700;
}
.lic-step.is-current { color: inherit; font-weight: 600; }
.lic-step.is-current .lic-step-num { background: var(--tri-green); color: #fff; }
.lic-step.is-done .lic-step-num { background: var(--tri-green); color: #fff; }

.lic-act-input { max-width: 16rem; }
.lic-done-icon { font-size: 3.5rem; }

/* Leerzustand der Lizenzseite und die Gegenüberstellung. */
.lic-empty {
    max-width: 46rem;
    padding: 2.5rem 2rem;
    text-align: center;
    border: 1px dashed var(--bs-border-color, #dee2e6);
    border-radius: .75rem;
}
.lic-empty-icon { font-size: 2.5rem; color: var(--tri-muted, #6c757d); }
.lic-compare { max-width: 46rem; }

/* Der QR-Code im Lizenzassistenten. OHNE feste Kante rendert das PNG von QRCoder in Naturgroesse
   (8 Pixel je Modul) und schiebt sich aus dem Dialog – genau das ist passiert. `max-width` allein
   genuegt nicht, weil das Bild quadratisch bleiben muss. */
.lic-qr {
    width: 100%;
    max-width: 200px;
    height: auto;
    aspect-ratio: 1 / 1;
    image-rendering: pixelated;   /* ein QR-Code darf nicht weichgezeichnet werden */
}

/* Die Freischalt-Adresse ist lang und hat keine Leerzeichen – ohne Umbruch sprengt sie die Spalte. */
.lic-act-link {
    display: inline-block;
    max-width: 100%;
    word-break: break-all;
}

/* Belegung neben dem Lizenzzertifikat: zwei Zahlen nebeneinander, auf schmalen Schirmen untereinander. */
.lic-usage {
    display: flex;
    flex-wrap: wrap;
    gap: 1.5rem;
    font-size: .9rem;
    color: var(--tri-text-muted, #6c757d);
}

/* ============================================================================================
   Agent Desk: Kacheln zum Starten von Agenten.

   GLOBAL statt bereichsbezogen (ab 2.0.531): Die Kachel erscheint an ZWEI Stellen - auf der Seite
   und als Vorschau im Einstellungsdialog. Ein bereichsbezogenes Stylesheet gilt nur fuer seine
   eigene Komponente; die Vorschau saehe damit anders aus als das Ergebnis, und genau das soll sie
   nicht. Die Klassennamen sind mit `desk-` eindeutig genug fuer den globalen Geltungsbereich.
   ============================================================================================ */
/* Agent Desk: Kacheln zum Starten von Agenten. Optik-Vorbild sind die Chat-Agentenkacheln (app.css),
   Schatten und Radius wie die Dashboard-Karten. Farben ausschließlich über die zentralen Tokens. */
.desk-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
    gap: 1.1rem;
}

.desk-tile {
    position: relative;
    display: flex;
    flex-direction: column;
    /* Inhalt beginnt OBEN. Vorher stand er unten (justify-content: flex-end) und wanderte damit je nach
       Laenge der Erklaerung und je nachdem, ob ein Hinweisschild eingeblendet war, auf eine andere Hoehe –
       nebeneinander liegende Kacheln hatten ihre Ueberschrift dann nicht auf einer Linie. Die
       Schaltflaechen bleiben unten, dafuer sorgt `margin-top: auto` am Fuss. */
    justify-content: flex-start;
    gap: .6rem;
    min-height: 12.5rem;
    padding: 1.1rem 1.15rem;
    /* Der Rahmen liest `--desk-border` MIT RUECKFALL: Die Vorgabe kommt von der Flaeche des Desks
       (vererbte Variable), eine Kachel mit eigener Farbe setzt sie in ihrem style-Attribut neu. Ein
       Attribut-Waehler (`[style*="--desk-border"]`) traefe nur den zweiten Fall. */
    border: 1px solid var(--desk-border, var(--tri-border));
    border-radius: 1rem;
    /* Ohne Bild: der gruene Hausverlauf - oder, wenn gewaehlt, ein leuchtender Verlauf aus der
       eigenen Grundfarbe. `color-mix` hellt sie dafuer auf, statt eine zweite Farbe zu verlangen:
       Eine Farbe zu waehlen ist eine Frage, zwei sind eine Bastelei. */
    /* Der Grund liegt auf einer eigenen Ebene (::before). Nur so laesst sich SEINE Deckkraft
       regeln: `opacity` an der Kachel selbst nimmt Text und Symbole mit. */
    background: transparent;
    box-shadow: 0 6px 16px rgba(0,0,0,.10), 0 1px 3px rgba(0,0,0,.08);
    /* Der Zeiger verspricht nur da einen Klick, wo einer etwas tut – siehe `.is-klickbar`. */
    cursor: default;
    overflow: hidden;
    transition: box-shadow .15s, transform .15s, border-color .15s;
}

/* DER GRUND JEDER KACHEL: der gruene Hausverlauf - oder, wenn gewaehlt, ein leuchtender Verlauf
   aus der eigenen Grundfarbe (siehe weiter unten), oder das Hintergrundbild. Immer dieselbe Ebene,
   immer mit derselben Deckkraft `--desk-tile-alpha`. */
.desk-tile::before {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(140deg, var(--tri-green-bg) 0%, #fff 55%);
    opacity: var(--desk-tile-alpha, 1);
}
/* Der Inhalt liegt ueber dem Grund - auf JEDER Kachel, nicht nur auf der mit Bild. */
.desk-tile > * { position: relative; z-index: 1; }

/* Anklickbar ist die ganze Kachel nur, wenn es GENAU EINE Aktion gibt (oder im Bearbeitungsmodus). */
.desk-tile.is-klickbar { cursor: pointer; }
/* Beim Darüberfahren wird die Kachel eine Spur groesser – gerade genug, dass man es merkt, ohne dass
   das Raster zu wackeln beginnt. Vorher hob sie sich nur um zwei Bildpunkte an; das ging bei einem
   Bild im Hintergrund leicht unter. */
.desk-tile:hover { border-color: var(--tri-green); box-shadow: 0 12px 28px rgba(0,0,0,.16); transform: scale(1.02); }

/* Mit Hintergrundbild: Bild als eigene Ebene, darüber ein Schleier – sonst ist der Text auf hellen
   Bildern weg. Deckung, Schleierfarbe und Weichzeichnung sind je Kachel einstellbar; sie kommen als
   CSS-Variablen (--desk-overlay, --desk-blur) aus dem Markup. Ein fester schwarzer Verlauf ging bei
   dunklen Fotos gut und bei hellen schlecht – und mit einem hellen Schleier braucht die Schrift
   umgekehrt Dunkel. Deshalb hängen hier BEIDE zusammen: Schleierfarbe und Schriftfarbe. */
.desk-tile.has-bg::before {
    content: ""; position: absolute; inset: 0;
    background: none;
    background-image: var(--desk-bg); background-size: cover; background-position: center;
    filter: blur(var(--desk-blur, 0px));
    /* Weichzeichnen zieht den Rand nach innen und zeigt eine helle Kante – etwas grösser gezogen
       verschwindet sie wieder. */
    transform: scale(1.06);
}
/* GLEICHMAESSIG gedeckt, kein Verlauf: Bis 2.0.531 lag hier ein Verlauf von oben nach unten, der
   die eingestellte Deckung nur in der Mitte traf - oben war das Bild heller, unten dunkler als
   gewaehlt. Ein Regler, der „90 %" sagt und etwas anderes zeigt, ist ein Regler zu wenig. */
.desk-tile.has-bg::after {
    content: ""; position: absolute; inset: 0;
    background: rgba(0, 0, 0, var(--desk-overlay, .55));
    opacity: var(--desk-tile-alpha, 1);
}
.desk-tile.has-bg.is-light::after {
    background: rgba(255, 255, 255, var(--desk-overlay, .55));
}
.desk-tile.has-bg .desk-tile-title,
.desk-tile.has-bg .desk-tile-desc { color: #fff; }
.desk-tile.has-bg .desk-tile-desc { color: rgba(255,255,255,.88); }
/* Heller Schleier heisst dunkle Schrift – sonst steht Weiss auf Weiss. */
.desk-tile.has-bg.is-light .desk-tile-title { color: var(--tri-text); }
.desk-tile.has-bg.is-light .desk-tile-desc { color: var(--tri-muted); }

/* Eine AUSDRUECKLICH gewaehlte Textfarbe schlaegt alles davor – auch die Kachel ohne Bild. Die
   Variablen stehen nur dann im style-Attribut, wenn wirklich etwas gewaehlt wurde; sonst bleibt es
   bei den Regeln daruber. */
.desk-tile[style*="--desk-title"] .desk-tile-title { color: var(--desk-title) !important; }
.desk-tile[style*="--desk-desc"] .desk-tile-desc,
.desk-tile[style*="--desk-desc"] .desk-tile-desc * { color: var(--desk-desc) !important; }
/* Auf einem Bild bleiben die Knöpfe lesbar: Chat hell, Start weiterhin kräftig grün. */
.desk-tile.has-bg .desk-btn { background: rgba(255,255,255,.92); border-color: transparent; }
.desk-tile.has-bg .desk-btn-start { background: var(--tri-green); color: #fff; }
.desk-tile.has-bg .desk-btn:hover { background: var(--tri-green); color: #fff; }
/* Eine eigens gewählte Farbe steht im style-Attribut und gilt auch beim Überfahren. */
.desk-tile .desk-btn[style]:hover { filter: brightness(1.08); }

/* Eine gewaehlte Grundfarbe (nur ohne Bild). Der Verlauf geht von der Farbe selbst zu einer
   deutlich aufgehellten Fassung - das ergibt das „Leuchten", ohne dass jemand zwei Farben waehlen
   muss. Die Schrift wird hell, weil der Verlauf oben kraeftig ist; eine ausdrueckliche Textfarbe
   schlaegt das weiterhin. */
.desk-tile[style*="--desk-color"]:not(.has-bg)::before {
    background: linear-gradient(140deg,
        var(--desk-color) 0%,
        color-mix(in srgb, var(--desk-color) 45%, #fff) 100%);
}
/* Eine Grundfarbe traegt ihren eigenen Rahmen (keinen) - es sei denn, einer ist gewaehlt. */
.desk-tile[style*="--desk-color"]:not(.has-bg) {
    border-color: var(--desk-border, transparent);
}
.desk-tile[style*="--desk-color"]:not(.has-bg) .desk-tile-title { color: #fff; }
.desk-tile[style*="--desk-color"]:not(.has-bg) .desk-tile-desc { color: rgba(255,255,255,.9); }
.desk-tile[style*="--desk-color"]:not(.has-bg) .desk-btn { background: rgba(255,255,255,.92); border-color: transparent; }

/* Das Bild des Agenten: rund, oben links, mit hellem Ring – damit es auf jedem Untergrund steht.

   Es steht IM FLUSS und nicht absolut. Die Kachel schiebt ihren Inhalt nach unten
   (justify-content: flex-end); `margin-bottom: auto` schluckt den freien Platz, setzt das Bild also
   nach oben und alles andere nach unten. Absolut positioniert lag es ueber der Ueberschrift, sobald
   diese zweizeilig wurde – ein Fehler, den man erst bei langen Titeln sieht. */
.desk-tile-avatar {
    align-self: flex-start;
    width: 3.25rem; height: 3.25rem; border-radius: 50%;
    object-fit: cover;
    /* Kein heller Ring: Er war als Rahmen gedacht, sah aber wie ein zweiter Kreis um das Gesicht aus.
       Was bleibt, ist ein weicher Schatten – der hebt das Bild von einem unruhigen Foto ab, ohne
       selbst als Linie zu erscheinen. */
    box-shadow: 0 2px 6px rgba(0,0,0,.25);
}

.desk-tile-body { display: flex; flex-direction: column; gap: .25rem; }
.desk-tile-title { font-weight: 700; font-size: 1.05rem; line-height: 1.25; color: var(--tri-text); }
.desk-tile-desc {
    font-size: .82rem; line-height: 1.35; color: var(--tri-muted);
    display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}
/* Markdown in Überschrift und Erklärung auf die Kachelschrift zwingen (keine großen Überschriften). */
.desk-tile-desc .markdown-body { display: contents; }
.desk-tile-title .markdown-inline { color: inherit; font: inherit; }
.desk-tile-title .markdown-inline :is(code, strong, em) { color: inherit; font-size: inherit; }
.desk-tile-title .markdown-inline code { background: rgba(0,0,0,.08); padding: 0 .2em; border-radius: .2em; }
.desk-tile-desc :is(h1,h2,h3,h4,h5,h6),
.desk-tile-desc p, .desk-tile-desc ul, .desk-tile-desc li {
    font-size: inherit; line-height: inherit; color: inherit; margin: 0; font-weight: 400;
}

/* Im Fuss stehen nur noch die Schaltflaechen - Agentenname und -nummer sind mit 2.0.531 entfallen. */
.desk-tile-foot { display: flex; align-items: center; gap: .5rem; margin-top: auto; }

/* Zeigt IRGENDEINE Kachel des Rasters ein Agentenbild, halten die uebrigen denselben Platz frei – sonst
   saesse deren Ueberschrift um die Hoehe des Bildes weiter oben und die Zeilen liefen ueber die Kacheln
   hinweg auseinander. Zeigt keine einzige eines, entfaellt der Platz ersatzlos. */
/* Platzhalter fuer das fehlende Agentenbild – ein ECHTES Element, kein Pseudo-Element.
   Bis 2.0.535 stand hier `.desk-tile:not(:has(.desk-tile-avatar))::before`. Das war falsch:
   `::before` traegt bei einer Kachel MIT Hintergrundbild die Bildebene (`.desk-tile.has-bg::before`).
   Die spaetere Regel setzte dort `height: 3.25rem` obendrauf – das Bild wurde auf einen Streifen am
   oberen Rand zusammengestaucht, der Rest der Kachel blieb grau. Zu sehen war es nur bei Kacheln
   OHNE Agentenbild und MIT Hintergrundbild. */
.desk-tile-avatar-platz { flex: 0 0 auto; height: 3.25rem; }
.desk-tile-actions { margin-left: auto; display: inline-flex; gap: .4rem; }

/* Zahnrad und Papierkorb im Bearbeitungsmodus: in die UNTERE LINKE ECKE der Kachel, nicht in die
   Fusszeile. Sie gehoeren nicht zum Inhalt der Kachel, sondern liegen fuer die Dauer des Einrichtens
   darauf – und sie sollen dabei so wenig wie moeglich verdecken. Leicht durchscheinend (80 %), beim
   Zeigen voll deckend: So bleibt erkennbar, was unter ihnen liegt.

   ABSOLUT, nicht im Fluss: Nur so liegen sie auf JEDER Kachel an derselben Stelle. Im Fluss
   wanderten sie mit der Laenge der Erklaerung – nebeneinander standen sie dann auf verschiedenen
   Hoehen, und beim Einrichten sucht man sie auf jeder Kachel neu. */
.desk-tile-actions.is-werkzeuge {
    position: absolute;
    left: .55rem;
    bottom: .55rem;
    z-index: 3;
    margin: 0;
    opacity: .8;
    transition: opacity .15s ease;
}
.desk-tile-actions.is-werkzeuge:hover { opacity: 1; }

.desk-btn {
    /* Die Groesse haengt an `--desk-icon` (1 = x1, 1.5, 2). Je Kachel einstellbar: Auf einer Kachel
       mit kraeftigem Bild geht ein kleiner Knopf unter, auf einer ruhigen wirkt ein grosser laut. */
    width: calc(2.3rem * var(--desk-icon, 1));
    height: calc(2.3rem * var(--desk-icon, 1));
    border-radius: calc(.7rem * var(--desk-icon, 1));
    font-size: calc(1rem * var(--desk-icon, 1));
    border: 1px solid var(--tri-border); background: #fff; color: var(--tri-green-dark);
    display: inline-flex; align-items: center; justify-content: center;
}
/* Die Werkzeuge des Bearbeitungsmodus bleiben klein: Sie gehoeren nicht zur Gestaltung der Kachel. */
.desk-tile-actions.is-werkzeuge .desk-btn {
    width: 2.3rem; height: 2.3rem; border-radius: .7rem; font-size: 1rem;
}
.desk-btn:hover { background: var(--tri-green); border-color: var(--tri-green); color: #fff; }
.desk-btn-start { background: var(--tri-green); border-color: var(--tri-green); color: #fff; }
.desk-btn-start:hover { background: var(--tri-green-hover); }
.desk-btn-del:hover { background: var(--tri-red); border-color: var(--tri-red); color: #fff; }

/* Bearbeitungsmodus: Kachel ist ziehbar, Hinweise oben rechts. */
.desk-tile.is-edit { cursor: grab; }
.desk-tile.desk-dragging { opacity: .4; }
.desk-tile-flags { position: absolute; top: .6rem; right: .6rem; z-index: 2; display: flex; gap: .3rem; flex-wrap: wrap; }
.desk-flag {
    font-size: .68rem; font-weight: 600; border-radius: .4rem; padding: .1rem .4rem;
    background: rgba(192,57,43,.12); color: var(--tri-red);
}

.desk-empty { text-align: center; color: var(--tri-muted); padding: 3.5rem 1rem; }
.desk-empty i { font-size: 2.4rem; display: block; margin-bottom: .6rem; opacity: .5; }

@media (max-width: 520px) {
    .desk-grid { grid-template-columns: 1fr; }
}

/* Die Vorschau im Dialog: dieselbe Kachel, nur kleiner und ohne Verhalten. */
.adk-vorschau { min-height: 9rem; cursor: default; }

/* Das Band ueber den Registern. Die Beschriftung steht NEBEN der Kachel und nicht darueber: Der
   Dialog hat eine feste Hoehe, und jede Zeile hier fehlt unten im Register. Die feste Breite haelt
   das Seitenverhaeltnis der echten Kachel – eine ueber die volle Breite gezogene Vorschau zeigte
   eine Kachel, die es so nie gibt. */
.adk-vorschau-band { display: flex; align-items: center; gap: 1rem; }
/* `zoom` und nicht kleinere Masse: Die Vorschau soll die ECHTE Kachel zeigen – dieselben Abstaende,
   dieselben Schriftgroessen, dasselbe Seitenverhaeltnis, nur kleiner. Mit eigenen Massen waere sie
   eine Nachbildung und haette genau die Fehler verschwiegen, wegen derer man hinschaut. Verkleinert
   wird, weil der Dialog eine feste Hoehe hat: Jeder Bildpunkt hier fehlt dem Register darunter. */
.adk-vorschau-band > .adk-vorschau { flex: 0 0 auto; width: 22rem; zoom: .85; }
@media (max-width: 575.98px) {
    .adk-vorschau-band { flex-direction: column; align-items: stretch; gap: .35rem; }
    .adk-vorschau-band > .adk-vorschau { width: auto; }
}
/* Auf flachen Bildschirmen (Laptop mit 800 Bildpunkten Hoehe) faellt die Vorschau kleiner aus. Sie hat
   feste Masse und nimmt dem Register darunter sonst genau die Zeile weg, die den Inhalt zum Scrollen
   brachte – und Scrollen ist in diesen Dialogen ausgeschlossen. */
@media (max-height: 900px) {
    .adk-vorschau-band > .adk-vorschau { zoom: .7; }
    .adk-vorschau-band { margin-bottom: .75rem !important; }
}
.adk-vorschau:hover { transform: none; border-color: var(--tri-border); box-shadow: 0 6px 16px rgba(0,0,0,.10), 0 1px 3px rgba(0,0,0,.08); }
.adk-vorschau .desk-btn { pointer-events: none; }
.adk-wert { min-width: 3.5rem; text-align: right; font-variant-numeric: tabular-nums; color: var(--tri-muted); font-size: .85rem; }

/* Farbwahl: Vorschlaege zum Antippen, die freie Wahl und der Hex-Code. */
.farbwahl { display: flex; flex-wrap: wrap; align-items: center; gap: .35rem; }
.farbwahl-feld {
    width: 1.7rem; height: 1.7rem; border-radius: .45rem; padding: 0;
    border: 1px solid var(--tri-border); background: #fff; cursor: pointer;
    display: inline-flex; align-items: center; justify-content: center; font-size: .9rem;
}
/* Der Rahmen allein war auf dunklen Feldern kaum zu sehen - deshalb Ring UND Haken. */
.farbwahl-feld.active { box-shadow: 0 0 0 2px #fff, 0 0 0 4px var(--tri-green); }
.farbwahl-vorgabe { color: var(--tri-muted); }

/* Die freie Wahl: als Farbrad erkennbar, nicht als weitere Farbe in der Reihe. */
.farbwahl-frei {
    position: relative; width: 1.7rem; height: 1.7rem; border-radius: .45rem;
    border: 1px solid var(--tri-border); cursor: pointer; overflow: hidden; margin: 0;
    display: inline-flex; align-items: center; justify-content: center;
}
.farbwahl-frei.active { box-shadow: 0 0 0 2px #fff, 0 0 0 4px var(--tri-green); }
.farbwahl-frei-rad {
    width: 100%; height: 100%;
    background: conic-gradient(#e74c3c, #f1c40f, #2ecc71, #1abc9c, #3498db, #9b59b6, #e74c3c);
}
.farbwahl-frei input[type="color"] {
    position: absolute; inset: 0; opacity: 0; cursor: pointer; border: 0; padding: 0;
}

/* Der Hex-Code: ablesbar und eintippbar - so laesst sich eine Hausfarbe uebernehmen. */
.farbwahl-hex { display: inline-flex; align-items: center; gap: .15rem; margin-left: .25rem; }
.farbwahl-hex > span { color: var(--tri-muted); font-size: .85rem; }
.farbwahl-hex input {
    width: 6.2rem; font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: .8rem; text-transform: lowercase;
}

/* ===== Gesperrte Funktionen =====================================================================
   Was in der lizenzierten Edition nicht enthalten ist, bleibt SICHTBAR und wird ausgegraut. Ein
   Hinweis beim Überfahren sagt, woran es liegt (siehe Components/FeatureLock.razor).

   pointer-events:none nimmt dem Inhalt jede Bedienbarkeit – auch dort, wo das umschlossene Element
   gar kein "disabled" kennt (ein Link, eine Karte). Der Hinweis selbst muss deshalb an der HÜLLE
   hängen: Sie behält ihre Zeigerereignisse und zeigt den title an. */
.feature-locked {
    opacity: .45;
    filter: grayscale(1);
    cursor: not-allowed;
}

.feature-locked > * {
    pointer-events: none;
}

/* Die Hülle darf den Fluss nicht verändern: In einer Knopfleiste oder einer Tabellenzelle stünde
   sonst plötzlich ein Block, wo vorher ein Element stand. */
span.feature-locked {
    display: inline-block;
}

/* Und in der Breite darf sie es auch nicht: Eine Schaltfläche, die als Zeile einer Liste über die
   ganze Breite ging, schrumpfte sonst auf ihren Inhalt zusammen, sobald die Hülle dazwischensteht –
   die gesperrten Zeilen standen schmaler da als die übrigen. */
div.feature-locked {
    display: block;
    width: 100%;
}

div.feature-locked > * {
    width: 100%;
}

/* ============================================================================================
   Markdown-Editor (EasyMDE): Symbole der Werkzeugleiste

   EasyMDE beschriftet seine Knöpfe fest mit Font-Awesome-Klassen („fa fa-bold"). Font Awesome ist in
   dieser Anwendung aber NIE eingebunden gewesen - geliefert werden Bootstrap Icons und Tabler Icons.
   Die Knöpfe waren deshalb leer: Kästchen mit Trennstrichen, ohne Sinnbild.

   Statt eine dritte Symbolschrift nachzuladen (Font Awesome bringt rund 75 KB mit, für ein Dutzend
   Zeichen), werden die fa-Klassen hier auf die Bootstrap Icons umgebogen, die ohnehin geladen sind.
   Nebeneffekt: Die Werkzeugleiste sieht aus wie der Rest der Oberfläche.

   Die Codepunkte stammen aus der ausgelieferten bootstrap-icons.min.css, nicht aus dem Gedächtnis.
   ============================================================================================ */
.editor-toolbar .fa,
.editor-toolbar [class^="fa-"],
.editor-toolbar [class*=" fa-"] {
    font-family: bootstrap-icons !important;
    font-style: normal;
    font-weight: normal;
    font-variant: normal;
    text-transform: none;
    line-height: 1;
    -webkit-font-smoothing: antialiased;
}

.editor-toolbar .fa-bold::before { content: "\f5f0"; }
.editor-toolbar .fa-italic::before { content: "\f5f4"; }
.editor-toolbar .fa-strikethrough::before { content: "\f5f5"; }
/* Überschriften: EasyMDE nutzt dieselbe Klasse mit Zusatz (header-1/-2/-3, -bigger, -smaller). Die
   spezifischeren Regeln stehen deshalb NACH der allgemeinen, sonst gewönne immer das schlichte „A". */
.editor-toolbar .fa-header::before,
.editor-toolbar .fa-heading::before { content: "\f3da"; }
.editor-toolbar .header-1::before { content: "\f5f1"; }
.editor-toolbar .header-2::before { content: "\f5f2"; }
.editor-toolbar .header-3::before { content: "\f5f3"; }
.editor-toolbar .fa-quote-left::before { content: "\f6b0"; }
.editor-toolbar .fa-list-ul::before { content: "\f478"; }
.editor-toolbar .fa-list-ol::before { content: "\f475"; }
.editor-toolbar .fa-link::before { content: "\f470"; }
.editor-toolbar .fa-image::before { content: "\f42a"; }
.editor-toolbar .fa-code::before { content: "\f2c8"; }
.editor-toolbar .fa-table::before { content: "\f5aa"; }
.editor-toolbar .fa-minus::before { content: "\f63b"; }
.editor-toolbar .fa-eye::before { content: "\f341"; }
.editor-toolbar .fa-columns::before { content: "\f460"; }
.editor-toolbar .fa-arrows-alt::before { content: "\f14d"; }
.editor-toolbar .fa-question-circle::before { content: "\f505"; }
.editor-toolbar .fa-info-circle::before { content: "\f431"; }
.editor-toolbar .fa-exclamation-circle::before { content: "\f333"; }
.editor-toolbar .fa-exclamation-triangle::before { content: "\f33b"; }
.editor-toolbar .fa-undo::before { content: "\f117"; }
.editor-toolbar .fa-repeat::before,
.editor-toolbar .fa-redo::before { content: "\f116"; }
.editor-toolbar .fa-eraser::before { content: "\f331"; }
.editor-toolbar .fa-indent::before { content: "\f5c5"; }
.editor-toolbar .fa-outdent::before { content: "\f5c6"; }
.editor-toolbar .fa-lightbulb-o::before,
.editor-toolbar .fa-lightbulb::before { content: "\f46b"; }
.editor-toolbar .fa-video-camera::before,
.editor-toolbar .fa-video::before { content: "\f21f"; }

/* Abschnitt und System-Prompt in der Karteikarte der 3D-Agentenwolke. Eigene Klassen, keine geteilten
   mit der Lesekarte des Brains: Die beiden Ansichten sollen sich nicht gegenseitig verstellen. */
.ac3d-lk-abschnitt {
    margin: .9rem 0 .35rem; font-size: .7rem; letter-spacing: .06em; text-transform: uppercase;
    color: #8a949c;
}
/* Umbruch erlaubt, Einrückungen bleiben: Der Prompt trägt seine Gliederung in den Zeilen. */
.ac3d-lk-prompt {
    margin: 0; white-space: pre-wrap; overflow-wrap: anywhere; font-size: .78rem; line-height: 1.45;
    color: #c2cbd3; background: rgba(255, 255, 255, .04); border: 1px solid #2c3236;
    border-radius: .4rem; padding: .5rem .6rem;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}

/* ---- 3D-Agentenwolke: randlos, Bedienleiste als Teil der Szene ---------------------------------
   Eigene Klassen (`ac3d-*`), KEINE Änderung an `.memory-map`: Brain und Memory liegen als KACHEL
   unter ihrem Register - mit dem üblichen Rand, der üblichen Rundung und der Polsterung der Seite.
   Randlos ist allein die Agentenwolke: Dort IST die Karte das Fenster, es gibt kein Register
   darüber und nichts daneben.

   Die negativen Ränder heben die Polsterung von `.page-content` auf (px-3 / px-lg-4 / pb-4). Dasselbe
   tut die 2D-Wolke seit jeher – siehe `.ag-cloud-embed`. */
/* Oben -1,5rem, nicht -0,5rem: Die Kopfzeile bringt einen eigenen Abstand nach unten mit.
   Gemessen blieb sonst ein 16 px hoher grauer Streifen zwischen Kopf und Zeichenflaeche. */
.map-randlos { margin: -1.5rem -1rem -1.5rem -1rem; }
@media (min-width: 992px) { .map-randlos { margin-left: -1.5rem; margin-right: -1.5rem; } }
.map-randlos .memory-map-canvas { border: none; border-radius: 0; min-height: 0; }
.map-randlos .sbm-kartenflaeche { min-height: 0; }

/* Die Leiste schwebt ÜBER der Zeichenfläche, wie der Regler unten rechts. Sie nimmt nur so viel
   Breite, wie sie braucht (`width: max-content`) – eine über die ganze Breite gezogene Leiste sähe
   wieder nach Kasten aus. */
/* Z-WERT 26, NICHT 8: Die schwebende Leiste MUSS über der unsichtbaren Schließfläche
   `.map-bar-schirm` (25) liegen. Sie ist selbst positioniert und bildet damit einen eigenen
   Stapelraum – die 30 der Aufklappliste gilt nur INNERHALB der Leiste und half nichts. Lag die
   Leiste darunter, fing die Schließfläche jeden Klick ab: Das Häkchen ließ sich nicht setzen,
   die Liste ging nur zu. (Galt in allen drei Karten – Agenten, Brain, Memory.) */
.map-bar-schwebend {
    position: absolute; left: .9rem; top: .9rem; z-index: 26;
    width: max-content; max-width: calc(100% - 1.8rem); margin: 0;
    background: rgba(255, 255, 255, .93); border: 1px solid var(--tri-border);
    border-radius: 1.6rem; padding: .4rem .85rem;
    box-shadow: 0 .35rem 1.1rem rgba(0, 0, 0, .14);
}
/* Auf dunklem Grund dreht sich die Leiste mit – sonst läge ein weißer Balken auf schwarzer Szene. */
.map-bar-schwebend.is-dark {
    background: rgba(16, 20, 24, .88); border-color: #2c3236; color: #d7dee4;
    box-shadow: 0 .35rem 1.1rem rgba(0, 0, 0, .5);
}
.map-bar-schwebend.is-dark .form-control,
.map-bar-schwebend.is-dark .input-group-text {
    background: rgba(255, 255, 255, .06); border-color: #363d44; color: #e6ecf2;
}
.map-bar-schwebend.is-dark .form-control::placeholder { color: #8d99a5; }
.map-bar-schwebend.is-dark .btn-outline-secondary { color: #cfd7df; border-color: #3c444c; }
.map-bar-schwebend.is-dark .form-check-label, .map-bar-schwebend.is-dark .map-bar-label { color: #cfd7df; }
.map-bar-schwebend.is-dark .map-bar-liste { background: #14181c; border-color: #2c3236; color: #d7dee4; }
/* Die Zeilen der Aufklappliste brauchen ihre EIGENE helle Farbe. Die Liste setzt zwar `color`, aber
   `.map-bar-name` traegt `var(--tri-text)` und `.map-bar-zahl` `var(--tri-muted)` – beide dunkel, beide
   staerker als die geerbte Farbe. Auf dem fast schwarzen Grund der Landkarte waren die Namen der
   Themengebiete dadurch kaum zu lesen. Trennstrich und Hover-Flaeche gehoeren aus demselben Grund dazu. */
.map-bar-schwebend.is-dark .map-bar-name { color: #e6ecf2; }
.map-bar-schwebend.is-dark .map-bar-zahl { color: #9aa6b2; }
.map-bar-schwebend.is-dark .map-bar-trenner { background: #2c3236; }
.map-bar-schwebend.is-dark label.map-bar-zeile:hover { background: rgba(255, 255, 255, .07); }

/* Dieselben dunklen Werte für die Leiste IM Banner. Sie trägt dort keinen eigenen Kasten – den
   stellt der Anbau des Banners – sondern nur die hellen Schriften und Felder. */
.map-bar-im-banner.is-dark { background: transparent; border: 0; box-shadow: none; color: #d7dee4; }
/* Die Flaeche traegt jetzt die GRUPPE (siehe unten); Feld und Lupe darin bleiben durchsichtig -
   sonst saesse ein Kasten im Kasten. */
.map-bar-im-banner.is-dark .form-control,
.map-bar-im-banner.is-dark .input-group-text {
    background: transparent; border-color: transparent; color: #e6ecf2;
}
.map-bar-im-banner.is-dark .form-control::placeholder { color: #8d99a5; }
.map-bar-im-banner.is-dark .btn-outline-secondary { color: #cfd7df; border-color: #3c444c; }
.map-bar-im-banner.is-dark .form-check-label, .map-bar-im-banner.is-dark .map-bar-label { color: #cfd7df; }
.map-bar-im-banner.is-dark .map-bar-liste { background: #14181c; border-color: #2c3236; color: #d7dee4; }
/* Die Zeilen der Aufklappliste brauchen ihre EIGENE helle Farbe. Die Liste setzt zwar `color`, aber
   `.map-bar-name` traegt `var(--tri-text)` und `.map-bar-zahl` `var(--tri-muted)` – beide dunkel, beide
   staerker als die geerbte Farbe. Auf dem fast schwarzen Grund der Landkarte waren die Namen der
   Themengebiete dadurch kaum zu lesen. Trennstrich und Hover-Flaeche gehoeren aus demselben Grund dazu. */
.map-bar-im-banner.is-dark .map-bar-name { color: #e6ecf2; }
.map-bar-im-banner.is-dark .map-bar-zahl { color: #9aa6b2; }
.map-bar-im-banner.is-dark .map-bar-trenner { background: #2c3236; }
.map-bar-im-banner.is-dark label.map-bar-zeile:hover { background: rgba(255, 255, 255, .07); }

/* Die beiden Knöpfe rechts oben (Neu anordnen, Vollbild) schweben ebenfalls. */
.map-ecke-schwebend { position: absolute; right: .9rem; top: .9rem; z-index: 8; display: flex; gap: .4rem; }

/* Auf der randlosen Szene undurchsichtiger: Dort liegt hinter ihr die Zeichenflaeche bis zum
   Fensterrand, und durchscheinende Knoten im Ruecken machen den Text unleserlich. */
.map-randlos .sbm-lesekarte {
    background: #0f1317;
    box-shadow: 0 .6rem 2rem rgba(0, 0, 0, .6);
}

/* ============================================================================================
   NUR-LESE-MODUS (Rolle „Audit")
   ============================================================================================
   Der Server weist jede schreibende Anfrage ohnehin mit 403 ab - das ist die Zusage. Hier geht es
   um die Anzeige: Eine Schaltfläche, die aussieht, als täte sie etwas, und dann eine Fehlermeldung
   bringt, ist schlechter als eine ausgegraute, an der steht, warum.

   AUSGEGRAUT WIRD NICHT WAHLLOS, SONDERN AN ZWEI STELLEN, die in dieser Anwendung immer schreiben:
   der Fuß eines Dialogs (dort steht „OK"/„Übernehmen") und der Fuß einer Karte (dort steht
   „Speichern"). Dazu alles in Rot - Löschen und Verwerfen sind nie lesend - und was ausdrücklich
   mit data-write gekennzeichnet ist.

   WAS BEWUSST NICHT GESPERRT WIRD: Filter, Suche, Blättern, Register. Sie tragen dieselben Klassen
   (btn-primary), stehen aber nicht in einem Fuß - und ein Prüfer, der nicht filtern kann, kann
   nicht prüfen. */
.app-readonly .user-modal-foot .btn-primary,
.app-readonly .card-footer .btn-primary,
.app-readonly .btn-danger,
.app-readonly .btn-outline-danger,
.app-readonly [data-write],
/* „Neu"/„Hinzufügen" tragen in dieser Anwendung durchgehend ein Plus. Das ist kein Zufall, sondern
   Hausstil - und damit ein verlässliches Erkennungszeichen für „legt etwas an". */
.app-readonly .btn:has(> .bi-plus-lg),
.app-readonly .btn:has(> .bi-plus) {
    opacity: .45;
    filter: grayscale(1);
    pointer-events: none;
    cursor: not-allowed;
}

/* Das Band über dem Inhalt. Es steht IMMER da, nicht nur beim ersten Versuch: Wer eine Stunde in
   einer Maske liest, soll nicht raten müssen, warum das Speichern grau ist. */
.readonly-banner {
    display: flex;
    align-items: center;
    gap: .5rem;
    padding: .4rem .9rem;
    background: #f3f4f6;
    border-bottom: 1px solid #e5e7eb;
    color: #4b5563;
    font-size: .82rem;
}

.readonly-banner i { color: #6b7280; }

/* AUSNAHMEN vom Nur-Lese-Modus: eigene Vorgänge.
   Nutzungsbedingungen, Profil und „Über" liegen im Layout AUSSERHALB von .page und sind von der
   Sperre ohnehin nicht betroffen - ohne sie käme ein Auditor nicht einmal ins System. Die Regeln
   hier sind der Riegel für den Fall, dass einer dieser Dialoge einmal in den Seitenbaum wandert:
   `ro-allow` an der Dialoghülle nimmt ihn ausdrücklich heraus. */
.app-readonly .terms-modal .btn,
.app-readonly .ro-allow .btn,
.app-readonly .ro-allow [data-write] {
    opacity: 1;
    filter: none;
    pointer-events: auto;
    cursor: pointer;
}

/* =====================================================================
   DATENSCHUTZ – Abschnittskarten
   Jeder Abschnitt ist eine eigene Karte: Sinnbild, Überschrift, ein Satz
   Zweck – darunter die Schalter als Zeilen mit dem Schalter rechts außen.
   Grund: Die Seite beantwortet lauter verschiedene Fragen (Assistenz,
   Speicher, Fristen, Sicherungen, Auskunft). In einer durchlaufenden
   Liste mit Trennstrichen verschwimmt, wozu ein Schalter gehört.
   ===================================================================== */
.prv-card {
    background: #fff;
    border-radius: .75rem;
    /* Der Haus-Schatten wie bei jeder anderen Flaeche. Der eigene Wert (1 px, 5 %) war so zart,
       dass die Bloecke auf dem hellgrauen Grund ineinander uebergingen. */
    box-shadow: var(--tri-shadow-flaeche);
    margin-bottom: 1.25rem;
    overflow: hidden;
}

.prv-card-head { display: flex; gap: .9rem; padding: 1.25rem 1.5rem 1.1rem; }

/* Das Sinnbild sitzt in einer hellen Kachel – es soll den Abschnitt kennzeichnen,
   nicht mit der Überschrift um Aufmerksamkeit ringen. */
.prv-card-icon {
    flex: 0 0 auto;
    width: 2.5rem; height: 2.5rem;
    display: flex; align-items: center; justify-content: center;
    border-radius: .6rem;
    background: var(--tri-green-bg);
    color: var(--tri-green);
    font-size: 1.1rem;
}

.prv-card-title { display: flex; align-items: center; gap: .6rem; font-weight: 700; font-size: 1.1rem; margin-bottom: .35rem; }
.prv-card-note { color: var(--tri-muted); font-size: .875rem; margin: 0; }

/* Eine Zeile = eine Entscheidung. Der Schalter steht rechts außen, damit alle
   Schalter einer Karte auf einer Linie liegen. */
.prv-row {
    display: flex; align-items: flex-start; gap: 1.5rem;
    padding: .9rem 1.5rem;
    border-top: 1px solid var(--tri-border);
}

.prv-row-label { flex: 1 1 auto; min-width: 0; }
.prv-row-label > strong { display: block; font-size: .95rem; }
.prv-row-hint { color: var(--tri-muted); font-size: .85rem; margin: .3rem 0 0; }
.prv-row-hint strong { color: var(--tri-muted-2); }

/* Untergeordnete Schalter: eingerückt und leicht abgesetzt – sie gelten nur,
   solange der Schalter darüber an ist. */
.prv-row.is-sub { padding-left: 2.6rem; background: #fafbfc; }

/* Abgeblendet statt ausgeblendet: Wer wieder einschaltet, soll sehen,
   wie die Unterschalter stehen. */
.prv-row.is-off { opacity: .55; }

/* Kleine Angaben, die kein eigener Satz sein müssen (Vorgaben, Einheiten). */
.prv-chip {
    display: inline-block;
    background: var(--tri-surface);
    color: var(--tri-muted-2);
    border-radius: 1rem;
    padding: .15rem .7rem;
    font-size: .78rem;
    margin: .5rem .4rem 0 0;
}

.prv-badge {
    background: var(--tri-green-bg);
    color: var(--tri-green);
    border-radius: 1rem;
    padding: .1rem .6rem;
    font-size: .72rem;
    font-weight: 700;
}

/* Die drei Datenspeicher nebeneinander: gleiche Bauart, gleiche Entscheidung. */
.prv-stores { display: grid; grid-template-columns: repeat(3, 1fr); gap: .75rem; padding: 0 1.5rem 1.1rem; }
@media (max-width: 767.98px) { .prv-stores { grid-template-columns: 1fr; } }

.prv-store {
    display: flex; align-items: center; justify-content: space-between; gap: .75rem;
    border: 1px solid var(--tri-border);
    border-radius: .6rem;
    padding: .7rem .9rem;
    /* Derselbe Haus-Schatten wie bei jeder anderen Flaeche: Es sind drei Kacheln NEBENEINANDER
       auf einer weissen Karte - ohne Schatten lagen sie flach darin und sahen aus wie Felder
       eines Formulars statt wie drei Schalter. */
    box-shadow: var(--tri-shadow-flaeche);
}
.prv-store.is-on { border-color: var(--tri-green-soft); background: var(--tri-green-bg); }
.prv-store-name { font-weight: 600; font-size: .95rem; }
.prv-store-state { color: var(--tri-muted); font-size: .8rem; }

/* Auskunftsrecht: was drin ist und was nicht, nebeneinander statt untereinander –
   die Auslassung ist genauso wichtig wie der Inhalt. */
.prv-scope { display: grid; grid-template-columns: 1fr 1fr; gap: 1.25rem; padding: 1rem 1.5rem .25rem; }
@media (max-width: 767.98px) { .prv-scope { grid-template-columns: 1fr; } }
.prv-scope-item { display: flex; gap: .6rem; font-size: .875rem; color: var(--tri-muted); }
.prv-scope-item strong { color: var(--tri-text); }
.prv-scope-mark {
    flex: 0 0 auto; width: 1.35rem; height: 1.35rem; border-radius: 50%;
    display: flex; align-items: center; justify-content: center; font-size: .7rem;
    background: var(--tri-surface); color: var(--tri-muted);
}
.prv-scope-mark.is-yes { background: var(--tri-green-bg); color: var(--tri-green); }

.prv-act { display: flex; align-items: center; gap: .75rem; flex-wrap: wrap; padding: .25rem 1.5rem 0; }
.prv-foot-note { color: var(--tri-muted); font-size: .82rem; padding: .75rem 1.5rem 1.25rem; margin: 0; }

/* Der Schalter rechts außen – etwas größer als der Bootstrap-Standard, damit er
   auf Abstand noch als Schalter zu erkennen ist. */
.prv-switch { flex: 0 0 auto; padding-top: .1rem; }
.prv-switch .form-check-input { width: 2.6rem; height: 1.4rem; margin: 0; cursor: pointer; }
.prv-switch .form-check-input:disabled { cursor: not-allowed; }

/* Das Wappen im Seitenkopf des Datenschutzes – die EINZIGE Stelle, an der ein Seiten-Sinnbild rot ist.
   Begründet: Die Seite schränkt ein, statt etwas anzubieten. */
.prv-head-icon { color: var(--tri-red); }

/* ---- Lauf-Detail: einklappbarer Kopf ----
   Die Zeile ist selbst der Schalter. Kein eigener Knopf daneben: Der Kopf hat keine andere Aufgabe,
   also darf die ganze Fläche ihn auf- und zuklappen. */
.rd-head-toggle {
    display: flex; align-items: center; gap: .55rem; flex-wrap: wrap;
    width: 100%; border: 0; background: transparent; text-align: left;
    padding: .85rem 1.25rem; color: var(--tri-text); font-size: .95rem;
    border-radius: .5rem;
}
.rd-head-toggle:hover { background: var(--tri-surface); }
.rd-head-toggle > .bi { color: var(--tri-muted); font-size: .85rem; }

/* Eingeklappt steht hier, was man im Blick behält – sonst wüsste niemand, was er aufklappt. */
.rd-head-summary { display: flex; align-items: center; gap: .9rem; margin-left: auto; font-size: .85rem; color: var(--tri-muted-2); }

/* Zahlen in den Laufdetails stehen in der NORMALEN Schrift, aber mit tabellarischen Ziffern: So
   bleiben Spalten und Zeiten untereinander auf derselben Breite, ohne dass die Seite wie ein Terminal
   aussieht. Schreibmaschinenschrift bleibt dort, wo sie etwas trägt – in Code- und JSON-Blöcken. */
.tl-stats, .tl-ov-times, .tl-time, .tl-meta, .tl-dur, .tl-detail-run, .tl-detail-time, .tl-facts b,
.erg-notif-times, .erg-notif-dur,
.rd-info-run, .rd-fact-value, .tok-num, .tok-anteil-zahl {
    font-variant-numeric: tabular-nums;
}

/* =====================================================================
   ZEITLEISTE eines Laufs (Register „Timeline")
   Links das Band, rechts die Einzelheiten. Das Band scrollt NICHT über
   `overflow`, sondern wird von run-timeline.js verschoben – nur so gibt
   es Nachlauf und Gummiband. Deshalb hier `overflow: hidden` und eine
   innere Lage, die transformiert wird.
   ===================================================================== */
/* Die Zeitleiste nimmt die Höhe, die ihr Platz lässt – nicht eine geratene Bildschirmhöhe. Klappt der
   Kopf der Seite zu, wächst sie um genau diesen Betrag. */
.tl { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 20rem; }

/* Eigene Zeile, volle Breite: Zwölf Arten passen nicht neben den Dichte-Umschalter. Sie bleiben
   trotzdem EINZEILIG und werden bei Platzmangel waagerecht gescrollt. Umbruch sah schlechter aus: Die
   zweite Zeile trug je nach Fenster einen oder zwei Reste, und die Zeitleiste darunter sprang in der
   Höhe. Eine Leiste, die immer gleich hoch ist, ist das Ruhigere. */
.tl-filters {
    display: flex; align-items: center; gap: .25rem; flex-wrap: nowrap;
    /* `flex: 0 0 auto` ist Pflicht: Sobald ein Flex-Element nicht mehr `overflow: visible` hat, darf der
       Browser es unter seine Inhaltshöhe quetschen - die Leiste schrumpfte sonst in der Spalte auf 15 px. */
    flex: 0 0 auto;
    overflow-x: auto; overflow-y: hidden; scrollbar-width: thin;
    /* Oben etwas Luft: Ohne Überschrift beginnt das Register sonst unmittelbar unter der Registerzeile. */
    padding: .9rem .25rem .45rem;
}
.tl-filters::-webkit-scrollbar { height: 5px; }
.tl-filters::-webkit-scrollbar-thumb { background: var(--tri-border); border-radius: 3px; }
.tl-pill {
    display: inline-flex; align-items: center; gap: .35rem; flex: 0 0 auto;
    border: 1px solid transparent; background: transparent; color: var(--tri-muted-2);
    border-radius: 1.2rem; padding: .18rem .6rem; font-size: .8rem; white-space: nowrap;
}
.tl-pill:hover { background: var(--tri-surface); }
.tl-pill.is-on { background: var(--tri-surface); border-color: var(--tri-border); color: var(--tri-text); font-weight: 600; }
.tl-pill-dot { width: .5rem; height: .5rem; border-radius: 50%; background: var(--tl-accent, var(--tri-faint)); }
.tl-dot-all { background: var(--tri-faint); }

/* ---- Stufen-Umschalter (Ansichten, Dichte …) ----
   Ein Feld mit mehreren Stufen, die einander ausschließen: heller Rahmen, die gewählte Stufe als weiße
   Kachel mit Hausgrün. Nicht vier gefüllte Knöpfe: Die sähen aus wie vier Handlungen. */
.seg-switch {
    display: inline-flex; align-items: center; gap: .15rem; flex: 0 0 auto;
    background: var(--tri-surface); border-radius: .7rem; padding: .2rem;
}
.seg-switch-btn {
    display: inline-flex; align-items: center; gap: .4rem; white-space: nowrap;
    border: 0; background: transparent; color: var(--tri-muted-2);
    /* Nur die GEWAEHLTE Stufe ist fett. Standen alle fett, las sich das Feld wie eine Reihe
       gleichrangiger Knoepfe - die Hervorhebung muss dem Auge sagen, wo man steht. */
    border-radius: .55rem; padding: .3rem .8rem; font-size: .9rem; font-weight: 500; cursor: pointer;
}
.seg-switch-btn:hover { color: var(--tri-text); }
.seg-switch-btn.is-on {
    background: #fff; color: var(--tri-green); font-weight: 600;
    box-shadow: 0 1px 2px rgba(16, 24, 40, .10), 0 0 0 1px rgba(16, 24, 40, .04);
}
/* Im Symbol-Modus des Seitenkopfs (.ph-compact) bleibt der Umschalter LESBAR: Er ist kein Aktionsknopf,
   sondern sagt, was man gerade sieht – ohne Text wären vier Symbole nebeneinander zu raten. */
.page-head.ph-compact .page-head-actions .seg-switch-btn { font-size: .9rem; }

/* Dichte-Umschalter: ein Feld mit drei Stufen statt zweier Knöpfe – man sieht, wo man steht. */
.tl-seg { display: inline-flex; background: var(--tri-surface); border-radius: .55rem; padding: .15rem; margin-left: auto; }
.tl-seg-btn {
    border: 0; background: transparent; color: var(--tri-muted);
    border-radius: .45rem; padding: .22rem .75rem; font-size: .82rem;
}
.tl-seg-btn.is-on { background: #fff; color: var(--tri-text); font-weight: 600; box-shadow: 0 1px 2px rgba(16,24,40,.12); }

/* ---- Überblicksbalken: der ganze Lauf auf einer Linie ---- */
.tl-overview { position: relative; padding: 0 .25rem .8rem; }
.tl-ov-bar { display: flex; gap: 2px; height: .55rem; }
.tl-ov-seg { background: var(--tl-accent, var(--tri-border)); border-radius: 2px; min-width: 3px; cursor: pointer; opacity: .55; transition: opacity .12s; }
.tl-ov-seg:hover { opacity: .85; }
.tl-ov-seg.is-on { opacity: 1; box-shadow: 0 0 0 2px rgba(var(--tri-green-rgb), .25); }
/* „Hier stehe ich gerade": Der oberste Eintrag des sichtbaren Ausschnitts, markiert durch einen dunklen
   Strich UNTER der Leiste. Bewusst anders als die Auswahl (heller Ring): Das eine ist, was man angeklickt
   hat, das andere, wo man beim Scrollen gelandet ist. */
.tl-ov-seg.is-view { opacity: 1; position: relative; }
.tl-ov-seg.is-view::after {
    content: ""; position: absolute; left: 0; right: 0; bottom: -.3rem; height: 2px; border-radius: 1px;
    background: var(--tri-text);
}
.tl-ov-times { display: flex; justify-content: space-between; font-size: .72rem; color: var(--tri-faint); margin-top: .3rem; }

/* Schwebekarte über der Überblicksleiste. Sie sitzt UNTER der Leiste, weil darüber die Filterzeile steht,
   und nimmt nie Zeigerereignisse an – sonst verlöre der Abschnitt darunter sofort wieder den Zeiger.
   `left` kommt als Prozentwert aus der Mitte des Abschnitts, `translateX(-50%)` zentriert sie darauf;
   am Rand schiebt sie sich damit über die Leiste hinaus statt den Zeiger zu verlieren. */
.tl-ov-tip {
    position: absolute; top: calc(.55rem + .55rem); transform: translateX(-50%);
    z-index: 5; pointer-events: none; width: max-content; max-width: 24rem;
    background: #fff; border: 1px solid var(--tri-border); border-radius: .6rem;
    box-shadow: 0 8px 24px rgba(16, 24, 40, .12); padding: .55rem .75rem;
}
.tl-ov-tip-kopf { display: flex; align-items: center; gap: .4rem; font-size: .76rem; }
.tl-ov-tip-dot { width: .5rem; height: .5rem; border-radius: 50%; background: var(--tl-accent, var(--tri-faint)); flex: 0 0 auto; }
.tl-ov-tip-art { font-weight: 700; color: var(--tl-accent, var(--tri-muted)); }
.tl-ov-tip-zeit { color: var(--tri-faint); font-variant-numeric: tabular-nums; }
.tl-ov-tip-titel { font-weight: 600; font-size: .9rem; color: var(--tri-text); margin-top: .15rem; }
.tl-ov-tip-text { font-size: .82rem; color: var(--tri-muted); margin-top: .15rem; }
.tl-ov-tip-fuss { display: flex; gap: .8rem; font-size: .76rem; color: var(--tri-faint); margin-top: .25rem; font-variant-numeric: tabular-nums; }
.tl-ov-tip-fuss:empty { display: none; }

.tl-body { display: grid; grid-template-columns: minmax(22rem, 2fr) 3fr; gap: 1rem; flex: 1 1 auto; min-height: 0; }
@media (max-width: 991.98px) { .tl-body { grid-template-columns: 1fr; } .tl-track { max-height: 24rem; } }

/* ---- Das Band ---- */
.tl-track {
    position: relative; overflow: hidden; min-height: 0;
    border-right: 1px solid var(--tri-border);
    cursor: grab;
}
.tl-track.is-dragging { cursor: grabbing; }
.tl-inner { padding: .25rem 1rem .5rem 0; will-change: transform; }
.tl-empty { padding: 2rem; color: var(--tri-muted); font-size: .9rem; text-align: center; }

/* Eine Zeile: Zeit und Punkt auf der Spur, Karte daneben. Die Einrückung zeigt die Tiefe im
   Lauf-Baum – ein Sub-Lauf steht sichtbar unter dem, der ihn gestartet hat. */
.tl-row {
    position: relative; display: grid; grid-template-columns: 5.6rem 1fr; gap: .75rem;
    /* 2 rem je Ebene: Bei 1,1 rem war die Einrückung zwar vorhanden, aber kaum zu sehen - und sie ist
       die einzige Stelle, an der man erkennt, dass hier ein Sub-Agent arbeitet. */
    padding: .25rem 0 .25rem calc(var(--tl-depth, 0) * 2rem);
}
.tl-rail { position: relative; display: flex; align-items: flex-start; justify-content: flex-end; gap: .6rem; padding-top: .75rem; }
.tl-time { font-size: .76rem; color: var(--tri-faint); white-space: nowrap; }
.tl-dot {
    flex: 0 0 auto; width: .72rem; height: .72rem; border-radius: 50%; margin-top: .22rem;
    background: var(--tl-accent, var(--tri-faint)); box-shadow: 0 0 0 3px #fff; z-index: 1;
}
/* Die Linie zwischen den Punkten. Sie macht aus einer Liste eine Leiste. */
.tl-row::after {
    content: ""; position: absolute; left: calc(var(--tl-depth, 0) * 2rem + 5.26rem);
    top: 1.4rem; bottom: -.25rem; width: 1px; background: var(--tri-border);
}
.tl-row:last-child::after { display: none; }

.tl-card {
    border: 1px solid var(--tri-border); border-radius: .6rem; padding: .6rem .85rem; background: #fff;
    transition: border-color .15s ease, box-shadow .15s ease; min-width: 0; cursor: pointer;
}
.tl-card:hover { border-color: #d6dae0; }
.tl-row.is-active > .tl-card {
    border-color: var(--tl-accent, var(--tri-green));
    box-shadow: 0 0 0 2px rgba(var(--tri-green-rgb), .12);
}

/* EINE Zeile, nie zwei: Art, Tokens, Agentenchip, Agentenname, rechts die Pause. Mit Umbruch rutschte
   ein langer Agentenname in eine zweite Zeile, und die Karte sah anders aus als alle anderen. Gekürzt
   wird allein der Name (`flex: 0 1 auto` + Ellipse), alles andere behält seine Breite. */
.tl-card-head { display: flex; align-items: baseline; gap: .35rem; flex-wrap: nowrap; min-width: 0; margin-bottom: .15rem; }
.tl-card-head > * { flex: 0 0 auto; }
.tl-kind { font-size: .82rem; font-weight: 700; color: var(--tl-accent, var(--tri-muted)); }
.tl-meta { font-size: .78rem; color: var(--tri-faint); }
/* Die Pause vor einem Eintrag, rechts außen. Wo Zeit verging, ist die interessanteste Stelle eines
   langen Laufs – deshalb steht sie an fester Stelle und nicht im Fließtext. */
.tl-dur { margin-left: auto; font-size: .78rem; color: var(--tri-muted); }
.tl-card-title { font-size: .95rem; font-weight: 600; color: var(--tri-text); overflow-wrap: anywhere; }
.tl-card-preview {
    font-size: .84rem; color: var(--tri-muted-2); line-height: 1.45; margin-top: .2rem;
    display: -webkit-box; -webkit-box-orient: vertical; overflow: hidden; overflow-wrap: anywhere;
}
.tl-card-preview.is-mono { font-size: .8rem; }

/* Mehrere gleichzeitige Kritiker: eine Karte, darin je Stimme eine Zeile. */
.tl-card-group { padding-bottom: .35rem; }
.tl-sub-row {
    display: flex; align-items: center; gap: .55rem;
    border: 1px solid var(--tri-border); border-radius: .45rem;
    padding: .3rem .5rem; margin-top: .35rem; background: #fcfcfd; cursor: pointer;
}
.tl-sub-row:hover { background: var(--tri-surface); }
.tl-sub-row.is-active { border-color: var(--tl-accent, var(--tri-green)); background: #fff; }
.tl-badge { font-size: .68rem; font-weight: 700; border-radius: .35rem; padding: .05rem .45rem; white-space: nowrap; }
.tl-badge.is-reject { background: #fdeceb; color: #a6342a; }
.tl-badge.is-ok { background: var(--tri-green-bg); color: var(--tri-green); }
.tl-sub-name { font-size: .84rem; font-weight: 600; color: var(--tri-text); white-space: nowrap; }
.tl-sub-text { font-size: .82rem; color: var(--tri-faint); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; flex: 1 1 auto; min-width: 0; }
.tl-sub-tokens { white-space: nowrap; }

/* Die drei Dichtestufen ändern, wie viel eine Zeile zeigt – nicht die Schriftgröße. */
.tl-z0 .tl-card-preview { display: none; }
.tl-z0 .tl-card { padding: .35rem .75rem; }
.tl-z0 .tl-sub-text { display: none; }
.tl-z1 .tl-card-preview { -webkit-line-clamp: 2; }
.tl-z2 .tl-card-preview { -webkit-line-clamp: 10; }

/* Farben je Art – dieselbe Sprache wie im Designer: Grün für den Agenten, Grau für Fremdes,
   Rot für den Gatekeeper. */
/* Je Art eine Farbe und eine Tönung davon. Die Tönung trägt die Kachel im Detailkopf und das
   Werkzeug-Ergebnis – dasselbe Zeichen in zwei Stärken, damit Band und Einzelheiten zusammengehören. */
.tl-user { --tl-accent: #2f7dd6; --tl-tint: #e9f1fb; }
.tl-agent { --tl-accent: var(--tri-green); --tl-tint: var(--tri-green-bg); }
/* Denkprozess und Zwischentext: dieselbe Familie wie die Antwort (es ist derselbe Agent, der spricht),
   aber blasser – sie sind Nebenwege des Zuges, nicht sein Ergebnis. */
.tl-think { --tl-accent: #8e7cc3; --tl-tint: #f1eef9; }
.tl-note { --tl-accent: #5f9ea0; --tl-tint: #e9f3f3; }
.tl-tool { --tl-accent: #b5760f; --tl-tint: #faefe0; }
.tl-toolresult { --tl-accent: #8a9099; --tl-tint: #f1f2f4; }
.tl-critic { --tl-accent: #7a869a; --tl-tint: #eef1f4; }
.tl-gatekeeper { --tl-accent: var(--tri-red); --tl-tint: #fbecea; }

/* ---- Die Einzelheiten ---- */
.tl-detail {
    display: flex; flex-direction: column; min-height: 0;
    border: 1px solid var(--tri-border); border-radius: .75rem; background: #fff; overflow: hidden;
}
.tl-detail-empty {
    flex: 1 1 auto; display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: .6rem; color: var(--tri-faint); font-size: .9rem;
}
.tl-detail-empty > .bi { font-size: 1.6rem; }

.tl-detail-head { display: flex; align-items: flex-start; gap: .85rem; padding: 1rem 1.1rem; }
/* Die Kachel links trägt den Punkt in der Farbe der Art – dasselbe Zeichen wie im Band, nur größer.
   So erkennt man ohne Lesen, womit man es zu tun hat. */
/* Die Höhe ist nicht geraten: Art-Zeile (1 rem × 1,2) plus Titel (1,45 rem × 1,2) ergeben rund 3 rem –
   so schliesst die Kachel oben und unten mit den beiden Textzeilen daneben ab. */
.tl-detail-mark {
    flex: 0 0 auto; width: 3rem; height: 3rem; border-radius: .8rem;
    display: flex; align-items: center; justify-content: center;
    background: var(--tl-tint, var(--tri-surface));
}
.tl-detail-mark .tl-dot { width: .95rem; height: .95rem; margin: 0; box-shadow: none; }
.tl-detail-kind { display: flex; align-items: baseline; gap: .4rem; }
.tl-detail-art { font-weight: 700; color: var(--tl-accent, var(--tri-muted)); }
.tl-detail-run { font-size: .85rem; color: var(--tri-faint); }
.tl-detail-title { font-size: 1.45rem; font-weight: 700; line-height: 1.2; color: var(--tri-text); overflow-wrap: anywhere; }
.tl-detail-time { font-size: .9rem; color: var(--tri-faint); padding-top: .15rem; }

.tl-nav { display: flex; gap: .4rem; }
.tl-nav-btn {
    width: 2.2rem; height: 2.2rem; border-radius: .55rem;
    border: 1px solid var(--tri-border); background: #fff; color: var(--tri-muted-2);
    display: flex; align-items: center; justify-content: center;
}
.tl-nav-btn:hover:not(:disabled) { border-color: var(--tri-green); color: var(--tri-green); }
.tl-nav-btn:disabled { opacity: .35; }

/* Die Fakten: Zahl zuerst, Bezeichner dahinter – so liest man sie in einem Zug. */
.tl-facts {
    display: flex; gap: .35rem 1.6rem; flex-wrap: wrap;
    padding: .65rem 1.1rem; background: #fafbfc;
    border-top: 1px solid var(--tri-border); border-bottom: 1px solid var(--tri-border);
    font-size: .88rem; color: var(--tri-faint);
}
.tl-facts b { font-weight: 600; color: var(--tri-text); }

.tl-detail-body { flex: 1 1 auto; min-height: 0; overflow: auto; padding: 1.1rem; }
.tl-detail-foot { padding: .6rem 1.1rem; border-top: 1px solid var(--tri-border); }

.tl-pre {
    margin: 0; white-space: pre-wrap; overflow-wrap: anywhere;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: .86rem; line-height: 1.75; color: var(--tri-text);
    background: #f6f7f5; border-radius: .6rem; padding: 1rem 1.1rem;
}
.tl-pre.is-error { background: #fdeceb; color: #8d2b22; }
.tl-pre-think { background: #f4f1fb; color: #4b4063; margin-bottom: .7rem; }
/* Gesetztes Markdown im Detailbereich: dieselbe Fläche wie der Block daneben, aber in der normalen
   Schrift – es ist Prosa, kein Maschinenformat. */
.tl-md { background: var(--tri-surface); border-radius: .6rem; padding: 1rem 1.1rem; font-size: .92rem; }
.tl-md .markdown-body { font-size: .92rem; }
.tl-md .markdown-body > :first-child { margin-top: 0; }
.tl-md .markdown-body > :last-child { margin-bottom: 0; }

/* Das Ergebnis eines Werkzeugs ist ein Satz an das Modell, kein Datenblock: normale Schrift, und in
   der Tönung der Art – damit sieht man auf einen Blick, dass es zum Aufruf darüber gehört.
   HEISST BEWUSST NICHT `.tl-result`: So heisst die ART „Ergebnis" (`tl-@art`), und der Kasten hier
   traf damit auch die Filter-Pille „Ergebnis" – die wurde dadurch zum grossen grünen Block. */
.tl-toolout {
    white-space: pre-wrap; overflow-wrap: anywhere;
    font-size: .92rem; line-height: 1.6; color: var(--tri-text);
    background: var(--tl-tint, var(--tri-surface)); border-radius: .6rem; padding: 1rem 1.1rem;
}
.tl-toolout.is-error { background: #fdeceb; color: #8d2b22; }

/* Die Start-Kästen: was vor dem ersten Ereignis an das Modell ging. Eine eigene, ruhige Farbe –
   sie gehören zur Leiste, sind aber kein Ereignis auf ihr. */
.tl-setup { --tl-accent: #6f5bd1; --tl-tint: #f1eefb; }

/* Delegationen: das Ergebnis eines Sub-Laufs, das in den Verlauf zurückkommt. */
.tl-delegation { --tl-accent: #2a8f8a; --tl-tint: #e6f4f3; }

/* Kleine Marken an einer Karte: Anhänge, Denkprozess, der Lauf einer Delegation. Sie stehen dort,
   weil der Chat-Verlauf sie auch zeigt – ein Eintrag mit angehängter Datei soll sich von einem ohne
   unterscheiden, ohne dass man ihn erst öffnet. */
.tl-chips { display: flex; flex-wrap: wrap; gap: .3rem; margin-top: .4rem; }
.tl-chip {
    font-size: .72rem; color: var(--tri-muted-2); background: var(--tri-surface);
    border-radius: 1rem; padding: .08rem .55rem; max-width: 14rem;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* Rückfragen und Hinweise an ihrer Stelle in der Zeit. Die Rückfrage ist gelb wie überall in der
   Anwendung – sie ist das, was einen Lauf anhält. */
.tl-question { --tl-accent: #b2860b; --tl-tint: #fdf4dd; }
.tl-notice { --tl-accent: #5c6470; --tl-tint: #eef0f3; }
.tl-chip.is-done { background: var(--tri-green-bg); color: var(--tri-green); }
.tl-chip.is-open { background: #fdf4dd; color: #8a6508; }

/* Dateien und das finale Ergebnis. Das Ergebnis ist das, wonach der ganze Lauf gefragt wurde – es
   bekommt den kräftigsten Akzent, damit es im Band nicht wie die zehnte Zwischenantwort aussieht. */
.tl-file { --tl-accent: #2f7dd6; --tl-tint: #e9f1fb; }
.tl-result { --tl-accent: var(--tri-green-active); --tl-tint: var(--tri-green-bg); }
/* KEIN farbiger Balken am Ergebnis: Die Karte sah damit anders aus als jede andere im Band. Die Farbe
   trägt der Punkt auf der Spur und die Art-Zeile – das genügt. */

/* =====================================================================
   ERGEBNIS eines Laufs
   Oben, WAS herauskam und was er gekostet hat; darunter die vier Dinge,
   die ein Lauf hinterlässt – jede Zeile mit ihrer Anzahl, auch der Null.
   „Keine Mails" ist eine Auskunft und kein fehlender Abschnitt.
   ===================================================================== */
.erg { display: flex; flex-direction: column; }

/* Zustands-Pille: der Punkt trägt die Farbe, der Text bleibt lesbar. */
.erg-pill {
    display: inline-flex; align-items: center; gap: .4rem;
    border-radius: 1.2rem; padding: .15rem .7rem; font-size: .8rem; font-weight: 600; white-space: nowrap;
}
.erg-pill-dot { width: .45rem; height: .45rem; border-radius: 50%; background: currentColor; }
.erg-pill.is-ok { background: var(--tri-green-bg); color: var(--tri-green); }
.erg-pill.is-warn { background: #fdf4dd; color: #8a6508; }
.erg-pill.is-err { background: #fdeceb; color: #8d2b22; }
.erg-pill.is-run { background: #e9f1fb; color: #2f7dd6; }

/* Die Kennzahlen: Beschriftung klein darüber, Wert groß darunter – man liest die Zahlen in einer Reihe. */

.erg-body { border: 1px solid var(--tri-border); border-radius: .75rem; overflow: hidden; background: #fff; }
/* Beschriftung ÜBER dem Inhalt, nicht daneben: Die feste Spalte von 15 rem liess den Text erst weit
   rechts beginnen und nahm ihm ein Viertel der Breite – bei Tabellen und langen Antworten merkt man das
   sofort. Jetzt nutzt jeder Abschnitt die volle Breite. */
.erg-row { display: block; padding: 1rem 1.25rem; border-bottom: 1px solid var(--tri-border); }
/* Die Beschriftung steht OBEN, nicht mittig: Bei einer langen Antwort rutschte sie sonst in die Mitte
   des Textes und sah aus wie eine Zwischenüberschrift. Sie ist zugleich der Schalter zum Auf- und
   Zuklappen – deshalb ein <button>, der sich wie Text gibt (kein Rahmen, keine Fläche). */
.erg-row-label {
    display: flex; align-items: center; gap: .5rem; align-self: start;
    background: none; border: 0; padding: 0; text-align: left; width: 100%;
    font-weight: 700; color: var(--tri-text); cursor: pointer;
}
.erg-row-label:hover { color: var(--tri-green); }
.erg-row-caret { font-size: .8rem; color: var(--tri-faint); }
.erg-row-label:hover .erg-row-caret { color: var(--tri-green); }
.erg-count { background: var(--tri-surface); color: var(--tri-muted-2); border-radius: 1rem; padding: .02rem .5rem; font-size: .76rem; font-weight: 700; }
.erg-row-content { min-width: 0; margin-top: .55rem; }
.erg-empty { color: var(--tri-faint); font-size: .92rem; }
/* Die finale Antwort bekommt einen grünen Rahmen: Sie ist das Ergebnis des Laufs und steht zwischen
   lauter gleich aussehenden Abschnitten – ohne Rahmen war nicht zu sehen, wo sie anfängt und aufhört.
   RUNDUM gleich stark, KEIN dicker Balken links: Der Nutzer will diesen Akzentstreifen grundsätzlich
   nirgends. */
.erg-final {
    font-size: .95rem; line-height: 1.6;
    border: 1px solid var(--tri-green-soft);
    border-radius: .6rem; background: #fcfefc; padding: .9rem 1.1rem;
}
.erg-final .markdown-body > :first-child { margin-top: 0; }
.erg-final .markdown-body > :last-child { margin-bottom: 0; }

/* Eine Benachrichtigung als Zeile: Kürzel, Frage, Zeiten, Dauer, Zustand. */
.erg-notif { display: flex; align-items: center; gap: .9rem; padding: .7rem 1.25rem; border-bottom: 1px solid var(--tri-border); }
.erg-notif:last-child { border-bottom: 0; }
.erg-initials {
    flex: 0 0 auto; width: 2.1rem; height: 2.1rem; border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    background: #fdf4dd; color: #8a6508; font-size: .76rem; font-weight: 700;
}
.erg-notif-main { flex: 1 1 auto; min-width: 0; }
.erg-notif-head { display: flex; align-items: center; gap: .55rem; flex-wrap: wrap; }
.erg-notif-subject { font-weight: 600; color: var(--tri-text); overflow-wrap: anywhere; }
.erg-tag { background: #fdf4dd; color: #8a6508; border-radius: .35rem; padding: .02rem .45rem; font-size: .72rem; font-weight: 600; }
.erg-notif-sub { font-size: .85rem; color: var(--tri-muted); }
.erg-notif-times { color: var(--tri-faint); }
.erg-notif-dur { font-size: .82rem; color: var(--tri-faint); white-space: nowrap; }

/* ---- Lauf-Informationen ----
   Felder in einem Raster statt in Spalten: Beschriftung klein darüber, Wert in Schreibmaschinenschrift
   darunter, bei Bedarf eine Fußnote. So stehen die Werte auf derselben Breite und lassen sich
   vergleichen – Zeiten, Zahlen und Fristen sind genau das, wofür man sie nebeneinander hält. */
.rd-info { overflow: hidden; }
.rd-info-head {
    display: flex; align-items: center; gap: .7rem; flex-wrap: wrap;
    width: 100%; border: 0; background: transparent; text-align: left;
    padding: .6rem 1.1rem; color: var(--tri-text);
}
.rd-info-head:hover { background: #fafbfc; }
.rd-info-caret { color: var(--tri-muted); font-size: .8rem; }
.rd-info-title { font-weight: 700; }
/* Die Laufnummer steht nur noch HIER (nicht mehr zusätzlich in der Kopfzeile) – deshalb fett und in
   der Textfarbe statt hellgrau: Sie ist die Kennung des Laufs, kein Beiwerk. */
.rd-info-run { font-size: .9rem; font-weight: 700; color: var(--tri-text); }
.rd-info-by { margin-left: auto; font-size: .88rem; color: var(--tri-muted); }

.rd-info-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr)); border-top: 1px solid var(--tri-border); }
.rd-fact { display: flex; flex-direction: column; gap: .05rem; padding: .55rem 1.1rem; border-right: 1px solid var(--tri-border); line-height: 1.3; }
.rd-fact:last-child { border-right: 0; }
.rd-fact-label { font-size: .78rem; color: var(--tri-muted); }
.rd-fact-value { font-size: .9rem; font-weight: 600; color: var(--tri-text); }
/* Der Kontext-Ring sitzt in einem Faktenfeld und soll dort nicht mehr Platz nehmen als eine Zeile Text. */
.rd-fact .form-text { margin-top: 0; }
.rd-fact-note { font-size: .76rem; color: var(--tri-faint); }
/* Einheit unter der Zahl im Kontext-Ring: klein und hell – die Zahl trägt die Auskunft. */
.rd-gauge-unit { font-size: .76rem; line-height: 1.3; color: var(--tri-faint); }

/* ---- Tokenverbrauch ----
   Der Balken oben zeigt die vier Anteile auf einen Blick; die Tabelle darunter nennt die Zahlen. Eine
   Tabelle allein beantwortet „wo gehen die Tokens hin?" erst, nachdem man vier Zahlen verglichen hat. */
.tok-bar { display: flex; gap: 2px; height: .6rem; margin-bottom: 1.1rem; }
.tok-seg { border-radius: 3px; background: var(--tok-accent, var(--tri-faint)); }
.tok-seg.is-out { opacity: .4; }
.tok-legend { display: flex; gap: 1.1rem; flex-wrap: wrap; font-size: .82rem; color: var(--tri-muted); margin-bottom: .45rem; }
.tok-leg { display: inline-flex; align-items: center; gap: .4rem; }
/* Der Punkt sitzt auf der MITTE der ersten Zeile, nicht an deren Oberkante: `align-items: flex-start`
   stellt ihn sonst oben bündig an den Zeilenkasten, und bei einem zweizeiligen Namen stand er sichtbar
   über dem Text. Die halbe Zeilenhöhe minus halbe Punkthöhe trifft die Mitte, auch wenn der Name umbricht. */
.tok-dot {
    width: .6rem; height: .6rem; border-radius: 2px; background: var(--tok-accent, var(--tri-faint));
    flex: 0 0 auto;
}
.tok-dot.is-out { opacity: .4; }

.is-worker { --tok-accent: var(--tri-green); }
.is-critic { --tok-accent: #7a869a; }
.is-gatekeeper { --tok-accent: var(--tri-red); }

.tok-table { display: flex; flex-direction: column; }
.tok-head, .tok-zeile {
    display: grid; grid-template-columns: minmax(14rem, 2fr) 7rem 7rem 7rem minmax(8rem, 1fr) 6rem;
    gap: 1rem; align-items: center; padding: .7rem 1.25rem;
}
.tok-head { background: #fafbfc; border-bottom: 1px solid var(--tri-border); font-size: .82rem; color: var(--tri-muted); }
.tok-zeile { border-bottom: 1px solid var(--tri-border); font-size: .9rem; }
.tok-zeile:last-child { border-bottom: 0; }
.tok-zeile.is-sum { background: #fafbfc; font-weight: 600; }
/* Die Zeile des gerade geöffneten Laufs: Die Tabelle zeigt die ganze Kette, also muss erkennbar sein,
   welcher davon der eigene ist. */
.tok-zeile.is-this { background: var(--tri-green-bg); }
/* Überschrift einer Provider-Gruppe: eine ruhige Zwischenzeile, kein zweiter Tabellenkopf. */
.tok-gruppe {
    padding: .55rem 1.25rem .3rem; font-size: .78rem; font-weight: 700; letter-spacing: .02em;
    color: var(--tri-muted-2); background: #fcfcfd; border-bottom: 1px solid var(--tri-border);
}
.tok-num { text-align: right; }
.tok-wer { display: flex; align-items: center; gap: .55rem; min-width: 0; }
.tok-wer-main { display: flex; flex-direction: column; min-width: 0; }
/* Der Agentenname bleibt EINZEILIG und kürzt mit „…": Ein umbrechender Name schob die Zeile auf zwei
   Zeilen, und die Tabelle verlor ihr Raster. Nummer-Chip und Rollen-Chip schrumpfen nie mit (`flex: 0 0 auto`),
   gekürzt wird allein der Name; der volle Name steht im `title`. */
.tok-name { display: flex; align-items: center; gap: .35rem; min-width: 0; font-weight: 600; color: var(--tri-text); }
.tok-name > .agent-num-inline, .tok-name > .tok-rolle { flex: 0 0 auto; margin-right: 0; margin-left: 0; }
.tok-name-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.tok-rolle { background: var(--tri-surface); color: var(--tri-muted-2); border-radius: .35rem; padding: .02rem .45rem; font-size: .72rem; font-weight: 600; margin-left: .35rem; }
.tok-anteil { display: flex; align-items: center; gap: .6rem; }
.tok-anteil-bar { flex: 1 1 auto; height: .4rem; background: var(--tri-surface); border-radius: 3px; overflow: hidden; }
.tok-anteil-fill { display: block; height: 100%; background: var(--tok-accent, var(--tri-faint)); border-radius: 3px; }
.tok-anteil-zahl { font-size: .82rem; color: var(--tri-muted); white-space: nowrap; }
@media (max-width: 991.98px) {
    .tok-head { display: none; }
    .tok-zeile { grid-template-columns: 1fr 1fr; }
}

/* Die Anzahl an jeder Filterpille; eine Art ohne Einträge bleibt sichtbar, aber abgeblendet. */
/* Agentenname im Detailkopf – nur bei Sub-Agenten, deshalb ruhig und klein neben der Art. */
/* Agent eines Sub-Laufes: Nummer im üblichen hellgrünen Chip, Name DANEBEN in derselben Größe. Nummer
   und Name sind EINE Angabe; ein kleinerer Name sah aus wie eine Fußnote zur Nummer. */
.tl-card-agent { font-size: .78rem; margin-right: 0; }
.tl-card-head > .tl-card-agentname {
    flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.tl-card-agentname { font-size: .78rem; font-weight: 600; color: var(--tri-muted); }
.tl-detail-agent { font-size: inherit; font-weight: 600; color: var(--tri-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tl-pill-n { font-size: .72rem; color: var(--tri-faint); font-variant-numeric: tabular-nums; }
.tl-pill.is-on .tl-pill-n { color: var(--tri-muted-2); }
.tl-pill.is-empty { opacity: .4; cursor: default; }
.tl-pill.is-empty:hover { background: transparent; }

/* ---- Lauf-Detailseite: Vollhöhe ----
   Kopf oben, Registerkarte nimmt den Rest, und innerhalb der Karte scrollt nur der Registerinhalt.
   So passt die Zeitleiste IMMER auf den Schirm – auch wenn der Kopf auf- oder zugeklappt wird. */
/* Die Lauf-Seite reicht bis an den unteren Rand. Der Standardabstand jeder Seite (`pb-4`) und der
   Abstand unter der Registerkarte standen sonst als graue Fläche darunter – zusammen rund 40 px, die
   dem Band fehlten. Die Karte selbst behält unten nur noch Luft zum Atmen. */
/* `!important`, weil `pb-4` eine Bootstrap-Hilfsklasse ist und die ihrerseits `!important` trägt –
   ohne das bliebe der Rand stehen, egal wie genau der Selektor ist. */
.page-content:has(> .rd-page) { padding-bottom: .5rem !important; }
.rd-page { display: flex; flex-direction: column; min-height: 0; }
/* Alles ausser der Registerkarte behält seine natürliche Höhe. Ohne das drückt die Flex-Spalte den
   Kopf zusammen, sein Inhalt läuft über die Karte hinaus, und das Zuklappen bringt fast nichts. */
.rd-page > * { flex: 0 0 auto; }
.rd-page > .rd-tabs { flex: 1 1 auto; display: flex; flex-direction: column; min-height: 0; overflow: hidden; }
.rd-tabs > .card-body { flex: 1 1 auto; min-height: 0; overflow: auto; }
/* Das Register „Timeline" scrollt NICHT als Ganzes – es teilt sich selbst in Band und Einzelheiten. */
.rd-tabs > .card-body:has(> .tl) { overflow: hidden; }

/* ---- Schwebender Kopf über einer Szene (Agentenwolke, 3D-Karte) ----
   Wolke und 3D leben von der Fläche. Ein Kopf, der 170 px davon wegnimmt, kostet dort mehr als er
   sagt – deshalb steht er NICHT in der Spalte, sondern liegt darüber. Die Szene reicht dann von
   oben bis unten, und der Kopf wirft einen Schatten darauf, damit beides nicht ineinanderläuft.
   Links und rechts genau so weit eingerückt wie der übrige Seiteninhalt (px-3 / px-lg-4): Absolut
   gesetzt wird am POLSTERKASTEN gemessen, nicht am Inhalt – 0 läge sonst unter dem Seitenrand. */
.page-content:has(> .rbh-sticky > .rbh-floating) { position: relative; }
.page-content > .rbh-sticky:has(> .rbh-floating) {
    position: absolute;
    top: 1rem;
    left: 1rem;
    right: 1rem;
    z-index: 30;
    padding: 0;
    background: transparent;
}
@media (min-width: 992px) {
    /* Auch OBEN 1,5 rem - genau wie links und rechts und wie der klebende Kopf der uebrigen
       Ansichten. Mit 1 rem sass der Kopf in Wolke und 3D acht Pixel tiefer als in Ordner und
       Liste, und beim Umschalten sprang er. */
    .page-content > .rbh-sticky:has(> .rbh-floating) { top: 1.5rem; left: 1.5rem; right: 1.5rem; }
}
/* Der Rand der Karte entfaellt: Die Lage bestimmt der Behaelter (`top`), ein Rand obendrauf
   verschoebe den Kopf ein zweites Mal. */
.page-content > .rbh-sticky:has(> .rbh-floating) > .rbh { margin-top: 0 !important; margin-bottom: 0; }

/* Ueber einer DUNKLEN Szene (3D-Ansicht mit „Dark Mode") gilt die hellere Grundfarbe: Dort zieht
   die Durchsicht nach unten, nicht nach oben. Erkannt wird das an der Bedienleiste im Anbau - sie
   traegt dort `is-dark`. */
.page-content .rbh.rbh-floating:has(.map-bar-im-banner.is-dark) .rbh-body {
    background: var(--wl-signature-float-dark, rgba(var(--tri-green-schwebend-dunkel-rgb), .85));
}

/* Die Bedienleiste der 3D-Ansicht, wenn sie IM Anbau des Kopfes steht statt über der Szene zu
   schweben: kein eigener Kasten mehr – der Anbau ist schon einer. */
.map-bar-im-banner { margin: 0; flex-wrap: wrap; }

/* ---- Die Leiste der Karten-Ansichten im Haus-Design ------------------------------------------
   Sie steht im weissen Anbau des Banners und trug noch Bootstraps `input-group` und `btn-sm`:
   zwei eckige Kaestchen nebeneinander und flache Knoepfe, waehrend direkt darunter die Listen mit
   runden Feldern stehen. Umgebaut wird NICHT das Markup (es bedient drei Karten - Agenten, Brain,
   Memory), sondern die Form - dieselben Werte wie `.rbh-suche` und `.rbh-feld`. */
.map-bar-im-banner .map-bar-suche { width: 17rem; max-width: 17rem; }
.map-bar-im-banner .input-group {
    display: flex;
    align-items: center;
    flex-wrap: nowrap;
    gap: .5rem;
    height: 42px;
    padding: 0 .85rem;
    border: 1px solid var(--tri-border);
    border-radius: .75rem;
    background: #fff;
}
.map-bar-im-banner .input-group > .input-group-text {
    border: 0; background: transparent; padding: 0; color: var(--tri-faint);
}
.map-bar-im-banner .input-group > .form-control {
    border: 0; background: transparent; padding: 0; box-shadow: none; font-size: .95rem; min-width: 0;
}
.map-bar-im-banner .input-group > .btn {
    border: 0; background: transparent; color: var(--tri-faint); padding: 0 .2rem; height: auto;
}
/* Die Aufklapper („Arten", „7 Provider") wie ein Auswahlfeld der Haus-Reihe. */
.map-bar-im-banner .map-bar-pop > .btn {
    display: inline-flex; align-items: center;
    height: 42px;
    padding: 0 .85rem;
    border: 1px solid var(--tri-border);
    border-radius: .75rem;
    background: #fff;
    color: var(--tri-text);
    font-size: .95rem;
}
.map-bar-im-banner .map-bar-pop > .btn:hover { background: var(--tri-surface); }

/* Im Dark Mode dieselbe Form, nur in den Farben der Szene. */
.map-bar-im-banner.is-dark .input-group,
.map-bar-im-banner.is-dark .map-bar-pop > .btn {
    background: rgba(255, 255, 255, .06);
    border-color: #3c444c;
    color: #d7dee4;
}
.map-bar-im-banner.is-dark .map-bar-pop > .btn:hover { background: rgba(255, 255, 255, .12); }

/* Der schwebende Kopf selbst: KEIN weisser Kasten darum. Die Karte gibt Rahmen und Grund ab, Kopf
   und Anbau tragen beides selbst – und zwar leicht durchscheinend, damit man sieht, dass die Szene
   darunter weitergeht. Die Weichzeichnung dahinter hält den Text trotzdem lesbar. */
.page-content .rbh.rbh-floating {
    border: 0;
    background: transparent;
    /* Der Schatten gehört zum schwebenden Kopf, nicht zu der Seite, die ihn benutzt – sonst müsste
       ihn jede neue Seite wieder mitbringen (der Designer hat genau das gebraucht). */
    box-shadow: 0 .6rem 1.8rem rgba(16, 24, 40, .18);
}
/* Der SCHWEBENDE Kopf liegt durchscheinend ueber einer Szene und wirkte dadurch heller (auf hellem
   Grund) bzw. dunkler (auf schwarzem) als jeder andere Banner. Die Grundfarbe ist deshalb so weit
   verschoben, dass bei 85 % Deckkraft wieder genau --tri-green herauskommt - Rechnung an den beiden
   Token. Welche der beiden gilt, entscheidet die Szene darunter (siehe die Regel fuer „Dark Mode"). */
.page-content .rbh.rbh-floating .rbh-body {
    /* Mit Branding die vorberechnete Grundfarbe des Kunden (`--wl-signature-float`, gesetzt von
       js/branding-boot.js); ohne Branding der vorberechnete Gruenton. Beide sind so abgedunkelt, dass
       bei 85 % Deckkraft ueber dem Blatt wieder die eigentliche Bandfarbe herauskommt. */
    background: var(--wl-signature-float, rgba(var(--tri-green-schwebend-rgb), .85));
    -webkit-backdrop-filter: blur(8px);
    backdrop-filter: blur(8px);
    /* Dieselben 18 px wie bei jedem anderen Banner - hier traegt der KOPF die Rundung, weil die
       Karte darum durchsichtig und randlos ist. */
    border-radius: 14px 14px 0 0;
}
.page-content .rbh.rbh-floating:not(:has(.rbh-attached)) .rbh-body { border-radius: 14px; }
.page-content .rbh.rbh-floating .rbh-attached {
    background: rgba(255, 255, 255, .72);
    -webkit-backdrop-filter: blur(8px);
    backdrop-filter: blur(8px);
    border-radius: 0 0 14px 14px;
}
/* „Dark Mode" der 3D-Ansicht: Der Anbau dreht mit. Ein weisser Streifen unter dem Kopf wäre auf
   schwarzer Szene das Hellste im Bild – und damit das, was man zuerst ansieht. */
.page-content .rbh.rbh-floating .rbh-attached:has(.map-bar-im-banner.is-dark) {
    /* Dunkelgrau statt fast schwarz und deutlich durchscheinender als der helle Fuss: Auf der
       dunklen Szene liegt ohnehin wenig Helligkeit – ein dichter schwarzer Streifen wirkte wie ein
       Loch, ein grauer Schleier wie eine Scheibe davor. */
    background: rgba(38, 43, 48, .62);
    color: #e2e8ee;
}

/* „Neu anordnen" und „Vollbild", wenn die Leiste im Banner steht: ans rechte Ende der Zeile. Sie
   handeln an der ANSICHT und nicht am Filter – deshalb abgesetzt, nicht eingereiht. */
.map-ecke-im-banner { display: flex; gap: .4rem; margin-left: auto; }

/* Meldungen auf einer Szene (Wolke, 3D). Der Kopf SCHWEBT dort, also liegt er über allem, was oben
   in der Spalte steht – ein Hinweisband wäre halb darunter verschwunden (genau so war es zu sehen).
   Es steht deshalb unten am Fenster: dort verdeckt es nichts und ist ganz zu lesen. */
.page-content:has(> .rbh-sticky > .rbh-floating) > .alert {
    position: absolute;
    left: 1rem;
    right: 1rem;
    bottom: 1rem;
    z-index: 40;
    margin: 0;
    box-shadow: 0 .6rem 1.8rem rgba(16, 24, 40, .25);
}
@media (min-width: 992px) {
    .page-content:has(> .rbh-sticky > .rbh-floating) > .alert { left: 1.5rem; right: 1.5rem; }
}

/* ---- Leiste der 3D-Ansicht im Banner: Feinheiten ----
   Die Schalter sind grösser als in der schwebenden Leiste: Dort war die ganze Leiste klein, hier
   steht sie in einer Zeile mit Suchfeld und Stufenfeld und muss deren Höhe mittragen. */
.map-bar-im-banner .form-check .form-check-input { width: 2.4rem; height: 1.3rem; }
.map-bar-im-banner .form-check .form-check-label { font-size: .875rem; }

/* Gruppierung (Provider/Ordner) als Stufenfeld in Haus-Optik, wie das Stufenfeld der Lauf-Übersicht. */
.map-bar-im-banner .seg-switch { padding: .25rem; border-radius: .75rem; }
.map-bar-im-banner .seg-switch-btn { font-weight: 400; font-size: .85rem; padding: .45rem .85rem; border-radius: .6rem; }
.map-bar-im-banner .seg-switch-btn.is-on { font-weight: 600; }
.map-bar-im-banner .seg-switch-btn i { font-size: .95em; }

/* Auf dunklem Grund dreht auch das Stufenfeld mit. */
.map-bar-im-banner.is-dark .seg-switch { background: rgba(255, 255, 255, .08); }
.map-bar-im-banner.is-dark .seg-switch-btn { color: #cfd7df; }
.map-bar-im-banner.is-dark .seg-switch-btn.is-on { background: #2b3238; color: #86e08f; box-shadow: none; }

/* Die Karteikarte der 3D-Ansicht beginnt UNTER dem schwebenden Kopf. Wie hoch der reicht, meldet
   js/sticky-banner.js als `--rbh-float-h` (Unterkante im Fenster); die Karte sitzt im Kartenfeld,
   das 1,5 rem weiter oben beginnt – deshalb der Zuschlag. */
.map-unter-banner .sbm-lesekarte { top: calc(var(--rbh-float-h, 3.5rem) + 1.5rem + .75rem); }

/* Der Chat-Kopf als Banner: OHNE die Mindesthöhe des vollen Kopfes. Die ist für die Lauf-Detailseite
   gerechnet (Pfad, Kennung, zwei Pillenzeilen); im Chat steht unter dem Namen oft gar nichts – dort
   wären es 90 px leeres Grün. Die alte Klasse `.chat-topbar` trägt er NICHT mehr: Sie bringt weissen
   Grund, eigene Kante und negative Ränder mit, alles für das frühere Kopfband gerechnet. */
/* `rbh-reihe`: EINE Zeile statt zweier – links das führende Bild mit Kennung und Name, rechts die
   Schaltflächen. Für Köpfe, die ein Bild tragen (und deshalb nicht `OneLine` sein können), aber
   keine Kennzahlenzeile füllen: Gestapelt stünden die Knöpfe allein in einer zweiten Zeile unter
   einer halb leeren ersten. Was sonst unter dem Namen stünde, rückt neben ihn und wird gekürzt. */
.page-content .rbh.rbh-reihe .rbh-body.is-tall { min-height: 0; }
/* Und in voller Grösse: Die 1,32 rem gelten dem VOLLEN Kopf der Lauf-Detailseite, in dem Abzeichen,
   Überschrift, zwei Pillenzeilen und vier Schaltflächen übereinander stehen. Hier steht die
   Überschrift allein in ihrer Zeile und soll so gross sein wie auf jeder anderen Seite. */
/* DIESELBEN 32 px wie in jedem anderen Banner. Die 1,6 rem stammten aus der Zeit, als der volle
   Kopf seine eigene Groesse hatte; in der Reihe steht die Ueberschrift aber allein in der Zeile -
   und dass dieselbe Komponente je nach Seite anders gross schreibt, sieht nach Versehen aus. */
.page-content .rbh.rbh-reihe .rbh-body.is-tall h1 { font-size: 32px; }
.page-content .rbh.rbh-reihe .rbh-body { flex-direction: row; align-items: center; }
.page-content .rbh.rbh-reihe .rbh-ident { flex: 0 1 auto; min-width: 0; }
.page-content .rbh.rbh-reihe .rbh-foot { flex: 1 1 auto; align-items: center; margin: 0; min-width: 0; }

/* Chat ohne gewählten Agenten: kein führendes Bild. Die Komponente legt den Platz dafür an, sobald
   ein `Leading` übergeben wird – und das wird es hier, nur bleibt es dann leer. */
.page-content .rbh.rbh-chat-ohnebild .rbh-visual { display: none; }

/* ---- Tabelle mit klebender Kopfzeile unter dem Seitenkopf ----
   Die Karte trägt `tabelle-klebend`, der Behälter darin `tabelle-klebend-wrap` (NICHT
   `table-responsive`: dessen `overflow` macht `position: sticky` in der Kopfzeile wirkungslos).
   Wie hoch der klebende Seitenkopf gerade ist, meldet js/sticky-banner.js als `--rbh-sticky-h`;
   ein Pixel darunter verdeckt sein Band die Kante, und es bleibt kein Spalt, durch den die Zeilen
   durchlaufen. Die Rundung tragen die vier Eck-Zellen selbst. */
/* ---- Die Liste unter dem Banner liegt leicht auf -------------------------------------------
   Derselbe Gedanke wie beim Kopf darueber, nur knapper: ein kurzer Kontaktschatten und ein
   weicher darunter. Bootstraps `shadow-sm` war dafuer zu zaghaft - zwischen zwei weissen Flaechen
   auf hellgrauem Grund war nicht zu sehen, dass die Liste eine eigene Flaeche ist. */
/* Gilt fuer JEDE Flaeche im Seiteninhalt, nicht nur fuer Listen: Unter einem Banner steht mal eine
   Tabelle, mal eine Karte mit Feldern, mal ein Kasten mit Text - sie alle sind dieselbe Art Flaeche
   und sollen gleich aufliegen. In DIALOGEN bleibt es beim zarten Haus-Schatten (siehe unten): Dort
   liegt die Karte schon auf einer schwebenden Flaeche, und zwei Schatten uebereinander wirken wie
   ein Fehler. */
.page-content .card,
.card:has(> .card-body.p-0),
.card:has(> .table-responsive),
.card:has(> .tabelle-klebend-wrap) {
    /* MIT NACHDRUCK: Bootstraps `.shadow-sm` traegt selbst `!important` und gewaenne sonst. */
    box-shadow: var(--tri-shadow-flaeche) !important;
}
.user-modal .card,
.user-modal .card:has(> .card-body.p-0),
.user-modal .card:has(> .table-responsive) {
    box-shadow: 0 .125rem .25rem rgba(0, 0, 0, .075) !important;
}

/* Eine Karte IN einer Karte steht WEISS AUF WEISS - der Schatten allein zeigt ihre Kante dort
   nicht, und die obere Kante verschwand ganz (Datenschutz, alle Register). Ein feiner Rahmen
   rundum macht sie sichtbar; er ist an allen vier Seiten gleich stark, nie nur an einer.
   `!important`, weil die Karten `border-0` tragen und Bootstrap das selbst mit Nachdruck setzt. */
.page-content .card .card {
    border: 1px solid var(--tri-border) !important;
}

/* ---- Die Kopfzeile JEDER Liste unter einem Banner bleibt beim Scrollen stehen ---------------
   Bisher war das eine Handarbeit je Seite (`tabelle-klebend`), und wo sie fehlte, scrollte die
   Kopfzeile weg - zuletzt bei den Skills. Jetzt gilt es fuer jede Tabelle, die eine Karte
   ausfuellt.

   ZWEI Dinge gehoeren dazu, und das zweite ist der Grund, warum es so lange Handarbeit war:
   `position: sticky` ist wirkungslos, sobald IRGENDEIN Vorfahre `overflow` traegt - und genau das
   bringt Bootstraps `table-responsive` mit. Es wird deshalb hier aufgehoben.

   Wie weit der Kopf oben reicht, meldet js/sticky-banner.js als `--rbh-sticky-h`; ein Pixel
   darunter, damit zwischen Band und Kopfzeile kein Spalt bleibt. */
.card:has(> .card-body.p-0) > .card-body.p-0 > .table-responsive,
.card:has(> .table-responsive) > .table-responsive,
/* Auch die Karte selbst und ein Polsterkasten dazwischen: Jedes `overflow` auf dem Weg nach oben
   macht das Kleben wirkungslos, egal an welchem der drei Kaesten es steht. */
.card:has(> .card-body.p-0) > .card-body.p-0,
.card:has(> .card-body.p-0),
.card:has(> .table-responsive) { overflow: visible; }
/* Und ohne eigenen Grund: Die Karte ist so hoch wie die ganze Tabelle und fuellte hinter der
   klebenden Kopfzeile deren runde Ecken wieder auf. Das Weiss kommt aus den Zellen. */
.card:has(> .card-body.p-0),
.card:has(> .table-responsive),
.card:has(> .tabelle-klebend-wrap) { background-color: transparent; }

.card:has(> .card-body.p-0) thead th,
.card:has(> .table-responsive) thead th,
.card:has(> .tabelle-klebend-wrap) thead th {
    position: sticky;
    top: calc(var(--rbh-sticky-h, 0px) - 1px);
    z-index: 5;
    /* Die Trennlinie als INNERER Schatten: Bootstrap zeichnet sie ueber `border-collapse` an der
       Tabelle, und eine klebende Zelle nimmt diese Kante nicht mit - beim Scrollen verschwand sie. */
    box-shadow: inset 0 -1px 0 var(--tri-border);
}

/* ---- Und dasselbe fuer Tabellen OHNE eigene Karte -------------------------------------------
   Drei Listen lagen nicht in einer eigenen Karte, sondern frei in einem Kasten (Erkennungslisten,
   Memory- und Brain-Inhalt). Sie trugen deshalb weiter den grauen Kopf, eckige Ecken und eine
   Kopfzeile, die beim Scrollen wegrutschte. Die Form haengt jetzt an der Tabelle selbst.

   ZWEI Arten von Rollbereich: Liegt die Tabelle in einem Kasten, der SELBST rollt (`fill-scroll`,
   Voll-Hoehe-Seiten), klebt die Kopfzeile an dessen Oberkante. Sonst rollt die Seite, und sie
   klebt unter dem Banner. Dort muss das `overflow` von `table-responsive` weichen - mit ihm waere
   `position: sticky` wirkungslos. */
.page-content .table-responsive > table > thead,
.page-content .table-responsive > table > thead.table-light {
    --bs-table-bg: #fff;
    --bs-table-color: var(--tri-muted);
}
.page-content .table-responsive > table > thead > tr:first-child > th:first-child { border-top-left-radius: .75rem; }
.page-content .table-responsive > table > thead > tr:first-child > th:last-child { border-top-right-radius: .75rem; }
.page-content .table-responsive > table > tbody > tr:last-child > td:first-child { border-bottom-left-radius: .75rem; }
.page-content .table-responsive > table > tbody > tr:last-child > td:last-child { border-bottom-right-radius: .75rem; }

.page-content .table-responsive:not(.fill-scroll) { overflow: visible; }
.page-content .table-responsive > table > thead > tr > th {
    position: sticky;
    top: calc(var(--rbh-sticky-h, 0px) - 1px);
    z-index: 5;
    box-shadow: inset 0 -1px 0 var(--tri-border);
}
.page-content .table-responsive.fill-scroll > table > thead > tr > th { top: 0; }

/* ---- Der Tabellenkopf unter einem Banner ist WEISS ------------------------------------------
   Vorbild ist die Lauf-Uebersicht. Bootstraps `table-light` faerbt den Kopf grau; zwischen dem
   gruenen Banner und der weissen Liste stand damit ein drittes Band in einer dritten Farbe.
   Getrennt wird durch die feine Linie darunter, nicht durch eine Flaeche.
   Gesetzt wird die Bootstrap-VARIABLE, nicht `background`: Die Zellen holen ihre Farbe ueber einen
   inneren Schatten aus `--bs-table-bg`, eine Hintergrundfarbe daneben bliebe wirkungslos. */
.card:has(> .card-body.p-0) thead,
.card:has(> .card-body.p-0) thead.table-light,
.card:has(> .table-responsive) thead,
.card:has(> .table-responsive) thead.table-light,
.card:has(> .tabelle-klebend-wrap) thead {
    --bs-table-bg: #fff;
    --bs-table-color: var(--tri-muted);
}

/* ---- Runde Ecken fuer eine Tabelle, die eine Karte ausfuellt --------------------------------
   Eine Karte mit `card-body p-0` gibt ihre Flaeche ganz der Tabelle. Beschneiden kann die Karte
   sie nicht: `overflow: hidden` an einer Karte macht jedes Kleben der Kopfzeile wirkungslos und
   schneidet Aufklappmenues ab. Die Rundung tragen deshalb die vier ECKZELLEN - dasselbe Rezept wie
   bei `tabelle-klebend`, nur ohne dass jede Seite es abschreiben muss. */
.card:has(> .card-body.p-0) thead tr:first-child th:first-child,
.card:has(> .table-responsive) thead tr:first-child th:first-child { border-top-left-radius: .75rem; }
.card:has(> .card-body.p-0) thead tr:first-child th:last-child,
.card:has(> .table-responsive) thead tr:first-child th:last-child { border-top-right-radius: .75rem; }
.card:has(> .card-body.p-0) tbody tr:last-child td:first-child,
.card:has(> .table-responsive) tbody tr:last-child td:first-child { border-bottom-left-radius: .75rem; }
.card:has(> .card-body.p-0) tbody tr:last-child td:last-child,
.card:has(> .table-responsive) tbody tr:last-child td:last-child { border-bottom-right-radius: .75rem; }
/* Der Rollbehaelter dazwischen darf die Ecken nicht quadratisch ueberdecken. */
.card:has(> .card-body.p-0) > .card-body.p-0,
.card:has(> .card-body.p-0) > .card-body.p-0 > .table-responsive,
.card:has(> .table-responsive) > .table-responsive { border-radius: inherit; }

.tabelle-klebend {
    border-radius: .75rem;
    /* KEIN eigener Grund. Die Karte ist so hoch wie die ganze Tabelle; beim Scrollen steht sie
       hinter der klebenden Kopfzeile als weisses Rechteck und fuellt deren runde Ecken wieder auf -
       die Tabelle sah oben eckig aus, sobald man scrollte. Das Weiss kommt jetzt aus den ZELLEN,
       und die Rundung der Eckzellen steht frei vor dem Seitengrund.
       Beschneiden (`overflow: hidden`) ist keine Loesung: Es macht das Kleben wirkungslos. */
    background-color: transparent;
}
.tabelle-klebend-wrap thead th {
    position: sticky;
    top: calc(var(--rbh-sticky-h, 0px) - 1px);
    z-index: 5;
    background: #fff;
    /* Als INNERER Schatten: Bootstrap zeichnet die Linie über `border-collapse` an der Tabelle, und
       eine klebende Zelle nimmt diese Kante nicht mit. */
    box-shadow: inset 0 -1px 0 var(--tri-border);
}
/* ---- Runde Ecken AUCH im geklebten Zustand ---------------------------------------------------
   Beim Scrollen laufen die Zeilen UNTER der klebenden Kopfzeile hindurch. In deren runder Ecke
   schaut dann die weisse Zelle dahinter hervor, und die Tabelle sieht oben wieder eckig aus.
   Beschneiden kann man es nicht - `overflow: hidden` an einem Vorfahren hebt das Kleben auf.

   Die Kopfzelle malt deshalb SELBST einen Keil in der Seitenfarbe in ihre Ecke: ein Quadrat von
   der Groesse des Radius, aus dem ein Viertelkreis ausgespart ist. Weil der Keil ein Kind der
   klebenden Zelle ist, liegt er ueber den durchlaufenden Zeilen. */
.tabelle-klebend-wrap thead th:first-child::before,
.tabelle-klebend-wrap thead th:last-child::before,
.aro-tabelle thead th:first-child::before,
.aro-tabelle thead th:last-child::before,
.agents-table-wrap thead th:first-child::before,
.agents-table-wrap thead th:last-child::before,
.card:has(> .card-body.p-0) thead th:first-child::before,
.card:has(> .card-body.p-0) thead th:last-child::before,
.card:has(> .table-responsive) thead th:first-child::before,
.card:has(> .table-responsive) thead th:last-child::before {
    content: '';
    position: absolute;
    top: 0;
    width: .75rem;
    height: .75rem;
    background: var(--tri-surface);
    pointer-events: none;
}
.tabelle-klebend-wrap thead th:first-child::before,
.aro-tabelle thead th:first-child::before,
.agents-table-wrap thead th:first-child::before,
.card:has(> .card-body.p-0) thead th:first-child::before,
.card:has(> .table-responsive) thead th:first-child::before {
    left: 0;
    -webkit-mask: radial-gradient(circle at 100% 100%, transparent 0 .75rem, #000 .75rem);
    mask: radial-gradient(circle at 100% 100%, transparent 0 .75rem, #000 .75rem);
}
.tabelle-klebend-wrap thead th:last-child::before,
.aro-tabelle thead th:last-child::before,
.agents-table-wrap thead th:last-child::before,
.card:has(> .card-body.p-0) thead th:last-child::before,
.card:has(> .table-responsive) thead th:last-child::before {
    right: 0;
    -webkit-mask: radial-gradient(circle at 0 100%, transparent 0 .75rem, #000 .75rem);
    mask: radial-gradient(circle at 0 100%, transparent 0 .75rem, #000 .75rem);
}

/* SONDERFALL: Steht die Tabelle in einer Karte, die selbst in einer Karte liegt (Datenschutz,
   Register „Audit-Protokoll"), ist der Grund dahinter WEISS und nicht die Seitenfarbe. Der Keil
   malte dort einen grauen Zwickel in die Ecke. Er malt immer das, was daneben liegt. */
.card .card:has(> .card-body.p-0) thead th::before,
.card .card:has(> .table-responsive) thead th::before { background: #fff; }

/* Die klebende Kopfzeile legt sich mit ihrer weissen Flaeche ueber die OBERE Kante der Karte, in
   der sie steht - der Rahmen war dort unterbrochen. Sie zieht die Linie deshalb selbst nach, oben
   wie unten. Nur in Karten, die einen Rahmen haben (Karte in Karte). */
.page-content .card .card thead > tr > th {
    box-shadow: inset 0 1px 0 var(--tri-border), inset 0 -1px 0 var(--tri-border);
}

.tabelle-klebend-wrap thead th:first-child { border-top-left-radius: .75rem; }
.tabelle-klebend-wrap thead th:last-child { border-top-right-radius: .75rem; }
.tabelle-klebend-wrap tbody tr:last-child td:first-child { border-bottom-left-radius: .75rem; }
.tabelle-klebend-wrap tbody tr:last-child td:last-child { border-bottom-right-radius: .75rem; }

/* Der Zeitraum im Audit-Protokoll: EINE Gruppe mit Rahmen, die Felder darin ohne eigenen -
   dieselbe Bauweise wie in der Lauf-Uebersicht. */
.aud-zeitraum {
    display: flex;
    align-items: center;
    gap: .35rem;
    height: 42px;
    padding: 0 .85rem;
    border: 1px solid var(--tri-border);
    border-radius: .75rem;
    background: #fff;
}
.aud-zeitraum > i { color: var(--tri-faint); flex: none; }
.aud-zeitraum input {
    /* KEINE feste Breite: Safari richtet die Felder eines Datumsfeldes immer links aus und laesst
       den Rest rechts leer - `text-align` greift dort nicht. Nur ein Feld, das sich auf seinen
       Inhalt zusammenzieht, laesst den Gedankenstrich wirklich mittig stehen. */
    width: auto;
    min-width: 0;
    border: 0;
    outline: none;
    background: transparent;
    padding: 0;
    font-size: .95rem;
    font-weight: 600;
    color: var(--tri-muted);
}
/* Der Gedankenstrich steht EXAKT in der Mitte: Das Feld ist breiter als das Datum, also waere der
   Rest des ersten Feldes als Luecke vor dem Strich sichtbar. Darum das erste Datum rechtsbuendig,
   das zweite linksbuendig - beide ruecken an den Strich heran. */
.aud-zeitraum input { text-align: right; }
.aud-zeitraum input ~ input { text-align: left; }
.aud-zeitraum input:focus { outline: none; box-shadow: none; }
.aud-zeitraum input::-webkit-calendar-picker-indicator { display: none; }
.aud-bis { color: var(--tri-faint); font-size: .9rem; margin: 0 -.15rem; }

/* ---- Triggerliste: zwei Zeilen je Zelle ------------------------------------------------------
   Der Name steht EINZEILIG und kuerzt mit Auslassungspunkten; darunter der Agent, den der Trigger
   startet. Vier eigene Spalten (Name, Typ, Agent, Details) liessen jeder Zelle so wenig Breite, dass
   fast jeder Name ueber zwei bis drei Zeilen lief - die Reihe war kaum noch als Reihe zu lesen. */
.trg-name {
    display: block;
    max-width: 26rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.trg-agent {
    display: inline-block;
    max-width: 26rem;
    margin-top: .15rem;
    font-size: .85rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    vertical-align: bottom;
}
.trg-details {
    display: block;
    max-width: 22rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
/* JEDE Zeile ist zwei Zeilen hoch - auch wo die zweite nichts zu sagen hat (ein Trigger ohne nähere
   Angabe). Sonst wäre die Liste ein Wechsel aus hohen und flachen Reihen, und das Auge liest den
   Unterschied als Bedeutung. */
.trg-agent, .trg-details { min-height: 1.15rem; line-height: 1.15rem; }

/* ---- Felder und Listen IM Dialogfenster ------------------------------------------------------
   Die Hausform der Seiten endete bisher an der Fensterkante: Die zentralen Regeln dafuer haengen an
   `.page-content` oder an der Karte, und in einem Dialog stand deshalb weiter Bootstraps Werksform -
   kleine Eckradien an den Feldern, ein nackter Tabellenkopf ohne Rahmen und ohne runde Ecken. */
.user-modal-body .form-control,
.user-modal-body .form-select {
    border-radius: .65rem;
    border-color: var(--tri-border);
}
.user-modal-body .form-control:focus,
.user-modal-body .form-select:focus { border-color: var(--tri-green-soft); box-shadow: none; }

/* Eine Liste im Dialog sieht aus wie eine Liste auf der Seite: EIN heller Rahmen um das Ganze,
   weisser Kopf mit grauer Schrift, runde Ecken - und der Kopf bleibt beim Rollen stehen. Beschnitten
   wird hier vom Rollbehaelter selbst (`table-responsive` bringt `overflow` mit), deshalb genuegen
   Rahmen und Radius an ihm; die Eckzellen brauchen nichts. */
.user-modal-body .table-responsive {
    border: 1px solid var(--tri-border);
    border-radius: .75rem;
}
.user-modal-body .table-responsive > table { margin-bottom: 0; }
.user-modal-body .table-responsive > table > thead,
.user-modal-body .table-responsive > table > thead.table-light {
    --bs-table-bg: #fff;
    --bs-table-color: var(--tri-muted);
}
.user-modal-body .table-responsive > table > thead > tr > th {
    position: sticky;
    top: 0;
    z-index: 5;
    box-shadow: inset 0 -1px 0 var(--tri-border);
}
/* Die letzte Zeile sitzt auf dem Rahmen - eine zweite Linie dicht darueber sieht aus wie ein Fehler. */
.user-modal-body .table-responsive > table > tbody > tr:last-child > td { border-bottom: 0; }

/* ---- Das Suchfeld im Anbau eines Banners: EINE Form fuer alle Seiten -------------------------
   Vorbild ist die Lauf-Uebersicht: eine Gruppe mit Rahmen, Lupe und einem Eingabefeld OHNE eigenen
   Rahmen. Bootstraps `input-group` setzte stattdessen zwei eckige Kaestchen aneinander - neben den
   runden Feldern daneben sah das aus wie aus einer anderen Zeit.

   Zentral und nicht je Seite: Es gab die Form dreimal in drei scoped Stylesheets, und jede neue
   Seite haette sie ein viertes Mal abgeschrieben. */
.rbh-suche {
    display: flex;
    align-items: center;
    gap: .5rem;
    height: 42px;
    padding: 0 .85rem;
    border: 1px solid var(--tri-border);
    /* Derselbe Radius wie Karte und Tabelle - die Pillenform (999px) fiel aus der Reihe. */
    border-radius: .75rem;
    background: #fff;
    /* Halb so breit wie zuvor (17 statt 34 rem): Ein Suchfeld, das die halbe Zeile fuellt, sieht
       nach Hauptsache aus - es ist aber eines von mehreren Kriterien. Es waechst nicht mehr mit,
       sondern haelt sein Mass. */
    flex: 0 1 17rem;
    min-width: 11rem;
    max-width: 17rem;
}
.rbh-suche > i { color: var(--tri-faint); flex: none; }
.rbh-suche input {
    flex: 1 1 auto;
    min-width: 0;
    border: 0;
    outline: none;
    background: transparent;
    padding: 0;
    font-size: .95rem;
    color: var(--tri-text);
}
.rbh-suche input:focus { outline: none; box-shadow: none; }
.rbh-suche input::placeholder { color: var(--tri-faint); font-weight: 400; }
/* Ein Knopf IN der Gruppe (z. B. „Zuruecksetzen"): ohne Flaeche, nur das Zeichen. */
.rbh-suche > .btn { border: 0; background: transparent; color: var(--tri-faint); padding: 0 .2rem; height: auto; }
.rbh-suche > .btn:hover { color: var(--tri-text); background: transparent; }

/* Ein AUSWAHLFELD im Anbau traegt dieselbe Form wie das Suchfeld daneben: gleiche Hoehe, gleiche
   Rundung, gleicher Rahmen. Bootstraps `form-select-sm` war flacher, eckiger und heller umrandet -
   zwei Bauarten in einer Zeile. */
.rbh-feld {
    height: 42px;
    padding: 0 2.2rem 0 .85rem;
    border: 1px solid var(--tri-border);
    border-radius: .75rem;
    background-color: #fff;
    font-size: .95rem;
    color: var(--tri-text);
}
.rbh-feld:focus { border-color: var(--tri-green-soft); box-shadow: none; }

/* ---- Seiten ohne Kopfzeile (Agent Desk, Dashboard) ----
   Die Regel `.page-content > :first-child` macht aus dem ERSTEN Element jeder Seite das weisse
   Kopfband mit Trennlinie. Auf diesen beiden Seiten ist das erste Element aber nur eine stille
   Werkzeugzeile – sie bekam dadurch 64 px Höhe, weissen Grund und eine Kante quer über die Seite.
   Klasse doppelt notiert (0,3,0) wie bei Dialog und Chat, damit diese spätere Stelle entscheidet. */
/* `ohne-kopfband` ist die allgemeine Form davon: ein Behälter, der die Regel auf sich nimmt, damit
   der Inhalt darin unangetastet bleibt. Eine Seite, deren erstes Element wechselt (Meldung, Lader,
   Raster), braucht genau das – sonst trifft das Kopfband mal dieses, mal jenes. */
.page-content > .ohne-kopfband.ohne-kopfband {
    display: block !important;
    align-items: stretch !important;
    min-height: 0;
    background: transparent;
    border-bottom: 0;
    margin: 0 !important;
    /* Oben so viel Luft, wie der Inhaltsbereich seitlich hat: Ohne Kopfband sässe die erste Kachel
       sonst auf der Fensterkante. Die anderen Seiten bekommen diesen Abstand von ihrem Kopfband. */
    padding: 1rem 0 0;
    position: static;
}

/* Ein führendes Bild OHNE Ring und ohne Fläche darunter. Der Ring hebt einen Agenten-Avatar vom
   Grün ab; ein Sinnbild, das seinen eigenen dunklen Grund mitbringt (das KI-Zeichen), bekam damit
   einen zweiten Rand um den ersten. */
.page-content .rbh.rbh-ohne-ring .rbh-visual { box-shadow: none; background: transparent; }
/* Das KI-Sinnbild bringt seinen Ring in der BILDDATEI mit: ein schmaler gruener Saum, der die dunkle
   Scheibe auf weissem Grund abgrenzt. Auf dem Gruen des Banners steht er als zweiter Kreis um den
   ersten. Statt einer zweiten Bilddatei wird er weggeschnitten - das Rund beschneidet ohnehin
   (`overflow: hidden`), ein leicht vergroessertes Bild schiebt den Saum nach aussen hinaus.
   Nur im Banner: Im Gespraech und im Menue steht das Bild auf Weiss, dort grenzt der Saum es ab. */
.page-content .rbh .rbh-visual .chat-avatar > img { transform: scale(1.13); }
/* Und es dreht sich - sehr langsam, eine Umdrehung in gut einer halben Minute. Gerade genug, dass
   man es bemerkt, wenn man hinsieht, und wenig genug, dass es beim Lesen daneben nicht stoert.
   Die Vergroesserung aus der Regel darueber muss in JEDEM Schritt mitlaufen: `transform` kennt nur
   EINEN Wert, eine Drehung allein setzte die Vergroesserung zurueck und der Saum kaeme wieder.
   NICHT waehrend die KI arbeitet - dann gilt ihre eigene, schnellere Drehung. */
.page-content .rbh .rbh-visual .chat-avatar:not(.is-thinking) > img {
    animation: rbh-ki-dreht 32s linear infinite;
}
@keyframes rbh-ki-dreht {
    from { transform: scale(1.13) rotate(0deg); }
    to { transform: scale(1.13) rotate(360deg); }
}
@media (prefers-reduced-motion: reduce) {
    .page-content .rbh .rbh-visual .chat-avatar:not(.is-thinking) > img { animation: none; }
}

/* ==========================================================================================
   MELDUNGEN – Erfolg und Fehler (Hausstandard)
   Jede Erfolgs- und jede Fehlermeldung sieht gleich aus: eine aufliegende Karte mit rundem
   Sinnbild links, Überschrift fett, Erläuterung darunter, Schließen-Kreuz rechts. Der Erfolg
   steht auf Weiß, der Fehler auf hellem Rot – die Fläche trägt die Aussage, nicht ein Balken
   an der Kante.

   Die Regeln hängen an `.alert-success` / `.alert-danger`, nicht an einer neuen Klasse: So erbt
   JEDE vorhandene Meldung den Hausstandard, ohne dass hundert Markup-Stellen angefasst werden.

   Hinweiskästen (`alert-warning`, `alert-info`, `alert-light`, `alert-secondary`) bleiben
   absichtlich unberührt. Das sind erklärende Kästen IM Formular – sie melden nichts über einen
   Vorgang und sollen auch nicht wie eine Meldung aussehen. */
.alert-success,
.alert-danger {
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: .85rem 1.05rem;
    border-radius: 14px;
    border: 1px solid var(--tri-border);
    background: #fff;
    color: var(--tri-text);
    box-shadow: var(--tri-shadow-flaeche);
}

/* Das Sinnbild gehört zur Meldung, nicht ins Markup: ein gefüllter Kreis mit hellem Hof. Als
   Pseudo-Element braucht es keine Zeile in der Razor-Datei und kann auch nicht vergessen werden. */
.alert-success::before,
.alert-danger::before {
    flex: 0 0 auto;
    width: 1.75rem;
    height: 1.75rem;
    border-radius: 50%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-family: bootstrap-icons;
    font-size: .95rem;
    line-height: 1;
    color: #fff;
}
.alert-success::before {
    content: "\f633";                                   /* bi-check-lg */
    background: var(--tri-green);
    box-shadow: 0 0 0 4px var(--tri-green-bg);
}
.alert-danger::before {
    content: "\f63c";                                   /* bi-exclamation-lg */
    background: var(--tri-red);
    box-shadow: 0 0 0 4px var(--tri-red-soft);
}

.alert-danger {
    background: var(--tri-red-bg);
    border-color: var(--tri-red-border);
    color: var(--tri-red-text);
}

/* Steht im Markup noch ein Haken- oder Ausrufezeichen-Symbol vorweg, verschwindet es: Das
   Sinnbild der Meldung ist der Kreis, zwei Zeichen nebeneinander lesen sich wie zwei Meldungen. */
.alert-success > i:first-child,
.alert-danger > i:first-child { display: none; }

/* Zweizeilige Form: Überschrift und Erläuterung. Einzeilige Meldungen brauchen nichts davon –
   sie stehen einfach als Text in der Karte. */
.alert-success > .alert-body,
.alert-danger > .alert-body { flex: 1 1 auto; min-width: 0; }
.alert-title {
    display: block;
    font-weight: 700;
    line-height: 1.3;
    color: var(--tri-ink);
}
.alert-text {
    display: block;
    line-height: 1.35;
    color: var(--tri-muted-2);
}
.alert-danger .alert-title { color: var(--tri-red-dark); }
.alert-danger .alert-text { color: var(--tri-red-text); }

/* Das Schließen-Kreuz steht immer ganz rechts, auch wenn davor nur ein Textknoten liegt. */
.alert-success > .btn-close,
.alert-danger > .btn-close {
    flex: 0 0 auto;
    margin-left: auto;
    opacity: .45;
}
.alert-success > .btn-close:hover,
.alert-danger > .btn-close:hover { opacity: .85; }
/* Im Fehler ist das Kreuz rot – ein schwarzes Kreuz auf rotem Grund wirkt wie ein Fremdkörper.
   Bootstrap zeichnet es als SVG im Hintergrund; hier dieselbe Form in der Hausfarbe. */
.alert-danger > .btn-close {
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23c0392b'%3e%3cpath d='M.293.293a1 1 0 0 1 1.414 0L8 6.586 14.293.293a1 1 0 1 1 1.414 1.414L9.414 8l6.293 6.293a1 1 0 0 1-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 0 1-1.414-1.414L6.586 8 .293 1.707a1 1 0 0 1 0-1.414'/%3e%3c/svg%3e");
    opacity: .7;
}

/* Schmale Form für Meldungen IM Dialog (`small`): gleiche Gestalt, kleineres Sinnbild. Ein
   Dialog hat wenig Höhe zu verschenken, und die Karte soll dort nicht das halbe Fenster füllen. */
.alert-success.small,
.alert-danger.small {
    gap: .7rem;
    padding: .6rem .8rem;
    border-radius: 12px;
}
.alert-success.small::before,
.alert-danger.small::before {
    width: 1.4rem;
    height: 1.4rem;
    font-size: .78rem;
    box-shadow: 0 0 0 3px var(--tri-green-bg);
}
.alert-danger.small::before { box-shadow: 0 0 0 3px var(--tri-red-soft); }

/* ---- Hintergrund des Agent Desks --------------------------------------------------------------
   Drei Ebenen, in dieser Reihenfolge: die Grundfarbe, darueber das Bild mit eigener Deckkraft und
   Weichzeichnung, darueber die Kacheln.

   BEIDE Ebenen sind Pseudo-Elemente und nicht der Hintergrund des Kastens selbst. Zwei Gruende:
   (1) Weichzeichnung und Deckkraft sollen NUR das Bild treffen, nicht die Farbe darunter und schon
   gar nicht die Kacheln darueber; (2) der Behaelter traegt `margin: 0 !important`
   (.ohne-kopfband) - eine Flaeche, die bis an die Kanten des Inhaltsbereichs reichen soll, kann sich
   also nicht per negativem Rand herausziehen. Die Ebenen tun es per negativer Lage.

   Die Klasse steht doppelt notiert am selben Element wie `.ohne-kopfband`: Dessen Regel
   (`.page-content > .ohne-kopfband.ohne-kopfband`) setzt `background: transparent` und
   `position: static` - ohne gleiche Gewichtung bliebe davon nichts uebrig. */
/* Die Weichzeichnung des Hintergrundbildes darf WEDER ins Menue laufen NOCH an den Raendern
   aufhellen. Beides kommt vom selben Umstand: Ein Weichzeichner zieht den Rand des Bildes nach
   innen (dort steht dann Nichts, also der helle Grund) und malt gleichzeitig ueber die Kante der
   Flaeche hinaus. Dagegen zwei Mittel - dieselben wie an der Kachel mit Bild:
   (1) Der Inhaltsbereich beschneidet, was ueber seine Kante hinauslaeuft;
   (2) die Bildebene wird eine Spur groesser gezogen, damit die ausgefranste Kante ausserhalb
       des sichtbaren Bereichs liegt. */
.page-content:has(> .adk-flaeche) { overflow: hidden; }
.page-content > .ohne-kopfband.adk-flaeche {
    position: relative;
    /* Die Flaeche reicht bis zum unteren Fensterrand, auch wenn nur drei Kacheln darauf liegen.
       Ohne diese Hoehe endete der Hintergrund unter der letzten Kachelreihe - darunter stand wieder
       das uebliche Grau, und das sah aus wie ein Fehler, nicht wie ein Hintergrund.
       Abzug: das untere Polster des Inhaltsbereichs (pb-4), das die Ebenen unten mit aufnehmen. */
    min-height: calc(100vh - 1.5rem);
}
.adk-flaeche::before,
.adk-flaeche::after {
    content: "";
    position: absolute;
    /* WEIT ueber die Flaeche hinaus (10 rem), nicht nur bis zur Kante des Inhaltsbereichs. Der
       Inhaltsbereich beschneidet ohnehin (siehe oben) - und erst so liegt die ausgefranste Kante
       des weichgezeichneten Bildes zuverlaessig ausserhalb des Sichtbaren. Ein Weichzeichner mit
       40 px verwischt ueber rund 120 px; genau abgezaehlte 1,5 rem Ueberstand reichten dafuer nicht
       (unten rechts blieb eine helle Ecke stehen). */
    inset: -10rem;
    pointer-events: none;
}
.adk-flaeche::before { background: var(--adk-bg-color, transparent); }
.adk-flaeche::after {
    background-image: var(--adk-bg-image, none);
    background-size: cover;
    background-position: center;
    filter: blur(var(--adk-bg-blur, 0px));
    opacity: var(--adk-bg-opacity, 1);
}
.adk-flaeche > * { position: relative; z-index: 1; }

/* Die Vorschau in den Einstellungen: dieselben Variablen, nur klein und mit Platzhalter-Kacheln. */
.adk-bg-vorschau {
    position: relative;
    display: flex;
    align-items: center;
    gap: .6rem;
    height: 11rem;
    padding: .9rem;
    overflow: hidden;
    border: 1px solid var(--tri-border);
    border-radius: .75rem;
    background: var(--adk-bg-color, var(--tri-surface));
}
.adk-bg-vorschau::before {
    content: "";
    position: absolute;
    inset: 0;
    background-image: var(--adk-bg-image, none);
    background-size: cover;
    background-position: center;
    filter: blur(var(--adk-bg-blur, 0px));
    opacity: var(--adk-bg-opacity, 1);
    transform: scale(1.08);
}
.adk-bg-kachel {
    position: relative;
    flex: 1 1 0;
    height: 100%;
    border-radius: .6rem;
    border: 1px solid var(--desk-border, var(--tri-border));
    background: linear-gradient(140deg, var(--tri-green-bg) 0%, #fff 55%);
    opacity: var(--desk-tile-alpha, 1);
    box-shadow: var(--tri-shadow-flaeche);
}

/* Der Kachel-Dialog ist eine Spur hoeher als der Hausstandard (780 px). Sein Register „Symbole"
   traegt zwei Symbolgitter, je zwei Farbwahlen, zwei Regler und die Groessenwahl; bei 780 px blieb
   die letzte Zeile unter der Kante - und der Hausstandard verbietet einen Rollbereich im Formular.
   FEST bleibt die Hoehe: Beim Registerwechsel springt weiterhin nichts. */
.user-modal.user-modal-fixed.adk-dialog { height: min(840px, 94vh); }

/* ---- Der weisse Anbau des Chat-Kopfes ---------------------------------------------------------
   Links die Beschreibung des Agenten, rechts die Handlungen am Gespraech (Kopieren, PDF, Details).
   Beides stand bis 2.0.649 im gruenen Band: die Beschreibung auf ein paar Woerter abgeschnitten,
   die Schaltflaechen so breit, dass vom Namen ein „C…" uebrig blieb. */
.chat-anbau {
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: .55rem .9rem;
}
.chat-anbau-text {
    flex: 1 1 auto;
    min-width: 0;
    color: var(--tri-muted);
    font-size: .875rem;
    line-height: 1.35;
    /* Hoechstens zwei Zeilen: Der Anbau soll den Kopf nicht in die Hoehe treiben - und wer die
       ganze Beschreibung lesen will, findet sie im Designer. */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
/* Die Beschreibung ist Markdown; ihre Absaetze duerfen hier keinen eigenen Abstand mitbringen. */
.chat-anbau-text p { margin: 0; }
.chat-anbau-tun { display: flex; align-items: center; gap: .4rem; flex: 0 0 auto; }

/* ===========================================================================================
   TELEFON-ANSICHT DES CHATS (MobileChat.razor, Praefix `mchat-`)
   ===========================================================================================
   Eine Zeile oben, der Verlauf, eine Zeile unten - mehr passt auf ein Telefon nicht, und mehr
   braucht ein Gespraech auch nicht. Die Seite fuellt das Fenster vollstaendig: kein Seitenpolster,
   keine Karte mit Rand, keine abgerundeten Ecken ins Leere. Was hier steht, kleidet zum Teil die
   gemeinsame Chat-Komponente neu ein (`.mchat .composer*`, `.mchat .chat-*`) - die Komponente
   selbst bleibt unveraendert, damit es weiterhin EINEN Chat gibt und nicht zwei.
   =========================================================================================== */
/* Klasse DOPPELT notiert und mit `!important`: Die Seite ist das erste Kind von `.page-content`,
   und dafuer gibt es eine allgemeine Regel, die jeden ersten Kasten zum klebenden Seitenkopf macht
   (sticky, zentriert, mit Polster). Dieselbe Falle wie bei `.chat-page` - dort steht die Begruendung
   ausfuehrlich. Die Telefon-Ansicht ist kein Seitenkopf, sondern die ganze Seite. */
.mchat,
.page-content > .mchat.mchat {
    position: fixed !important;
    inset: 0 !important;
    display: flex !important;
    flex-direction: column;
    align-items: stretch !important;
    margin: 0 !important;
    padding: 0 !important;
    border: 0 !important;
    background: #f4f6f4 !important;
    /* UNTER der Seitenleiste (1020) und ihrem Klickfaenger (1019): Das Menue soll sich darueber
       legen koennen, sonst waere es auf dieser Seite nicht zu oeffnen. */
    z-index: 5 !important;
}

/* Der schwebende schwarze Knopf des Hauptlayouts entfaellt hier - die Zeile oben hat einen eigenen. */
.page:has(.mchat) .mobile-menu-toggle { display: none !important; }

/* ---- Die obere Zeile ---- */
.mchat-bar {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.55rem 0.5rem;
    background: var(--wl-signature, var(--tri-green));
    color: #fff;
    /* Der Streifen des Systems (Uhr, Akku) ueberlagert die Seite auf dem Telefon - `safe-area-inset`
       haelt die Zeile darunter. Ohne iPhone-Kerbe ist der Wert 0 und die Regel folgenlos. */
    padding-top: calc(0.55rem + env(safe-area-inset-top, 0px));
}

.mchat-ic {
    flex: 0 0 auto;
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 38px;
    border: none;
    border-radius: 10px;
    background: transparent;
    color: #fff;
    font-size: 1.25rem;
}

.mchat-ic:active { background: rgba(255, 255, 255, 0.18); }

.mchat-badge {
    position: absolute;
    top: 1px;
    right: 1px;
    min-width: 18px;
    padding: 0 4px;
    border-radius: 999px;
    background: #fff;
    color: var(--tri-green);
    font-size: 0.66rem;
    font-weight: 700;
    line-height: 18px;
}

.mchat-avatar { flex: 0 0 auto; border-radius: 50%; }

.mchat-ident { flex: 1 1 auto; min-width: 0; }
.mchat-name { font-weight: 700; font-size: 1rem; line-height: 1.2; }
.mchat-name, .mchat-sub { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mchat-sub { font-size: 0.78rem; opacity: 0.85; }
.mchat-num { font-weight: 700; }

/* ---- Der Rumpf ---- */
.mchat-body { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; background: #fff; }
.mchat-body > .chat-conv { flex: 1 1 auto; min-height: 0; }

/* Der Verlauf steht auf WEISS und ohne eigenes Polster an den Raendern: Auf 390 px zaehlt jeder
   Millimeter, und eine Karte in der Karte sieht man ohnehin nicht. Getrennt werden die Beitraege
   nicht mehr durch Striche, sondern durch ihre Blasen - auf einem Telefon ist das die vertraute
   Form, und sie sagt mit der Farbe zugleich, von wem der Beitrag kommt. */
.mchat .chat-thread { padding: 0.75rem 0.5rem; background: #fff; }

.mchat .chat-msg { border-bottom: 0; padding: 0.35rem 0.25rem; }

/* Der Agent: leichtes Grau. Die Blase umschliesst den ganzen Beitrag - auch die Denkschritte und
   die Zeile mit den Token, denn beide gehoeren zu dieser Antwort und zu keiner anderen. */
.mchat .chat-msg .chat-msg-body {
    background: #f2f4f3;
    border-radius: 1.1rem;
    padding: 0.7rem 0.95rem;
    max-width: 100%;
}

/* Der Benutzer: leichtes Gruen - dieselbe Familie wie die Signaturfarbe, nur so hell, dass
   schwarze Schrift darauf ruhig bleibt. */
.mchat .chat-msg.user .chat-msg-body {
    background: #e4f0e6;
    max-width: 85%;
}

/* Innerhalb einer Blase braucht die Denkschritt-Zeile keinen eigenen Kasten mehr. */
.mchat .chat-activity { background: transparent; border: 0; padding: 0; }
.mchat .chat-composer { padding: 0.5rem 0.6rem calc(0.5rem + env(safe-area-inset-bottom, 0px)); }

/* Die Eingabe als EINE Zeile, nach der Vorlage: der Anhang-Knopf LINKS AUSSERHALB, in der Mitte
   eine Pille mit Feld und Mikrofon, rechts aussen der runde Senden-Knopf. Die Dreiteilung ist nicht
   Geschmack: Anhaengen und Senden sind Befehle, das Feld ist der Ort, an dem man schreibt - und auf
   einem Telefon unterscheidet man sie am schnellsten daran, was innerhalb und was ausserhalb der
   Pille sitzt. Die Bauform liefert die Komponente selbst (CompactComposer); hier steht ihre Form. */
.mchat .composer.composer-compact {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0;
    border: 0;
    border-radius: 0;
    background: transparent;
    box-shadow: none;
}

.mchat .composer-add-top {
    /* `position: relative` MUSS bleiben. Die Dateiauswahl im Inneren ist ein unsichtbares Feld, das
       sich mit `inset: 0` ueber sein positioniertes Elternteil legt. Stand hier `static`, suchte es
       sich das naechste positionierte Elternteil - und das ist `.mchat` selbst (fixed). Das Feld lag
       damit ueber dem GANZEN Bildschirm: Jeder Tipp, auch auf „Senden", oeffnete den Dateidialog. */
    position: relative;
    top: auto;
    right: auto;
    flex: 0 0 auto;
    width: 44px;
    height: 44px;
    border-radius: 50%;
    background: #f1f3f1;
    color: #5b6160;
    font-size: 1.3rem;
}

/* Die Pille: Feld und Mikrofon in EINEM Rahmen. */
.mchat .composer-pill {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    align-items: center;
    gap: 0.25rem;
    padding: 0.1rem 0.5rem 0.1rem 0.9rem;
    border: 1px solid #dfe3e1;
    border-radius: 999px;
    background: #fff;
}

.mchat .composer-pill:focus-within { border-color: var(--tri-green); }

/* Die Hoehe muss GESETZT werden, nicht nur begrenzt: `rows` allein gibt dem Feld vier Zeilen.
   Auf dem Telefon ist es eine Zeile, die beim Tippen bis auf 6 rem mitwaechst. */
.mchat .composer-text {
    flex: 1 1 auto;
    min-width: 0;
    height: 42px;
    min-height: 42px;
    max-height: 6rem;
    padding: 0.6rem 0 0.5rem;
    border: 0;
    background: transparent;
    line-height: 1.3;
    resize: none;
    field-sizing: content;
}

.mchat .composer-text:focus { outline: none; box-shadow: none; }

.mchat .composer-pill .voice-wrap .btn,
.mchat .composer-pill .voice-wrap button {
    border: 0;
    background: transparent;
    color: #5b6160;
    padding: 0.25rem 0.3rem;
}

/* Rund und ohne Beschriftung: Der Pfeil sagt es, und das Wort „Senden" kostet ein Drittel der Zeile. */
.mchat .composer-send {
    flex: 0 0 auto;
    width: 46px;
    height: 46px;
    padding: 0;
    border-radius: 50%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 1.2rem;
}

.mchat .composer-send i { margin: 0 !important; }

/* ---- Die Vorstellung im leeren Verlauf ---- */
.mchat-intro {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 0.6rem;
    padding: 2.5rem 1.5rem;
}

.mchat-intro-avatar { border-radius: 50%; box-shadow: 0 0 0 4px #fff, 0 2px 10px rgba(0, 0, 0, 0.08); }
.mchat-intro-name { font-size: 1.35rem; font-weight: 700; }

.mchat-intro-rolle {
    padding: 0.2rem 0.75rem;
    border-radius: 999px;
    background: #e3efe4;
    color: var(--tri-green);
    font-size: 0.85rem;
    font-weight: 600;
}

.mchat-intro-text { color: var(--tri-muted); max-width: 30rem; }

.mchat-link {
    border: none;
    background: none;
    padding: 0;
    color: var(--tri-green);
    font-weight: 600;
    text-decoration: underline;
}


/* ---- Agentenauswahl ---- */
.mchat-pick { flex: 1 1 auto; overflow: auto; padding: 0.75rem; background: #f4f6f4; }
.mchat-pick-search { position: relative; margin-bottom: 0.75rem; }
.mchat-pick-search i { position: absolute; left: 0.8rem; top: 50%; transform: translateY(-50%); color: var(--tri-faint); }
.mchat-pick-search .form-control { padding-left: 2.3rem; border-radius: 999px; }

.mchat-pick-count { padding: 0 0.25rem 0.4rem; color: var(--tri-muted); font-size: 0.82rem; }

.mchat-pick-item {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    width: 100%;
    margin-bottom: 0.55rem;
    padding: 0.7rem 0.8rem;
    border: 1px solid #e8ebe8;
    border-radius: 16px;
    background: #fff;
    text-align: left;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
}

.mchat-pick-avatar { flex: 0 0 auto; border-radius: 50%; }
.mchat-pick-text { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 0.15rem; }
.mchat-pick-name { font-weight: 700; }

/* Hoechstens zwei Zeilen Beschreibung, dann bricht der Text sauber ab. Gekuerzt wird in der
   DARSTELLUNG und nicht im Text: Wo genau zwei Zeilen enden, weiss nur der Browser - er kennt die
   Breite des Geraets, die Schrift und die Sprache. */
.mchat-pick-desc {
    color: var(--tri-muted);
    font-size: 0.84rem;
    line-height: 1.3;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.mchat-pick-chevron { flex: 0 0 auto; color: var(--tri-faint); font-size: 1.05rem; }

/* ---- Die Blaetter von unten ---- */
.mchat-sheet-backdrop { position: fixed; inset: 0; z-index: 1060; background: rgba(0, 0, 0, 0.35); }

.mchat-sheet {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 1061;
    max-height: 70vh;
    overflow: auto;
    padding: 0.5rem 0.5rem calc(0.75rem + env(safe-area-inset-bottom, 0px));
    border-radius: 18px 18px 0 0;
    background: #fff;
    box-shadow: 0 -8px 30px rgba(0, 0, 0, 0.22);
}

.mchat-sheet-head { padding: 0.6rem 0.75rem; font-weight: 700; }

.mchat-sheet-item, .mchat-sheet-row {
    display: flex;
    width: 100%;
    padding: 0.7rem 0.75rem;
    border: none;
    border-radius: 12px;
    background: none;
    text-align: left;
    color: var(--tri-text);
    text-decoration: none;
}

.mchat-sheet-item { flex-direction: column; gap: 0.15rem; }
.mchat-sheet-row { align-items: center; gap: 0.7rem; }
.mchat-sheet-row i { color: var(--tri-green); font-size: 1.1rem; }
.mchat-sheet-item.is-active { background: #eef5ef; }
.mchat-sheet-title { font-weight: 600; }
.mchat-sheet-meta { color: var(--tri-muted); font-size: 0.78rem; }
