/* /Components/ChatConversationSidebar.razor.rz.scp.css */
/*
    Die Liste sitzt in der Navigationsleiste und nimmt deren Breite. Ihre Hoehe kommt vom
    Elternteil; nur die Liste selbst scrollt, "Neuer Chat" bleibt stehen.

    min-width: 0 ist hier Pflicht, nicht Kosmetik: ein Flex-Element ist per Voreinstellung
    (min-width: auto) mindestens so breit wie sein laengster unumbrechbarer Inhalt. Ohne
    diese Zeile zieht ein langer Konversationstitel die Leiste auf und das
    text-overflow: ellipsis unten greift nie.
*/
/* Nimmt die Hoehe, die die Leiste ihr gibt, und gibt sie an die Liste weiter -- nur die
   scrollt. */
.conversation-sidebar[b-6fc4jxlebx] {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    min-width: 0;
    min-height: 0;
}

.conversation-new[b-6fc4jxlebx] {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: var(--app-space-2);
    padding: var(--app-space-2);
    border: 1px solid var(--app-border);
    border-radius: var(--app-radius-sm);
    background: var(--app-surface);
    color: var(--app-text);
    text-decoration: none;
    font-size: .9rem;
    white-space: nowrap;
}

.conversation-new:hover[b-6fc4jxlebx] {
    background: var(--app-hover-bg);
}

.conversation-new svg[b-6fc4jxlebx] {
    width: 1.15rem;
    height: 1.15rem;
    flex: 0 0 auto;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.6;
    stroke-linecap: round;
}

/* Die festen Ziele unter "Neuer Chat": gleiche Zeilenform wie die Historie, aber mit Symbol,
   damit sie in der eingeklappten Leiste stehen bleiben koennen.

   ::deep, weil NavLink sein <a> selbst rendert und die Scope-Kennung dort nicht ankommt
   (dasselbe wie bei .rail-link in NavRail.razor.css). */
.conversation-shortcuts[b-6fc4jxlebx] {
    flex: 0 0 auto;
    margin-top: var(--app-space-2);
}

.conversation-shortcuts[b-6fc4jxlebx]  .conversation-shortcut {
    display: flex;
    align-items: center;
    gap: var(--app-space-2);
    padding: .35rem var(--app-space-2);
    border-radius: var(--app-radius-sm);
    color: var(--app-text);
    text-decoration: none;
    font-size: .875rem;
    white-space: nowrap;
}

.conversation-shortcuts[b-6fc4jxlebx]  .conversation-shortcut:hover {
    background: var(--app-hover-bg);
}

.conversation-shortcuts[b-6fc4jxlebx]  .conversation-shortcut.active {
    background: var(--app-accent-subtle);
    color: var(--app-accent);
}

.conversation-shortcuts[b-6fc4jxlebx]  .conversation-shortcut span {
    overflow: hidden;
    text-overflow: ellipsis;
}

.conversation-shortcuts[b-6fc4jxlebx]  .conversation-shortcut svg {
    width: 1.15rem;
    height: 1.15rem;
    flex: 0 0 auto;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.6;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.conversation-empty[b-6fc4jxlebx] {
    margin: var(--app-space-2) 0 0;
    font-size: .8rem;
    color: var(--app-text-muted);
}

.conversation-list[b-6fc4jxlebx] {
    flex: 1 1 auto;
    list-style: none;
    margin: var(--app-space-2) 0 0 0;
    padding: 0;
    overflow-y: auto;
    /* Der Platz fuer den Balken ist immer reserviert. Sonst springt die ganze Liste um seine
       Breite, sobald eine Konversation dazukommt oder wegfaellt. */
    scrollbar-gutter: stable;
    min-width: 0;
    min-height: 0;
}

/*
    position: relative traegt das Aktionsmenue, das UEBER der Zeile liegt statt neben ihr.

    --conv-row-bg ist die Farbe, in die der Titel unter dem Menue ausblendet. Sie muss der
    Fuellung der Zeile folgen, sonst steht dort ein andersfarbiger Streifen -- deshalb setzt
    sie jeder Zustand mit, und nicht die Regel weiter unten.
*/
.conversation-item[b-6fc4jxlebx] {
    position: relative;
    display: flex;
    align-items: center;
    min-width: 0;
    border-radius: var(--app-radius-sm);
    --conv-row-bg: var(--app-surface-2);
}

.conversation-item:hover[b-6fc4jxlebx] {
    background: var(--app-hover-bg);
    --conv-row-bg: var(--app-hover-bg);
}

.conversation-item.active[b-6fc4jxlebx] {
    background: var(--app-accent-subtle);
    --conv-row-bg: var(--app-accent-subtle);
}

/* Der Titel ist die Schaltflaeche und nimmt die GANZE Zeile: das Menue liegt darueber und
   nimmt ihm keine Breite mehr weg. Vorher endete jeder Titel schon dort, wo drei Punkte
   haetten stehen koennen -- auch in den 99% der Zeit, in denen keine da waren. */
.conversation-select[b-6fc4jxlebx] {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: .1rem;
    padding: .35rem var(--app-space-2);
    color: var(--app-text);
    text-decoration: none;
}

.conversation-title[b-6fc4jxlebx] {
    width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: .875rem;
}

/* Die Ueberschrift eines Buendels. Sie ersetzt den Zeitstempel, der vorher unter jedem
   Titel stand: die Frage "wann war das" beantwortet sie einmal je Gruppe statt einmal je
   Zeile. Das genaue Datum und die Nachrichtenzahl stehen weiter im title des Links. */
.conversation-group[b-6fc4jxlebx] {
    padding: var(--app-space-3) var(--app-space-2) var(--app-space-1);
    font-size: .7rem;
    text-transform: uppercase;
    letter-spacing: .06em;
    color: var(--app-text-muted);
}

.conversation-group:first-child[b-6fc4jxlebx] {
    padding-top: var(--app-space-1);
}

/*
    Das Aktionsmenue erscheint erst beim Ueberfahren der Zeile. :focus-within haelt es
    offen, solange der Knopf den Fokus hat -- sonst waere es per Tastatur nicht erreichbar
    und wuerde beim Aufklappen unter dem Mauszeiger verschwinden.

    Es LIEGT UEBER der Zeile und steht nicht darin. Der Verlauf davor blendet den Titel in
    die Farbe der Zeile aus, statt ihn hart abzuschneiden: so ist zu sehen, dass der Text
    weitergeht, und der Titel behaelt seine volle Breite, solange kein Menue da ist.
*/
.conversation-actions[b-6fc4jxlebx] {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    display: flex;
    align-items: center;
    /* Die Strecke, auf der der Titel ausblendet -- links davon ist er unberuehrt. */
    padding-left: 1.75rem;
    padding-right: .15rem;
    border-radius: var(--app-radius-sm);
    background: linear-gradient(to right, transparent 0, var(--conv-row-bg) 1.75rem);
    visibility: hidden;
}

.conversation-item:hover .conversation-actions[b-6fc4jxlebx],
.conversation-item:focus-within .conversation-actions[b-6fc4jxlebx] {
    visibility: visible;
}

/* Der ...-Knopf. Ein schlichter <button> und kein DxButton: es gibt ihn einmal je Zeile, und
   alles DevExpress-Seitige je Zeile kostete beim Neuladen eine Exception je JS-Referenz
   (siehe das DxContextMenu in der .razor-Datei). */
.conversation-menu-button[b-6fc4jxlebx] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 1.75rem;
    height: 1.75rem;
    padding: 0 .35rem;
    border: 0;
    border-radius: var(--app-radius-sm);
    background: transparent;
    color: var(--app-text-muted);
    font-size: 1rem;
    line-height: 1;
    cursor: pointer;
}

.conversation-menu-button:hover[b-6fc4jxlebx],
.conversation-menu-button:focus-visible[b-6fc4jxlebx] {
    background: var(--app-hover-bg);
    color: var(--app-text);
}

/* Zeigegeraete ohne Hover: sonst waere das Menue dort nie erreichbar. */
@media (hover: none) {
    .conversation-actions[b-6fc4jxlebx] {
        visibility: visible;
    }
}

/* Eingeklappte Leiste: nur "Neuer Chat" als Symbol, die Liste verschwindet.

   Nur ab 48rem, aus demselben Grund wie die Gegenstuecke in NavRail.razor.css: data-rail
   liegt im localStorage und traegt einen am Schreibtisch eingeklappten Zustand mit aufs
   Telefon. Die ausgefahrene Schublade haette dort sonst keine Chatliste. */
@media (min-width: 48rem) {
    :root[data-rail="collapsed"] .conversation-list[b-6fc4jxlebx],
    :root[data-rail="collapsed"] .conversation-empty[b-6fc4jxlebx],
    :root[data-rail="collapsed"] .conversation-new span[b-6fc4jxlebx],
    :root[data-rail="collapsed"] .conversation-shortcuts[b-6fc4jxlebx]  .conversation-shortcut span {
        display: none;
    }

    :root[data-rail="collapsed"] .conversation-new[b-6fc4jxlebx],
    :root[data-rail="collapsed"] .conversation-shortcuts[b-6fc4jxlebx]  .conversation-shortcut {
        justify-content: center;
    }
}
/* /Components/Chat/ChatComposer.razor.rz.scp.css */
/*
    Der Verfasser steht in DERSELBEN Lesespalte wie die Nachrichten: gedeckelt wird jedes
    Kind auf min(46rem, 100%), zentriert wird hier mit align-items -- Zeile fuer Zeile
    dieselbe Mechanik wie in ChatMessageList.razor.css, damit man sie nur einmal verstehen
    muss.

    DIE WAAGERECHTE POLSTERUNG MUSS MIT .chat-messages UEBEREINSTIMMEN (dort 1rem). Sie
    bezieht sich in beiden Faellen auf die Inhaltsbox; laufen die Werte auseinander, sind die
    Kanten von Verlauf und Eingabefeld unterhalb von 46rem sichtbar versetzt.

    Keine Oberkante mehr: eine Linie ueber die volle Breite unter einer zentrierten Spalte
    gehoert zu nichts. Die Abgrenzung leistet der Kasten selbst, der Abstand nach unten haelt
    den Verlauf davon ab, ihn zu beruehren.
*/
.chat-composer[b-9e41hckc1t] {
    flex: 0 0 auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: .4rem 1rem .75rem;
    background: transparent;
}

.chat-composer > *[b-9e41hckc1t] {
    width: min(46rem, 100%);
}

.chat-composer-box[b-9e41hckc1t] {
    display: flex;
    flex-direction: column;
    gap: .1rem;
    padding: .3rem .3rem .3rem;
    border: 1px solid var(--app-border-strong);
    border-radius: var(--app-radius-lg);
    background: var(--app-surface);
}

/* Der Fokusring sitzt am Kasten, nicht am Textfeld -- sonst umrandete er ein Feld ohne
   eigenen Rahmen mitten in einem Kasten, der auch einen hat. */
.chat-composer-box:focus-within[b-9e41hckc1t] {
    border-color: var(--app-accent);
    box-shadow: var(--app-focus-ring);
}

.chat-input[b-9e41hckc1t] {
    width: 100%;
    min-height: 2.1rem;
    /* chat.js grows it with its content and caps it at 240px. */
    max-height: 15rem;
    resize: none;
    border: 0;
    background: transparent;
    padding: .45rem .5rem .2rem;
    line-height: 1.45;
}

/* Die Werkzeugzeile unter dem Text: Bueroklammer links, alles Uebrige rechts. Die
   Auswahlknoepfe kommen von der Seite (Controls) und schieben sich mit margin-left: auto an
   den Senden-Knopf heran. */
.chat-composer-toolbar[b-9e41hckc1t] {
    display: flex;
    align-items: center;
    gap: .25rem;
    min-width: 0;
}

.chat-composer-controls[b-9e41hckc1t] {
    margin-left: auto;
    display: flex;
    align-items: center;
    justify-content: flex-end;
    flex-wrap: wrap;
    gap: .15rem;
    min-width: 0;
}

.chat-composer-controls:empty[b-9e41hckc1t],
.chat-composer-notices:empty[b-9e41hckc1t] {
    display: none;
}

/* Die Hinweise ueber dem Feld. Gestaltet werden die einzelnen Zeilen auf der Seite, die sie
   liefert (Chat.razor.css); hier nur der Abstand zum Kasten. */
.chat-composer-notices[b-9e41hckc1t] {
    display: flex;
    flex-direction: column;
    gap: .3rem;
    margin-bottom: .4rem;
}

/* Kein eigener Umriss: der Kasten drumherum zeigt den Fokus schon an. */
.chat-input:focus[b-9e41hckc1t] { outline: none; }

.chat-input:disabled[b-9e41hckc1t] { background: transparent; color: var(--app-text-muted); }

.chat-composer-hint[b-9e41hckc1t] {
    margin: .3rem 0 0;
    text-align: center;
    font-size: .75rem;
    color: var(--app-text-muted);
}

/* Auf einem Telefon gibt es kein Shift+Enter, und der Platz ist knapper. */
@media (max-width: 47.99rem) {
    .chat-composer-hint[b-9e41hckc1t] { display: none; }
}

.chat-send[b-9e41hckc1t],
.chat-attach[b-9e41hckc1t] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.1rem;
    height: 2.1rem;
    flex: 0 0 auto;
    padding: 0;
    border-radius: var(--app-radius-pill);
}

.chat-attach[b-9e41hckc1t] {
    border: 0;
    color: var(--app-text-muted);
    cursor: pointer;
    background: transparent;
}

.chat-attach:hover[b-9e41hckc1t] { background: var(--app-hover-bg); color: var(--app-text); }

.chat-send svg[b-9e41hckc1t],
.chat-attach svg[b-9e41hckc1t] {
    width: 1.1rem;
    height: 1.1rem;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.5;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.chat-send svg rect[b-9e41hckc1t] { fill: currentColor; stroke: none; }

.chat-composer-attachments[b-9e41hckc1t] {
    display: flex;
    flex-wrap: wrap;
    gap: .35rem;
    margin-bottom: .4rem;
}

.chat-chip-remove[b-9e41hckc1t] {
    border: 0;
    background: transparent;
    color: var(--app-text-muted);
    cursor: pointer;
    line-height: 1;
    padding: 0 0 0 .1rem;
}

.chat-chip-remove:hover[b-9e41hckc1t] { color: var(--app-danger-text); }

.chat-file-error[b-9e41hckc1t] {
    margin: 0 0 .4rem;
    font-size: .85rem;
    color: var(--app-danger-text);
}

/* Eine Zeile je abgewiesener Datei, hoechstens fuenf (UploadMessages). */
.chat-file-error p[b-9e41hckc1t] { margin: 0; }

/* Was das gewaehlte Modell nicht annimmt. Leise wie der Tastenhinweis, aber auch auf dem
   Telefon sichtbar: dort fehlt sonst jede Erklaerung, warum der Dateidialog Bilder ausgraut. */
.chat-capability-note[b-9e41hckc1t] {
    margin: 0 0 .4rem;
    font-size: .8rem;
    color: var(--app-text-muted);
}

/* Das Modell nimmt gar keine Datei an: die Bueroklammer bleibt sichtbar, damit das Feld nicht
   springt, reagiert aber nicht mehr. */
.chat-attach-disabled[b-9e41hckc1t] {
    opacity: .4;
    cursor: not-allowed;
}

.chat-attach-disabled:hover[b-9e41hckc1t] { background: transparent; color: var(--app-text-muted); }

.chat-composer-skills[b-9e41hckc1t] {
    display: flex;
    flex-wrap: wrap;
    gap: .35rem;
    margin-bottom: .4rem;
}

/* Die /-Auswahl. Im Kasten ueber dem Textfeld, nicht schwebend: sie gehoert zum Feld, und
   ein Popup braeuchte eine Position, die beim Mitwachsen des Feldes nachgezogen werden muesste. */
.chat-skill-picker[b-9e41hckc1t] {
    list-style: none;
    margin: 0 0 .2rem;
    padding: .2rem;
    max-height: 16rem;
    overflow-y: auto;
    border-bottom: 1px solid var(--app-border);
}

.chat-skill-picker li[b-9e41hckc1t] {
    display: flex;
    align-items: baseline;
    gap: var(--app-space-2);
    padding: .3rem .5rem;
    border-radius: var(--app-radius-sm);
    cursor: pointer;
}

.chat-skill-picker li:hover[b-9e41hckc1t] { background: var(--app-hover-bg); }
.chat-skill-picker li.active[b-9e41hckc1t] { background: var(--app-accent-subtle); }

.chat-skill-name[b-9e41hckc1t] {
    font-family: var(--app-font-mono);
    font-size: .85rem;
    white-space: nowrap;
}

.chat-skill-own[b-9e41hckc1t] {
    font-size: .7rem;
    color: var(--app-text-muted);
    border: 1px solid var(--app-border);
    border-radius: var(--app-radius-pill);
    padding: 0 .35rem;
}

.chat-skill-description[b-9e41hckc1t] {
    font-size: .8rem;
    color: var(--app-text-muted);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
}
/* /Components/Chat/ChatMessageBubble.razor.rz.scp.css */
/* The rendered Markdown. Tight margins, because a bubble is not a document.

   Lesetext, nicht Formulartext: etwas kleiner als die Oberflaeche ringsum und mit deutlich
   mehr Zeilenabstand. Die Antwort ist das einzige auf dieser Seite, das man am Stueck liest. */
.chat-text[b-rtwc70b4eq] {
    font-size: .9375rem;
    line-height: 1.65;
}

.chat-text[b-rtwc70b4eq] >  :first-child { margin-top: 0; }
.chat-text[b-rtwc70b4eq] >  :last-child  { margin-bottom: 0; }

.chat-text[b-rtwc70b4eq]  p { margin-bottom: .5rem; }

.chat-text[b-rtwc70b4eq]  pre {
    background: var(--app-surface-2);
    border: 1px solid var(--app-border);
    border-radius: var(--app-radius-sm);
    padding: .5rem .65rem;
    /* Its own scroller: a long line must not widen the whole page. */
    overflow-x: auto;
    margin: .5rem 0;
}

.chat-text[b-rtwc70b4eq]  code {
    font-size: .875em;
    word-break: break-word;
}

.chat-text[b-rtwc70b4eq]  pre code { word-break: normal; }

/* Mermaid-Diagramme.

   Solange nichts gezeichnet ist, IST der Block ein Codeblock und sieht auch so aus: die
   Regeln oben greifen, der Quelltext ist lesbar. Erst der fertige Zustand stellt den Rahmen
   um. Die Auswahl ist absichtlich spezifischer als ".chat-text ::deep pre" -- beides sind
   bereichsbegrenzte Regeln in derselben Datei, es entscheidet die Spezifitaet.

   Ausserhalb von .chat-text steht derselbe Block im Denkfeld; deshalb haengen diese Regeln
   am ::deep der Blase und nicht am Text. */
[b-rtwc70b4eq] pre.chat-mermaid[data-mermaid-state="done"] {
    background: transparent;
    border: 0;
    padding: 0;
    /* Der weisse Hintergrund des SVG kommt aus dem Mermaid-Thema, der Rahmen hier waere ein
       zweiter um dasselbe Bild. */

    /* Die Breite selbst setzt chat.js an das Element: nur dort ist bekannt, wie breit diese
       eine Zeichnung ist. Hier steht nur der Deckel -- die Blase gibt vor, wie weit es nach
       rechts geht, und darueber hinaus skaliert das SVG herunter. */
    max-width: 100%;
}

[b-rtwc70b4eq] pre.chat-mermaid svg {
    /* Fuellt den Kasten, den chat.js aufgespannt hat. Die Obergrenze dafuer kommt von
       Mermaid selbst (Inline-Stil auf die natuerliche Breite) -- nach oben wird nicht
       skaliert, nach unten, wenn die Blase enger ist, schon. */
    width: 100%;
    height: auto;
}

/* Ungueltiges Mermaid: der Quelltext steht wieder da, mit einer Zeile darueber, die sagt
   warum. Der genaue Fehler haengt im title des Blocks. */
[b-rtwc70b4eq] pre.chat-mermaid[data-mermaid-state="failed"]::before {
    content: "Diagramm konnte nicht gezeichnet werden";
    display: block;
    margin-bottom: .35rem;
    font-family: var(--bs-body-font-family);
    font-size: .75rem;
    color: var(--app-text-muted);
}

.chat-text[b-rtwc70b4eq]  table {
    border-collapse: collapse;
    margin: .5rem 0;
    display: block;
    overflow-x: auto;
}

.chat-text[b-rtwc70b4eq]  th,
.chat-text[b-rtwc70b4eq]  td {
    border: 1px solid var(--app-border);
    padding: .25rem .5rem;
}

.chat-text[b-rtwc70b4eq]  blockquote {
    border-left: 3px solid var(--app-border);
    padding-left: .75rem;
    margin: .5rem 0;
    color: var(--app-gray-700);
}

.chat-text[b-rtwc70b4eq]  ul,
.chat-text[b-rtwc70b4eq]  ol { margin: .5rem 0 .5rem 1.25rem; padding: 0; }

/* Attachment chips. */
.chat-bubble-attachments[b-rtwc70b4eq] {
    display: flex;
    flex-wrap: wrap;
    gap: .35rem;
    margin-top: .5rem;
}

/* .chat-chip steht in wwwroot/css/components.css: er wird hier UND im Verfasser
   gebraucht, und scoped CSS kann nichts teilen. */

/*
    DIE FUSSZEILE DER BLASE: Aktionen links, Quittung rechts -- eine Zeile fuer beides.

    Sie nimmt die volle Breite der Lesespalte, damit die Zahlen ueber mehrere Antworten
    hinweg in einer Flucht stehen (zusammen mit dem tabular-nums der Quittung). Bei der
    eigenen Frage gibt es nichts rechts, dort rueckt die Zeile geschlossen nach rechts, wo
    auch die Blase steht.

    Die reservierte Hoehe kommt aus den Knoepfen: die Quittung entsteht erst am Ende des
    Zuges und haette allein darunter die fertige Antwort nach unten geschoben.
*/
.chat-footnote[b-rtwc70b4eq] {
    display: flex;
    /* flex-start, NICHT center: die Quittung ist ein <details> und wird beim Aufklappen
       vielzeilig. Zentriert waeren die Knoepfe dann mitten an einem Block gewandert, zu dem
       sie nicht gehoeren -- sie bleiben oben, wo die Zeile beginnt. Dass die geschlossene
       Quittung trotzdem auf Knopfhoehe sitzt, macht das min-height an ihrer Zusammenfassung
       weiter unten. */
    align-items: flex-start;
    gap: .75rem;
    width: 100%;
    margin-top: .15rem;
}

.chat-row-user .chat-footnote[b-rtwc70b4eq] {
    width: auto;
    justify-content: flex-end;
}

/* The action row: under the bubble, out of the way until the row is touched.

   The hover lives on the ROW, not on the bubble: the bar is outside the bubble now, so a
   bubble-bound rule would hide it the moment the pointer left the bubble to reach it. */
[b-rtwc70b4eq] .chat-actions {
    display: flex;
    gap: .15rem;
    opacity: 0;
    transition: opacity .12s ease-in-out;
}

.chat-row:hover[b-rtwc70b4eq]  .chat-actions,
.chat-row:focus-within[b-rtwc70b4eq]  .chat-actions {
    opacity: 1;
}

/* Touch devices have no hover — there the row is simply always visible. */
@media (hover: none) {
    [b-rtwc70b4eq] .chat-actions { opacity: 1; }
}

[b-rtwc70b4eq] .chat-action {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.6rem;
    height: 1.6rem;
    padding: 0;
    border: 0;
    border-radius: var(--app-radius-sm);
    background: transparent;
    color: var(--app-text-muted);
    cursor: pointer;
}

[b-rtwc70b4eq] .chat-action:hover:not(:disabled) { background: var(--app-hover-bg); color: var(--app-text); }
[b-rtwc70b4eq] .chat-action:disabled { opacity: .4; cursor: default; }
[b-rtwc70b4eq] .chat-action-danger:hover:not(:disabled) { background: var(--app-danger-bg); color: var(--app-danger-text); }

[b-rtwc70b4eq] .chat-action svg {
    width: 1rem;
    height: 1rem;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.4;
    stroke-linecap: round;
    stroke-linejoin: round;
}

/* Editing one's own question. */
.chat-edit-input[b-rtwc70b4eq] {
    width: 100%;
    resize: vertical;
    border: 1px solid var(--app-border-strong);
    border-radius: var(--app-radius-sm);
    padding: .4rem .5rem;
}

.chat-edit-buttons[b-rtwc70b4eq] {
    display: flex;
    gap: .4rem;
    margin-top: .4rem;
}

/* The thinking disclosure. Same frame as the tool calls below — it is the same kind of
   thing: context above the answer, shut until asked for. */
[b-rtwc70b4eq] .chat-reasoning {
    margin-bottom: .5rem;
    border: 1px solid var(--app-border);
    border-radius: var(--app-radius-sm);
    background: var(--app-surface-2);
}

[b-rtwc70b4eq] .chat-reasoning-summary {
    cursor: pointer;
    padding: .3rem .5rem;
    font-size: .85rem;
    color: var(--app-gray-700);
}

/* Sits in the summary, so it brings its own size, colour and spacing — like the pending
   marker of a tool call that has no result yet. */
[b-rtwc70b4eq] .chat-reasoning-pending {
    margin-left: .35rem;
    font-style: italic;
    font-size: .75rem;
    color: var(--app-text-muted);
}

/* The rendered thinking. Smaller and quieter than the answer: it is not the answer. */
[b-rtwc70b4eq] .chat-reasoning-text {
    padding: 0 .5rem .5rem;
    font-size: .85rem;
    color: var(--app-gray-700);
}

[b-rtwc70b4eq] .chat-reasoning-text > :first-child { margin-top: 0; }
[b-rtwc70b4eq] .chat-reasoning-text > :last-child { margin-bottom: 0; }
[b-rtwc70b4eq] .chat-reasoning-text p { margin-bottom: .5rem; }

/* Die Zeitachse. Sie sitzt ueber der Nachricht, daher margin-bottom.

   KEIN KASTEN MEHR. Als gefuellter, gerahmter Balken wog sie optisch schwerer als die
   Antwort darunter -- und sie ist die Fussnote, nicht der Text. Zugeklappt ist sie jetzt
   eine leise Zeile; die Flaeche entsteht erst, wenn jemand sie aufklappt, und auch dann nur
   als Kante links. */
[b-rtwc70b4eq] .chat-tools {
    margin-bottom: .4rem;
    border: 0;
    background: transparent;
}

[b-rtwc70b4eq] .chat-tools-summary {
    cursor: pointer;
    padding: .1rem 0;
    font-size: .8rem;
    color: var(--app-text-muted);
}

[b-rtwc70b4eq] .chat-tools-summary:hover { color: var(--app-text); }

[b-rtwc70b4eq] .chat-tool { padding: .15rem 0 .35rem; }

/* Ein Schritt der Zeitachse. Eine durchgehende Kante links haelt die Schritte zusammen und
   rueckt sie zugleich vom Antworttext ab -- Rahmen um jeden Schritt wurde unruhig, und eine
   Trennlinie je Schritt war eine Linie zu viel neben dieser. */
[b-rtwc70b4eq] .chat-timeline .chat-step {
    border-left: 2px solid var(--app-border);
    padding-left: .6rem;
}

[b-rtwc70b4eq] .chat-timeline .chat-step + .chat-step {
    padding-top: .35rem;
}

/* Im Inneren der Zeitachse traegt der Gedanke keinen eigenen Rahmen mehr: den stellt das
   umgebende Feld. Ausserhalb (falls je wieder allein verwendet) bleibt er, wie er war. */
[b-rtwc70b4eq] .chat-timeline .chat-reasoning {
    margin-bottom: 0;
    border: 0;
    border-radius: 0;
    background: transparent;
}

[b-rtwc70b4eq] .chat-timeline .chat-reasoning-summary { padding: .2rem 0; }
[b-rtwc70b4eq] .chat-timeline .chat-reasoning-text { padding-inline: 0; }

/* One call, itself collapsed: with several calls the flat list was a wall of JSON. */
[b-rtwc70b4eq] .chat-tool-name {
    cursor: pointer;
    font-weight: 600;
    font-size: .85rem;
}

[b-rtwc70b4eq] .chat-tool-label {
    font-size: .75rem;
    color: var(--app-text-muted);
    margin-top: .25rem;
}

/* Sits in the summary, so it brings its own size, colour and spacing. */
[b-rtwc70b4eq] .chat-tool-pending {
    margin-left: .35rem;
    font-style: italic;
    font-weight: 400;
    font-size: .75rem;
    color: var(--app-text-muted);
}

/* Ein gescheiterter Aufruf: dieselbe Groesse wie "noch kein Ergebnis", aber als Marke in der
   Gefahrfarbe -- sie muss auch bei zugeklapptem Schritt auffallen. */
[b-rtwc70b4eq] .chat-tool-error {
    margin-left: .35rem;
    padding: 0 .3rem;
    border: 1px solid var(--app-danger-border);
    border-radius: var(--app-radius-sm);
    background: var(--app-danger-bg);
    color: var(--app-danger-text);
    font-weight: 600;
    font-size: .72rem;
}

/* Die MCP-Rueckfrage als Schritt der Zeitachse. Die Karte bringt ihren eigenen Aussenabstand
   fuer den Fall mit, dass sie frei im Verlauf steht; hier sorgt der Schrittabstand dafuer.
   Die Regel ist spezifischer als die der Karte (zwei Klassen plus Bereichskennung gegen eine
   Klasse plus Kennung) und gewinnt deshalb. */
[b-rtwc70b4eq] .chat-timeline .elicitation-card {
    margin: 0;
}

/* Der Hinweis ueber einer Karte, wenn der vorige Aufruf scheiterte. Leise, aber in der
   Gefahrfarbe: er erklaert, warum dieselbe Frage noch einmal kommt. */
[b-rtwc70b4eq] .chat-step-notice {
    margin-bottom: .25rem;
    font-size: .8rem;
    color: var(--app-danger-text);
}

[b-rtwc70b4eq] .chat-tool-json {
    margin: .15rem 0 0;
    padding: .35rem .5rem;
    background: var(--app-surface);
    border: 1px solid var(--app-border);
    border-radius: var(--app-radius-sm);
    font-size: .78rem;
    max-height: 16rem;
    overflow: auto;
}

/* The receipt under an answer. Quiet by construction: it sits on every assistant bubble and
   must not compete with the answer, so it is small, muted, and shut.

   Und sie erscheint erst bei Beruehrung -- dieselbe Behandlung wie die Aktionsleiste weiter
   oben, aus demselben Grund: eine Zahlenzeile unter jeder Antwort ist Entwicklersicht, und
   wer sie sucht, faehrt hin.

   opacity und nicht visibility oder display: die Hoehe bleibt reserviert, nichts springt
   beim Ueberfahren -- und innerText liest den Text weiter, woran ein Browsertest haengt. */
[b-rtwc70b4eq] .chat-usage {
    font-size: .75rem;
    color: var(--app-text-muted);
    opacity: 0;
    transition: opacity .12s ease-in-out;
}

.chat-row:hover[b-rtwc70b4eq]  .chat-usage,
.chat-row:focus-within[b-rtwc70b4eq]  .chat-usage,
[b-rtwc70b4eq] .chat-usage[open] {
    opacity: 1;
}

/* Am rechten Rand der Zeile -- auch dann, wenn links keine Aktionen stehen: margin-left:
   auto schiebt sie hin, ohne dass die leere Seite eine Fuellung braucht. */
.chat-footnote[b-rtwc70b4eq]  .chat-usage {
    flex: 0 0 auto;
    margin-left: auto;
}

/* Die geschlossene Quittung fluchtet mit den Knoepfen (1,6rem hoch), obwohl ihre Schrift
   kleiner ist. Die Hoehe steht an der ZUSAMMENFASSUNG und nicht am <details>, damit der
   aufgeklappte Block direkt darunter weiterlaeuft. */
.chat-footnote[b-rtwc70b4eq]  .chat-usage-summary {
    min-height: 1.6rem;
    align-items: center;
}

/* Zeigegeraete ohne Hover: dort gaebe es sonst keinen Weg hin. */
@media (hover: none) {
    [b-rtwc70b4eq] .chat-usage { opacity: 1; }
}

[b-rtwc70b4eq] .chat-usage-summary {
    cursor: pointer;
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: .5rem;
    list-style: none;
}

/* The default disclosure triangle would pull the eye to a line that is meant to recede. */
[b-rtwc70b4eq] .chat-usage-summary::-webkit-details-marker { display: none; }
[b-rtwc70b4eq] .chat-usage-summary::marker { content: ""; }

[b-rtwc70b4eq] .chat-usage-figure { font-variant-numeric: tabular-nums; }

/* More than one provider round means the whole history was sent again -- the cheapest signal
   there is that a turn was expensive, so it is the one thing here that is allowed to stand out. */
[b-rtwc70b4eq] .chat-usage-rounds {
    padding: 0 .3rem;
    border: 1px solid var(--app-border);
    border-radius: var(--app-radius-sm);
    color: var(--app-gray-700);
}

[b-rtwc70b4eq] .chat-usage-cost { font-variant-numeric: tabular-nums; }

[b-rtwc70b4eq] .chat-usage-detail {
    display: grid;
    grid-template-columns: auto auto;
    gap: .1rem .6rem;
    justify-content: start;
    margin: .35rem 0 0;
}

[b-rtwc70b4eq] .chat-usage-detail dt { color: var(--app-text-muted); }
[b-rtwc70b4eq] .chat-usage-detail dd { margin: 0; font-variant-numeric: tabular-nums; }

.chat-bubble-skills[b-rtwc70b4eq] {
    display: flex;
    flex-wrap: wrap;
    gap: .35rem;
    margin-top: .5rem;
}
/* /Components/Chat/ChatMessageList.razor.rz.scp.css */
/* The scroll container. It takes the height the chat host gives it and scrolls inside.

   DIE LESESPALTE HAENGT AN align-items, NICHT AN AUTO-RAENDERN. Der Bildlaufbereich bleibt so
   breit wie das Fenster -- gedeckelt wird jedes Kind einzeln (width: min(46rem, 100%)), und
   zentriert werden sie alle hier mit einer Zeile. Die naheliegende Alternative
   "margin-inline: auto" an jedem Kind funktioniert zwar, aber sie wuergt still ab: ein
   Auto-Rand in der Querachse frisst den freien Platz VOR align-self, und jedes align-self im
   Rest dieser Datei waere danach eine wirkungslose Zeile, die weiterhin so aussieht, als
   taete sie etwas.

   Die waagerechte Polsterung ist mit der des Verfassers abgestimmt (ChatComposer.razor.css):
   laufen die beiden auseinander, fluchten Nachrichtenspalte und Eingabefeld unterhalb von
   46rem nicht mehr. */
.chat-messages[b-wqqyf0fn9c] {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    /* both-edges, nicht nur stable: der Bildlaufbalken nimmt seine Breite aus der
       Inhaltsbox, und eine zentrierte Spalte rutscht dadurch um die halbe Balkenbreite nach
       links -- sichtbar gegen den Verfasser, der keinen Balken hat. Auf beiden Seiten
       reserviert, bleibt die Mitte die Mitte. */
    scrollbar-gutter: stable both-edges;
    padding: 1rem;
    display: flex;
    flex-direction: column;
    align-items: center;
    /* Groesser als die frueheren .75rem: zwischen zwei Blasen trennte der Rahmen, zwischen
       einer Frage und einer rahmenlosen Antwort trennt nur noch der Abstand. */
    gap: 1.25rem;
}

/* margin: auto traegt hier die Zentrierung in BEIDEN Achsen -- in der senkrechten ist das
   der Grund, warum die Anrede im leeren Chat nicht oben klebt. Nicht durch align-items
   ersetzen, das gilt nur quer. */
.chat-empty[b-wqqyf0fn9c] {
    margin: auto;
    max-width: 32rem;
    text-align: center;
    color: var(--app-text-muted);
}

.chat-empty-greeting[b-wqqyf0fn9c] {
    margin: 0;
    font-size: 1.35rem;
    font-weight: 600;
    color: var(--app-text);
}

/* align-items: stretch ausdruecklich, nicht als Vorgabe verlassen: die Karten tragen
   unterschiedlich lange Texte, und nebeneinander stehende Karten unterschiedlicher Hoehe
   sehen aus wie ein Fehler. */
.chat-suggestions[b-wqqyf0fn9c] {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: stretch;
    gap: var(--app-space-2);
    margin-top: var(--app-space-5);
}

/* Karten, keine Knoepfe mit Rahmenfarbe: sie sind ein Angebot, keine Aufforderung. Der Text
   darin ist linksbuendig, weil er ein Satz ist und kein Etikett. */
.chat-suggestion[b-wqqyf0fn9c] {
    flex: 0 1 15rem;
    padding: var(--app-space-2) var(--app-space-3);
    border: 1px solid var(--app-border);
    border-radius: var(--app-radius);
    background: var(--app-surface);
    color: var(--app-text);
    font: inherit;
    font-size: .85rem;
    text-align: left;
    cursor: pointer;
}

.chat-suggestion:hover[b-wqqyf0fn9c] {
    border-color: var(--app-border-strong);
    background: var(--app-hover-bg);
}

/* ::deep, because the bubbles are rendered by a child component and scoped CSS only
   reaches this component's own markup.

   WARUM "> ::deep" UND NICHT "> *": Blazor haengt die Bereichskennung an die LETZTE Einheit
   eines Selektors. ".chat-messages > *" wird zu ".chat-messages[b-list] > *[b-list]" und
   trifft damit ausgerechnet die Zeilen NICHT -- die rendert ChatMessageBubble, sie tragen
   dessen Kennung. Bei "> ::deep .chat-row" wandert die Kennung an das Element davor
   (".chat-messages[b-list] > .chat-row"), und genau das ist gemeint. */

/* A message is a row: the bubble plus the action bar below it. The row is what this
   container lays out and what caps the width; the typing and error bubbles have no row and
   are laid out as bubbles directly, which is why the width rule below names both. */
.chat-messages[b-wqqyf0fn9c] >  .chat-row,
.chat-messages > .chat-bubble[b-wqqyf0fn9c] {
    width: min(46rem, 100%);
}

[b-wqqyf0fn9c] .chat-row {
    display: flex;
    flex-direction: column;
}

/* Nur noch die Ausrichtung INNERHALB der Zeile. Die Zeile selbst steht in der Spalte, die
   align-items des Bildlaufbereichs vorgibt -- ein align-self haette hier nichts mehr zu
   entscheiden. */
[b-wqqyf0fn9c] .chat-row-user { align-items: flex-end; }
[b-wqqyf0fn9c] .chat-row-assistant { align-items: flex-start; }

/* Kein Rahmen und keine Flaeche in der Grundregel: die Antwort bekommt beides nie, und
   haette die Grundregel sie, haenge das Entrahmen unten an der Zeilenreihenfolge statt an
   der Spezifitaet (beide Selektoren wiegen gleich). */
[b-wqqyf0fn9c] .chat-bubble {
    max-width: 100%;
    padding: .6rem .85rem;
    border-radius: var(--app-radius-bubble);
    word-wrap: break-word;
}

/* Die Frage ist eine Blase. Sie bleibt schmaler als die Spalte, sonst ist die Ausrichtung
   nach rechts nicht zu sehen. */
[b-wqqyf0fn9c] .chat-bubble-user {
    max-width: 85%;
    background: var(--app-surface-3);
}

/* Die Antwort ist KEINE Blase, sondern Fliesstext auf der Seitenflaeche -- so machen es
   ChatGPT, Claude und Open WebUI, und aus gutem Grund: ein Kasten, der sich nach dem Inhalt
   richtet, springt bei jeder Antwort auf eine andere Breite. */
[b-wqqyf0fn9c] .chat-bubble-assistant {
    padding-inline: 0;
    background: transparent;
}

/* Die Fehlermeldung behaelt ihren Kasten, steht aber wie alles andere in der Lesespalte;
   ihre frueheren Sonderrechte (align-self: stretch, max-width: none) waren gegen die Spalte
   ohnehin wirkungslos. */
[b-wqqyf0fn9c] .chat-bubble-error {
    border: 1px solid var(--app-danger-border);
    border-radius: var(--app-radius);
    background: var(--app-danger-bg);
    color: var(--app-danger-text);
}

/* Three dots while nothing has arrived yet.

   Kein "width: fit-content" mehr: die Regel wog genauso viel wie die Spaltenbreite oben, es
   haette also die Zeilenreihenfolge entschieden. Die Punkte sitzen jetzt links in der
   Spalte, dort, wo gleich der erste Buchstabe der Antwort steht. */
.chat-typing[b-wqqyf0fn9c] {
    display: flex;
    gap: .3rem;
    align-items: center;
    justify-content: flex-start;
}

.chat-typing span[b-wqqyf0fn9c] {
    width: .45rem;
    height: .45rem;
    border-radius: 50%;
    background: var(--app-gray-400);
    animation: chat-typing-bounce-b-wqqyf0fn9c 1.2s infinite ease-in-out;
}

.chat-typing span:nth-child(2)[b-wqqyf0fn9c] { animation-delay: .15s; }
.chat-typing span:nth-child(3)[b-wqqyf0fn9c] { animation-delay: .3s; }

@keyframes chat-typing-bounce-b-wqqyf0fn9c {
    0%, 60%, 100% { opacity: .35; transform: translateY(0); }
    30%           { opacity: 1;   transform: translateY(-.2rem); }
}

@media (prefers-reduced-motion: reduce) {
    .chat-typing span[b-wqqyf0fn9c] { animation: none; }
}

/*
    Der Ladezustand. Er sitzt in derselben Lesespalte wie die Nachrichten (width: min(46rem,
    100%)), damit die Platzhalter genau dort stehen, wo gleich die Blasen stehen -- ein
    Wechsel der Breite waere ein zweiter Sprung nach dem, den dieser Zustand gerade
    verhindert.
*/
.chat-skeleton[b-wqqyf0fn9c] {
    width: min(46rem, 100%);
    display: flex;
    flex-direction: column;
    gap: 1.25rem;
    padding-top: .5rem;
}

.chat-skeleton-row[b-wqqyf0fn9c] {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: .45rem;
    width: 100%;
}

/* Die Frage steht rechts, wie ihre Blase. */
.chat-skeleton-user[b-wqqyf0fn9c] {
    align-items: flex-end;
}

/*
    Der Schimmer laeuft EINMAL durch und wiederholt sich -- er ist die einzige Bewegung auf
    der Seite und sagt "es geschieht etwas". Ohne ihn waeren es drei graue Balken, und die
    sind von einem Fehler nicht zu unterscheiden.
*/
.chat-skeleton-bar[b-wqqyf0fn9c] {
    height: .85rem;
    border-radius: var(--app-radius-pill);
    background: var(--app-surface-3);
    background-image: linear-gradient(
        90deg,
        transparent 0,
        var(--app-surface-2) 40%,
        transparent 80%);
    background-size: 14rem 100%;
    background-repeat: no-repeat;
    animation: chat-skeleton-shimmer-b-wqqyf0fn9c 1.2s ease-in-out infinite;
}

.chat-skeleton-user .chat-skeleton-bar[b-wqqyf0fn9c] {
    height: 1.6rem;
    border-radius: var(--app-radius-bubble);
}

@keyframes chat-skeleton-shimmer-b-wqqyf0fn9c {
    from { background-position: -14rem 0; }
    to   { background-position: calc(100% + 14rem) 0; }
}

/* Kein Flimmern fuer alle, die darum gebeten haben: die Balken stehen dann still da und
   sagen dasselbe, nur leiser. */
@media (prefers-reduced-motion: reduce) {
    .chat-skeleton-bar[b-wqqyf0fn9c] {
        background-image: none;
        animation: none;
    }
}
/* /Components/ElicitationCard.razor.rz.scp.css */
/*
    Die Elicitation-Karte als Schritt im Zug des Assistenten.

    Sie steht zwischen den anderen Schritten der Zeitachse (Werkzeugaufrufe, Denken) und soll
    sich davon abheben, ohne sie zu ueberragen -- deshalb keine feste Breite, keine
    Positionierung, knappe Abstaende und nur Tokens aus wwwroot/css/tokens.css. Beantwortet
    schrumpft sie auf eine Zeile.
*/

.elicitation-card[b-ymmkor1oc7] {
    border: 1px solid var(--app-border);
    border-left: 3px solid var(--app-accent);
    border-radius: var(--app-radius-sm);
    background: var(--app-surface);
    padding: var(--app-space-2) var(--app-space-3);
    margin: var(--app-space-1) 0;
    font-size: .875rem;
}

/* Beantwortet: nur noch ein Vermerk. Kein Akzentrand mehr, der um Aufmerksamkeit wirbt. */
.elicitation-card.is-answered[b-ymmkor1oc7] {
    border-left-color: var(--app-border-strong);
    background: transparent;
    padding: var(--app-space-1) var(--app-space-2);
}

.elicitation-head[b-ymmkor1oc7],
.elicitation-line[b-ymmkor1oc7] {
    display: flex;
    align-items: center;
    gap: var(--app-space-2);
    min-width: 0;
}

.elicitation-head[b-ymmkor1oc7] {
    margin-bottom: var(--app-space-1);
}

.elicitation-line[b-ymmkor1oc7] {
    cursor: pointer;
    list-style: none;
}

.elicitation-line[b-ymmkor1oc7]::-webkit-details-marker {
    display: none;
}

.elicitation-badge[b-ymmkor1oc7] {
    flex: 0 0 auto;
    padding: 0 var(--app-space-1);
    border-radius: var(--app-radius-sm);
    background: var(--app-accent);
    color: var(--app-accent-contrast);
    font-size: .6875rem;
    font-weight: 600;
    letter-spacing: .03em;
}

.is-answered .elicitation-badge[b-ymmkor1oc7] {
    background: var(--app-surface-3);
    color: var(--app-text-muted);
}

.elicitation-title[b-ymmkor1oc7] {
    font-weight: 600;
    min-width: 0;
    overflow-wrap: anywhere;
}

.elicitation-tool[b-ymmkor1oc7] {
    font-family: var(--app-font-mono);
    font-size: .8125rem;
    font-weight: 400;
}

.elicitation-outcome[b-ymmkor1oc7] {
    color: var(--app-text-muted);
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.elicitation-done[open] .elicitation-outcome[b-ymmkor1oc7] {
    white-space: normal;
}

.elicitation-done[open] > .elicitation-message[b-ymmkor1oc7] {
    margin-top: var(--app-space-2);
}

/*
    Die Nachricht des Servers als Markdown, mit den Massen der Chatblase, nur enger.
    Zeilenumbrueche im Text bleiben Zeilenumbrueche (pre-line am Absatz, nicht am Behaelter --
    sonst wuerden die Zeilenwechsel zwischen den Bloecken zu Leerzeilen).
*/
.elicitation-message[b-ymmkor1oc7] {
    margin: 0 0 var(--app-space-2);
    line-height: 1.5;
    overflow-wrap: anywhere;
}

.elicitation-message[b-ymmkor1oc7] >  :first-child { margin-top: 0; }
.elicitation-message[b-ymmkor1oc7] >  :last-child  { margin-bottom: 0; }

.elicitation-message[b-ymmkor1oc7]  p,
.elicitation-message[b-ymmkor1oc7]  li {
    white-space: pre-line;
}

.elicitation-message[b-ymmkor1oc7]  p { margin: 0 0 var(--app-space-1); }

.elicitation-message[b-ymmkor1oc7]  ul,
.elicitation-message[b-ymmkor1oc7]  ol {
    margin: var(--app-space-1) 0 var(--app-space-1) var(--app-space-4);
    padding: 0;
}

.elicitation-message[b-ymmkor1oc7]  pre {
    background: var(--app-surface-2);
    border: 1px solid var(--app-border);
    border-radius: var(--app-radius-sm);
    padding: var(--app-space-1) var(--app-space-2);
    overflow-x: auto;
    margin: var(--app-space-1) 0;
}

.elicitation-message[b-ymmkor1oc7]  code {
    font-size: .875em;
    word-break: break-word;
}

.elicitation-message[b-ymmkor1oc7]  table {
    border-collapse: collapse;
    margin: var(--app-space-1) 0;
}

.elicitation-message[b-ymmkor1oc7]  th,
.elicitation-message[b-ymmkor1oc7]  td {
    border: 1px solid var(--app-border);
    padding: 0 var(--app-space-2);
}

.elicitation-hint[b-ymmkor1oc7] {
    margin: 0 0 var(--app-space-2);
    color: var(--app-text-muted);
}

.elicitation-errors[b-ymmkor1oc7] {
    margin: 0 0 var(--app-space-2);
    padding-left: var(--app-space-4);
    color: var(--app-danger);
}

/*
    Mehrspaltig, damit auch ein Formular mit vier Feldern die Zeitachse nicht in die Laenge
    zieht. Unter 14rem Spaltenbreite bleibt es einspaltig.
*/
.elicitation-form[b-ymmkor1oc7] {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
    gap: var(--app-space-2) var(--app-space-3);
}

.elicitation-field[b-ymmkor1oc7] {
    min-width: 0;
}

.elicitation-buttons[b-ymmkor1oc7] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--app-space-2);
    margin-top: var(--app-space-2);
}

/* Technische Details: zurueckhaltend, eingeklappt, fuer die Fehlersuche. */
.elicitation-tech[b-ymmkor1oc7] {
    margin-top: var(--app-space-2);
    font-size: .8125rem;
    color: var(--app-text-muted);
}

.elicitation-tech > summary[b-ymmkor1oc7] {
    cursor: pointer;
    width: fit-content;
}

.elicitation-facts[b-ymmkor1oc7] {
    display: grid;
    grid-template-columns: max-content 1fr;
    gap: 0 var(--app-space-3);
    margin: var(--app-space-1) 0;
}

.elicitation-facts dt[b-ymmkor1oc7] {
    font-weight: 600;
}

.elicitation-facts dd[b-ymmkor1oc7] {
    margin: 0;
    font-family: var(--app-font-mono);
    overflow-wrap: anywhere;
}

.elicitation-raw-label[b-ymmkor1oc7] {
    margin-top: var(--app-space-1);
    font-weight: 600;
}

.elicitation-raw[b-ymmkor1oc7] {
    margin: 0;
    max-height: 16rem;
    overflow: auto;
    padding: var(--app-space-1) var(--app-space-2);
    background: var(--app-surface-2);
    border: 1px solid var(--app-border);
    border-radius: var(--app-radius-sm);
    font-family: var(--app-font-mono);
    font-size: .75rem;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
    color: var(--app-text);
}
/* /Components/Layout/AuthLayout.razor.rz.scp.css */
/* Eine schmale Karte in der Mitte, eine Leiste darueber. Mehr braucht eine Seite nicht,
   auf der man nur ankommt. */
.auth-shell[b-fwo6yomd0g] {
    display: flex;
    flex-direction: column;
    min-height: 100dvh;
}

.auth-bar[b-fwo6yomd0g] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: var(--app-space-3) var(--app-space-4);
    border-bottom: 1px solid var(--app-border);
}

.auth-brand[b-fwo6yomd0g] {
    font-weight: 600;
}

.auth-icon-button[b-fwo6yomd0g] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2rem;
    height: 2rem;
    padding: 0;
    border: 0;
    border-radius: var(--app-radius-sm);
    background: transparent;
    color: var(--app-text-muted);
    cursor: pointer;
}

.auth-icon-button:hover[b-fwo6yomd0g] {
    background: var(--app-hover-bg);
    color: var(--app-text);
}

.auth-icon-button svg[b-fwo6yomd0g] {
    width: 1.15rem;
    height: 1.15rem;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.6;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.auth-card[b-fwo6yomd0g] {
    width: 100%;
    max-width: 26rem;
    margin: var(--app-space-6) auto;
    padding: 0 var(--app-space-4);
}
/* /Components/Layout/MainLayout.razor.rz.scp.css */
/*
    Die Huelle ist genau eine Bildschirmhoehe hoch und scrollt nicht. Wer scrollt, ist der
    Inhalt -- und im Chat sogar nur die Nachrichtenliste, damit der Verfasser unten stehen
    bleibt.

    dvh statt vh: auf Mobilgeraeten aendert die ein- und ausfahrende Adressleiste die
    sichtbare Hoehe, und 100vh rechnet mit der groesseren. Der Verfasser sitzt sonst
    dauerhaft unter dem Bildschirmrand.
*/
.app-shell[b-3vao5ceq1v] {
    display: flex;
    height: 100dvh;
    overflow: hidden;
}

/*
    min-width: 0 ist Pflicht, nicht Kosmetik: ein Flex-Element ist per Voreinstellung
    mindestens so breit wie sein laengster unumbrechbarer Inhalt. Ohne diese Zeile schiebt
    eine breite Tabelle auf einer Admin-Seite die Navigationsleiste aus dem Bild.

    Selbst eine Spalte, nicht nur ein Kasten: der Chat soll genau den Rest der Hoehe
    bekommen und INNEN scrollen. Waere hier kein Flex-Kontext, muesste er height: 100%
    nehmen -- und das rechnet die Polsterung oben drauf, also scrollt die Seite doch.
*/
.app-content[b-3vao5ceq1v] {
    flex: 1 1 auto;
    min-width: 0;
    min-height: 0;
    display: flex;
    flex-direction: column;
    overflow: auto;
    padding: var(--app-space-6);
}


/* Die Kinder von .app-content duerfen nicht schrumpfen -- die Regel dazu steht in
   wwwroot/css/components.css und NICHT hier: sie muss den Inhalt von @Body treffen, und
   der traegt die Scope-Kennung dieses Layouts nicht. */

/*
    Der mobile Kopfbalken und der Hintergrund der Schublade. Beide stehen im Markup immer,
    sichtbar sind sie nur unter dem Umbruchpunkt -- das ist billiger und ehrlicher als sie
    per Render-Bedingung ein- und auszubauen.
*/
.app-bar[b-3vao5ceq1v],
.nav-backdrop[b-3vao5ceq1v] {
    display: none;
}

/*
    Auf schmalen Anzeigen: ein Balken oben, die Leiste wird zur Schublade darueber.

    flex-direction: column BLEIBT -- darauf sitzt der Balken als erstes Flusskind. Die
    Leiste ist unter diesem Umbruchpunkt position: fixed (NavRail.razor.css) und damit
    ohnehin aus dem Fluss; die Spaltenrichtung betrifft nur noch Balken und Inhalt.
*/
@media (max-width: 47.99rem) {
    .app-shell[b-3vao5ceq1v] {
        flex-direction: column;
    }

    .app-content[b-3vao5ceq1v] {
        padding: var(--app-space-4);
    }

    .app-bar[b-3vao5ceq1v] {
        display: flex;
        flex: 0 0 auto;
        align-items: center;
        gap: var(--app-space-2);
        padding: var(--app-space-2) var(--app-space-3);
        border-bottom: 1px solid var(--app-border);
        background: var(--app-surface-2);
    }

    /* Dieselbe Maske wie in der Leiste: eine Bilddatei, die Farbe aus --app-brand, der
       Dunkelmodus zieht ohne zweite Fassung mit. */
    .app-bar-logo[b-3vao5ceq1v] {
        flex: 0 0 auto;
        width: 1.6rem;
        height: 1.38rem;
        background-color: var(--app-brand);
        -webkit-mask: url(/img/gowbox-logo.svg) center / contain no-repeat;
        mask: url(/img/gowbox-logo.svg) center / contain no-repeat;
    }

    .app-bar-title[b-3vao5ceq1v] {
        min-width: 0;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        font-weight: 600;
    }

    .app-bar-button[b-3vao5ceq1v] {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        flex: 0 0 auto;
        width: 2.25rem;
        height: 2.25rem;
        padding: 0;
        border: 0;
        border-radius: var(--app-radius-sm);
        background: transparent;
        color: var(--app-text-muted);
        cursor: pointer;
    }

    .app-bar-button:hover[b-3vao5ceq1v] {
        background: var(--app-hover-bg);
        color: var(--app-text);
    }

    .app-bar-button svg[b-3vao5ceq1v] {
        width: 1.35rem;
        height: 1.35rem;
        fill: none;
        stroke: currentColor;
        stroke-width: 1.8;
        stroke-linecap: round;
    }

    /* 1040 und 1045 sind Bootstraps eigene Offcanvas-Werte -- damit kommt kein drittes
       Nummernschema ins Haus, und ein DxPopup (1055) legt sich korrekt darueber. */
    :root[data-nav="open"] .nav-backdrop[b-3vao5ceq1v] {
        display: block;
        position: fixed;
        inset: 0;
        z-index: 1040;
        background: var(--app-backdrop);
    }
}

/*
    Absichtlich "light only": der Fehlerbalken soll in jedem Thema gleich alarmierend
    aussehen, und ohne diese Zeile wuerde der Browser seine Formularelemente und
    Bildlaufleisten im Dunkelmodus umfaerben.
*/
#blazor-error-ui[b-3vao5ceq1v] {
    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%;
    /* Angehoben von 1000: das ist die letzte Meldung, die die Anwendung noch absetzen kann,
       und sie laege sonst unter der Schublade (1045) und unter jedem DxPopup (1055). */
    z-index: 1060;
}

    #blazor-error-ui .dismiss[b-3vao5ceq1v] {
        cursor: pointer;
        position: absolute;
        right: 0.75rem;
        top: 0.5rem;
    }
/* /Components/Layout/NavRail.razor.rz.scp.css */
/*
    Die Leiste: Kopf (fest), Mitte (scrollt), Fuss (fest). Die Mitte nimmt spaeter die
    Chatliste auf, die beliebig lang werden kann -- deshalb scrollt nur sie.

    Farben kommen ausnahmslos aus css/tokens.css. Die Vorgaengerversion hatte einen festen
    Farbverlauf von Blau nach Violett und weisse Schrift; genau das hat einen Dunkelmodus
    unmoeglich gemacht.
*/
/*
    Zwei Variablen, zwei Besitzer: --rail-user-width setzt shell.js am <html>, wenn jemand
    die Leiste breiter gezogen hat; --rail-width setzt die Eingeklappt-Regel direkt an .rail
    und gewinnt damit, ohne dass die gemerkte Breite verloren geht.
*/
.rail[b-0sh5pnt548] {
    position: relative;
    flex: 0 0 var(--rail-width, var(--rail-user-width, 14rem));
    display: flex;
    flex-direction: column;

    /*
        min-width: 0 ist hier Pflicht: ein Flex-Element ist per Voreinstellung
        (min-width: auto) mindestens so breit wie sein Inhalt, und die Leiste war damit
        gemessene 270px breit statt der deklarierten 14rem. Die Beschriftungen kuerzen sich
        selbst per text-overflow, die Breite gibt also die Deklaration vor -- nicht der
        laengste Konversationstitel.
    */
    min-width: 0;
    min-height: 0;
    background: var(--app-surface-2);
    border-right: 1px solid var(--app-border);
}

/* Eingeklappt bleibt nur die Symbolspalte stehen. Das Attribut sitzt am <html>
   (wwwroot/js/shell.js), damit der Zustand schon im ersten Anstrich stimmt und jede
   Navigation ueberlebt.

   NUR AB 48rem. data-rail wird im localStorage gehalten: wer am Schreibtisch einklappt,
   traegt den Zustand mit aufs Telefon, und dort waere die Schublade dann ein schmaler
   Streifen aus Symbolen -- ohne Beschriftungen und ohne Chatliste. Auf schmalen Anzeigen
   gibt es keine eingeklappte Leiste, nur eine geschlossene Schublade. Dieselbe Klammer
   liegt aus demselben Grund um die Regeln in ChatConversationSidebar.razor.css. */
@media (min-width: 48rem) {
    /* Eine gemerkte Breite aus einem grossen Fenster darf ein kleines nicht zuschieben. */
    .rail[b-0sh5pnt548] {
        max-width: 50vw;
    }

    :root[data-rail="collapsed"] .rail[b-0sh5pnt548] {
        --rail-width: 3.5rem;
    }

    :root[data-rail="collapsed"] .rail-label[b-0sh5pnt548],
    :root[data-rail="collapsed"] .rail-brand[b-0sh5pnt548],
    :root[data-rail="collapsed"] .rail-user-chevron[b-0sh5pnt548],
    :root[data-rail="collapsed"] .rail-section-title[b-0sh5pnt548] {
        display: none;
    }

    :root[data-rail="collapsed"] .rail-head[b-0sh5pnt548],
    :root[data-rail="collapsed"] .rail-foot[b-0sh5pnt548],
    :root[data-rail="collapsed"] .rail-back[b-0sh5pnt548],
    :root[data-rail="collapsed"] .rail-admin-entry[b-0sh5pnt548],
    :root[data-rail="collapsed"] .rail-user-toggle[b-0sh5pnt548],
    :root[data-rail="collapsed"] .rail-sections[b-0sh5pnt548]  .rail-link {
        justify-content: center;
    }

    /* Die Gruppen bleiben als Abstand erkennbar, auch ohne Ueberschrift. */
    :root[data-rail="collapsed"] .rail-section + .rail-section[b-0sh5pnt548] {
        border-top: 1px solid var(--app-border);
        padding-top: var(--app-space-1);
    }

    /* In der Symbolspalte waere ein 3,5rem breites Menue unlesbar: es klappt daneben auf und
       behaelt seine Beschriftungen. Die Regel ist spezifischer als das display: none oben,
       also gewinnt sie ohne !important. */
    :root[data-rail="collapsed"] .rail-menu[b-0sh5pnt548] {
        left: 100%;
        right: auto;
        bottom: 0;
        width: 15rem;
        margin-left: var(--app-space-1);
    }

    :root[data-rail="collapsed"] .rail-menu .rail-label[b-0sh5pnt548] {
        display: block;
    }
}

.rail-head[b-0sh5pnt548] {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: var(--app-space-2);
    padding: var(--app-space-3);
}

.rail-brand[b-0sh5pnt548] {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    align-items: center;
    gap: var(--app-space-2);
    font-weight: 600;
    color: var(--app-text);
    text-decoration: none;
}

/*
    Das Logo liegt als MASKE ueber einer Flaeche, nicht als <img>. Ein <img> brachte die Farbe
    aus der Datei mit, und der Dunkelmodus haette eine zweite, aufgehellte Fassung gebraucht --
    zwei Dateien, die auseinanderlaufen koennen. So gibt --app-brand die Farbe, und tokens.css
    bleibt die einzige Stelle, an der eine Farbe steht.

    Das Seitenverhaeltnis stammt aus der viewBox der Datei (486.56 x 417.28 = 1.166); contain
    laesst das Zeichen darin nicht verzerren.
*/
.rail-logo[b-0sh5pnt548] {
    flex: 0 0 auto;
    width: 2rem;
    height: 1.72rem;
    background-color: var(--app-brand);
    -webkit-mask: url(/img/gowbox-logo.svg) center / contain no-repeat;
    mask: url(/img/gowbox-logo.svg) center / contain no-repeat;
}

.rail-brand-text[b-0sh5pnt548] {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/*
    Der einzige wachsende Abschnitt. Gescrollt wird NICHT hier, sondern eine Ebene tiefer in
    .conversation-list -- so bleibt "Neuer Chat" am oberen Rand der Chats stehen, waehrend
    die Historie darunter laeuft.
*/
.rail-chats[b-0sh5pnt548] {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
    padding: 0 var(--app-space-2);
}

/*
    Der Verwaltungsbereich: "Zurueck zum Chat" oben (fest), darunter die Gruppen (scrollen).
    Dieselbe Spaltenmechanik wie .rail-chats, damit Kopf und Fuss der Leiste stehen bleiben.
*/
.rail-admin[b-0sh5pnt548] {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
    padding: 0 var(--app-space-2);
}

/* Gleiche Form wie "Neuer Chat" (ChatConversationSidebar.razor.css) -- an derselben Stelle
   steht im anderen Bereich derselbe Griff. */
.rail-back[b-0sh5pnt548] {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: var(--app-space-2);
    padding: var(--app-space-2);
    border: 1px solid var(--app-border);
    border-radius: var(--app-radius-sm);
    background: var(--app-surface);
    color: var(--app-text);
    text-decoration: none;
    font-size: .9rem;
    white-space: nowrap;
}

.rail-back:hover[b-0sh5pnt548] {
    background: var(--app-hover-bg);
}

.rail-sections[b-0sh5pnt548] {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    scrollbar-gutter: stable;
    margin-top: var(--app-space-2);
}

.rail-section + .rail-section[b-0sh5pnt548] {
    margin-top: var(--app-space-3);
}

/* Die Gruppenueberschrift: klein und gedaempft, aber in normaler Schreibung -- sie benennt,
   was darunter steht, und muss sich nicht gegen die Eintraege behaupten. */
.rail-section-title[b-0sh5pnt548] {
    margin: 0;
    padding: var(--app-space-1) var(--app-space-2);
    font-size: .75rem;
    font-weight: 600;
    color: var(--app-text-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.rail-section-list[b-0sh5pnt548] {
    list-style: none;
    margin: 0;
    padding: 0;
}

/* Der Eintrag "Verwaltung" ueber dem Fuss. Er sieht aus wie ein Eintrag der Gliederung, zu
   der er fuehrt. */
.rail-nav-block[b-0sh5pnt548] {
    flex: 0 0 auto;
    padding: var(--app-space-2) var(--app-space-2) 0;
    border-top: 1px solid var(--app-border);
}

.rail-admin-entry[b-0sh5pnt548] {
    display: flex;
    align-items: center;
    gap: var(--app-space-3);
    padding: var(--app-space-2);
    border-radius: var(--app-radius-sm);
    color: var(--app-text-muted);
    text-decoration: none;
    font-size: .9rem;
    white-space: nowrap;
}

.rail-admin-entry:hover[b-0sh5pnt548] {
    background: var(--app-hover-bg);
    color: var(--app-text);
}

.rail-admin-entry svg[b-0sh5pnt548],
.rail-back svg[b-0sh5pnt548],
.rail-user-chevron[b-0sh5pnt548] {
    width: 1.15rem;
    height: 1.15rem;
    flex: 0 0 auto;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.6;
    stroke-linecap: round;
    stroke-linejoin: round;
}

/*
    Das Profilmenue: der Name ist der Schalter, das Menue geht nach OBEN auf und legt sich
    ueber die Leiste, statt sie zu verschieben. bottom: 100% setzt seine Unterkante an die
    Oberkante des Blocks.
*/
.rail-user-block[b-0sh5pnt548] {
    position: relative;
    flex: 1 1 auto;
    min-width: 0;
}

.rail-user-toggle[b-0sh5pnt548] {
    display: flex;
    width: 100%;
    align-items: center;
    gap: var(--app-space-2);
    padding: var(--app-space-1) var(--app-space-2);
    border: 0;
    border-radius: var(--app-radius-sm);
    background: transparent;
    color: var(--app-text);
    font: inherit;
    font-size: .85rem;
    text-align: left;
    cursor: pointer;
}

.rail-user-toggle:hover[b-0sh5pnt548],
:root[data-user-menu="open"] .rail-user-toggle[b-0sh5pnt548] {
    background: var(--app-hover-bg);
}

/* Der Kreis mit dem Anfangsbuchstaben -- in der eingeklappten Leiste das Einzige, was vom
   Benutzer bleibt. */
.rail-avatar[b-0sh5pnt548] {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.75rem;
    height: 1.75rem;
    border-radius: 50%;
    background: var(--app-accent-subtle);
    color: var(--app-accent);
    font-size: .8rem;
    font-weight: 600;
}

.rail-user-name[b-0sh5pnt548] {
    flex: 1 1 auto;
    min-width: 0;
    white-space: nowrap;
}

.rail-user-chevron[b-0sh5pnt548] {
    color: var(--app-text-muted);
    transition: transform .15s ease;
}

:root[data-user-menu="open"] .rail-user-chevron[b-0sh5pnt548] {
    transform: rotate(180deg);
}

@media (prefers-reduced-motion: reduce) {
    .rail-user-chevron[b-0sh5pnt548] { transition: none; }
}

/* Mindestens 14rem breit, auch wenn die Leiste schmaler gezogen ist -- dann ragt es ueber
   ihren Rand, statt die Eintraege abzuschneiden. */
.rail-menu[b-0sh5pnt548] {
    position: absolute;
    bottom: calc(100% + var(--app-space-1));
    left: 0;
    min-width: max(100%, 14rem);
    z-index: 30;
    list-style: none;
    margin: 0;
    padding: var(--app-space-1);
    border: 1px solid var(--app-border);
    border-radius: var(--app-radius);
    background: var(--app-surface);
    box-shadow: var(--app-shadow);
}

:root:not([data-user-menu="open"]) .rail-menu[b-0sh5pnt548] {
    display: none;
}

.rail-menu-separator[b-0sh5pnt548] {
    height: 1px;
    margin: var(--app-space-1) 0;
    background: var(--app-border);
}

.rail-logout[b-0sh5pnt548] {
    margin: 0;
}

/*
    ::deep, weil NavLink sein <a> SELBST rendert: die Scope-Kennung dieser Komponente kommt
    dort nicht an, und eine Regel ohne ::deep greift schlicht nicht (nachgemessen -- das
    Element trug nur href, id, class und aria-current). Der Inhalt DES Links (.rail-label,
    das svg) steht dagegen in dieser Datei und ist normal gescoped.
*/
[b-0sh5pnt548] .rail-link {
    display: flex;
    align-items: center;
    gap: var(--app-space-3);
    padding: var(--app-space-2) var(--app-space-2);
    margin-bottom: 1px;
    border-radius: var(--app-radius-sm);
    color: var(--app-text-muted);
    text-decoration: none;
    font-size: .9rem;
    white-space: nowrap;
}

/* Thema und Abmelden sind Knoepfe, stehen aber zwischen Links -- sie sehen aus wie einer. */
button.rail-link[b-0sh5pnt548] {
    width: 100%;
    border: 0;
    background: transparent;
    font: inherit;
    font-size: .9rem;
    text-align: left;
    cursor: pointer;
}

[b-0sh5pnt548] .rail-link:hover {
    background: var(--app-hover-bg);
    color: var(--app-text);
}

/* NavLink setzt "active" selbst. Es vergleicht ohne Abfragezeichenfolge, das ?tenant=
   am href stoert also nicht (nachgemessen). */
[b-0sh5pnt548] .rail-link.active {
    background: var(--app-accent-subtle);
    color: var(--app-accent);
}

.rail-label[b-0sh5pnt548] {
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Ein Symbol erbt die Schriftfarbe und macht damit Hell und Dunkel ohne zweite Datei mit.
   Die Vorgaengerversion hatte die weisse Fuellung fest in eine data:-URI eingebacken. */
[b-0sh5pnt548] .rail-link svg,
.rail-icon-button svg[b-0sh5pnt548] {
    width: 1.15rem;
    height: 1.15rem;
    flex: 0 0 auto;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.6;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.rail-icon-button[b-0sh5pnt548] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 2rem;
    height: 2rem;
    padding: 0;
    border: 0;
    border-radius: var(--app-radius-sm);
    background: transparent;
    color: var(--app-text-muted);
    cursor: pointer;
}

.rail-icon-button:hover[b-0sh5pnt548] {
    background: var(--app-hover-bg);
    color: var(--app-text);
}

.rail-foot[b-0sh5pnt548] {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: var(--app-space-2);
    padding: var(--app-space-2);
    border-top: 1px solid var(--app-border);
}

.rail-link-compact[b-0sh5pnt548] {
    flex: 1 1 auto;
    justify-content: center;
}

/*
    Der Griff liegt AUF der rechten Kante, halb innen, halb aussen -- so trifft man ihn, ohne
    zu zielen, und er nimmt der Leiste keinen Platz. Sichtbar wird er erst beim Ueberfahren,
    beim Ziehen und mit dem Tastaturfokus: eine dauerhafte Linie waere nur ein zweiter Rand.
*/
.rail-resizer[b-0sh5pnt548] {
    position: absolute;
    top: 0;
    bottom: 0;
    right: -4px;
    width: 8px;
    z-index: 40;
    cursor: col-resize;
    touch-action: none;
}

.rail-resizer[b-0sh5pnt548]::after {
    content: "";
    position: absolute;
    top: 0;
    bottom: 0;
    left: 3px;
    width: 2px;
    background: transparent;
    transition: background-color .12s ease;
}

.rail-resizer:hover[b-0sh5pnt548]::after,
.rail-resizer:focus-visible[b-0sh5pnt548]::after,
:root[data-rail-resizing] .rail-resizer[b-0sh5pnt548]::after {
    background: var(--app-accent);
}

.rail-resizer:focus-visible[b-0sh5pnt548] {
    outline: none;
}

/* Waehrend des Ziehens: keine Textauswahl quer durch die Seite, und der Zeiger bleibt der
   Spaltenpfeil, auch wenn er den Griff ueberholt. */
:root[data-rail-resizing][b-0sh5pnt548],
:root[data-rail-resizing] *[b-0sh5pnt548] {
    cursor: col-resize !important;
    user-select: none;
}

@media (min-width: 48rem) {
    :root[data-rail="collapsed"] .rail-resizer[b-0sh5pnt548] {
        display: none;
    }
}

@media (prefers-reduced-motion: reduce) {
    .rail-resizer[b-0sh5pnt548]::after { transition: none; }
}

/* Der Schliessen-Knopf gibt es nur in der Schublade; am Schreibtisch schliesst man nichts. */
.rail-close[b-0sh5pnt548] {
    display: none;
}

/*
    Schmale Anzeigen: die Leiste ist eine Schublade ueber dem Inhalt.

    DIE VORGAENGERREGEL WAR DER FEHLER. Sie legte die Leiste oben hin und deckelte sie mit
    max-height: 40dvh -- ohne overflow. .rail ist aber eine Flex-Spalte, deren Kopf,
    Verwaltungsblock und Fuss alle flex: 0 0 auto tragen; nur .rail-chats kann nachgeben,
    und irgendwann ist die bei null. Der Rest lief aus der Leiste heraus und legte sich
    ueber den Seiteninhalt: "VERWALTUNG" auf "Neuer Chat", "Mandanten" auf die
    Chat-Ueberschrift.

    inset-block: 0 gibt der Leiste ihre volle Hoehe zurueck. Damit greift ihre vorhandene
    Innenmechanik wieder (.rail-chats waechst, .conversation-list scrollt), und der
    Ueberlauf ist nicht zugedeckt, sondern weg.
*/
@media (max-width: 47.99rem) {
    .rail[b-0sh5pnt548] {
        position: fixed;
        inset-block: 0;
        inset-inline-start: 0;
        width: min(18rem, 85vw);
        flex: none;
        max-height: none;
        border-right: 1px solid var(--app-border);
        border-bottom: 0;
        z-index: 1045;

        /* Geschlossen ist die Leiste nicht nur verschoben, sondern unsichtbar im Sinne des
           Browsers: keine Tabreihenfolge, kein Barrierefreiheitsbaum. Ohne das waere die
           geschlossene Schublade ein unsichtbares Tab-Loch vor jeder Seite. Die Verzoegerung
           laesst sie erst NACH dem Hinausfahren verschwinden. */
        visibility: hidden;
        transform: translateX(-100%);
        transition: transform .2s ease, visibility 0s .2s;
        overscroll-behavior: contain;
    }

    :root[data-nav="open"] .rail[b-0sh5pnt548] {
        visibility: visible;
        transform: none;
        transition: transform .2s ease;
    }

    .rail-collapse[b-0sh5pnt548] { display: none; }
    .rail-close[b-0sh5pnt548] { display: inline-flex; }
    .rail-resizer[b-0sh5pnt548] { display: none; }
}

@media (prefers-reduced-motion: reduce) {
    .rail[b-0sh5pnt548] { transition: none; }
}
/* /Components/Layout/ReconnectModal.razor.rz.scp.css */
.components-reconnect-first-attempt-visible[b-kn35kakn2o],
.components-reconnect-repeated-attempt-visible[b-kn35kakn2o],
.components-reconnect-failed-visible[b-kn35kakn2o],
.components-pause-visible[b-kn35kakn2o],
.components-resume-failed-visible[b-kn35kakn2o],
.components-rejoining-animation[b-kn35kakn2o] {
    display: none;
}

#components-reconnect-modal.components-reconnect-show .components-reconnect-first-attempt-visible[b-kn35kakn2o],
#components-reconnect-modal.components-reconnect-show .components-rejoining-animation[b-kn35kakn2o],
#components-reconnect-modal.components-reconnect-paused .components-pause-visible[b-kn35kakn2o],
#components-reconnect-modal.components-reconnect-resume-failed .components-resume-failed-visible[b-kn35kakn2o],
#components-reconnect-modal.components-reconnect-retrying[b-kn35kakn2o],
#components-reconnect-modal.components-reconnect-retrying .components-reconnect-repeated-attempt-visible[b-kn35kakn2o],
#components-reconnect-modal.components-reconnect-retrying .components-rejoining-animation[b-kn35kakn2o],
#components-reconnect-modal.components-reconnect-failed[b-kn35kakn2o],
#components-reconnect-modal.components-reconnect-failed .components-reconnect-failed-visible[b-kn35kakn2o] {
    display: block;
}


#components-reconnect-modal[b-kn35kakn2o] {
    background-color: white;
    width: 20rem;
    margin: 20vh auto;
    padding: 2rem;
    border: 0;
    border-radius: 0.5rem;
    box-shadow: 0 3px 6px 2px rgba(0, 0, 0, 0.3);
    opacity: 0;
    transition: display 0.5s allow-discrete, overlay 0.5s allow-discrete;
    animation: components-reconnect-modal-fadeOutOpacity-b-kn35kakn2o 0.5s both;
    &[open]

{
    animation: components-reconnect-modal-slideUp-b-kn35kakn2o 1.5s cubic-bezier(.05, .89, .25, 1.02) 0.3s, components-reconnect-modal-fadeInOpacity-b-kn35kakn2o 0.5s ease-in-out 0.3s;
    animation-fill-mode: both;
}

}

#components-reconnect-modal[b-kn35kakn2o]::backdrop {
    background-color: rgba(0, 0, 0, 0.4);
    animation: components-reconnect-modal-fadeInOpacity-b-kn35kakn2o 0.5s ease-in-out;
    opacity: 1;
}

@keyframes components-reconnect-modal-slideUp-b-kn35kakn2o {
    0% {
        transform: translateY(30px) scale(0.95);
    }

    100% {
        transform: translateY(0);
    }
}

@keyframes components-reconnect-modal-fadeInOpacity-b-kn35kakn2o {
    0% {
        opacity: 0;
    }

    100% {
        opacity: 1;
    }
}

@keyframes components-reconnect-modal-fadeOutOpacity-b-kn35kakn2o {
    0% {
        opacity: 1;
    }

    100% {
        opacity: 0;
    }
}

.components-reconnect-container[b-kn35kakn2o] {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1rem;
}

#components-reconnect-modal p[b-kn35kakn2o] {
    margin: 0;
    text-align: center;
}

#components-reconnect-modal button[b-kn35kakn2o] {
    border: 0;
    background-color: #6b9ed2;
    color: white;
    padding: 4px 24px;
    border-radius: 4px;
}

    #components-reconnect-modal button:hover[b-kn35kakn2o] {
        background-color: #3b6ea2;
    }

    #components-reconnect-modal button:active[b-kn35kakn2o] {
        background-color: #6b9ed2;
    }

.components-rejoining-animation[b-kn35kakn2o] {
    position: relative;
    width: 80px;
    height: 80px;
}

    .components-rejoining-animation div[b-kn35kakn2o] {
        position: absolute;
        border: 3px solid #0087ff;
        opacity: 1;
        border-radius: 50%;
        animation: components-rejoining-animation-b-kn35kakn2o 1.5s cubic-bezier(0, 0.2, 0.8, 1) infinite;
    }

        .components-rejoining-animation div:nth-child(2)[b-kn35kakn2o] {
            animation-delay: -0.5s;
        }

@keyframes components-rejoining-animation-b-kn35kakn2o {
    0% {
        top: 40px;
        left: 40px;
        width: 0;
        height: 0;
        opacity: 0;
    }

    4.9% {
        top: 40px;
        left: 40px;
        width: 0;
        height: 0;
        opacity: 0;
    }

    5% {
        top: 40px;
        left: 40px;
        width: 0;
        height: 0;
        opacity: 1;
    }

    100% {
        top: 0px;
        left: 0px;
        width: 80px;
        height: 80px;
        opacity: 0;
    }
}
/* /Components/Pages/Admin/ElicitationAuditAdmin.razor.rz.scp.css */
/* Die Detailzeile des Rückfragen-Audits: Fakten als Raster, das Schema als Rohtext.
   Nur Tokens aus wwwroot/css/tokens.css. */

.audit-facts[b-vx2gl4b9nh] {
    display: grid;
    grid-template-columns: max-content 1fr;
    gap: var(--app-space-1) var(--app-space-3);
    margin: 0 0 var(--app-space-2);
    font-size: .875rem;
}

.audit-facts dt[b-vx2gl4b9nh] {
    color: var(--app-text-muted);
    font-weight: 500;
}

.audit-facts dd[b-vx2gl4b9nh] {
    margin: 0;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}

.audit-raw-label[b-vx2gl4b9nh] {
    color: var(--app-text-muted);
    font-size: .8125rem;
}

.audit-raw[b-vx2gl4b9nh] {
    margin: 0;
    padding: var(--app-space-2);
    max-height: 20rem;
    overflow: auto;
    border: 1px solid var(--app-border);
    border-radius: var(--app-radius-sm);
    background: var(--app-surface);
    font-size: .8125rem;
}
/* /Components/Pages/Chat.razor.rz.scp.css */
/*
    Der Chat fuellt die Inhaltsspalte und scrollt NICHT als Seite: das tut nur die
    Nachrichtenliste, damit der Verfasser unten stehen bleibt. Die Seite ist eine Spalte aus
    Kopf (fest), Chat (waechst) und dem stillen Diagnoseblock.
*/
/*
    overflow: hidden ist hier kein Schoenheitsmittel, sondern der Deckel gegen einen ZWEITEN
    Bildlaufbalken. Laeuft irgendetwas in dieser Spalte ueber -- und der Kopf tat das --,
    entkommt der Ueberlauf bis zum naechsten Bildlaufbehaelter, und das ist .app-content mit
    overflow: auto. Ergebnis war ein aeusserer Balken neben dem der Nachrichtenliste.

    Unbedenklich, weil das Einzige, was aus dieser Spalte herausragen soll, position: fixed
    ist: .chat-page-foot und der DxPopup. Fixierte Nachfahren schneidet overflow nicht ab.
*/
.chat-page[b-v79dii8czu] {
    position: relative;
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    min-height: 0;
    overflow: hidden;
}

/*
    Die Ablageflaeche beim Hineinziehen von Dateien. data-drop-active setzt filedrop.js;
    die Ueberlagerung ist ein Pseudoelement, damit sie keine Kinder bekommt, die selbst
    dragenter/dragleave ausloesen -- und pointer-events: none aus demselben Grund.
*/
.chat-page[data-drop-active][b-v79dii8czu]::after {
    content: "Dateien hier ablegen";
    position: absolute;
    inset: 0;
    z-index: 10;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 2px dashed var(--app-accent);
    border-radius: var(--app-radius-lg);
    /* Fast deckend: durchscheinend kollidierte die Aufschrift mit dem Text darunter. */
    background: color-mix(in srgb, var(--app-surface) 92%, transparent);
    color: var(--app-accent);
    font-size: 1.1rem;
    font-weight: 600;
    pointer-events: none;
}

.chat-page[data-drop-active="blocked"][b-v79dii8czu]::after {
    content: "Dieses Modell nimmt keine Dateien an";
    border-color: var(--app-danger);
    color: var(--app-danger-text);
}

.chat-page[data-drop-active="busy"][b-v79dii8czu]::after {
    content: "Es wird noch hochgeladen …";
}

/*
    flex-wrap ist Pflicht: der Titel schrumpft per min-width: 0 bis auf null, die beiden
    Abzeichen rechts tun das nicht. Ohne Umbruch lief die Zeile auf schmalen Anzeigen
    waagerecht ueber -- bei 390px sind nach der Polsterung keine 360px mehr da, und ein
    Modellname plus Tokenzahl liegt darueber.
*/
.chat-page-head[b-v79dii8czu] {
    flex: 0 0 auto;
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--app-space-3);
    row-gap: var(--app-space-1);
    min-width: 0;
    margin-bottom: var(--app-space-2);
}

.chat-title[b-v79dii8czu] {
    flex: 1 1 auto;
    min-width: 0;
    margin: 0;
    font-size: 1.15rem;
    font-weight: 600;
    /* Der Inhalt kuerzt sich selbst (Knopf bzw. Feld darunter); die Ueberschrift ist nur
       noch der Kasten, in dem er steht. */
    display: flex;
    min-height: 1.9rem;
    align-items: center;
}

/*
    Der Titel IST die Schaltflaeche zum Umbenennen -- kein Stift daneben, kein Menue anderswo.
    Er sieht dabei aus wie eine Ueberschrift und nicht wie ein Knopf: erst beim Ueberfahren
    zeigt die Flaeche, dass hier etwas geht. Dasselbe Verhalten wie bei der Modellauswahl
    daneben, damit der Kopf eine Formsprache behaelt.
*/
.chat-title-button[b-v79dii8czu],
.chat-title-static[b-v79dii8czu] {
    min-width: 0;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/*
    KEIN NEGATIVER RAND, auch wenn er den Titel buendig mit dem linken Rand halten wuerde:
    .chat-page traegt overflow: hidden (siehe oben), und die Ueberschrift steht an dessen
    linker Kante. Alles, was nach links aus ihr herausragt -- Rand, Rahmen, Fokusring --,
    wird dort abgeschnitten. Die Polsterung liegt deshalb vollstaendig INNEN; der Titel
    beginnt um sie versetzt, und das ist der ganze Preis.
*/
.chat-title-button[b-v79dii8czu] {
    font: inherit;
    color: inherit;
    text-align: left;
    background: transparent;
    border: 1px solid transparent;
    border-radius: var(--app-radius-sm);
    padding: .1rem .35rem;
    cursor: text;
}

.chat-title-button:hover[b-v79dii8czu] {
    background: var(--app-hover-bg);
}

/* Der Fokusring liegt INNEN (negativer Versatz), aus demselben Grund: nach aussen gezeichnet
   waere er links weg. */
.chat-title-button:focus-visible[b-v79dii8czu] {
    outline: 2px solid var(--app-accent);
    outline-offset: -2px;
}

/* Das Feld steht genau dort, wo eben noch der Titel stand -- gleiche Schrift, gleiche
   Polsterung, gleicher Ursprung. Nur die Kante kommt dazu, damit klar ist, dass jetzt
   getippt wird. */
.chat-title-input[b-v79dii8czu] {
    flex: 1 1 auto;
    min-width: 0;
    max-width: 28rem;
    font: inherit;
    color: inherit;
    background: var(--bs-body-bg);
    border: 1px solid var(--app-border-strong);
    border-radius: var(--app-radius-sm);
    padding: .1rem .35rem;
}

.chat-title-input:focus[b-v79dii8czu],
.chat-title-input:focus-visible[b-v79dii8czu] {
    border-color: var(--app-accent);
    outline: 2px solid var(--app-accent);
    outline-offset: -2px;
}

/*
    Modell und Denkintensitaet in der Werkzeugzeile des Verfassers. Leise wie Beschriftungen,
    nicht wie Formularfelder: erst beim Ueberfahren zeigt die Flaeche, dass hier etwas geht.
    DxDropDownButton rendert sein Element selbst, deshalb ::deep unter einem Element dieser
    Seite. Das Menue selbst haengt ausserhalb der Seite (Portal) und steht in components.css.
*/
.chat-page[b-v79dii8czu]  .chat-picker.dxbl-btn {
    font-size: .8rem;
    color: var(--app-text-muted);
    padding-inline: .5rem;
    border-radius: var(--app-radius-pill);
    max-width: 16rem;
}

.chat-page[b-v79dii8czu]  .chat-picker.dxbl-btn:hover,
.chat-page[b-v79dii8czu]  .chat-picker.dxbl-btn:focus-visible {
    color: var(--app-text);
    background: var(--app-hover-bg);
}

/* Der Pfeil von DevExpress ist fuer einen Knopf in Normalgroesse gezeichnet; in der
   leisen Werkzeugzeile waere er das lauteste Zeichen. */
.chat-page[b-v79dii8czu]  .chat-picker.dxbl-btn .dxbl-image {
    width: .75rem;
    height: .75rem;
}

/* Ohne eigene Chat-Modelle gibt es nichts zu waehlen -- dann steht nur der Modellname da. */
.chat-picker-static[b-v79dii8czu] {
    padding: 0 .5rem;
    font-size: .8rem;
    color: var(--app-text-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 16rem;
}

/* Werkzeuge fuer dieses Modell aus. Ein Hinweis in Warnfarbe, kein Alarm: es ist eine
   Eigenschaft des gewaehlten Modells, kein Ausfall. Er steht direkt vor der Modellwahl, die
   ihn verursacht. */
.chat-tools-off[b-v79dii8czu] {
    padding: .05rem .5rem;
    border: 1px solid var(--app-warning-border);
    border-radius: var(--app-radius-pill);
    background: var(--app-warning-bg);
    color: var(--app-warning-text);
    font-size: .75rem;
    white-space: nowrap;
}

/*
    Ein Hinweis ueber dem Verfasser. Die Farben kommen aus den --bs-alert-*-Variablen, die
    Bootstraps alert-info/-warning/-success setzen -- die Form (schmal, abgerundet wie der
    Kasten darunter, Schliessen rechts) ist eigene. Ein volles .alert waere ein Kasten mit
    Rand und grosser Polsterung, der ueber dem Feld mehr Gewicht haette als das Feld.
*/
.chat-notice[b-v79dii8czu] {
    display: flex;
    align-items: flex-start;
    gap: var(--app-space-2);
    padding: .4rem .6rem .4rem .75rem;
    border: 1px solid var(--bs-alert-border-color);
    border-radius: var(--app-radius);
    background: var(--bs-alert-bg);
    color: var(--bs-alert-color);
    font-size: .85rem;
    line-height: 1.4;
}

.chat-notice > span[b-v79dii8czu],
.chat-notice-rows[b-v79dii8czu] {
    flex: 1 1 auto;
    min-width: 0;
}

.chat-notice-rows[b-v79dii8czu] {
    display: flex;
    flex-direction: column;
    gap: .2rem;
}

.chat-notice-close[b-v79dii8czu] {
    flex: 0 0 auto;
    border: 0;
    background: transparent;
    color: inherit;
    opacity: .7;
    font-size: 1rem;
    line-height: 1;
    padding: 0 .15rem;
    cursor: pointer;
}

.chat-notice-close:hover[b-v79dii8czu] { opacity: 1; }

/* Eine Zeile je Server: Text links, Anmelden rechts -- der Knopf steht immer an derselben
   Stelle, egal wie lang der Name ist. */
.chat-mcp-signin-row[b-v79dii8czu] {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--app-space-3);
}

/* Der Gesamtverbrauch des Chats, neben dem Modell. Bewusst genauso leise wie das
   Modell-Badge: es ist eine Kennzahl, keine Warnung. */
.chat-usage-badge[b-v79dii8czu] {
    flex: 0 1 auto;
    min-width: 0;
    font-size: .8rem;
    color: var(--app-text-muted);
    font-variant-numeric: tabular-nums;
}

/* Schmale Anzeigen: der Titel nimmt die ganze erste Zeile, die Abzeichen fallen darunter.
   Sie nebeneinander zu quetschen hiesse, beide unlesbar zu machen. */
@media (max-width: 47.99rem) {
    .chat-title[b-v79dii8czu] { flex: 1 1 100%; }
}

/*
    Die Diagnose. Zu zeigen, wenn man sie sucht -- nicht dauerhaft ueber dem Gespraech.

    Sie sitzt jetzt IM Kopf und klappt darunter auf, statt als Block ueber der Nachrichtenliste
    zu stehen: das Oeffnen schob vorher das ganze Gespraech nach unten.
*/
.chat-details[b-v79dii8czu] {
    position: relative;
    flex: 0 0 auto;
    font-size: .85rem;
}

.chat-details-summary[b-v79dii8czu] {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    cursor: pointer;
    padding: .05rem .4rem;
    border-radius: var(--app-radius-pill);
    color: var(--app-text-muted);
    white-space: nowrap;
}

.chat-details-summary:hover[b-v79dii8czu] {
    background: var(--app-hover-bg);
    color: var(--app-text);
}

/* Der Zustandspunkt. Zwei Zustaende, mehr sagt ein Punkt nicht: etwas fehlt (warn) oder es
   geht gerade gar nichts (bad). Ist alles in Ordnung, ist er nicht da -- ein gruener Punkt
   waere eine Dauermeldung ueber den Normalfall. */
.chat-details-dot[b-v79dii8czu] {
    flex: 0 0 auto;
    width: .5rem;
    height: .5rem;
    border-radius: 50%;
}

.chat-details-dot[data-state="warn"][b-v79dii8czu] { background: var(--app-warning); }
.chat-details-dot[data-state="bad"][b-v79dii8czu]  { background: var(--app-danger); }

/*
    Das aufgeklappte Feld liegt UEBER dem Gespraech, nicht darin.

    max-height und overflow sind Pflicht, nicht Vorsicht: .chat-page traegt overflow: hidden
    (siehe oben), ein zu hohes Feld wuerde also unten schlicht abgeschnitten.
*/
.chat-details-panel[b-v79dii8czu] {
    position: absolute;
    top: calc(100% + var(--app-space-1));
    right: 0;
    z-index: 5;
    width: min(34rem, 90vw);
    max-height: 70vh;
    overflow: auto;
    padding: var(--app-space-3);
    border: 1px solid var(--app-border);
    border-radius: var(--app-radius);
    background: var(--app-surface);
    box-shadow: var(--app-shadow);
}

.chat-details-panel > :first-child[b-v79dii8czu] { margin-top: 0; }
.chat-details-panel > :last-child[b-v79dii8czu] { margin-bottom: 0; }

.chat-detail-line[b-v79dii8czu] {
    margin: var(--app-space-2) 0;
    color: var(--app-text-muted);
}

.chat-body[b-v79dii8czu] {
    flex: 1 1 auto;
    display: flex;
    min-width: 0;
    min-height: 0;
}

/*
    Der Rahmen um den Chat ist weg: die Seite IST der Chat. Nur der Verfasser bekommt
    unten eine Kante, damit er sich vom Verlauf abhebt (siehe ChatComposer.razor.css).
*/
.chat-host[b-v79dii8czu] {
    position: relative;
    flex: 1 1 auto;
    min-width: 0;
    min-height: 0;
    display: flex;
}

/*
    Das Wasserzeichen haengt am WIRT, nicht am Bildlaufbereich. Ein absolut positioniertes
    Kind von .chat-messages haette im gescrollten Inhalt gelegen und waere mit der Historie
    nach oben gewandert; hier steht es fest hinter dem Verlauf.

    Maske ueber einer Flaeche statt <img>, wie in der Navigationsleiste: die Farbe kommt aus
    --app-brand, also zieht der Dunkelmodus ohne zweite Bilddatei mit.

    NUR IM LEEREN CHAT. Der frueheren Fassung fehlte diese Bedingung, und die Annahme "die
    Blasen decken es ab" traegt nicht mehr: die Antwort hat keine eigene Flaeche mehr,
    sondern steht direkt auf der Seite. Das Zeichen lag damit unter dem Text. Ein
    Wasserzeichen gehoert dorthin, wo nichts ist -- also genau in den leeren Chat.
*/
.chat-host[data-empty][b-v79dii8czu]::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    background-color: var(--app-brand);
    /* Etwas kraeftiger als die frueheren .05: das Zeichen liegt jetzt ausschliesslich auf
       leerer Flaeche und muss dort mit keinem Text mehr um Aufmerksamkeit ringen. */
    opacity: .07;
    -webkit-mask: url(/img/gowbox-logo.svg) center / min(45%, 22rem) no-repeat;
    mask: url(/img/gowbox-logo.svg) center / min(45%, 22rem) no-repeat;
}

/* Rot auf fast Schwarz traegt weniger weit als Rot auf Weiss -- bei .07 waere im Dunkeln
   zu wenig da. */
[data-bs-theme="dark"] .chat-host[data-empty][b-v79dii8czu]::after {
    opacity: .09;
}

/* Ohne position/z-index laege der Chat hinter dem ::after: ein positioniertes Element mit
   z-index 0 zeichnet ueber den nicht positionierten Geschwistern im Fluss. */
[b-v79dii8czu] .chat-component {
    position: relative;
    z-index: 1;
    flex: 1 1 auto;
    min-width: 0;
    min-height: 0;
    display: flex;
    flex-direction: column;
}

/*
    Solange nichts gesagt wurde, stehen Anrede und Verfasser zusammen in der Mitte -- so
    macht es jeder Chat-Client, und es ist die ehrlichere Anordnung: unten am Rand klebt ein
    Eingabefeld, zu dem es noch nichts gibt.

    Damit das geht, muss die Nachrichtenliste ihr flex: 1 abgeben; sonst nimmt sie die ganze
    Hoehe und drueckt den Verfasser wieder nach unten. Mit der ersten Nachricht faellt
    data-empty weg und beides rutscht in einem Schritt an seinen Platz.
*/
[b-v79dii8czu] .chat-component[data-empty] {
    justify-content: center;
}

[b-v79dii8czu] .chat-component[data-empty] .chat-messages {
    flex: 0 1 auto;
}

/*
    Der Block bleibt im Dokument und wird nur aus dem Bild geschoben. Kein display:none und
    kein .visually-hidden: Playwright liest ihn ueber innerText, und das ist CSS-abhaengig
    -- nicht gerendert liefert einen leeren String, und das white-space:nowrap von
    .visually-hidden wuerde die Zeilenumbrueche verschlucken, nach denen der Parser trennt.
*/
.chat-page-foot[b-v79dii8czu] {
    position: fixed;
    left: -10000px;
    top: 0;
    width: 40rem;
}

/* Der Anmeldelink eines OAuth-MCP-Servers steht rechts in der Zeile seines Hinweises. */
.chat-mcp-signin-link[b-v79dii8czu] {
    flex: 0 0 auto;
    font-weight: 600;
    color: inherit;
    white-space: nowrap;
}

/* Abmelden und neu anmelden stehen klein hinter dem Abzeichen des Servers im Details-Feld --
   ein Knopf, der wie ein Link aussieht, weil er neben einem Link steht. */
.chat-mcp-signout[b-v79dii8czu],
.chat-mcp-resignin[b-v79dii8czu] {
    margin-left: 0.5rem;
    font-size: 0.8125rem;
}

.chat-mcp-signout[b-v79dii8czu] {
    padding: 0;
    border: 0;
    background: none;
    color: var(--bs-link-color);
    text-decoration: underline;
    cursor: pointer;
}

.chat-mcp-signout:disabled[b-v79dii8czu] {
    color: var(--bs-secondary-color);
    cursor: default;
}
/* /Components/Pages/Diagnostics/RawChatLog.razor.rz.scp.css */
/* Zwei Spalten: links die Chats, rechts die Runden. Unter 60rem untereinander -- die Liste
   ist dann ein Kopf, kein Seitenstreifen. */
.raw-layout[b-qzfab1zt3p] {
    display: grid;
    grid-template-columns: minmax(14rem, 18rem) minmax(0, 1fr);
    gap: var(--app-space-4);
    align-items: start;
}

@media (max-width: 60rem) {
    .raw-layout[b-qzfab1zt3p] { grid-template-columns: minmax(0, 1fr); }
}

/* --- Links: die Chats ------------------------------------------------------------------- */

.raw-chats ul[b-qzfab1zt3p] {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--app-space-1);
}

.raw-chat[b-qzfab1zt3p] {
    display: flex;
    flex-direction: column;
    gap: .1rem;
    width: 100%;
    text-align: left;
    padding: var(--app-space-2);
    border: 1px solid var(--app-border);
    border-radius: var(--app-radius);
    background: var(--app-surface);
    color: var(--app-text);
    cursor: pointer;
}

.raw-chat:hover[b-qzfab1zt3p] { background: var(--app-hover-bg); }

.raw-chat.is-active[b-qzfab1zt3p] {
    background: var(--app-active-bg);
    border-color: var(--app-accent);
}

.raw-chat-title[b-qzfab1zt3p] {
    font-weight: 600;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.raw-chat-meta[b-qzfab1zt3p] {
    font-size: .78rem;
    color: var(--app-text-muted);
}

/* --- Rechts: die Runden ----------------------------------------------------------------- */

.raw-toolbar[b-qzfab1zt3p] {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--app-space-3);
    margin-bottom: var(--app-space-3);
}

.raw-switch[b-qzfab1zt3p] {
    display: flex;
    align-items: center;
    gap: var(--app-space-1);
    margin: 0;
}

.raw-note[b-qzfab1zt3p],
.raw-muted[b-qzfab1zt3p] {
    font-size: .8rem;
    color: var(--app-text-muted);
}

.raw-empty[b-qzfab1zt3p] { color: var(--app-text-muted); }

.raw-turn[b-qzfab1zt3p] { margin-bottom: var(--app-space-4); }

.raw-turn-head[b-qzfab1zt3p] {
    font-size: .95rem;
    font-weight: 600;
    margin: 0 0 var(--app-space-2);
}

.raw-round[b-qzfab1zt3p] {
    border: 1px solid var(--app-border);
    border-radius: var(--app-radius);
    margin-bottom: var(--app-space-2);
    overflow: hidden;
}

.raw-round.is-open[b-qzfab1zt3p] { border-color: var(--app-accent); }

/* Die Kopfzeile einer Runde ist EINE Zeile mit allem, wonach man sucht: Runde, Status, Ziel,
   Modell, Dauer, Groesse. Umbruch erlaubt, damit auf schmalen Fenstern nichts verschwindet. */
.raw-round-head[b-qzfab1zt3p] {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--app-space-2);
    width: 100%;
    text-align: left;
    padding: var(--app-space-2);
    border: 0;
    background: var(--app-surface-2);
    color: var(--app-text);
    cursor: pointer;
}

.raw-round-head:hover[b-qzfab1zt3p] { background: var(--app-hover-bg); }

.raw-badge[b-qzfab1zt3p] {
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

.raw-status[b-qzfab1zt3p] {
    font-family: var(--app-font-mono);
    font-size: .8rem;
    padding: .05rem .4rem;
    border-radius: var(--app-radius-sm);
}

.raw-status.is-ok[b-qzfab1zt3p] {
    background: var(--app-success-bg);
    color: var(--app-success-text);
}

.raw-status.is-bad[b-qzfab1zt3p] {
    background: var(--app-danger-bg);
    color: var(--app-danger-text);
}

/* Die URL darf den Rest nicht aus der Zeile schieben, ist aber das Erste, was man liest. */
.raw-uri[b-qzfab1zt3p] {
    flex: 1 1 12rem;
    min-width: 0;
    font-family: var(--app-font-mono);
    font-size: .8rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.raw-detail[b-qzfab1zt3p] { padding: var(--app-space-2); }

.raw-body-loading[b-qzfab1zt3p] {
    padding: var(--app-space-2);
    color: var(--app-text-muted);
}

.raw-block[b-qzfab1zt3p] { margin-bottom: var(--app-space-3); }
.raw-block:last-child[b-qzfab1zt3p] { margin-bottom: 0; }

.raw-block-head[b-qzfab1zt3p] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--app-space-2);
    margin-bottom: var(--app-space-1);
}

.raw-block-head h3[b-qzfab1zt3p] {
    font-size: .9rem;
    font-weight: 600;
    margin: 0;
}

.raw-headers[b-qzfab1zt3p] {
    margin-bottom: var(--app-space-1);
    font-size: .8rem;
}

.raw-headers summary[b-qzfab1zt3p] {
    cursor: pointer;
    color: var(--app-text-muted);
}

.raw-truncated[b-qzfab1zt3p] {
    margin: 0 0 var(--app-space-1);
    font-size: .8rem;
    color: var(--app-warning-text);
}

/* Der Koerper. Umbruch statt Querscrollen: eine JSON-Zeile ohne Einrueckung ist sonst
   zehntausend Zeichen breit und praktisch unlesbar. Die Hoehe ist gedeckelt, damit die
   naechste Runde noch in Reichweite bleibt. */
.raw-pre[b-qzfab1zt3p] {
    margin: 0;
    padding: var(--app-space-2);
    max-height: 28rem;
    overflow: auto;
    background: var(--app-surface-3);
    border: 1px solid var(--app-border);
    border-radius: var(--app-radius-sm);
    font-family: var(--app-font-mono);
    font-size: .78rem;
    line-height: 1.45;
    white-space: pre-wrap;
    word-break: break-word;
}
/* /Components/Pages/Diagnostics/TokenUsageReport.razor.rz.scp.css */
/* Zeitraumwahl und Neu-Laden, eine Zeile ueber den Tafeln. */
.usage-toolbar[b-cb6xzynma2] {
    display: flex;
    align-items: center;
    gap: var(--app-space-2);
    margin-bottom: var(--app-space-3);
}

.usage-toolbar select[b-cb6xzynma2] { width: auto; }

/* Die Kopfzahlen. Grid statt flex, damit sie auf schmalen Fenstern umbrechen, ohne dass
   einzelne Kacheln unterschiedlich breit werden. */
.usage-kpis[b-cb6xzynma2] {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
    gap: var(--app-space-3);
    padding: var(--app-space-3);
}

.usage-kpi[b-cb6xzynma2] {
    display: flex;
    flex-direction: column;
    gap: .15rem;
}

.usage-kpi-value[b-cb6xzynma2] {
    font-size: 1.35rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

.usage-kpi-label[b-cb6xzynma2] {
    font-size: .8rem;
    color: var(--app-text-muted);
}

/* Die Brandherde. Bewusst als Fliesstext mit Handlungsempfehlung und nicht als weitere
   Zahlenkolonne: eine Liste, aus der keine Handlung folgt, hilft niemandem. */
.usage-hotspots[b-cb6xzynma2] {
    margin: 0;
    padding-left: 1.1rem;
}

.usage-hotspots li[b-cb6xzynma2] { margin-bottom: .4rem; }
.usage-hotspots li:last-child[b-cb6xzynma2] { margin-bottom: 0; }

.usage-note[b-cb6xzynma2] {
    margin: 0;
    padding: 0 var(--app-space-3) var(--app-space-2);
    font-size: .85rem;
    color: var(--app-text-muted);
}

.usage-empty[b-cb6xzynma2] { color: var(--app-text-muted); }

.usage-muted[b-cb6xzynma2] {
    color: var(--app-text-muted);
    font-size: .8rem;
}

/* Zahlen rechtsbuendig und mit gleicher Ziffernbreite -- sonst sind zwei Zeilen einer
   Spalte nicht vergleichbar, und genau dafuer ist die Tabelle da. */
.table .num[b-cb6xzynma2] {
    text-align: right;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* Ein Server mit Kosten und null Aufrufen ist der haeufigste Fund dieser Seite. */
.usage-row-warn[b-cb6xzynma2] { background: var(--app-warning-bg, rgba(255, 193, 7, .12)); }

.usage-tag[b-cb6xzynma2] {
    margin-left: .4rem;
    padding: 0 .3rem;
    border: 1px solid var(--app-border);
    border-radius: .25rem;
    font-size: .7rem;
    color: var(--app-text-muted);
    white-space: nowrap;
}

/* Der Pruefvertrag fuer die Browsertests. Aus dem Bild geschoben statt display:none --
   innerText liefert fuer Unsichtbares einen leeren String, und .visually-hidden setzt
   white-space:nowrap und frisst damit die Zeilenumbrueche, nach denen der Parser trennt.
   Dasselbe Muster wie .chat-page-foot. */
.usage-foot[b-cb6xzynma2] {
    position: fixed;
    left: -10000px;
    top: 0;
    width: 40rem;
}
