﻿/* ChatPage Styles - Data Agent Chat. Colours draw from the governed set (tokens.css) via
   color-mix() for translucent overlays rather than hardcoded rgba() literals (PRS-1). */
.chat-page-container {
    display: flex;
    flex-direction: column;
    height: 93dvh;
    max-width: 100%;
    margin: 0;
    padding: 0;
    gap: 0;
    width: 100%;
    overflow: hidden;
    position: relative;
}

/* Chat Drawer Mode - the hosting drawer owns the width (half the viewport, or full screen);
   the chat itself simply fills it. */
.chat-page-container.chat-drawer-mode {
    width: 100%;
}

/* Fullscreen chat covers everything left of the right rail, but the drawer sits outside normal
   document flow (Fixed MudDrawer), so the page behind it keeps its own natural scroll unless
   explicitly locked - without this, expanding to fullscreen showed two independent scrollbars
   (the page's and the chat's own .messages-area), even though the page was no longer visible
   underneath. ChatComponent toggles this class on <body> only while fullscreen. */
body.sk-chat-fullscreen-lock {
    overflow: hidden;
}

/* Minimize/full-screen controls (drawer mode only - see the markup's own EnableResizableBorder
   gate). A slim bar above the messages area, not a full MudAppBar - the drawer already has no
   title of its own to show here. */
.chat-header {
    display: flex;
    justify-content: flex-end;
    align-items: center;
    gap: 2px;
    flex-shrink: 0;
    padding: 6px 10px;
    border-bottom: 1px solid var(--dtx-border-divider);
    background: var(--dtx-surface-card);
}

.chat-header__btn {
    color: var(--dtx-text-muted);
}

.chat-header__btn:hover {
    color: var(--dtx-text-body);
}

/* Messages Area */
.messages-area {
    flex: 1;
    overflow-y: auto;
    padding: 24px 20px 16px 20px;
    -webkit-overflow-scrolling: touch;
    scroll-behavior: smooth;
    min-height: 0;
    width: 100%;
}

.messages-area.scrolling-to-bottom {
    scroll-behavior: auto;
}

.welcome-container {
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 400px;
    margin-left:20px;
    margin-right:20px;
}

/* The gradient recipe used everywhere else the shell needs a dark brand surface (NavMenu's sidebar,
   the edit-page banners) - mostly dark navy with only a thin green tint at the bottom edge, not a
   flat fill in either colour. Deliberately not tied to --chat-avatar-color (that variable now holds
   the small round avatars' dark chip colour, a different, flatter treatment than this card wants). */
.welcome-card {
    max-width: min(600px, 100%);
    background: var(--dtx-gradient-shell);
    border-radius: 24px;
}

/* More breathing room above the icon and below the last suggestion than MudCardContent's own
   16px default gives - the card's rounded top/bottom corners were sitting right up against the
   icon and the last chip. Left/right stay at the 16px default; only vertical grows. */
.welcome-card .mud-card-content {
    padding-top: 32px !important;
    padding-bottom: 32px !important;
}

/* The card renders as .mud-paper, which forces color: var(--mud-palette-text-primary)
   on all descendants. On a colored card that makes text unreadable for themes with a
   dark text-primary, so override the card and its typography to the governed on-fill text. */
.welcome-card,
.welcome-card .mud-typography {
    color: var(--dtx-text-on-fill) !important;
}

.welcome-icon {
    width: var(--dtx-space-16);
    height: var(--dtx-space-16);
}

/* Force on-fill text on the colored welcome card so it stays readable
   regardless of the active tenant theme's text-primary/secondary colors
   (MudBlazor typography would otherwise override these). */
.welcome-card .welcome-title {
    color: var(--dtx-text-on-fill) !important;
    margin-bottom: 16px;
}

.welcome-card .welcome-subtitle {
    color: color-mix(in srgb, var(--dtx-text-on-fill) 90%, transparent) !important;
}

.welcome-card .welcome-suggestions-title {
    color: color-mix(in srgb, var(--dtx-text-on-fill) 80%, transparent) !important;
}

/* C6/DAG-33: same muted on-fill treatment as .welcome-suggestions-title above the chips, so the
   two read as a matched pair rather than one looking like a smaller afterthought. */
.welcome-card .ask-your-own-question-label {
    color: color-mix(in srgb, var(--dtx-text-on-fill) 80%, transparent) !important;
}

/* MudBlazor's own .mud-chip is white-space:nowrap with a fixed 32px height (mock-up feedback: a
   longer translation - French routinely runs longer than English - overflowed past the pill's own
   edge instead of the pill growing to fit, since nowrap text can't shrink and there was nothing here
   overriding it to wrap). Wrapping to multiple lines and letting height grow to fit keeps every
   language inside the card's own padding regardless of string length. */
.suggestion-chip {
    background: color-mix(in srgb, var(--dtx-text-on-fill) 20%, transparent) !important;
    color: var(--dtx-text-on-fill) !important;
    cursor: pointer;
    border-radius: 20px;
    height: auto !important;
    min-height: 32px;
    white-space: normal !important;
    text-align: center;
    padding-top: 6px;
    padding-bottom: 6px;
}

.suggestion-chip .mud-chip-content {
    white-space: normal;
    height: auto;
}

.suggestion-chip:hover {
    background: color-mix(in srgb, var(--dtx-text-on-fill) 30%, transparent) !important;
}

/* Stands in for the suggestion chips while the welcome-card prompts are loading (chat just
   opened) - same pill shape and fill as the real chip's own 20% background (design consistency:
   this should read as a light placeholder, not a heavier, more solid shape than what it is
   standing in for). MudSkeleton's default pulse animation dips to 40% of the base opacity, which
   at 20% faded past visible against the welcome card's dark background; the animation is
   redeclared here (not just the base colour) with a shallower dip - down to 75% rather than 40% -
   so the pulse still reads as "loading" without ever fading past visible or looking heavier than
   the chips it is standing in for. */
.suggestion-chip-skeleton {
    border-radius: 20px !important;
    margin: 0 auto;
    background-color: color-mix(in srgb, var(--dtx-text-on-fill) 20%, transparent) !important;
    animation: sk-suggestion-chip-skeleton-pulse 1.5s ease-in-out 0.5s infinite !important;
}

@keyframes sk-suggestion-chip-skeleton-pulse {
    0%, 100% {
        opacity: 1;
    }

    50% {
        opacity: 0.75;
    }
}

/* Messages Stack - a centered column (ChatGPT/Claude Code style) rather than bubbles stretched
   to the panel's own edges, so the conversation reads as one column regardless of how wide the
   surrounding panel is. */
.messages-stack {
    display: flex;
    flex-direction: column;
    gap: 16px;
    padding: 8px;
    width: 100%;
    max-width: 900px;
    margin: 0 auto;
}

.message-row {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    max-width: 85%;
    position: relative;
}

.message-row-user {
    align-self: flex-end;
    flex-direction: row-reverse;
}

.message-row-bot {
    align-self: flex-start;
}

.message-avatar {
    flex-shrink: 0;
    width: 40px;
    height: 40px;
    margin-top: auto;
}

.message-avatar-logo {
    width: 24px;
    height: 24px;
}

.message-content-wrapper {
    display: flex;
    flex-direction: column;
    max-width: 100%;
    gap: 4px;
}

.message-content-wrapper-user {
    align-items: flex-end;
}

.message-content-wrapper-bot {
    align-items: flex-start;
}

/* Sits in the message-content-wrapper's own column flow (not absolutely positioned) so it can
   never overlap the next message row - the previous absolute + negative-offset layout let this
   strip render into the space of whichever row followed, which both misdrew the next message and
   put the buttons outside the box that ".message-row:hover" tracks, so the hover state (and the
   tooltip riding on it) was lost the moment the pointer reached them. */
.message-actions-container {
    display: flex;
}

.message-actions {
    display: flex;
    gap: 4px;
    align-items: center;
    opacity: 0;
    transition: opacity var(--dtx-motion-base) var(--dtx-motion-easing);
}

.message-row:hover .message-actions,
.message-row:focus-within .message-actions {
    opacity: 1;
}

/* Cost and Token Usage Info */
.message-cost-info {
    display: flex;
    gap: 12px;
    align-items: center;
    margin-right: 8px;
    white-space: nowrap;
    flex-shrink: 0;
}

.cost-text {
    font-size: 0.75rem;
    color: var(--dtx-text-muted);
    font-weight: 500;
    white-space: nowrap;
}

.cost-text .cached-tokens {
    color: var(--dtx-text-muted);
    font-size: 0.7rem;
}

.action-btn {
    min-width: 28px;
    width: 28px;
    height: 28px;
    padding: 4px;
    color: var(--dtx-text-muted);
}

.action-btn:hover {
    background: color-mix(in srgb, var(--dtx-color-text-primary) 5%, transparent);
    color: var(--chat-user-name-color, var(--dtx-btn-primary-bg));
}

.message-header {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 0 4px;
}

.message-user-name {
    font-weight: 600;
    font-size: 0.85rem;
    color: var(--chat-user-name-color, var(--dtx-btn-primary-bg));
}

.message-time {
    font-size: 0.75rem;
    color: var(--dtx-text-muted);
}

.message-bubble {
    padding: 12px 16px;
    max-width: 100%;
    border-radius: 18px;
    box-shadow: var(--dtx-elevation-card);
}

/* Follow-up suggestion chips (DAG-23) - a light label plus a wrapping row of chips under the
   finished answer, sized and spaced to read as a suggestion rail rather than more of the answer. */
.followup-suggestions {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin-top: 2px;
}

.followup-suggestions-label {
    font-size: 0.75rem;
    color: var(--dtx-text-muted);
}

.followup-suggestions-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

.followup-suggestion-chip {
    cursor: pointer;
}

.message-bubble-user {
    background: var(--chat-message-bubble-color, var(--dtx-surface-sunken));
    color: var(--chat-message-text-color, var(--dtx-text-body));
    border-radius: 18px 18px 4px 18px;
}

.message-bubble-bot {
    background: var(--chat-message-bubble-color, var(--dtx-surface-sunken));
    color: var(--chat-message-text-color, var(--dtx-text-body));
    border-radius: 18px 18px 18px 4px;
}

.message-content {
    margin-bottom: 0;
    font-size: 0.9rem;
    word-wrap: break-word;
    white-space: normal;
    line-height: 1.5;
}

.message-bubble-user .message-content {
    color: var(--chat-message-text-color, var(--dtx-text-body));
}

.message-bubble-bot .message-content {
    color: var(--chat-message-text-color, var(--dtx-text-body));
}

/* Markdown styles */
.message-content strong {
    font-weight: 700;
}

.message-content em {
    font-style: italic;
}

.message-content p {
    margin: 0 0 8px 0;
}

.message-content p:last-child {
    margin-bottom: 0;
}

.message-content ul, .message-content ol {
    margin: 8px 0;
    padding-left: 24px;
}

.message-content li {
    margin-bottom: 4px;
}

.message-content code {
    background: color-mix(in srgb, var(--dtx-color-text-primary) 10%, transparent);
    padding: 2px 6px;
    border-radius: 4px;
    font-family: 'Consolas', 'Monaco', monospace;
    font-size: 0.9em;
}

.message-bubble-user .message-content code {
    background: color-mix(in srgb, var(--dtx-text-on-fill) 20%, transparent);
}

.message-content pre {
    background: color-mix(in srgb, var(--dtx-color-text-primary) 5%, transparent);
    padding: 12px;
    border-radius: 8px;
    overflow-x: auto;
    margin: 8px 0;
}

.message-content blockquote {
    border-left: 3px solid var(--dtx-btn-primary-bg);
    padding-left: 12px;
    margin: 8px 0;
    color: var(--dtx-text-secondary);
}

/* Table styles */

/* A month-by-territory answer is a dozen columns wide and this panel is narrow. Confining the
   sideways scroll to the table keeps the rest of the message readable, and keeps the right-hand
   columns reachable instead of clipped away with nothing to show they exist. */
.chat-table-scroll {
    overflow-x: auto;
    max-width: 100%;
    margin: 12px 0;
}

/* The download button lives inside the last header cell, next to its label, rather than floated over
   the table - the cell simply grows to fit both, so there is no overlap to guard against regardless
   of how narrow that last column is or how long its header text runs. */
.message-content .chat-table-scroll th.chat-table-header-menu {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
}

.chat-table-header-label {
    min-width: 0;
}

.chat-table-download-btn {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    padding: 4px;
    border: none;
    border-radius: 50%;
    background: var(--dtx-surface-sunken);
    color: var(--dtx-text-muted);
    box-shadow: var(--dtx-elevation-card);
    cursor: pointer;
}

.chat-table-download-btn:hover {
    background: color-mix(in srgb, var(--dtx-color-text-primary) 5%, transparent);
    color: var(--chat-user-name-color, var(--dtx-btn-primary-bg));
}

.chat-table-download-btn svg {
    width: 100%;
    height: 100%;
}

.message-content .chat-table-scroll table {
    /* Overrides width: 100% below: inside a scroll container that would shrink the table back to the
       panel width and squeeze the columns rather than letting them scroll. */
    width: auto;
    min-width: 100%;
    margin: 0;
}

.message-content table {
    border-collapse: collapse;
    width: 100%;
    margin: 12px 0;
    font-size: 0.9rem;
}

/* The row label has to stay visible while the months scroll past it, or a scrolled table is a grid of
   numbers with nothing to say which territory each row is. */
.message-content .chat-table-scroll th:first-child,
.message-content .chat-table-scroll td:first-child {
    position: sticky;
    left: 0;
    background: var(--dtx-surface-card);
    z-index: 1;
}

.message-content .chat-table-scroll th:first-child {
    background: color-mix(in srgb, var(--dtx-btn-primary-bg) 15%, transparent);
}

.message-content th, .message-content td {
    border: 1px solid var(--dtx-border-divider);
    padding: 8px 12px;
    /* !important: GFM's `---:`/`:---:` column-alignment syntax makes Markdig emit an inline
       text-align on the cell, which otherwise wins over this rule regardless of selector
       specificity. Every column - measures included - reads left-aligned here regardless of what
       alignment the answer's markdown asked for. */
    text-align: left !important;
}

.message-content th {
    background: color-mix(in srgb, var(--dtx-btn-primary-bg) 10%, transparent);
    font-weight: 600;
}

.message-bubble-user .message-content table {
    border-color: color-mix(in srgb, var(--dtx-text-on-fill) 30%, transparent);
}

.message-bubble-user .message-content th {
    background: color-mix(in srgb, var(--dtx-text-on-fill) 15%, transparent);
}

.message-content tr:nth-child(even) {
    background: color-mix(in srgb, var(--dtx-color-text-primary) 2%, transparent);
}

.message-content tr:hover {
    background: color-mix(in srgb, var(--dtx-color-text-primary) 5%, transparent);
}

.message-timestamp {
    font-size: 0.7rem;
    margin-top: 6px;
    opacity: 0.7;
}

.message-bubble-user .message-timestamp {
    color: color-mix(in srgb, var(--dtx-text-on-fill) 80%, transparent);
}

.message-bubble-bot .message-timestamp {
    color: var(--dtx-text-muted);
}

.loading-bubble {
    background: var(--dtx-surface-sunken);
    padding: 16px 20px;
    border-radius: 24px 24px 24px 8px;
}

.loading-text {
    color: var(--dtx-text-secondary);
    font-style: italic;
    font-size: 0.85rem;
}

/* Summary row folding a finished turn's working steps. Sized and coloured to read as a control
   the answer sits under, not as another line of the answer. */
.turn-summary {
    align-self: flex-start;
    min-height: 0;
    padding: 2px 8px;
    margin-bottom: 2px;
    color: var(--dtx-text-secondary);
    font-size: 0.8rem;
    font-weight: 500;
    text-transform: none;
    letter-spacing: normal;
    border-radius: 12px;
    background-color: color-mix(in srgb, var(--dtx-color-text-primary) 3%, transparent);
}

.turn-summary:hover {
    background-color: color-mix(in srgb, var(--dtx-color-text-primary) 7%, transparent);
    color: var(--dtx-text-heading);
}

.turn-summary .mud-button-icon-start {
    margin-right: 4px;
    margin-left: -2px;
}

/* The expanded steps read as a sidebar to the answer rather than part of it. */
.turn-timeline .turn-action {
    padding-left: 6px;
    border-left: 2px solid color-mix(in srgb, var(--dtx-color-text-primary) 7%, transparent);
}

/* Collapse/expand animates to the steps' real height with no JS and no fixed pixel value to keep in
   sync: a single-row grid track sized 0fr (collapsed) or 1fr (expanded) transitions smoothly between
   "no space" and "exactly the content's own height," and the inner wrapper's overflow:hidden clips
   whatever the track hasn't grown into yet. The steps stay in the DOM the whole time (see the
   component's own remark on why), so this is genuinely a transition, not a mount/unmount swap. */
.turn-timeline-fold {
    display: grid;
    grid-template-rows: 0fr;
    transition: grid-template-rows var(--dtx-motion-base) var(--dtx-motion-easing);
    width: 100%;
}

.turn-timeline-fold--expanded {
    grid-template-rows: 1fr;
}

.turn-timeline-fold-inner {
    overflow: hidden;
    min-height: 0;
}

/* Input Row */
.input-row {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 12px 24px;
    padding-bottom: max(12px, env(safe-area-inset-bottom, 12px));
    background: var(--dtx-surface-card);
    border-top: 1px solid var(--dtx-border-divider);
    flex-shrink: 0;
    box-shadow: var(--dtx-elevation-card);
}

.chat-input-field {
    flex: 1;
    position: relative;
}

/* C10/DAG-37: matches .input-row's own horizontal inset above it rather than sitting flush
   against the panel edge, and reads as a quiet footnote (centered, muted) rather than a stray
   left-aligned line of body text. */
.ai-content-reminder {
    padding: 4px 24px 10px;
    text-align: center;
    color: var(--dtx-text-muted);
    background: var(--dtx-surface-card);
}

/* DAG-41: the link to the conversation-retention explanation, on the reminder's own line. Reads as part
   of the footnote (same size and colour), underlined so it is recognisable as a link. */
.ai-content-reminder__link {
    background: none;
    border: 0;
    padding: 0;
    margin-left: 4px;
    font: inherit;
    color: inherit;
    text-decoration: underline;
    cursor: pointer;
}

/* Conversation info dialog (DAG-41) */
.conversation-info-dialog p {
    margin: 0 0 12px;
    line-height: 1.5;
}

.conversation-info-dialog strong {
    color: var(--dtx-text-heading);
}

.chat-input-field .mud-input-outlined-border {
    border-radius: 30px !important;
}

.chat-input-field > div {
    background: var(--dtx-surface-sunken);
    border-radius: 30px !important;
}

.chat-textarea {
    width: 100%;
    padding: 12px 20px;
    font-size: 1rem;
    font-family: inherit;
    line-height: 1.6;
    border: none;
    background: var(--dtx-surface-sunken);
    border-radius: 30px;
    resize: none;
    overflow-y: auto;
    box-sizing: border-box;
    vertical-align: middle;
    max-height: 240px;
    white-space: pre-wrap;
}

/* The message box keeps its sunken pill in every state, and focus is shown by the governed ring.

   It previously did the opposite, and that is the reported bug: a `:focus-visible` rule repainted
   the box --dtx-surface-card, which is exactly what .input-row behind it is painted, so clicking
   into the box made its pill vanish into the row instead of lifting out of it. (A text field
   matches :focus-visible on a plain mouse click, so this fired every time, not only on Tab.)

   Restoring the ring here needs this rule, rather than nothing at all. PRS-5's second exception in
   app.css suppresses the governed ring on every `input`/`select`/`textarea`, on the stated ground
   that those "already carry their own built-in MudBlazor focus styling (a colour-changed
   underline/border)". That premise does not hold for this one: it is a plain <textarea> with
   `border: none` and no MudBlazor class, so the exception would leave the chat's only text entry
   with no focus affordance whatsoever. Re-applying the governed value here is the exception's
   intent, not a departure from it.

   `!important` and two classes: app.css's exception is `outline: none !important` at (0,1,1), so an
   important declaration at higher specificity is what it takes to win - the same lever tokens.css
   documents for MudBlazor's own bundled reset. */
.chat-textarea:focus-visible {
    outline: var(--dtx-focus-ring) !important;
    outline-offset: var(--dtx-focus-ring-offset) !important;
}

.chat-textarea:disabled {
    opacity: 0.6;
    cursor: not-allowed;
}

/* Stands in for the message box while a selected library prompt's full text is being fetched by
   id (design.md D4) - same pill shape and footprint as the real textarea, so the input row does
   not jump once the fetch completes and the textarea reappears with the loaded text. */
.chat-textarea-skeleton {
    width: 100%;
    height: 46px;
    border-radius: 30px !important;
}

.quick-prompts-menu {
    flex-shrink: 0;
}

/* The popover renders at body level, outside the input row, so its width is bounded here rather
   than by any parent. MudBlazor puts no nowrap on menu item text and no max-width on the popover,
   so without this the popover simply grows as wide as its longest single-line label - which is how
   the French set (longer category headers and prompt names than the English one) pushed it past the
   chat panel's right edge. Capped, a long label wraps instead. Paired with the AnchorOrigin/
   TransformOrigin on the menu itself, which is what makes it open leftward in the first place. */
.quick-prompts-menu-popover {
    max-width: 320px;
}

/* Occupies the same slot as the MudIconButton it stands in for while the library is loading
   (design.md "load prompts on open"), so the toolbar does not jump when the icon appears. */
.quick-prompts-menu-loading {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    flex-shrink: 0;
}

/* Conversation Stats Dialog */
.conversation-stats-dialog {
    padding: 8px 0;
}

.conversation-stats-dialog .stat-row {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 0;
    font-size: 0.9rem;
}

.conversation-stats-dialog .stat-row strong {
    min-width: 140px;
    color: var(--dtx-text-heading);
}

.send-button {
    flex-shrink: 0;
}

.action-button {
    flex-shrink: 0;
}

/* Scrollbar Styling */
.messages-area {
    scrollbar-width: thin;
    scrollbar-color: var(--dtx-border-control) transparent;
}

.messages-area::-webkit-scrollbar {
    width: 8px;
}

.messages-area::-webkit-scrollbar-track {
    background: transparent;
}

.messages-area::-webkit-scrollbar-thumb {
    background: var(--dtx-border-control);
    border-radius: 4px;
}

.messages-area::-webkit-scrollbar-thumb:hover {
    background: var(--dtx-text-muted);
}

/* Organisation monthly AI allowance indicator (USG-7).
   Every value here comes from a governed role token: no colour, spacing or radius literal, and no
   rgba() with hardcoded channels - translucency composes a token through color-mix instead
   (.claude/rules/presentation.md). The three states map onto the platform's existing success,
   warning and error roles, so this surface adds nothing to the governed set. */
/* Status control: the ring's filled arc is the conversation's context, and that is all it
   carries - the monthly allowance lives in the tooltip and the panel it opens. Replaces both the
   permanent allowance bar above the messages area and the Info button that used to sit here
   (USG-7, DAG-28). */
.chat-status {
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

/* The ring IS the button: no glyph inside it, so what the member reads is how full the
   conversation is. The conic gradient stops at --chat-status-fill percent, and the ::before hole
   turns the resulting pie into a ring. */
.chat-status__ring {
    position: relative;
    width: 24px;
    height: 24px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    cursor: pointer;
    background: conic-gradient(
        var(--chat-status-fill-color) calc(var(--chat-status-fill, 0) * 1%),
        var(--dtx-surface-sunken) 0
    );
    transition: background var(--dtx-motion-base) var(--dtx-motion-easing);
}

/* The hole. Painted with the surface the input row sits on, so the ring reads as a ring rather
   than a pie with a lighter middle. */
.chat-status__ring::before {
    content: "";
    position: absolute;
    inset: 5px;
    border-radius: 50%;
    background: var(--dtx-surface-card);
}

/* Graded state of the filled arc. Colour is one of three carriers only: the percentage is in the
   control's accessible name and its tooltip as well. */
.chat-status--ok .chat-status__ring {
    --chat-status-fill-color: var(--dtx-success);
}

.chat-status--warning .chat-status__ring {
    --chat-status-fill-color: var(--dtx-warning);
}

.chat-status--critical .chat-status__ring {
    --chat-status-fill-color: var(--dtx-error);
}

/* The panel the ring opens: a small anchored popover, not a dialog. Two figures and a link, sized
   to be read at a glance and dismissed by clicking away (MudMenu owns that behaviour). */
.chat-status-popover .mud-list {
    padding: 0;
}

.chat-status-panel {
    display: flex;
    flex-direction: column;
    gap: var(--dtx-space-2);
    min-width: 260px;
    padding: var(--dtx-space-3);
}

.chat-status-panel__row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--dtx-space-3);
    font-size: 0.8125rem;
}

.chat-status-panel__label {
    color: var(--dtx-text-muted);
    white-space: nowrap;
}

.chat-status-panel__value {
    color: var(--dtx-text-body);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.chat-status-panel__track {
    display: block;
    height: 4px;
    border-radius: var(--dtx-radius);
    background: var(--dtx-surface-sunken);
    overflow: hidden;
}

.chat-status-panel__fill {
    display: block;
    height: 100%;
    border-radius: var(--dtx-radius);
    transition: width var(--dtx-motion-base) var(--dtx-motion-easing);
}

.chat-status-panel__fill--context {
    background: var(--dtx-btn-primary-bg);
}

.chat-status-panel__fill--ok {
    background: var(--dtx-success);
}

.chat-status-panel__fill--warning {
    background: var(--dtx-warning);
}

.chat-status-panel__fill--critical {
    background: var(--dtx-error);
}

/* Section heading between the two figures, so the allowance does not read as a second context bar. */
.chat-status-panel__section {
    margin-top: var(--dtx-space-2);
    padding-top: var(--dtx-space-2);
    border-top: 1px solid var(--dtx-border-divider);
    color: var(--dtx-text-muted);
    font-size: 0.75rem;
}

/* A button, not a link: it opens a dialog rather than navigating, so it must not read as a URL to
   a screen reader. Styled as a link, and it keeps the governed focus ring. */
.chat-status-panel__link {
    margin-top: var(--dtx-space-2);
    padding: 0;
    border: 0;
    background: none;
    color: var(--dtx-text-muted);
    font: inherit;
    font-size: 0.8125rem;
    text-align: left;
    cursor: pointer;
}

.chat-status-panel__link:hover {
    color: var(--dtx-text-body);
}
