/* ===========================================================================
   card.css — panels, stat tiles, and the empty/loading/error states that
   live inside them.
   ---------------------------------------------------------------------------
   Replaces .page-card / .panel / .stat-box / .metric-card / .hero-card and
   the several inline-styled containers in the old pages.
   =========================================================================== */

.card {
    display: flex;
    flex-direction: column;
    background: var(--surface-raised);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    /* Clips a table's sticky header and any full-bleed child to the radius. */
    overflow: hidden;
}

.card--flush {
    /* For cards whose only child is a table: the table owns the padding. */
    padding: 0;
}

.card--sunken {
    background: var(--surface-sunken);
    border-color: var(--border-subtle);
}

.card--ghost {
    background: transparent;
    border-style: dashed;
}

/* Interactive card (a market row, a strategy tile). Uses a real <a>/<button>
   inside for semantics; this class only supplies affordance. */
.card--link {
    cursor: pointer;
    transition:
        border-color var(--duration-fast) var(--ease-out),
        background-color var(--duration-fast) var(--ease-out);
}

.card--link:hover {
    border-color: var(--border-strong);
    background: var(--surface-hover);
}

/* ---------------------------------------------------------------------------
   Regions
   --------------------------------------------------------------------------- */
.card__header {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--pad-card-sm) var(--pad-card);
    border-block-end: 1px solid var(--border-subtle);
    /* min-height keeps headers aligned across a row of cards even when one
       has no action button. */
    min-height: 52px;
}

.card__title {
    font-size: var(--text-md);
    font-weight: var(--weight-semibold);
    letter-spacing: var(--tracking-normal);
    /* Lets a long title truncate rather than push the action out of view. */
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.card__subtitle {
    font-size: var(--text-xs);
    color: var(--text-muted);
    font-weight: var(--weight-regular);
}

/* Pushes actions to the inline end — logical, so it flips in RTL. */
.card__actions {
    margin-inline-start: auto;
    display: flex;
    align-items: center;
    gap: var(--space-2);
    flex-shrink: 0;
}

.card__body {
    padding: var(--pad-card);
    display: flex;
    flex-direction: column;
    gap: var(--gap-stack);
    /* flex:1 makes cards in a grid row match height with the body absorbing
       the slack, so footers stay bottom-aligned. */
    flex: 1 1 auto;
    min-width: 0;
}

.card__body--tight {
    padding: var(--pad-card-sm);
}

.card__footer {
    padding: var(--pad-card-sm) var(--pad-card);
    border-block-start: 1px solid var(--border-subtle);
    background: var(--surface-sunken);
    display: flex;
    align-items: center;
    gap: var(--space-3);
    font-size: var(--text-xs);
    color: var(--text-muted);
}

/* ---------------------------------------------------------------------------
   STAT TILE — the balance/equity/margin figures.

   Reading order is label → value → delta, and the value is the largest thing
   in the tile. The old dashboard used the same size for label and value,
   which made scanning six tiles slow.
   --------------------------------------------------------------------------- */
.stat {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    padding: var(--pad-card);
    background: var(--surface-raised);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    min-width: 0;
}

.stat__label {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    font-size: var(--text-xs);
    font-weight: var(--weight-semibold);
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: var(--tracking-caps);
}

.stat__value {
    font-family: var(--font-mono);
    font-variant-numeric: tabular-nums;
    font-size: var(--text-3xl);
    font-weight: var(--weight-bold);
    line-height: 1.1;
    letter-spacing: var(--tracking-tight);
    color: var(--text);
    direction: ltr;
    unicode-bidi: isolate;
    /* A long balance shrinks rather than overflowing its tile. */
    overflow-wrap: anywhere;
}

/* The asset unit rides smaller and muted next to the figure so the digits
   stay the dominant element. */
.stat__unit {
    font-size: var(--text-md);
    font-weight: var(--weight-medium);
    color: var(--text-muted);
    margin-inline-start: var(--space-1);
}

.stat__delta {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    font-family: var(--font-mono);
    font-variant-numeric: tabular-nums;
    font-size: var(--text-sm);
    font-weight: var(--weight-semibold);
    direction: ltr;
    unicode-bidi: isolate;
}

.stat__meta {
    font-size: var(--text-xs);
    color: var(--text-faint);
}

/* The one figure a dashboard leads with (total equity). */
.stat--hero .stat__value {
    font-size: var(--text-4xl);
}

.stat--hero {
    background:
        radial-gradient(120% 140% at 0% 0%, var(--accent-dim), transparent 60%),
        var(--surface-raised);
    border-color: var(--border-strong);
}

/* Tiles whose value is itself directional (PnL). The accent bar on the
   inline-start edge gives a second, non-colour cue. */
.stat--up { border-inline-start: 3px solid var(--up); }
.stat--down { border-inline-start: 3px solid var(--down); }
.stat--warning { border-inline-start: 3px solid var(--warning); }

/* Smaller variant for secondary figures in a dense row. */
.stat--sm {
    padding: var(--pad-card-sm);
    gap: var(--space-1);
}

.stat--sm .stat__value {
    font-size: var(--text-xl);
}

/* ---------------------------------------------------------------------------
   Grids
   --------------------------------------------------------------------------- */

/* Auto-fitting stat row: as many tiles as fit at >= 200px, then wraps.
   No breakpoint needed — this is the whole responsive behaviour. */
.stat-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(200px, 100%), 1fr));
    gap: var(--space-4);
}

.stat-grid--wide {
    grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr));
}

/* On a phone the 200px minimum leaves one tile per row: the dashboard's four
   figures took 1,100px before anything else. Two per row; the hero figure
   and an odd one out take the full width. */
@media (max-width: 480px) {
    .stat-grid,
    .stat-grid--wide {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: var(--space-3);
    }

    /* The odd tile out: odd position in a plain grid, even position when a
       full-width hero tile leads (dashboard: hero + three). */
    .stat-grid > .stat--hero,
    .stat-grid > :last-child:nth-child(odd):not(.stat--hero ~ *),
    .stat-grid > .stat--hero:first-child ~ :last-child:nth-child(even) {
        grid-column: 1 / -1;
    }

    .stat-grid > .stat {
        padding: var(--pad-card-sm);
    }

    .stat-grid > .stat:not(.stat--hero) .stat__value {
        font-size: var(--text-xl);
    }
}

/* Generic card grid. */
.card-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr));
    gap: var(--space-5);
}

/* Explicit two-column split for "form + summary" layouts, collapsing at the
   tablet breakpoint. */
.split {
    display: grid;
    gap: var(--space-5);
    grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr);
    align-items: start;
}

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

/* ---------------------------------------------------------------------------
   Definition list — key/value pairs inside a card (order summary, position
   details, estimated margin). Values are numeric and end-aligned.
   --------------------------------------------------------------------------- */
.kv {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    margin: 0;
}

.kv__row {
    display: flex;
    align-items: baseline;
    gap: var(--space-3);
    padding-block: var(--space-2);
    border-block-end: 1px solid var(--border-subtle);
}

.kv__row:last-child {
    border-block-end: 0;
}

.kv__key {
    font-size: var(--text-sm);
    color: var(--text-muted);
    flex: 0 1 auto;
}

.kv__val {
    margin-inline-start: auto;
    font-family: var(--font-mono);
    font-variant-numeric: tabular-nums;
    font-size: var(--text-sm);
    font-weight: var(--weight-semibold);
    color: var(--text);
    text-align: end;
    direction: ltr;
    unicode-bidi: isolate;
}

/* A total row reads heavier than the lines above it. */
.kv__row--total {
    border-block-start: 1px solid var(--border);
    border-block-end: 0;
    margin-block-start: var(--space-1);
    padding-block-start: var(--space-3);
}

.kv__row--total .kv__key {
    color: var(--text);
    font-weight: var(--weight-semibold);
}

.kv__row--total .kv__val {
    font-size: var(--text-md);
    font-weight: var(--weight-bold);
}

/* ---------------------------------------------------------------------------
   EMPTY STATE. Every list in the product renders one of these instead of a
   blank area. Each has a heading, one line of explanation, and — where an
   action exists — a way out.
   --------------------------------------------------------------------------- */
.empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--space-3);
    padding: var(--space-12) var(--space-6);
    text-align: center;
    color: var(--text-muted);
}

.empty__icon {
    display: grid;
    place-content: center;
    width: 52px;
    height: 52px;
    border-radius: var(--radius-lg);
    background: var(--surface-sunken);
    border: 1px solid var(--border-subtle);
    color: var(--text-faint);
    font-size: var(--text-xl);
    /* Decorative — the heading carries the meaning. */
}

.empty__title {
    font-size: var(--text-md);
    font-weight: var(--weight-semibold);
    color: var(--text);
}

.empty__text {
    font-size: var(--text-sm);
    max-width: 44ch;
    color: var(--text-muted);
}

.empty--sm {
    padding: var(--space-8) var(--space-4);
}

/* ---------------------------------------------------------------------------
   ERROR STATE. Distinct from empty: something failed and a retry exists.
   --------------------------------------------------------------------------- */
.error-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-10) var(--space-6);
    text-align: center;
}

.error-state__icon {
    display: grid;
    place-content: center;
    width: 52px;
    height: 52px;
    border-radius: var(--radius-lg);
    background: var(--danger-dim);
    color: var(--danger);
    font-size: var(--text-xl);
}

.error-state__title {
    font-size: var(--text-md);
    font-weight: var(--weight-semibold);
    color: var(--text);
}

.error-state__text {
    font-size: var(--text-sm);
    color: var(--text-muted);
    max-width: 48ch;
}

/* ---------------------------------------------------------------------------
   Inline notice — form-level messages, page banners.
   --------------------------------------------------------------------------- */
.notice {
    display: flex;
    align-items: flex-start;
    gap: var(--space-3);
    padding: var(--pad-card-sm);
    border-radius: var(--radius-md);
    border: 1px solid var(--border);
    background: var(--surface-sunken);
    font-size: var(--text-sm);
    line-height: var(--leading-snug);
}

.notice__icon {
    flex-shrink: 0;
    font-size: var(--text-md);
    line-height: 1.3;
}

.notice__body {
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
}

.notice__title {
    font-weight: var(--weight-semibold);
    color: var(--text);
}

.notice__text {
    max-width: none;
    color: var(--text-secondary);
}

.notice--info { border-color: var(--info); background: var(--info-dim); }
.notice--info .notice__icon { color: var(--info); }

.notice--success { border-color: var(--success); background: var(--success-dim); }
.notice--success .notice__icon { color: var(--success); }

.notice--warning { border-color: var(--warning); background: var(--warning-dim); }
.notice--warning .notice__icon { color: var(--warning); }

.notice--danger { border-color: var(--danger); background: var(--danger-dim); }
.notice--danger .notice__icon { color: var(--danger); }

/* A demo-data marker. Required by product policy: any figure that is not a
   real balance or a real market price must be labelled where it appears, and
   this is the one treatment used for it. */
.notice--demo {
    border-style: dashed;
    border-color: var(--pending);
    background: var(--pending-dim);
}

.notice--demo .notice__icon { color: var(--pending); }

/* ---------------------------------------------------------------------------
   Section heading — above a group of cards, outside any card.
   --------------------------------------------------------------------------- */
.section {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
}

.section__head {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    flex-wrap: wrap;
}

.section__title {
    font-size: var(--text-lg);
    font-weight: var(--weight-bold);
}

.section__hint {
    font-size: var(--text-xs);
    color: var(--text-muted);
}

.section__actions {
    margin-inline-start: auto;
    display: flex;
    align-items: center;
    gap: var(--space-2);
}

/* ---------------------------------------------------------------------------
   MASTER–DETAIL — a narrow pick list beside a wide detail pane.

   `.split` puts the weight on the start side (form + summary). Review screens
   invert that: the list is an index you scan, the detail is the work. It gets
   a fixed-ish start column instead of a ratio so the detail pane does not
   shrink as the list's longest email grows.

   Below 1024px both panes become full width and the detail follows the list in
   document order — which is also the order a keyboard walks them, so choosing
   a row moves focus forward rather than backwards.
   --------------------------------------------------------------------------- */
.split--detail {
    grid-template-columns: minmax(0, 360px) minmax(0, 1fr);
}

@media (max-width: 1024px) {
    .split--detail {
        grid-template-columns: 1fr;
    }
}

/* ---------------------------------------------------------------------------
   PICK LIST — a scrollable list of records where one is selected.

   A <table> would be wrong: these rows are navigation, not data to compare
   across columns. Built on a real <button> per row so Tab reaches them, Enter
   and Space activate them, and the selected one is announced — a clickable
   <div> gets none of that.
   --------------------------------------------------------------------------- */
.pick-list {
    display: flex;
    flex-direction: column;
    max-height: min(68vh, 720px);
    overflow-y: auto;
    overscroll-behavior: contain;
}

.pick-list__item {
    display: block;
    width: 100%;
    text-align: start;
    font: inherit;
    color: inherit;
    background: none;
    border: 0;
    border-block-end: 1px solid var(--border-subtle);
    /* The selected marker is an inline-start border that must not shift the
       text when it appears, so the padding is reserved from the start. */
    border-inline-start: 3px solid transparent;
    padding: var(--space-3) var(--space-4);
    cursor: pointer;
    transition: background-color var(--duration-fast) var(--ease-out);
}

.pick-list__item:hover {
    background: var(--surface-hover);
}

.pick-list__item:focus-visible {
    outline: none;
    box-shadow: inset var(--shadow-focus);
}

.pick-list__item[aria-current="true"] {
    background: var(--surface-active);
    border-inline-start-color: var(--accent);
}

.pick-list__line {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2);
}

.pick-list__title {
    /* A <span> is inline by default, and overflow/ellipsis do nothing on an
       inline box — the title and the meta line ran together on one line. */
    display: block;
    font-size: var(--text-sm);
    font-weight: var(--weight-bold);
    color: var(--text);
    margin-block-start: var(--space-1);
    /* One line: a long legal name must not push the meta line out of view and
       make every row a different height. */
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.pick-list__meta {
    display: block;
    font-size: var(--text-2xs);
    color: var(--text-muted);
    margin-block-start: 2px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ---------------------------------------------------------------------------
   THUMB GRID — uploaded files shown as previews (KYC documents).
   --------------------------------------------------------------------------- */
.thumb-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(180px, 100%), 1fr));
    gap: var(--space-4);
}

.thumb {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    padding: var(--space-3);
    background: var(--surface-sunken);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
}

.thumb__kind {
    font-size: var(--text-2xs);
    font-weight: var(--weight-bold);
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--text-muted);
}

/* The preview is a button, not a bare <img>: opening the viewer is an action.
   Fixed height keeps a portrait passport scan and a landscape utility bill on
   the same grid line. */
.thumb__preview {
    display: block;
    width: 100%;
    height: 160px;
    padding: 0;
    background: var(--surface-overlay);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-sm);
    overflow: hidden;
    cursor: zoom-in;
}

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

.thumb__preview:focus-visible {
    outline: none;
    box-shadow: var(--shadow-focus);
}

/* A PDF cannot be previewed inline — it is served as a download on purpose
   (an uploaded PDF can carry script that the browser viewer would run). */
.thumb__file {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-direction: column;
    gap: var(--space-2);
    width: 100%;
    height: 160px;
    background: var(--surface-overlay);
    border: 1px dashed var(--border);
    border-radius: var(--radius-sm);
    color: var(--text-muted);
    font-size: var(--text-xs);
    font-weight: var(--weight-semibold);
    text-decoration: none;
    cursor: pointer;
}

.thumb__file:hover {
    background: var(--surface-hover);
    color: var(--text);
}

.thumb__meta {
    display: flex;
    justify-content: space-between;
    gap: var(--space-2);
    font-size: var(--text-2xs);
    color: var(--text-faint);
}

/* The row mirrors in RTL, as a row should, but each item is one atomic Latin
   run: without isolation "7 KB" is reordered to "KB 7" on an Arabic page.
   Same rule the numbers policy in base.css applies to prices. */
.thumb__meta > * {
    direction: ltr;
    unicode-bidi: isolate;
}

/* ---------------------------------------------------------------------------
   IDENTITY — the "who am I looking at" header on a per-client screen.

   Every admin screen scoped to one customer opens with the same question, and
   answering it consistently matters: an operator about to deduct a balance
   should see the same name block, in the same place, as the one who just
   approved that person's withdrawal.
   --------------------------------------------------------------------------- */
.identity {
    display: flex;
    align-items: center;
    gap: var(--space-4);
    flex-wrap: wrap;
}

.identity__avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    inline-size: 48px;
    block-size: 48px;
    flex: none;
    background: var(--accent-dim);
    color: var(--accent-text);
    border-radius: var(--radius-pill);
    font-size: var(--text-md);
    font-weight: var(--weight-bold);
    /* Initials are Latin and must not mirror on an Arabic page. */
    direction: ltr;
    unicode-bidi: isolate;
}

.identity__name {
    font-size: var(--text-lg);
    font-weight: var(--weight-bold);
    color: var(--text);
    margin: 0;
}

.identity__meta {
    font-size: var(--text-xs);
    color: var(--text-muted);
    margin: 0;
    overflow-wrap: anywhere;
}

.identity__end {
    margin-inline-start: auto;
    display: flex;
    align-items: center;
    gap: var(--space-3);
    flex-wrap: wrap;
}

/* On a phone the name block already used the full width, so pushing the
   status and the link to the far end just puts them on their own line with a
   gap above; let them sit under the name instead. */
@media (max-width: 560px) {
    .identity__end {
        margin-inline-start: 0;
        inline-size: 100%;
    }
}

/* ---------------------------------------------------------------------------
   TABS — one record set shown several ways (a client's positions, orders and
   ledger entries).

   Real <button role="tab"> elements inside a role="tablist", not links: the
   panels are already in the document, nothing navigates, and a link would
   put a dead #fragment in the address bar and in the back button. Arrow-key
   movement between tabs is wired in core/ui.js.
   --------------------------------------------------------------------------- */
.tabs {
    display: flex;
    gap: var(--space-1);
    border-block-end: 1px solid var(--border);
    /* A long tab row scrolls rather than wrapping into two ragged lines. */
    overflow-x: auto;
    scrollbar-width: none;
}

.tabs::-webkit-scrollbar {
    display: none;
}

.tabs__tab {
    flex: none;
    appearance: none;
    background: none;
    border: 0;
    border-block-end: 2px solid transparent;
    /* The selected tab's underline must not shift the label, so the space is
       reserved on every tab from the start. */
    margin-block-end: -1px;
    padding: var(--space-3) var(--space-4);
    font: inherit;
    font-size: var(--text-sm);
    font-weight: var(--weight-semibold);
    color: var(--text-muted);
    cursor: pointer;
    white-space: nowrap;
    transition: color var(--duration-fast) var(--ease-out);
}

.tabs__tab:hover {
    color: var(--text);
}

.tabs__tab:focus-visible {
    outline: none;
    box-shadow: var(--shadow-focus);
    border-radius: var(--radius-sm);
}

.tabs__tab[aria-selected="true"] {
    color: var(--accent-text);
    border-block-end-color: var(--accent);
}

.tabs__count {
    display: inline-block;
    margin-inline-start: var(--space-2);
    padding-inline: var(--space-2);
    background: var(--surface-sunken);
    border-radius: var(--radius-pill);
    font-size: var(--text-2xs);
    font-variant-numeric: tabular-nums;
    color: var(--text-muted);
}

.tab-panel[hidden] {
    display: none;
}

/* ---------------------------------------------------------------------------
   RECORD CARD — one record as a tile in a grid, optionally selectable.

   Used for the users list, where a row per account would waste the width on
   a desktop and a table would bury the one thing an operator scans for (is
   this person active, are they online).

   The whole tile is NOT a click target. A clickable <div> is invisible to the
   keyboard and to assistive tech, which is what the old page did — every card
   carried onclick="openClientDesk(id)" and nothing else. Here the name is a
   real link and the action is a real button; the tile is just their container.
   --------------------------------------------------------------------------- */
.record-card {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    padding: var(--pad-card-sm);
    background: var(--surface-raised);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    transition:
        border-color var(--duration-fast) var(--ease-out),
        background-color var(--duration-fast) var(--ease-out);
}

.record-card:hover {
    border-color: var(--border-strong);
}

/* Selection is shown on the card, not only in the checkbox, because the
   checkbox is 16px and the decision it drives affects a real account. */
.record-card:has(.record-card__select:checked) {
    border-color: var(--accent);
    background: var(--surface-active);
}

/* :has() is widely supported but not universally; the class is set by JS too
   so selection is never invisible. */
.record-card.is-selected {
    border-color: var(--accent);
    background: var(--surface-active);
}

.record-card__head {
    display: flex;
    align-items: flex-start;
    gap: var(--space-3);
}

.record-card__select {
    margin: 0;
    flex: none;
    inline-size: 18px;
    block-size: 18px;
    accent-color: var(--accent);
    cursor: pointer;
}

.record-card__body {
    min-inline-size: 0;
    flex: 1;
}

/* The name is the link to the record. Underlined on hover only — a grid of
   permanently underlined names is noise. */
.record-card__title {
    display: block;
    font-size: var(--text-sm);
    font-weight: var(--weight-bold);
    color: var(--text);
    text-decoration: none;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.record-card__title:hover {
    text-decoration: underline;
}

.record-card__sub {
    font-size: var(--text-2xs);
    color: var(--text-muted);
    margin-block-start: 2px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.record-card__tags {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    flex-wrap: wrap;
}

.record-card__foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2);
    padding-block-start: var(--space-3);
    border-block-start: 1px solid var(--border-subtle);
}

/* ---------------------------------------------------------------------------
   PRESENCE — a live session, shown as a dot plus a word.

   Never the dot alone: colour is not information anyone can rely on
   (WCAG 1.4.1), and "online" is a word worth reading.
   --------------------------------------------------------------------------- */
.presence {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    font-size: var(--text-2xs);
    color: var(--text-muted);
}

.presence__dot {
    inline-size: 7px;
    block-size: 7px;
    border-radius: var(--radius-pill);
    background: var(--text-faint);
    flex: none;
}

.presence--on .presence__dot {
    background: var(--success);
}

.presence--on {
    color: var(--success);
}

/* Admin -> Settings -> Platform logo: preview beside the controls. */
.logo-field {
    display: flex;
    align-items: center;
    gap: var(--space-4);
    padding-block-end: var(--space-4);
    margin-block-end: var(--space-4);
    border-block-end: 1px solid var(--border-subtle);
}

.logo-field__preview {
    display: grid;
    place-items: center;
    flex: 0 0 auto;
    width: 96px;
    height: 72px;
    padding: var(--space-2);
    background: var(--surface-sunken);
    border: 1px dashed var(--border);
    border-radius: var(--radius-md);
}

.logo-field__preview img {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
}

.logo-field__body {
    min-width: 0;
}
