/* ════════════════════════════════════════════════════════════════════════════
   Northside BOL App — shared theme engine (T183, Theme Build 1a)
   ────────────────────────────────────────────────────────────────────────────
   Loaded by every CONVERTED page AFTER its own <style> block, so these tokens
   win over any page-local :root that survives. Spec: "🗃️ Spec — User Account
   Options + Theme System", ⭐ 2026-10-25 section (tokens + Refined rules).

   Model:  theme ∈ refined | slate | classic   ×   mode ∈ light | dark
           (user pref `system` is resolved to light/dark by js/theme-boot.js)
   Selectors:
     :root                                      = Refined light (the default)
     html[data-theme="refined"][data-mode="dark"] = Refined dark
     Slate + Classic token blocks arrive in Theme Build 2 on the same hooks.

   Rules of the house (Refined): one sans (Inter) · sentence case · white cards
   with a 1 px border, radius 10 / 6 / 12 · brand colour only on the primary
   action + active nav · semantic status colours are NEVER the brand colour.
   ════════════════════════════════════════════════════════════════════════════ */

/* ── Self-hosted Inter (latin subset, variable 100–900; SIL OFL 1.1, see
      fonts/Inter-OFL.txt). font-src 'self' already allows it (T83 CSP). ── */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('/fonts/Inter-latin.var.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ── Refined · light (default) ─────────────────────────────────────────────── */
:root {
  color-scheme: light;

  /* surfaces + chrome */
  --bg:            #F5F5F4;
  --surface:       #FFFFFF;
  --surface-2:     #FAFAF9;   /* readonly inputs, hover rows, nested panels */
  --border:        #E7E5E4;
  --input-border:  #8F8A84;   /* T185: was #D6D3D1 (1.49:1). Spec said #949089 (3.18:1 on white) but that is 2.91:1 on --bg,
                                 where the toolbar inputs sit; #8F8A84 clears 3:1 on white, --bg and --surface-2 (3.42 / 3.14 / 3.28). */
  --header-bg:     #FFFFFF;

  /* text */
  --text:          #1C1917;
  --muted:         #57534E;
  --placeholder:   #78716C;
  --label:         #44403C;

  /* brand / primary action */
  --accent:        #8B1519;
  --accent-hover:  #6E1012;
  --accent-text:   #8B1519;   /* links + accent text on --bg/--surface */
  --accent-soft:   #FBEBEC;   /* tinted hover / selected backgrounds */
  --on-accent:     #FFFFFF;   /* text on an --accent fill */

  /* semantic status — constant meaning across themes, tuned per mode.
     Each pair is text-on-bg ≥ 4.5:1 (see test/theme-contrast-t183.js). */
  --ok:            #15803D;  --ok-bg:     #DCFCE7;
  --warn:          #92400E;  --warn-bg:   #FEF3C7;
  --danger:        #B91C1C;  --danger-bg: #FEE2E2;
  --info:          #1D4ED8;  --info-bg:   #DBEAFE;

  /* dispatch map (T185): pickup / delivery pin fills, the unassigned connector and the
     selected-pin ring. JS reads these via getComputedStyle so the Google markers and the
     legend dots share one source; each mode tunes them so pins read on that basemap. */
  --map-pickup:    #1D4ED8;
  --map-delivery:  #B91C1C;
  --map-line:      #78716C;
  --map-selected:  #1C1917;
  --map-label:     #FFFFFF;

  /* shape */
  --radius-card:   10px;
  --radius-ctl:    6px;
  --radius-phone:  12px;
  --shadow:        0 1px 2px rgba(0,0,0,0.06);
  --shadow-lg:     0 12px 32px rgba(0,0,0,0.16);
  --overlay:       rgba(28,25,23,0.45);

  /* type */
  --font-ui:       'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --font-mono:     ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --case-overline: none;      /* Classic (Build 2) sets uppercase */
  --tracking-overline: normal;

  /* ── Legacy bridge ────────────────────────────────────────────────────────
     The pre-theme pages share a 15-var palette (--red --gold --brown --ink …).
     Re-point those names at the new tokens so any rule not yet converted
     degrades to the current theme instead of to hard maroon/gold/cream.
     Unconverted pages still carry their own :root and load nothing from here;
     they pick this up the moment they drop that block (Builds 1b/1c). */
  --red:        var(--accent);
  --red-dark:   var(--accent-hover);
  --red-light:  var(--accent-soft);
  --red-pale:   var(--accent-soft);
  --gold:       var(--input-border);
  --gold-dark:  var(--label);
  --gold-light: var(--surface-2);
  --gold-pale:  var(--surface-2);
  --brown:      var(--text);
  --ink:        var(--text);
  --white:      var(--surface);
}

/* ── Refined · dark ────────────────────────────────────────────────────────── */
html[data-theme="refined"][data-mode="dark"] {
  color-scheme: dark;

  --bg:            #0C0A09;
  --surface:       #1C1917;
  --surface-2:     #292524;
  --border:        #3A3532;
  --input-border:  #78716C;   /* T185: was #57534E (2.29:1) — now ≥ 3.6:1 on the dark surfaces */
  --header-bg:     #1C1917;

  --text:          #F5F5F4;
  --muted:         #A8A29E;
  --placeholder:   #8A837E;
  --label:         #D6D3D1;

  --accent:        #C8333A;
  --accent-hover:  #B52C32;   /* darker on hover in dark mode: white label stays ≥ 4.5:1 */
  --accent-text:   #F28B8B;
  --accent-soft:   #3B1416;
  --on-accent:     #FFFFFF;

  --ok:            #86EFAC;  --ok-bg:     #0F2A1A;
  --warn:          #FCD34D;  --warn-bg:   #3A2A0A;
  --danger:        #FCA5A5;  --danger-bg: #3B1416;
  --info:          #93C5FD;  --info-bg:   #172554;

  --map-pickup:    #60A5FA;
  --map-delivery:  #F87171;
  --map-line:      #A8A29E;
  --map-selected:  #F5F5F4;
  --map-label:     #0C0A09;

  --shadow:        0 1px 2px rgba(0,0,0,0.4);
  --shadow-lg:     0 12px 32px rgba(0,0,0,0.6);
  --overlay:       rgba(0,0,0,0.6);
}

/* ── Base ──────────────────────────────────────────────────────────────────── */
html { background: var(--bg); }
body {
  font-family: var(--font-ui);
  background: var(--bg);
  color: var(--text);
  -webkit-font-smoothing: antialiased;
}
::placeholder { color: var(--placeholder); opacity: 1; }
::selection { background: var(--accent-soft); }
a { color: var(--accent-text); }

/* Inline SVG icons (js/icons.js) inherit the surrounding text colour. */
.icon { width: 1em; height: 1em; display: inline-block; vertical-align: -0.15em; flex-shrink: 0; }

/* ── Shared app header (converted pages) ───────────────────────────────────
   Wraps, never side-scrolls: the brand tile + nav + user cluster are flex
   items that flow onto a second row below ~700 px. */
.app-header {
  background: var(--header-bg);
  border-bottom: 1px solid var(--border);
  padding: 0 24px;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 4px 20px;
  min-height: 56px;
}
.app-brand { display: flex; align-items: center; padding: 4px 0; }
/* T185: the transparent mark (operator asset, PR #15) — 48 px tall, no tile, reads on both modes. */
.app-brand img { height: 48px; width: auto; display: block; }
.app-nav { display: flex; align-items: center; flex-wrap: wrap; gap: 2px 4px; flex: 1 1 auto; min-width: 0; }
.nav-link {
  font: 500 14px/1 var(--font-ui);
  color: var(--muted);
  text-decoration: none;
  background: none; border: 0; cursor: pointer;
  padding: 18px 10px 16px;
  border-bottom: 2px solid transparent;
  white-space: nowrap;
}
.nav-link:hover { color: var(--text); }
.nav-link.active { color: var(--text); border-bottom-color: var(--accent); }
.nav-link:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; border-radius: 4px; }
.app-user { display: flex; align-items: center; gap: 10px; margin-left: auto; padding: 8px 0; }
.app-user .user-name { font-size: 13px; color: var(--muted); white-space: nowrap; }

/* ── Tablet band (T187, ~721–1023 px): the seven links no longer fit beside the brand and the
   user cluster, so the NAV takes a full second row while brand + user name + Log out stay on
   the first row (the user cluster never drops below the nav). Just above the band the name is
   hidden and the link padding tightened so one row holds up to ~1100 px. ── */
@media (max-width: 1100px) {
  .app-header { gap: 4px 12px; }
  .nav-link { padding: 18px 8px 16px; }
  .app-user .user-name { display: none; }
}
@media (min-width: 721px) and (max-width: 1023px) {
  .app-nav { order: 10; flex: 1 1 100%; margin-top: -10px; }
  .app-nav .nav-link { padding: 8px 10px 14px; }
  .app-user { margin-left: auto; }
}

/* ── Phone nav (T185) — js/ui.js injects one <button class="nav-menu-btn" aria-expanded>
   into .app-user; below 720 px the nav links collapse behind it into a full-width
   disclosure under the one-row header. Desktop is unchanged (button hidden). ── */
.app-header .nav-menu-btn { display: none; }
@media (max-width: 720px) {
  .app-header { padding: 0 16px; gap: 4px 10px; }
  .app-header .nav-menu-btn { display: inline-flex; }
  .app-nav {
    display: none; order: 10; flex: 1 1 100%; flex-direction: column; align-items: stretch;
    gap: 0; padding: 4px 0 8px; border-top: 1px solid var(--border);
  }
  .app-header.nav-open .app-nav { display: flex; }
  .app-nav .nav-link { padding: 12px 10px; border-bottom: 0; border-left: 3px solid transparent; border-radius: 0 var(--radius-ctl) var(--radius-ctl) 0; }
  .app-nav .nav-link.active { border-left-color: var(--accent); background: var(--accent-soft); color: var(--text); }
  .app-user { gap: 6px; }
}
@media (max-width: 480px) {
  .app-user .user-name { display: none; }   /* the name is non-essential on a phone; Log out stays */
}

/* ── Buttons (Refined) ─────────────────────────────────────────────────────── */
.btn, .btn-quiet {
  font: 500 14px/1 var(--font-ui);
  border-radius: var(--radius-ctl);
  cursor: pointer;
  display: inline-flex; align-items: center; gap: 8px;
  height: 40px; padding: 0 16px;
  border: 1px solid transparent;
  transition: background 0.15s, border-color 0.15s, color 0.15s;
  white-space: nowrap;
}
.btn:disabled, .btn-quiet:disabled { opacity: 0.5; cursor: not-allowed; }
.btn:focus-visible, .btn-quiet:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.btn-primary { background: var(--accent); color: var(--on-accent); }
.btn-primary:hover:not(:disabled) { background: var(--accent-hover); }
.btn-secondary { background: var(--surface); color: var(--text); border-color: var(--input-border); }
.btn-secondary:hover:not(:disabled) { background: var(--surface-2); border-color: var(--muted); }
.btn-quiet { background: transparent; color: var(--muted); padding: 0 10px; }
.btn-quiet:hover:not(:disabled) { color: var(--text); background: var(--surface-2); }
.btn-quiet.danger:hover:not(:disabled) { color: var(--danger); background: var(--danger-bg); }
.btn-sm { height: 32px; padding: 0 12px; font-size: 13px; }
/* T185: a filled destructive button (inline "Yes, remove" confirmations); same label rule as the modal. */
.btn-danger-solid { background: var(--danger); color: #FFFFFF; }
.btn-danger-solid:hover:not(:disabled) { filter: brightness(0.92); }
html[data-mode="dark"] .btn-danger-solid { color: #1C1917; }

/* ── Status pill ───────────────────────────────────────────────────────────── */
.pill {
  display: inline-flex; align-items: center; gap: 6px;
  font: 500 12px/1 var(--font-ui);
  padding: 5px 10px; border-radius: 999px;
  border: 1px solid transparent; white-space: nowrap;
}
.pill-ok     { color: var(--ok);     background: var(--ok-bg); }
.pill-warn   { color: var(--warn);   background: var(--warn-bg); }
.pill-danger { color: var(--danger); background: var(--danger-bg); }
.pill-info   { color: var(--info);   background: var(--info-bg); }
.pill-neutral{ color: var(--muted);  background: var(--surface-2); border-color: var(--border); }

/* ── In-page confirm modal (js/ui.js) ──────────────────────────────────────── */
.modal-overlay {
  position: fixed; inset: 0; background: var(--overlay); z-index: 1000; padding: 20px;
  display: none; align-items: center; justify-content: center;
}
.modal-overlay.show { display: flex; }
.modal-card {
  background: var(--surface); color: var(--text);
  border: 1px solid var(--border); border-radius: var(--radius-card); box-shadow: var(--shadow-lg);
  width: 100%; max-width: 440px; padding: 22px 24px;
}
.modal-title { font: 600 18px/1.3 var(--font-ui); color: var(--text); margin-bottom: 8px; display: flex; align-items: center; gap: 10px; }
.modal-card.danger .modal-title { color: var(--danger); }
.modal-body { font-size: 14px; color: var(--muted); line-height: 1.55; white-space: pre-line; }
.modal-actions { display: flex; justify-content: flex-end; gap: 10px; margin-top: 20px; flex-wrap: wrap; }
.modal-btn {
  font: 500 14px/1 var(--font-ui); height: 40px; padding: 0 16px; border-radius: var(--radius-ctl);
  cursor: pointer; border: 1px solid transparent; transition: background 0.15s, border-color 0.15s, color 0.15s;
}
.modal-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.modal-btn-cancel { background: var(--surface); color: var(--text); border-color: var(--input-border); }
.modal-btn-cancel:hover { background: var(--surface-2); }
.modal-btn-confirm { background: var(--accent); color: var(--on-accent); }
.modal-btn-confirm:hover { background: var(--accent-hover); }
.modal-card.danger .modal-btn-confirm { background: var(--danger); color: #FFFFFF; }
html[data-mode="dark"] .modal-card.danger .modal-btn-confirm { color: #1C1917; }

/* ── Toast ─────────────────────────────────────────────────────────────────── */
#toast {
  position: fixed; bottom: 90px; right: 24px;
  display: flex; align-items: center; gap: 8px;
  padding: 12px 16px; border-radius: var(--radius-ctl);
  font: 500 14px/1.3 var(--font-ui);
  background: var(--surface); color: var(--text);
  border: 1px solid var(--border); border-left-width: 4px;
  box-shadow: var(--shadow-lg); z-index: 999;
  transform: translateY(20px); opacity: 0; transition: all 0.3s ease; pointer-events: none;
  max-width: min(420px, calc(100vw - 48px));
}
#toast.show { transform: none; opacity: 1; }
#toast.success { border-left-color: var(--ok); }
#toast.error   { border-left-color: var(--danger); }
#toast.info    { border-left-color: var(--info); }
#toast .icon   { font-size: 18px; }
#toast.success .icon { color: var(--ok); }
#toast.error .icon   { color: var(--danger); }
#toast.info .icon    { color: var(--info); }

/* ── Version footer (js/version-footer.js) — in normal page flow since T185, so it never
      sits under a sticky bottom bar; the script already uses the token for its colour. ── */
#app-version-footer { color: var(--muted); }

/* ═══════════════════════════════════════════════════════════════════════════
   T185 (Theme Build 1b) — shared page components for the converted list / admin /
   dispatch pages. index.html and settings.html carry their own (identical-rule)
   copies from Build 1a; these are the one definition the other pages lean on.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Page head: title left, helper line, optional actions right ── */
.page-head { display: flex; align-items: flex-start; gap: 16px; flex-wrap: wrap; margin-bottom: 20px; }
.page-head .ph-main { flex: 1 1 320px; min-width: 0; }
.page-head h1 { font-size: 24px; font-weight: 600; letter-spacing: -0.01em; color: var(--text); line-height: 1.2; margin: 0; }
.page-head .ph-help { font-size: 13px; color: var(--muted); margin-top: 6px; display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.page-head .ph-actions { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; padding-top: 2px; }

/* ── Card: white surface, 1 px border, radius 10, icon + title header (no coloured bar).
      Class names .card-hd / .card-bd (not index's .card-header / .card-body) so these
      shared rules cannot restyle the Build 1a pages, whose headers differ slightly. ── */
.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow);
  margin-bottom: 18px;
}
.card-hd {
  padding: 14px 20px;
  display: flex; align-items: center; gap: 10px; justify-content: space-between;
  border-bottom: 1px solid var(--border);
  border-radius: var(--radius-card) var(--radius-card) 0 0;
  background: transparent; color: var(--text);
}
.card-hd.toggle { cursor: pointer; user-select: none; }
.card-hd.toggle:hover { background: var(--surface-2); }
.card-hd-left { display: flex; align-items: center; gap: 10px; min-width: 0; }
.card-hd-left .icon { color: var(--muted); }
.card-hd-title { font-size: 15px; font-weight: 600; color: var(--text); }
.card-hd-title h2 { font: inherit; margin: 0; }
.card-caret { color: var(--muted); transition: transform 0.2s; display: inline-flex; }
.card.collapsed .card-caret { transform: rotate(-90deg); }
.card.collapsed .card-hd { border-bottom-color: transparent; }
.card.collapsed .card-bd { display: none; }
.card-bd { padding: 20px; }
.card-bd.flush { padding: 0; overflow-x: auto; }   /* a wide table scrolls inside the card, never the page */
.tbl-wrap { overflow-x: auto; }
.card-bd.flush > .tbl { border-radius: 0 0 var(--radius-card) var(--radius-card); overflow: hidden; }

/* ── Inputs: 40 px, radius 6, 1 px --input-border, accent focus ring. The legacy class
      names the converted pages already use (.search-input / .form-input) are aliased
      here so their JS-built markup needs no churn. ── */
.input, .search-input, .form-input {
  font: 400 14px/1.3 var(--font-ui);
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--input-border);
  border-radius: var(--radius-ctl);
  height: 40px; padding: 0 12px;
  transition: border-color 0.15s, box-shadow 0.15s;
  appearance: none; -webkit-appearance: none;
}
.input:focus, .search-input:focus, .form-input:focus {
  outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft);
}
.input:disabled, .search-input:disabled, .form-input:disabled, .input[readonly], .search-input[readonly] { background: var(--surface-2); color: var(--muted); }
.input-sm { height: 32px; padding: 0 10px; font-size: 13px; }
select.input, select.search-input, select.form-input {
  cursor: pointer; padding-right: 30px;
  /* appearance:none drops the native arrow; a background-image cannot read a token, so the
     chevron is the one place a colour literal lives in this file (one per mode). */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%2357534E' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 10px center;
}
html[data-mode="dark"] select.input, html[data-mode="dark"] select.search-input, html[data-mode="dark"] select.form-input {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%23A8A29E' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}
textarea.input { height: auto; padding: 10px 12px; }
.field-label { font-size: 13px; font-weight: 500; color: var(--label); }
.field-error { font-size: 12px; color: var(--danger); }
.check-label { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; color: var(--text); cursor: pointer; white-space: nowrap; }
.check-label input[type="checkbox"], input.hold-check { width: 16px; height: 16px; accent-color: var(--accent); cursor: pointer; }

/* ── Data table: label-row headings, 1 px row rules, hover tint ── */
.tbl { width: 100%; border-collapse: collapse; font-size: 14px; }
.tbl th {
  font-size: 13px; font-weight: 500; color: var(--label);
  text-align: left; padding: 10px 16px;
  border-bottom: 1px solid var(--border);
  background: var(--surface-2); white-space: nowrap;
}
.tbl td { padding: 10px 16px; border-bottom: 1px solid var(--border); vertical-align: middle; color: var(--text); }
.tbl tbody tr:last-child td { border-bottom: none; }
.tbl tbody tr:hover td { background: var(--surface-2); }
.tbl .num { text-align: right; font-variant-numeric: tabular-nums; }
.tbl .actions-cell, .tbl td.col-actions { white-space: nowrap; text-align: right; }
.tbl .actions-cell .btn-quiet { height: 32px; padding: 0 8px; }
.mono { font-family: var(--font-mono); font-size: 13px; }
.muted { color: var(--muted); }
.empty-state { text-align: center; color: var(--muted); font-size: 14px; padding: 36px 16px; }

/* ── Filter chips (segmented toggles) ── */
.chip {
  font: 500 13px/1 var(--font-ui); color: var(--muted);
  background: var(--surface); border: 1px solid var(--input-border); border-radius: 999px;
  height: 32px; padding: 0 12px; cursor: pointer; display: inline-flex; align-items: center; gap: 6px;
  transition: background 0.12s, border-color 0.12s, color 0.12s; white-space: nowrap;
}
.chip:hover { color: var(--text); border-color: var(--muted); background: var(--surface-2); }
.chip.active { background: var(--text); border-color: var(--text); color: var(--surface); }
.chip.chip-danger.active { background: var(--danger-bg); border-color: var(--danger); color: var(--danger); }
.chip:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ── Status bands (banner-style status, icon + text, never colour alone).
      Named .band (index.html owns .notice for its inline field notes). ── */
.band {
  display: flex; align-items: flex-start; gap: 10px;
  border: 1px solid var(--border); border-left-width: 4px; border-radius: var(--radius-ctl);
  background: var(--surface); color: var(--text); padding: 10px 14px; font-size: 14px; line-height: 1.45;
}
.band .icon { flex-shrink: 0; margin-top: 0.15em; }
.band-ok     { border-left-color: var(--ok);     background: var(--ok-bg);     color: var(--ok); }
.band-warn   { border-left-color: var(--warn);   background: var(--warn-bg);   color: var(--warn); }
.band-danger { border-left-color: var(--danger); background: var(--danger-bg); color: var(--danger); }
.band-info   { border-left-color: var(--info);   background: var(--info-bg);   color: var(--info); }
.band-neutral{ border-left-color: var(--muted);  background: var(--surface-2); color: var(--muted); }

/* ── Sticky bottom save bar (list pages) ── */
.save-bar {
  position: sticky; bottom: 0; z-index: 100;
  background: var(--surface); border-top: 1px solid var(--border);
  padding: 12px 24px; display: flex; gap: 12px; justify-content: flex-end; align-items: center; flex-wrap: wrap;
}

/* Inline link-style action (quiet text button inside tables / rows) */
.btn-link {
  background: none; border: 0; padding: 4px 6px; cursor: pointer;
  font: 500 13px/1 var(--font-ui); color: var(--accent-text); border-radius: 4px; white-space: nowrap;
}
.btn-link:hover { text-decoration: underline; }
.btn-link.danger { color: var(--danger); }
.btn-link:disabled { opacity: 0.5; cursor: not-allowed; text-decoration: none; }
.btn-link:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Avatar / initials disc (dispatch run cards) */
.avatar {
  width: 36px; height: 36px; border-radius: 50%; flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  font: 600 13px/1 var(--font-ui); color: var(--text);
  background: var(--surface-2); border: 1px solid var(--border);
}
