/* Cars24 brand — single fixed theme. Light surfaces, electric indigo (#4845FF)
   accent, DM Sans typography. No light/dark toggle. */
/* Activity panel step detail (added so admins can see exactly what data each
   step pulls without expanding the row). */
.tool-event-head .name-wrap { display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 0; }
.tool-event-head .name { font-weight: 600; color: #1a1a2e; }
.tool-event-head .step-detail {
  font-size: 11.5px; color: #6b7280; line-height: 1.3;
  font-weight: 500;
}
.tool-event-head .step-result {
  font-size: 11.5px; color: #5B4DFF;
  font-family: "JetBrains Mono", "SF Mono", Menlo, monospace;
  font-weight: 600; line-height: 1.3;
  margin-top: 2px;
}
.tool-event.errored .step-result { color: #DC2626; }
/* "skipped" is the new soft-failure state — agent tried something, it
   didn't work, agent moved on. Reads as a quiet amber note, not an
   alarming red error, so consumers don't think the system is broken. */
.tool-event.skipped .step-result { color: #92763a; }
.tool-event.skipped .status-dot  { background: #d1b06b; box-shadow: 0 0 5px rgba(209,176,107,0.55); }
.tool-event.skipped .status-text { color: #92763a; font-style: italic; }
.tool-event-dax {
  margin: 6px 12px 0; padding: 8px 10px;
  background: rgba(91,77,255,0.04);
  border-left: 2px solid rgba(91,77,255,0.30);
  border-radius: 6px;
  font-size: 11.5px; line-height: 1.5;
  color: #374151;
  font-family: "JetBrains Mono", "SF Mono", Menlo, monospace;
  white-space: pre-wrap; word-break: break-word;
  max-height: 80px; overflow: hidden;
}

/* "Admin Console" link in the profile popover renders as a plain row,
   matching "Sign out" — no special highlighting. The old indigo-gradient
   treatment was removed so it reads as a discoverable option, not a
   marketing CTA. */

/* ── Workspace / Dataset chips: pulse-blink + status dot while empty so
      users notice the first thing they need to do is pick context. The dot
      flips red→green the moment a selection lands. ──────────────────────── */
@keyframes apex-needs-pick-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(220, 38, 38, 0.55); border-color: rgba(220,38,38,0.55); }
  50%      { box-shadow: 0 0 0 6px rgba(220, 38, 38, 0.0); border-color: rgba(220,38,38,1.0); }
}
@keyframes apex-needs-pick-dot {
  0%, 100% { transform: scale(1);   opacity: 1;   }
  50%      { transform: scale(1.3); opacity: 0.6; }
}
.tb-chip {
  position: relative;                          /* anchor for the status dot */
}
/* The status dot — green by default (selected), red + pulsing when empty.
   Sits on the trailing edge of the chip so it reads as "status" rather than
   decoration. */
.tb-chip::after {
  content: ""; position: absolute;
  top: 50%; right: 8px; transform: translateY(-50%);
  width: 8px; height: 8px; border-radius: 50%;
  background: #10B981;                          /* emerald — selected */
  box-shadow: 0 0 0 2px rgba(16,185,129,0.20);
  transition: background 160ms ease, box-shadow 160ms ease;
}
.tb-chip.needs-pick {
  animation: apex-needs-pick-pulse 1.4s ease-in-out infinite;
  border: 1.5px solid rgba(220,38,38,0.7);
  background: rgba(220,38,38,0.04);
  padding-right: 26px;                          /* room for the bigger dot */
}
.tb-chip.needs-pick::after {
  background: #DC2626;                          /* red — needs picking */
  box-shadow: 0 0 0 2px rgba(220,38,38,0.20);
  animation: apex-needs-pick-dot 1.0s ease-in-out infinite;
}
.tb-chip.needs-pick .tb-chip-value { color: rgba(220,38,38,1); font-weight: 600; }
/* One-shot wobble fired when the user tries to send without picking. Adds
   urgency without becoming annoying. */
@keyframes apex-needs-pick-shake {
  0%, 100% { transform: translateX(0); }
  20%      { transform: translateX(-4px); }
  40%      { transform: translateX(4px); }
  60%      { transform: translateX(-3px); }
  80%      { transform: translateX(3px); }
}
.tb-chip.needs-pick-shake { animation: apex-needs-pick-shake 0.55s ease-in-out, apex-needs-pick-pulse 1.4s ease-in-out infinite; }

/* Inline banner above the composer when chat is blocked because no
   workspace/dataset is picked. Slides up + fades in, auto-clears after 6s. */
.context-required-banner {
  display: flex; align-items: center; gap: 10px;
  margin: 0 auto 8px auto; max-width: 920px;
  padding: 8px 14px;
  background: rgba(220,38,38,0.06);
  border: 1px solid rgba(220,38,38,0.20);
  border-left: 3px solid #DC2626;
  border-radius: 10px;
  color: #1a1a2e;
  font-size: 13px;
  opacity: 0; transform: translateY(6px);
  transition: opacity 200ms ease, transform 200ms ease;
  pointer-events: none;
}
.context-required-banner.show { opacity: 1; transform: translateY(0); pointer-events: auto; }
.context-required-banner .crb-dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: #DC2626;
  box-shadow: 0 0 0 2px rgba(220,38,38,0.20);
  animation: apex-needs-pick-dot 1.0s ease-in-out infinite;
  flex-shrink: 0;
}
.context-required-banner .crb-text { flex: 1; }
.context-required-banner .crb-text strong { color: #DC2626; font-weight: 700; }
.context-required-banner .crb-action {
  background: #DC2626; color: #ffffff; border: none;
  padding: 4px 12px; border-radius: 999px;
  font-size: 12px; font-weight: 600; cursor: pointer;
  transition: background 120ms ease;
}
.context-required-banner .crb-action:hover { background: #b91c1c; }

/* ── Session-item subtitle: small workspace · dataset chips below the title
      so users glancing at the sidebar know what cube each chat queried. ─ */
.session-context {
  display: flex; flex-wrap: wrap; gap: 4px;
  margin-top: 3px; padding-left: 22px;        /* aligns under the title */
}
.session-context-pill {
  font-size: 10px; line-height: 1.4;
  padding: 1px 6px; border-radius: 999px;
  background: rgba(72,69,255,0.08);
  color: rgba(72,69,255,0.95);
  font-weight: 600;
  max-width: 180px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.session-context-pill.session-context-ds {
  background: rgba(13,148,136,0.10);
  color: rgba(13,148,136,1);
}

/* ── Admin chat-history viewer (added in Postgres cutover) ── */
.chat-modal { position: fixed; inset: 0; z-index: 9999; display: flex; align-items: center; justify-content: center; }
.chat-modal.hidden { display: none; }
.chat-modal-backdrop { position: absolute; inset: 0; background: rgba(0,0,0,0.5); }
.chat-modal-card { position: relative; background: var(--bg, #fff); width: min(900px, 95vw); max-height: 90vh; border-radius: 12px; box-shadow: 0 20px 60px rgba(0,0,0,0.3); display: flex; flex-direction: column; overflow: hidden; }
.chat-modal-head { display: flex; align-items: center; justify-content: space-between; padding: 16px 20px; border-bottom: 1px solid var(--border, #e5e7eb); }
.chat-modal-body { padding: 16px 20px; overflow-y: auto; }
.chat-msg { padding: 10px 12px; border-radius: 8px; margin-bottom: 10px; border: 1px solid var(--border, #e5e7eb); }
.chat-msg-user { background: rgba(99,102,241,0.06); }
.chat-msg-assistant { background: rgba(16,185,129,0.05); }
.chat-msg-tool { background: rgba(0,0,0,0.03); font-size: 0.85em; }
.chat-msg-role { font-size: 0.7em; text-transform: uppercase; letter-spacing: 0.08em; color: var(--muted, #6b7280); }
.chat-msg-content { margin-top: 4px; white-space: pre-wrap; word-wrap: break-word; }
.chat-msg-tools { margin-top: 6px; font-size: 0.85em; }
.chat-msg-tools pre, .chat-msg-tool pre { white-space: pre-wrap; word-wrap: break-word; max-height: 280px; overflow: auto; background: rgba(0,0,0,0.04); padding: 8px; border-radius: 6px; }
.chat-msg-rate { margin-top: 8px; display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.chat-msg-rate-current { font-size: 0.85em; color: var(--muted, #6b7280); }
.btn-sm { font-size: 0.85em; padding: 4px 10px; }
.admin-page-actions-row { display: flex; gap: 8px; align-items: center; }
.admin-input { padding: 6px 10px; border: 1px solid var(--border, #e5e7eb); border-radius: 6px; min-width: 220px; }
/* Admin chat-history table: question/outcome + ws/ds pills */
.chat-title-cell { font-weight: 600; color: #1a1a2e; line-height: 1.3; }
.chat-outcome {
  margin-top: 4px; font-size: 12px; color: #6b7280; line-height: 1.4;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden; max-width: 480px;
}
.chat-context { display: flex; flex-direction: column; gap: 4px; align-items: flex-start; }
.ws-pill, .ds-pill {
  display: inline-block; max-width: 200px;
  padding: 2px 8px; border-radius: 999px;
  font-size: 11px; font-weight: 600;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.ws-pill { background: rgba(72,69,255,0.10); color: #4845FF; }
.ds-pill { background: rgba(13,148,136,0.10); color: rgb(13,148,136); }
.ws-guid, .ds-guid {
  font-size: 11px; color: #9ca3af; padding: 1px 6px;
  background: rgba(0,0,0,0.04); border-radius: 4px;
}
.muted { color: #9ca3af; }

:root {
  --bg:        #ffffff;
  --bg-1:      #ffffff;
  --bg-2:      #f6f7fb;
  --panel:     #ffffff;
  --panel-2:   #f1f3f8;
  --border:    #e3e6ee;
  --text:      #15171d;
  --muted:     #5b6273;
  --accent:    #4845ff;
  --accent-2:  #6666ff;
  --accent-grad: linear-gradient(135deg, #4845ff 0%, #6666ff 100%);
  --on-accent: #ffffff;
  --good:      #16a34a;
  --warn:      #d97706;
  --bad:       #dc2626;
  --shadow:    0 12px 32px rgba(15, 17, 30, 0.08);
  --radius:    12px;
  --sidebar-w: 260px;
  --topbar-h:  54px;

  /* Page-background ambient gradient — soft Cars24-blue wash */
  --bg-gradient:
    radial-gradient(1100px 520px at 8% -8%, rgba(72,69,255,0.10), transparent 60%),
    radial-gradient(900px 460px at 110% 0%, rgba(102,102,255,0.07), transparent 60%);

  /* Surface tints for hovers, popovers, soft fills */
  --surface-hover:  rgba(15,17,30,0.05);
  --surface-soft:   rgba(15,17,30,0.025);
  --surface-strong: #d8dde7;     /* scrollbar thumb, user avatar bg */
  --text-strong:    #0c0e15;     /* H2/H3, bold body, popover names */
  --text-soft:      #475066;     /* secondary copy under headings */
  --accent-soft:    #3d3ae0;     /* readable Cars24 blue on white */
  --success-soft:   #15803d;
  --danger-soft:    #b91c1c;
  --code-bg:        #f1f3f8;     /* DAX/code blocks, tool result panes */
  --topbar-bg:      rgba(255,255,255,0.85);
  --main-head-bg:   rgba(255,255,255,0.6);
  --input-bg:       #ffffff;
  --placeholder:    #98a0b3;
  --btn-ghost-hover-border: #c5cbdc;
  --composer-bg:    rgba(255,255,255,0.78);
  --surface-inset:  rgba(15,17,30,0.04);
  --surface-deep:   rgba(15,17,30,0.025);
}

* { box-sizing: border-box; }
html, body { height: 100%; margin: 0; }
body {
  font-family: 'DM Sans', 'Inter', system-ui, -apple-system, sans-serif;
  background: var(--bg-gradient), var(--bg);
  color: var(--text);
  -webkit-font-smoothing: antialiased;
  font-size: 14px;
}
code, pre, .mono { font-family: 'JetBrains Mono', ui-monospace, Menlo, monospace; }

/* Inherit the prose font everywhere by default — buttons, inputs, textareas
 * and SVG <text> all default to platform UA fonts otherwise, which makes
 * the UI look mismatched. Code blocks override above. */
button, input, textarea, select, optgroup, svg text {
  font-family: inherit;
}

/* =================== Layout =================== */
.app {
  display: grid;
  grid-template-columns: var(--sidebar-w) 1fr;
  grid-template-rows: var(--topbar-h) 1fr;
  grid-template-areas:
    "topbar topbar"
    "sidebar main";
  /* dvh keeps the layout stable when iOS Safari hides/shows its address bar
     mid-scroll; vh would jitter. Falls back to vh on browsers w/o dvh. */
  height: 100vh;
  height: 100dvh;
}
.app.sidebar-collapsed {
  grid-template-columns: 0 1fr;
}
.app.sidebar-collapsed .sidebar { display: none; }

/* Mobile drawer backdrop (only visible when drawer is open on narrow viewports). */
.sidebar-backdrop {
  position: fixed; inset: 0;
  background: rgba(15,17,30,0.45);
  opacity: 0;
  pointer-events: none;
  z-index: 20;
  transition: opacity 0.2s ease;
}

/* =================== Mobile / narrow tablet (≤ 900px) ===================
   Triggers for: phones (any orientation), small tablets in portrait
   (iPad mini ≈ 744px, iPad portrait = 768px, Android tablets ≈ 800px),
   and phones in landscape (~736–926px). Anything wider keeps the
   desktop two-column layout. */
@media (max-width: 900px) {
  html, body { overflow-x: hidden; }

  .app {
    /* Single-column layout — sidebar overlays the main pane on demand. */
    grid-template-columns: 1fr;
    grid-template-areas:
      "topbar"
      "main";
  }
  .sidebar {
    position: fixed;
    top: var(--topbar-h);
    left: 0; bottom: 0;
    width: min(86vw, 320px);
    transform: translateX(-100%);
    transition: transform 0.22s ease;
    z-index: 25;
    box-shadow: 0 14px 40px rgba(15,17,30,0.18);
    /* Resize handle is desktop-only — touch users have no pointer to drag it. */
  }
  .sidebar-resize { display: none; }
  .app.mobile-drawer-open .sidebar { transform: translateX(0); }
  .app.mobile-drawer-open .sidebar-backdrop { opacity: 1; pointer-events: auto; }
  .app.sidebar-collapsed .sidebar { display: flex; }      /* override desktop hide */

  /* Composer respects the iOS home-indicator safe area so the input stays
     visible above it, and the bottom is touchable past the indicator. */
  .composer { padding-bottom: max(14px, env(safe-area-inset-bottom)); }

  /* Tighter topbar on mobile. */
  .topbar { padding: 0 10px; gap: 8px; }
  /* Compress chips so they don't overflow on a 360–430px viewport. */
  .tb-chip { padding: 6px 10px; font-size: 12px; }
  .tb-chip-label { display: none; }   /* hide "WORKSPACE" / "DATASETS" labels */
  .tb-chip-caret { margin-left: 2px; }

  /* The kebab on session rows has no hover concept on touch — show it
     always, dimmed, so it's tappable without a pre-tap. */
  .session-kebab {
    opacity: 0.55;
    background: transparent;
    border-color: transparent;
  }
  .session-item .session-kebab { opacity: 0.55; }
  .session-kebab:active {
    background: #e9e8ff;
    border-color: rgba(72,69,255,0.30);
    color: var(--accent);
  }

  /* Main content: padding shrinks; let charts/tables scroll horizontally. */
  .main-head { padding: 10px 12px; }
  .messages-scroll { padding: 12px; }
  .table-card, .chart-card { overflow-x: auto; }

  /* KPI grid collapses to two columns on narrow viewports; one column on
     phone-size. (Desktop default is 4 columns.) */
  .kpi-grid { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; }
}

@media (max-width: 480px) {
  /* Phone — single-column KPI cards, smaller composer hint, no model badge. */
  .kpi-grid { grid-template-columns: 1fr !important; }
  .composer-hint { flex-direction: column; gap: 4px; }
  .composer-model { font-size: 10px; padding: 1px 7px; }
  /* Brand "APEX" word hides; keep just the cube logo to save space. */
  .bl-word-apex { display: none; }
}

/* Coarse pointer (touch) — show kebab always even on tablets/desktops with
   touch input, since hover isn't reliable on those devices. */
@media (hover: none) {
  .session-kebab { opacity: 0.55; }
  .session-item:hover .session-kebab { opacity: 0.55; }
  .session-kebab:active {
    opacity: 1;
    background: #e9e8ff;
    border-color: rgba(72,69,255,0.30);
    color: var(--accent);
  }
}

/* =================== TOPBAR =================== */
.topbar {
  grid-area: topbar;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 16px;
  border-bottom: 1px solid var(--border);
  background: var(--topbar-bg);
  backdrop-filter: blur(8px);
  z-index: 10;
}
.topbar-icon { color: var(--muted); }
.brand-mini {
  display: flex; align-items: center; gap: 8px;
  font-weight: 600;
  letter-spacing: -0.005em;
  margin-right: 6px;
}
.brand-logo {
  width: 26px; height: 26px;
  border-radius: 7px;
  background: var(--accent-grad);
  color: var(--on-accent);
  display: grid; place-items: center;
  box-shadow: 0 4px 14px rgba(72,69,255,0.30);
}
.brand-text { font-size: 13.5px; }
.topbar-spacer { flex: 1; }

.tb-chip {
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 6px 10px;
  font-size: 12px;
  color: var(--text-strong);
  cursor: pointer;
  transition: all 0.15s ease;
  max-width: 240px;
  font-family: inherit;
}
.tb-chip:hover {
  background: rgba(72,69,255,0.10);
  border-color: rgba(72,69,255,0.35);
}
.tb-chip-label {
  color: var(--muted);
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-weight: 500;
}
.tb-chip-value {
  color: var(--text-strong);
  font-weight: 600;
  font-size: 12px;
  max-width: 160px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.tb-chip-caret { color: var(--muted); font-size: 9px; }

.topbar-divider {
  width: 1px; height: 26px;
  background: var(--border);
  margin: 0 4px;
}
.dot { width: 8px; height: 8px; border-radius: 50%; background: var(--bad); box-shadow: 0 0 8px var(--bad); }
.dot.on { background: var(--good); box-shadow: 0 0 10px var(--good); }

/* Profile chip — single user-icon button replacing the auth strip */
.profile-chip {
  position: relative;
  appearance: none; border: 0; cursor: pointer;
  width: 34px; height: 34px;
  border-radius: 50%;
  padding: 0;
  background: linear-gradient(135deg, #4845ff 0%, #7a5cff 100%);
  color: #fff;
  font-weight: 600; font-size: 13px;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 2px 6px rgba(72,69,255,0.30), inset 0 0 0 1px rgba(255,255,255,0.10);
  transition: transform 0.08s ease, box-shadow 0.2s ease, filter 0.15s ease;
  font-family: inherit;
}
.profile-chip:hover { filter: brightness(1.10); transform: translateY(-1px); }
.profile-chip:active { transform: translateY(0); }
.profile-avatar { line-height: 1; letter-spacing: 0.2px; }
.profile-status-dot {
  position: absolute;
  right: -2px; bottom: -2px;
  width: 11px; height: 11px;
  border-radius: 50%;
  background: var(--bad);
  border: 2px solid var(--bg-1);
  transition: background 0.2s ease, box-shadow 0.2s ease;
}
.profile-status-dot.on { background: var(--good); box-shadow: 0 0 6px rgba(34,197,94,0.6); }

/* Profile popover */
.profile-pop {
  width: 280px;
  padding: 0;
  overflow: hidden;
}
.profile-pop-head {
  display: flex; align-items: center; gap: 12px;
  padding: 14px 14px 12px;
  border-bottom: 1px solid var(--border);
  background: linear-gradient(180deg, rgba(72,69,255,0.08) 0%, transparent 100%);
}
.profile-pop-avatar {
  width: 40px; height: 40px;
  border-radius: 50%;
  background: linear-gradient(135deg, #4845ff 0%, #7a5cff 100%);
  display: flex; align-items: center; justify-content: center;
  color: #fff; font-weight: 700; font-size: 15px;
  flex-shrink: 0;
}
.profile-pop-meta { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.profile-pop-name {
  font-size: 13.5px; font-weight: 600; color: var(--text-strong);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.profile-pop-sub {
  font-size: 11.5px; color: var(--muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.profile-pop-pbi {
  display: flex; align-items: center; gap: 8px;
  padding: 10px 14px;
  border-bottom: 1px solid var(--border);
  font-size: 12px;
  color: var(--muted);
}
.profile-pop-pbi .dot { width: 7px; height: 7px; }
.profile-pop-pbi .pbi-text {
  flex: 1;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.profile-pop-pbi .pbi-action {
  appearance: none; border: 0; background: transparent;
  color: var(--accent-soft); cursor: pointer;
  font-size: 11.5px; font-weight: 600; font-family: inherit;
  padding: 2px 6px; border-radius: 5px;
}
.profile-pop-pbi .pbi-action:hover { background: rgba(72,69,255,0.18); }


.profile-pop-actions { display: flex; flex-direction: column; padding: 6px; }
.profile-pop-action {
  appearance: none; border: 0; background: transparent;
  cursor: pointer;
  display: flex; align-items: center; gap: 10px;
  padding: 9px 10px;
  border-radius: 8px;
  font-size: 13px;
  font-family: inherit;
  color: var(--text);
  text-align: left;
}
.profile-pop-action:hover { background: var(--surface-hover); }
.profile-pop-action.danger { color: var(--danger-soft); }
.profile-pop-action.danger:hover { background: rgba(239,68,68,0.10); }
.profile-pop-action svg { flex-shrink: 0; opacity: 0.85; }

/* Profile-edit / change-password modal form */
.modal.modal-form {
  text-align: left;
  gap: 14px;
  width: min(420px, 92vw);
}
.modal.modal-form h3 { font-size: 16px; }
.form-row { display: flex; flex-direction: column; gap: 6px; }
.form-row label {
  font-size: 11.5px;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-weight: 600;
}
.form-row input {
  appearance: none;
  border: 1px solid var(--border);
  background: var(--bg-2);
  border-radius: 8px;
  padding: 9px 11px;
  font: inherit;
  font-size: 13px;
  color: var(--text);
  outline: none;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.form-row input:focus {
  border-color: rgba(72,69,255,0.55);
  box-shadow: 0 0 0 2px rgba(72,69,255,0.18);
}
.modal-actions {
  display: flex; gap: 8px; justify-content: flex-end;
  margin-top: 4px;
}
.form-error {
  color: var(--danger-soft);
  font-size: 12px;
  min-height: 16px;
}

.btn {
  appearance: none; border: 0; cursor: pointer;
  display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 12px; border-radius: 8px;
  font-weight: 600; font-size: 13px;
  font-family: inherit;
  transition: transform 0.05s ease, box-shadow 0.2s ease, background 0.2s ease, filter 0.15s ease;
}
.btn svg { flex-shrink: 0; }
.btn:active { transform: translateY(1px); }
.btn-sm { padding: 5px 10px; font-size: 12px; }
.btn-primary {
  background: var(--accent-grad); color: var(--on-accent);
  box-shadow: 0 4px 14px rgba(72,69,255,0.25);
}
.btn-primary:hover { filter: brightness(1.05); }
.btn-primary:disabled { opacity: 0.5; cursor: not-allowed; }
.btn-ghost {
  background: transparent; color: var(--muted);
  border: 1px solid var(--border);
}
.btn-ghost:hover { color: var(--text); border-color: var(--btn-ghost-hover-border); }
.hidden { display: none !important; }
.icon-btn {
  background: transparent; border: 0; color: var(--muted); cursor: pointer;
  padding: 6px; border-radius: 6px;
}
.icon-btn:hover { color: var(--text); background: var(--surface-hover); }

/* =================== SIDEBAR (sessions) =================== */
.sidebar {
  grid-area: sidebar;
  background: linear-gradient(180deg, var(--panel) 0%, var(--bg-2) 100%);
  border-right: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  padding: 12px 10px;
  gap: 10px;
  overflow: hidden;
  min-width: 0;
  position: relative;       /* anchor for the resize handle */
}
.sidebar-resize {
  position: absolute;
  top: 0; bottom: 0;
  right: -3px;
  width: 6px;
  cursor: col-resize;
  z-index: 5;
  background: transparent;
  transition: background 0.15s ease;
}
.sidebar-resize:hover,
.sidebar-resize.dragging { background: rgba(72,69,255,0.35); }
body.is-resizing-sidebar { cursor: col-resize; user-select: none; }
body.is-resizing-sidebar iframe,
body.is-resizing-sidebar canvas { pointer-events: none; }
.sidebar-toolbar {
  display: flex;
  align-items: center;
  gap: 6px;
}
.sidebar-toolbar .sidebar-search { flex: 1; min-width: 0; }
.sidebar-icon-btn {
  flex: 0 0 auto;
  width: 32px; height: 32px;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--surface-inset);
  border: 1px solid var(--border);
  border-radius: 8px;
  color: var(--text);
  cursor: pointer;
  padding: 0;
  transition: background 0.15s ease, border-color 0.15s ease, filter 0.15s ease;
}
.sidebar-icon-btn:hover {
  background: rgba(72,69,255,0.10);
  border-color: rgba(72,69,255,0.35);
  color: var(--accent-soft, #b9a9ff);
}
.sidebar-icon-btn.primary {
  background: var(--accent-grad);
  border-color: transparent;
  color: #fff;
  box-shadow: 0 4px 14px rgba(72,69,255,0.22);
}
.sidebar-icon-btn.primary:hover {
  background: var(--accent-grad);
  border-color: transparent;
  color: #fff;
  filter: brightness(1.07);
}

.sidebar-search {
  display: flex; align-items: center; gap: 6px;
  background: var(--surface-inset);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 6px 8px;
}
.sidebar-search svg { color: var(--muted); flex-shrink: 0; }
.sidebar-search input {
  flex: 1; min-width: 0;
  background: transparent; border: 0; outline: 0;
  color: var(--text); font-family: inherit; font-size: 12.5px;
}
.sidebar-search input::placeholder { color: var(--placeholder); }

.sessions-scroll {
  flex: 1; min-height: 0;
  overflow-y: auto;
  padding-right: 4px;
}
.sessions-scroll::-webkit-scrollbar { width: 6px; }
.sessions-scroll::-webkit-scrollbar-thumb { background: var(--surface-strong); border-radius: 3px; }
.sessions-list { display: flex; flex-direction: column; gap: 2px; }

.session-group-head {
  font-size: 10px;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: var(--muted);
  padding: 12px 8px 4px;
  font-weight: 500;
}
.session-group-head:first-child { padding-top: 4px; }

.session-item {
  display: flex; flex-direction: column; gap: 2px;
  padding: 7px 8px;
  border-radius: 7px;
  cursor: pointer;
  border: 1px solid transparent;
  position: relative;
  font-size: 12.5px;
  color: var(--text);
  transition: background 0.12s ease, border-color 0.12s ease;
}
.session-row {
  position: relative;
  display: flex; align-items: center; gap: 6px;
  width: 100%;
}
.session-item:hover {
  background: var(--surface-hover);
  border-color: var(--border);
}
.session-item.active {
  background: rgba(72,69,255,0.10);
  border-color: rgba(72,69,255,0.35);
  color: var(--text-strong);
}
.session-title {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Pinned-state indicator (small filled pin) sits inline before the title.
   It's a visual marker, not interactive — actions live in the kebab menu. */
.session-pin-badge {
  flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center;
  width: 14px; height: 14px;
  color: var(--accent);
}
/* Kebab (⋯) — overlays the right end of the row on hover. Solid background
   so it doesn't visually crash into the title text underneath. */
.session-kebab {
  position: absolute;
  right: 2px; top: 50%;
  transform: translateY(-50%);
  display: inline-flex; align-items: center; justify-content: center;
  width: 24px; height: 24px;
  background: var(--panel);
  border: 1px solid transparent;
  color: var(--muted);
  border-radius: 6px;
  cursor: pointer;
  opacity: 0;
  padding: 0;
  transition: opacity 0.12s ease, background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.session-kebab svg { display: block; pointer-events: none; }
.session-kebab svg circle { fill: currentColor; }
.session-item:hover .session-kebab { opacity: 1; }
.session-item.active .session-kebab { background: var(--panel); }
/* Solid pre-blended tint on hover/open — must be opaque so the title
   text under the absolutely-positioned button cannot bleed through and
   wash out the 3 dots. */
.session-kebab:hover,
.session-kebab.is-open {
  opacity: 1;
  background: #e9e8ff;
  border-color: rgba(72,69,255,0.30);
  color: var(--accent);
}
/* "Show more / Show less" toggle at the bottom of the non-pinned groups. */
.sessions-show-more {
  margin: 8px 4px 4px;
  padding: 7px 10px;
  background: transparent;
  border: 1px dashed var(--border);
  color: var(--muted);
  border-radius: 8px;
  cursor: pointer;
  font: inherit;
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.02em;
  transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}
.sessions-show-more:hover {
  background: rgba(72,69,255,0.06);
  border-color: rgba(72,69,255,0.40);
  color: var(--accent-soft);
}
.session-meta {
  display: inline-flex; gap: 6px; align-items: center;
  padding-left: 1px;
  font-size: 10.5px;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}
.session-meta-dot { opacity: 0.5; }
.session-meta-cost { color: var(--success-soft); }
/* Time stamp — quiet, sits before the token+cost on each session row. */
.session-meta-time {
  color: rgba(15, 23, 42, 0.50);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
}

/* Streaming indicator on sessions whose chat is still running in the background */
.session-streaming-dot {
  color: var(--accent);
  font-size: 11px;
  margin-right: 5px;
  flex-shrink: 0;
  animation: pulse 1.4s ease-in-out infinite;
}
.session-item.is-streaming { border-left: 2px solid var(--accent); padding-left: 6px; }
.session-item.is-streaming .session-title { font-weight: 600; }

.empty {
  font-size: 12px; color: var(--muted);
  padding: 12px 10px;
  font-style: italic;
  text-align: center;
}

/* =================== MAIN =================== */
.main {
  grid-area: main;
  display: grid;
  grid-template-rows: auto 1fr auto;
  min-height: 0;
  min-width: 0;
}

.main-head {
  padding: 12px 28px;
  border-bottom: 1px solid var(--border);
  display: flex; justify-content: space-between; align-items: center; gap: 16px;
  background: var(--main-head-bg);
}
.chat-title {
  margin: 0;
  font-size: 15px;
  font-weight: 600;
  letter-spacing: -0.005em;
  color: var(--text-strong);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 60%;
}
.pills { display: flex; gap: 6px; flex-wrap: wrap; }
.pill {
  font-size: 10.5px; padding: 4px 8px; border-radius: 999px;
  background: var(--panel-2); border: 1px solid var(--border);
  color: var(--muted);
}
.pill.on { color: var(--accent-soft); border-color: rgba(72,69,255,0.4); background: rgba(72,69,255,0.08); }

/* ---------- Messages ---------- */
.messages {
  overflow-y: auto;
  padding: 24px 28px 16px;
}
.messages::-webkit-scrollbar { width: 8px; }
.messages::-webkit-scrollbar-thumb { background: var(--surface-strong); border-radius: 4px; }

.welcome { display: grid; place-items: center; min-height: 60vh; }
.welcome-card {
  width: min(720px, 100%);
  background: linear-gradient(180deg, rgba(72,69,255,0.06), rgba(102,102,255,0.04));
  border: 1px solid var(--border);
  border-radius: 18px;
  padding: 32px;
  text-align: center;
  box-shadow: var(--shadow);
}
.welcome-card h2 { margin: 0 0 6px; font-size: 22px; letter-spacing: -0.01em; }
.welcome-card p  { margin: 0; color: var(--muted); }

/* "+N more" hover chip — lists remaining datasets */
.ds-more {
  position: relative;
  display: inline-block;
  padding: 1px 7px;
  margin: 0 1px;
  border: 1px dashed var(--border);
  border-radius: 999px;
  background: var(--surface-hover);
  color: var(--text);
  font-size: 12px;
  font-weight: 600;
  line-height: 1.4;
  cursor: help;
  vertical-align: baseline;
  outline: none;
}
.ds-more:hover, .ds-more:focus-visible {
  border-color: var(--accent);
  color: var(--accent);
}
.ds-more-pop {
  position: absolute;
  left: 50%;
  bottom: calc(100% + 8px);
  transform: translateX(-50%) translateY(4px);
  min-width: 220px;
  max-width: 360px;
  padding: 10px 12px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: var(--shadow);
  text-align: left;
  font-size: 12.5px;
  font-weight: 500;
  color: var(--text);
  opacity: 0;
  pointer-events: none;
  transition: opacity 120ms ease, transform 120ms ease;
  z-index: 50;
  white-space: normal;
}
.ds-more:hover .ds-more-pop,
.ds-more:focus-visible .ds-more-pop {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}
.ds-more-pop::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 100%;
  transform: translateX(-50%);
  border: 6px solid transparent;
  border-top-color: var(--panel);
}
.ds-more-pop-title {
  display: block;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 6px;
}
.ds-more-pop ul {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.ds-more-pop li {
  padding: 3px 0;
  border-top: 1px solid var(--border);
  color: var(--text);
  font-weight: 500;
  word-break: break-word;
}
.ds-more-pop li:first-child { border-top: none; padding-top: 0; }

.msg { display: flex; gap: 12px; margin: 18px 0; max-width: 920px; align-items: flex-start; }
/* User messages: bubble flows right (no avatar — the "You" label was removed
   for a cleaner, professional outlook). Action chips ("Rephrase" / "Edit")
   wrap to their own line below the bubble, hidden until hover. */
.msg.user {
  justify-content: flex-end;
  margin-left: auto;
  align-items: flex-start;
  flex-wrap: wrap;
}

.msg-actions {
  order: 99;             /* push to end of flex row */
  flex-basis: 100%;      /* force a wrap to its own line */
  display: flex; gap: 6px;
  justify-content: flex-end;
  margin-top: 4px;
  /* Reserve no space until hover so the gap between consecutive turns
     doesn't grow. The action area is height: 0 collapsed, restored on hover. */
  max-height: 0;
  overflow: hidden;
  opacity: 0;
  transition: max-height 0.16s ease, opacity 0.14s ease;
}
.msg.user:hover .msg-actions,
.msg.user:focus-within .msg-actions {
  max-height: 32px;
  opacity: 1;
}
.msg-action-btn {
  background: var(--surface-deep);
  border: 1px solid var(--border);
  border-radius: 999px;
  height: 24px;
  padding: 0 10px;
  display: inline-flex; align-items: center; gap: 5px;
  color: var(--muted);
  font-family: inherit;
  cursor: pointer;
  transition: color 0.12s ease, border-color 0.12s ease, background 0.12s ease;
}
.msg-action-btn:hover {
  color: var(--accent);
  border-color: var(--accent);
  background: rgba(72,69,255,0.10);
}
.avatar {
  width: 36px; height: 36px;
  border-radius: 10px;                                    /* rounded square — modern, brand-mark feel */
  display: grid; place-items: center;
  font-size: 12px; font-weight: 700; flex-shrink: 0;
  letter-spacing: 0.02em;
}
/* Assistant (dataeze) avatar — 2026-05-28 redesigned.
   Brand-tinted gradient background instead of plain white, hairline
   indigo border, soft indigo shadow. Reads as a proper premium brand
   chip rather than a beige icon-in-a-circle. The dataeze-icon.png
   inside renders at its native colour against the tinted bg. */
.avatar.a {
  background: linear-gradient(135deg, #ffffff 0%, #F4F2FF 100%);
  border: 1px solid rgba(72, 69, 255, 0.18);
  box-shadow: 0 2px 6px rgba(72, 69, 255, 0.10),
              0 1px 2px rgba(15, 23, 42, 0.04);
  padding: 5px;
}
.avatar.a img { width: 100%; height: 100%; object-fit: contain; display: block; }
.avatar.u { background: var(--surface-strong); color: var(--text); }     /* legacy — no longer rendered */

.bubble {
  padding: 14px 18px;
  border-radius: 14px;
  max-width: 760px;
  line-height: 1.6;
  border: 1px solid #eef0f4;
  background: #ffffff;
  white-space: pre-wrap;
  word-wrap: break-word;
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.03);
}
/* User bubble — solid CARS24 indigo with white text. Reads as "the user
   said this", crisp and professional, matches premium chat UIs. */
.msg.user .bubble {
  background: #5B4DFF;
  color: #ffffff;
  border-color: transparent;
  border-radius: 14px 14px 4px 14px;       /* tail toward the right edge */
  box-shadow: 0 2px 6px rgba(91, 77, 255, 0.18);
  font-weight: 500;
}
/* Assistant bubble — soft white card with a subtle gray border + shadow.
   The agent's role badge ("A" avatar) sits to the left as before. */
.msg.assistant .bubble {
  border-radius: 4px 14px 14px 14px;       /* tail toward the left edge */
  background: #ffffff;
  border-color: #eaeef3;
}

/* Markdown rendering inside assistant bubbles */
.msg.assistant .bubble { white-space: normal; max-width: 920px; }
.msg.assistant .bubble h1,
.msg.assistant .bubble h2,
.msg.assistant .bubble h3 {
  margin: 16px 0 8px;
  font-weight: 700;
  letter-spacing: -0.01em;
}
.msg.assistant .bubble h1 { font-size: 1.25rem; }
.msg.assistant .bubble h2 { font-size: 1.10rem; color: var(--text-strong); }
.msg.assistant .bubble h3 { font-size: 1.00rem; color: var(--text-soft); }
.msg.assistant .bubble h1:first-child,
.msg.assistant .bubble h2:first-child,
.msg.assistant .bubble h3:first-child { margin-top: 2px; }
.msg.assistant .bubble p { margin: 8px 0; }
.msg.assistant .bubble ul,
.msg.assistant .bubble ol { margin: 8px 0; padding-left: 22px; }
.msg.assistant .bubble li { margin: 3px 0; }
.msg.assistant .bubble strong { color: var(--text-strong); }
.msg.assistant .bubble code {
  font-family: "JetBrains Mono", monospace;
  font-size: 0.85em;
  background: rgba(72,69,255,0.12);
  padding: 1px 6px;
  border-radius: 4px;
  border: 1px solid rgba(72,69,255,0.18);
}
.msg.assistant .bubble pre {
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 10px 12px;
  overflow-x: auto;
  margin: 10px 0;
}
.msg.assistant .bubble pre code {
  background: transparent; border: none; padding: 0; font-size: 0.85em;
}
.msg.assistant .bubble table {
  border-collapse: collapse;
  margin: 12px 0;
  width: 100%;
  font-size: 0.92em;
  background: var(--surface-deep);
  border-radius: 8px;
  overflow: hidden;
}
.msg.assistant .bubble th,
.msg.assistant .bubble td {
  border-bottom: 1px solid var(--border);
  padding: 7px 12px;
  text-align: left;
  vertical-align: top;
}
.msg.assistant .bubble th {
  background: rgba(72,69,255,0.10);
  color: var(--text-strong);
  font-weight: 600;
  font-size: 0.85em;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  border-bottom: 1px solid rgba(72,69,255,0.25);
}
.msg.assistant .bubble tr:last-child td { border-bottom: none; }
.msg.assistant .bubble tr:hover td { background: rgba(72,69,255,0.04); }
.msg.assistant .bubble td:nth-child(n+2) { font-variant-numeric: tabular-nums; }
.msg.assistant .bubble blockquote {
  margin: 10px 0;
  padding: 6px 12px;
  border-left: 3px solid rgba(72,69,255,0.5);
  color: var(--text-soft);
  background: rgba(72,69,255,0.05);
}
.msg.assistant .bubble hr {
  border: none; border-top: 1px solid var(--border); margin: 16px 0;
}

/* ---------- Rich answer blocks (KPI / chart / callout) ---------- */
.md-section { margin: 6px 0; }
.md-section:first-child { margin-top: 0; }

/* KPI cards — match the old agent's tile language exactly. White surface,
   thin gray border, faint shadow, vertical left accent stripe color-coded
   by trend (green up / red down / indigo neutral / gray flat). Left-aligned
   content, uppercase label, big tabular-nums value, color-coded delta. */
.kpi-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 10px;
  margin: 12px 0;
}
.kpi-card {
  position: relative;
  overflow: hidden;
  background: #ffffff;
  border: 1px solid #e5e7eb;
  border-radius: 12px;
  padding: 12px 14px 12px 18px;     /* extra left padding so text clears the accent */
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04);
}
.kpi-card::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
  background: #5B4DFF;              /* CARS24 indigo (matches old agent) */
}
.kpi-card.kpi-up::before   { background: #059669; }   /* emerald-600 */
.kpi-card.kpi-down::before { background: #DC2626; }   /* red-600 */
.kpi-card.kpi-flat::before { background: #94a3b8; }   /* slate-400 */

.kpi-label {
  font-size: 10px; color: #6b7280;
  text-transform: uppercase; letter-spacing: 0.06em;
  margin-bottom: 6px; font-weight: 600;
}
.kpi-value {
  font-size: 1.45rem; font-weight: 800;
  color: #1a1a2e; letter-spacing: -0.01em;
  line-height: 1.15;
  font-variant-numeric: tabular-nums;
  margin-bottom: 4px;
}
.kpi-delta {
  font-size: 11px; color: #6b7280;
  display: inline-flex; align-items: center; gap: 4px;
  font-weight: 700;
}
.kpi-card.kpi-up   .kpi-delta { color: #059669; }
.kpi-card.kpi-down .kpi-delta { color: #DC2626; }
.kpi-arrow { font-size: 9px; line-height: 1; }

.chart-card {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 14px 16px 8px;
  margin: 12px 0;
}
.chart-title {
  font-size: 13px; font-weight: 600;
  color: var(--text-strong); margin-bottom: 8px;
  letter-spacing: -0.005em;
}
.chart-canvas-wrap { position: relative; height: 240px; }
.chart-empty {
  display: flex; align-items: center; justify-content: center;
  height: 120px;
  color: #9da3ad;
  font-size: 12px;
  font-style: italic;
  border: 1px dashed var(--border);
  border-radius: 8px;
  background: var(--surface-soft);
}

.callout {
  display: flex; gap: 12px;
  padding: 12px 14px;
  border-radius: 10px;
  margin: 8px 0;
  border: 1px solid var(--border);
  background: var(--bg-2);
  align-items: flex-start;
}
.callout-icon {
  flex-shrink: 0;
  font-size: 16px; line-height: 1.4;
  width: 24px; height: 24px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 6px;
}
.callout-content { flex: 1; min-width: 0; }
.callout-title {
  font-weight: 600; color: var(--text-strong);
  font-size: 13px; margin-bottom: 2px;
}
.callout-body { font-size: 13px; color: var(--text-soft); line-height: 1.5; }
.callout-insight { border-color: rgba(72,69,255,0.35); background: rgba(72,69,255,0.06); }
.callout-insight .callout-icon { background: rgba(72,69,255,0.18); }
.callout-anomaly { border-color: rgba(248,113,113,0.35); background: rgba(248,113,113,0.05); }
.callout-anomaly .callout-icon { background: rgba(248,113,113,0.18); }
.callout-warning { border-color: rgba(251,191,36,0.35); background: rgba(251,191,36,0.05); }
.callout-warning .callout-icon { background: rgba(251,191,36,0.18); }
.callout-next-step { border-color: rgba(80,200,120,0.35); background: rgba(80,200,120,0.06); }
.callout-next-step .callout-icon { background: rgba(80,200,120,0.18); color: var(--success-soft); font-weight: 700; }

/* ---------- Drill-down question chips ----------
   Replaces the model's bullet list under "## Drill-down next" with a vertical
   stack of clickable cards. Click → composer auto-fills + the message sends.
*/
.drill-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin: 6px 0 4px;
}
.drill-q {
  display: flex; align-items: center; gap: 12px;
  width: 100%;
  text-align: left;
  background: var(--panel);
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: 10px;
  padding: 12px 14px;
  cursor: pointer;
  font-family: inherit;
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--text);
  transition: background 0.15s ease, border-color 0.15s ease, transform 0.05s ease, box-shadow 0.15s ease;
}
.drill-q:hover {
  background: rgba(72,69,255,0.04);
  border-color: rgba(72,69,255,0.40);
  border-left-color: var(--accent);
  box-shadow: 0 4px 14px rgba(72,69,255,0.10);
}
.drill-q:active { transform: translateY(1px); }
.drill-q-text {
  flex: 1;
  min-width: 0;
}
.drill-q-icon {
  flex-shrink: 0;
  color: var(--accent);
  opacity: 0.55;
  transition: opacity 0.15s ease, transform 0.15s ease;
}
.drill-q:hover .drill-q-icon { opacity: 1; transform: translateX(2px); }
.drill-q:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px rgba(72,69,255,0.20);
  border-color: rgba(72,69,255,0.55);
}

/* ---------- DAX panel ---------- */
.dax-panel {
  border: 1px solid var(--border);
  background: var(--bg-2);
  border-radius: 10px;
  overflow: hidden;
  max-width: 920px;
  font-size: 12px;
}
.dax-panel.hidden { display: none; }
.dax-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 8px 12px; cursor: pointer;
  background: rgba(102,102,255,0.06);
  border-bottom: 1px solid var(--border);
  user-select: none;
}
.dax-title {
  display: flex; align-items: center; gap: 8px;
  color: var(--text-strong); font-weight: 600; font-size: 12px;
  letter-spacing: 0.01em;
}
.dax-title svg { color: #6666ff; }
.dax-count {
  color: var(--muted); font-size: 11px;
  padding: 1px 8px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface-inset);
}
.dax-head .caret {
  color: var(--muted); font-size: 10px;
  transition: transform 0.2s ease;
}
.dax-panel.collapsed .dax-head { border-bottom-color: transparent; }
.dax-panel.collapsed .dax-head .caret { transform: rotate(-90deg); }
.dax-panel.collapsed .dax-body { display: none; }
.dax-body {
  padding: 8px;
  display: flex; flex-direction: column; gap: 6px;
  background: var(--surface-deep);
}
.dax-block {
  margin: 0;
  padding: 10px 12px;
  background: var(--code-bg);
  border: 1px solid var(--border);
  border-radius: 6px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11.5px;
  color: var(--text);
  white-space: pre-wrap;
  word-break: break-word;
  overflow-x: auto;
}

/* ---------- Activity panel ---------- */
.turn-body { display: flex; flex-direction: column; gap: 10px; flex: 1; min-width: 0; }
.activity {
  border: 1px solid var(--border);
  background: var(--bg-2);
  border-radius: 10px;
  overflow: hidden;
  max-width: 920px;
  font-size: 12px;
}
.activity-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 8px 12px; cursor: pointer;
  background: rgba(72,69,255,0.06);
  border-bottom: 1px solid var(--border);
  user-select: none;
}
.activity-head .activity-title {
  display: flex; align-items: center; gap: 10px;
  color: var(--accent-soft);
  font-weight: 500; font-size: 12.5px;
}
.activity-head .activity-label { font-weight: 500; }
.activity-head .activity-count {
  color: var(--muted); font-size: 11px;
  padding: 1px 8px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface-inset);
}
.activity-head .caret { color: var(--muted); font-size: 10px; transition: transform 0.2s ease; }
.activity.collapsed .activity-head { border-bottom-color: transparent; }
.activity.collapsed .activity-head .caret { transform: rotate(-90deg); }
.activity.collapsed .activity-body { display: none; }
.activity.done .activity-head { background: rgba(80,200,120,0.05); }
.activity.done .activity-head .activity-label { color: #9da3ad; }
.activity.done.stopped .activity-head { background: rgba(248,113,113,0.06); }
.activity.done.stopped .activity-head .activity-label { color: var(--danger-soft); }
.activity.hidden { display: none; }

/* Reassurance line that fades in at the 45-second mark while the agent
   is still working. Sits between the activity bar and the (still-empty)
   answer bubble, styled like a soft italic side-note so the user reads
   it as "the agent is being thorough" not "the system is broken". */
.patience-note {
  margin: 8px 2px 0;
  padding: 8px 12px;
  font-size: 12.5px;
  font-style: italic;
  color: #6b7280;
  background: linear-gradient(180deg, rgba(91,77,255,0.04), rgba(91,77,255,0.02));
  border-left: 3px solid rgba(91,77,255,0.35);
  border-radius: 6px;
  line-height: 1.45;
  animation: patience-fade-in 0.6s ease-out;
}
.patience-note.hidden { display: none; }
@keyframes patience-fade-in {
  from { opacity: 0; transform: translateY(-2px); }
  to   { opacity: 1; transform: none; }
}

/* Activity meta — live timer, token count, cost */
.activity-head .activity-meta {
  display: flex; align-items: center; gap: 10px;
  margin-left: auto;
  padding-right: 10px;
  font-size: 11.5px;
  font-variant-numeric: tabular-nums;
  color: var(--muted);
}
.activity-head .meta-timer,
.activity-head .meta-tokens,
.activity-head .meta-cost {
  white-space: nowrap;
}
.activity-head .meta-timer {
  color: var(--accent-soft);
  font-variant-numeric: tabular-nums;
}
.activity.done .activity-head .meta-timer { color: var(--muted); }
.activity-head .meta-tokens.hidden,
.activity-head .meta-cost.hidden { display: none; }
.activity-head .meta-cost {
  color: var(--success-soft);
}

/* Compact meta strip rendered under replayed assistant turns. The live
 * activity panel is hidden on replay (it's already a closed chapter), so
 * we surface tokens / cost / elapsed inline here. */
.replay-meta {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin-top: 8px;
  padding: 4px 10px;
  border: 1px solid var(--border);
  border-radius: 999px;
  font-size: 11px;
  color: var(--muted);
  background: var(--surface-soft);
  font-variant-numeric: tabular-nums;
  width: fit-content;
}
.replay-meta .rm-tok   { color: var(--text); }
.replay-meta .rm-cost  { color: var(--success-soft); }
.replay-meta .rm-time  { color: var(--accent-soft); }
.replay-meta .rm-model { color: var(--muted); font-style: italic; }
.replay-meta .rm-dot   { opacity: 0.45; }

.activity-body {
  padding: 8px;
  display: flex; flex-direction: column; gap: 6px;
  background: var(--surface-deep);
}

.spinner {
  width: 12px; height: 12px;
  border: 2px solid rgba(72,69,255,0.25);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
  flex-shrink: 0;
}
@keyframes spin { to { transform: rotate(360deg); } }

.tool-event {
  margin: 0;
  border: 1px solid var(--border);
  background: var(--bg-2);
  border-radius: 8px;
  overflow: hidden;
  font-size: 12px;
}
.tool-event-head {
  display: flex; align-items: center;
  padding: 7px 11px; cursor: pointer;
  background: rgba(72,69,255,0.05);
  border-bottom: 1px solid var(--border);
}
.tool-event.collapsed .tool-event-head { border-bottom-color: transparent; }
.tool-event-head .name {
  /* Now reads as a human description, not a code identifier — drop the
     mono font so it sits with the rest of the UI. */
  font-family: inherit;
  color: var(--text);
  font-weight: 600;
  flex: 1;
}
.tool-event-head .tool-raw {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10.5px;
  color: var(--muted);
  opacity: 0.7;
  margin-right: 8px;
  flex-shrink: 0;
}
.tool-event-head .status-dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 6px var(--accent);
  flex-shrink: 0;
  margin-right: 8px;
}
.tool-event.ok .status-dot { background: #50c878; box-shadow: 0 0 6px #50c878; }
.tool-event.errored .status-dot { background: #f87171; box-shadow: 0 0 6px #f87171; }
.tool-event.pending .status-dot { animation: pulse 1.2s ease-in-out infinite; }
@keyframes pulse { 0%,100%{opacity:1} 50%{opacity:0.3} }
.tool-event-head .status-text {
  font-size: 11px; color: var(--muted);
  margin-right: 10px;
  text-transform: uppercase; letter-spacing: 0.05em;
}
.tool-event.errored .status-text { color: var(--danger-soft); }
.tool-event.ok .status-text { color: var(--success-soft); }
.kv-label {
  font-size: 10px;
  text-transform: uppercase;
  color: var(--muted);
  letter-spacing: 0.08em;
  margin: 4px 0 4px;
}
.kv-label:first-child { margin-top: 0; }
.tool-event-head .caret { color: var(--muted); font-size: 10px; }
.tool-event-body {
  padding: 10px 12px;
  max-height: 260px; overflow: auto;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11.5px; color: var(--text-soft);
  background: var(--code-bg);
}
.tool-event-body::-webkit-scrollbar { width: 6px; height: 6px; }
.tool-event-body::-webkit-scrollbar-thumb { background: var(--surface-strong); border-radius: 3px; }
.tool-event.collapsed .tool-event-body { display: none; }

.thinking { display: flex; gap: 6px; margin: 10px 0 10px 42px; }
.thinking span {
  width: 6px; height: 6px; border-radius: 50%; background: var(--muted);
  animation: bounce 1.2s infinite ease-in-out;
}
.thinking span:nth-child(2) { animation-delay: 0.15s; }
.thinking span:nth-child(3) { animation-delay: 0.3s; }
@keyframes bounce { 0%,80%,100% { transform: scale(0.7); opacity: 0.5; } 40% { transform: scale(1); opacity: 1; } }

.error-bubble {
  margin: 8px 0 8px 42px;
  padding: 10px 12px;
  border: 1px solid rgba(248,113,113,0.4);
  background: rgba(248,113,113,0.08);
  color: #fecaca;
  border-radius: 10px;
  font-size: 13px;
}

/* ---------- Composer ---------- */
.composer {
  padding: 12px 28px 18px;
  border-top: 1px solid var(--border);
  background: var(--composer-bg);
  backdrop-filter: blur(8px);
}
/* Composer — pill bar matching the old agent's polished style:
   2px violet-tinted border, fully rounded (28px), generous left padding,
   soft outer shadow, expressive focus ring. */
.composer-inner {
  display: flex; gap: 10px; align-items: center;
  background: #ffffff;
  border: 2px solid #e8e5ff;
  border-radius: 28px;
  padding: 8px 8px 8px 18px;
  transition: border-color 0.2s ease, box-shadow 0.2s ease;
  /* Full-width composer (was capped at 920px which made the pill look
     marooned in the middle of wide screens). Now stretches to whatever
     padding .composer applies on the outside (12px 28px 18px). */
  max-width: none;
  margin: 0;
  box-shadow: 0 2px 20px rgba(91,77,255,0.06);
}
.composer-inner:focus-within {
  border-color: #5B4DFF;
  box-shadow: 0 0 0 4px rgba(91,77,255,0.08), 0 2px 20px rgba(91,77,255,0.10);
}
#input {
  flex: 1; resize: none; background: transparent; border: 0; outline: 0;
  color: #1a1a2e;
  font-family: inherit; font-size: 14.5px; line-height: 1.6;
  max-height: 180px; padding: 4px 0;
}
#input::placeholder { color: #c4c0e0; }
/* iOS Safari auto-zooms when an <input>/<textarea> with font-size <16px gains
   focus, which shifts the whole layout uncomfortably on phones. Bumping
   the font-size past 16px on small viewports disables that behaviour. */
@media (max-width: 900px) {
  #input { font-size: 16px; }
  .composer-hint { font-size: 11px; }
}
/* Round indigo→violet send button (matches old agent). */
.btn-send {
  width: 38px; height: 38px; min-width: 38px; border-radius: 50%;
  background: #5B4DFF;
  color: #ffffff;
  display: grid; place-items: center;
  box-shadow: none;
  border: 0; cursor: pointer; flex-shrink: 0;
  transition: background 0.14s ease;
}
/* Send arrow SVG: 16×16 grid, symmetric stem+arrowhead — no transform
   hack needed. Explicit display:block + sizing prevents any stray
   inline-baseline offset from shifting it inside the grid cell. */
.btn-send svg {
  display: block;
  width: 16px;
  height: 16px;
}
.btn-send:hover {
  background: #4a3fd6;
}
.btn-send:active { background: #3f35bd; }
.btn-send:disabled { opacity: 0.3; cursor: not-allowed; transform: none; box-shadow: none; }
.btn-send.is-streaming {
  background: linear-gradient(135deg, #f87171 0%, #ef4444 100%);
  color: #fff;
  box-shadow: 0 6px 18px rgba(239,68,68,0.30);
}
.btn-send.is-streaming:hover { filter: brightness(1.05); }
.composer-hint {
  margin-top: 8px;
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 12px;
  color: var(--muted);
  font-size: 11px;
}
.composer-hint-text { color: var(--muted); }
.composer-model {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 2px 9px;
  border: 1px solid var(--border);
  border-radius: 999px;
  font-family: "JetBrains Mono", "SF Mono", Menlo, monospace;
  font-size: 10.5px;
  letter-spacing: 0.02em;
  color: var(--muted);
  background: rgba(255,255,255,0.02);
}
.composer-model:empty { display: none; }
.composer-model::before {
  content: "";
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--accent, #4845ff);
  box-shadow: 0 0 6px rgba(72,69,255,0.4);
}

/* Inline variant — sits on the LEFT inside the composer pill, next to
   the textarea. Slightly tinted indigo so it reads as a "context" chip
   that the user can scan at a glance, not as a prominent CTA. */
.composer-model-inline {
  flex: 0 0 auto;
  height: 28px;
  padding: 0 12px 0 10px;
  border: 1px solid rgba(91, 77, 255, 0.22);
  background: rgba(91, 77, 255, 0.06);
  color: #4338ca;
  font-weight: 600;
  font-size: 11.5px;
  letter-spacing: 0;
  margin-right: 4px;
  white-space: nowrap;
  font-family: "DM Sans", system-ui, sans-serif;
  transition: background 140ms ease, border-color 140ms ease;
}
.composer-model-inline:hover {
  background: rgba(91, 77, 255, 0.10);
  border-color: rgba(91, 77, 255, 0.32);
}
.composer-model-inline::before {
  width: 7px; height: 7px;
  background: #5B4DFF;
  box-shadow: 0 0 6px rgba(91, 77, 255, 0.45);
}
@media (max-width: 600px) {
  .composer-model-inline { font-size: 10.5px; padding: 0 9px 0 8px; height: 24px; }
}

/* ---------- Modal (device-code login) ---------- */
.modal-backdrop {
  position: fixed; inset: 0;
  background: rgba(4, 6, 10, 0.7);
  backdrop-filter: blur(6px);
  display: grid; place-items: center;
  z-index: 50;
  animation: fadein 0.15s ease;
}
@keyframes fadein { from { opacity: 0; } to { opacity: 1; } }
.modal {
  width: min(460px, 92vw);
  background: linear-gradient(180deg, var(--panel) 0%, var(--bg-2) 100%);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 28px;
  box-shadow: var(--shadow);
  text-align: center;
  display: flex; flex-direction: column; gap: 12px;
}
.modal h3 { margin: 0; font-size: 18px; }
.modal-sub { margin: 0; color: var(--muted); font-size: 13px; }
.modal-hint { margin: 8px 0 0; color: var(--muted); font-size: 11px; }
.code-box {
  font-family: 'JetBrains Mono', monospace;
  font-size: 28px; font-weight: 700; letter-spacing: 6px;
  padding: 18px;
  background: rgba(72,69,255,0.08);
  border: 1px solid rgba(72,69,255,0.35);
  border-radius: 12px;
  color: var(--accent-soft);
  user-select: all;
}
.modal .btn { text-decoration: none; text-align: center; }

/* =================== Login page =================== */
.login-body {
  background: var(--bg-gradient), var(--bg);
}
/* ===== Brand lockup — Cars24 + APEX (used in login + topbars) ===== */
.brand-lockup {
  display: inline-flex; align-items: center; gap: 10px;
  color: var(--accent);
}
.bl-mark { display: inline-flex; line-height: 0; color: var(--accent); flex-shrink: 0; }
.bl-mark svg, .bl-mark img.bl-img { display: block; }
.bl-mark img.bl-img { object-fit: contain; width: auto; }
/* Default tenant lockup size (login hero) — full wordmark / mark image,
   height-locked. 80px so the customer's brand is unambiguously the hero;
   the dataeze mark next to it sits as 'partner' even when the tenant
   uploads a vertical crest-style logo (e.g. Red Mat Pilates) which would
   otherwise read as smaller than the wide dataeze wordmark. */
.bl-mark-c24 img.bl-img { height: 80px; max-width: 240px; }
.bl-mark-apex svg       { width: 32px; height: 32px; }
/* Same constraint when the platform mark is an <img> (dataeze PNG) instead
   of the original inline SVG. Without this the img renders at natural
   resolution and overflows the topbar. Two flavours:
   - Square icon-only (.bl-img alone): height-locked AND width-capped.
   - Full wordmark (.bl-img.bl-logo-full): height-locked, width auto so the
     wordmark can be as wide as it needs (aspect ~6:1). */
.bl-mark-apex img.bl-img             { height: 32px; max-width: 38px; }
.bl-mark-apex img.bl-img.bl-logo-full { height: 32px; max-width: none; width: auto; }
.bl-word {
  font-weight: 800; letter-spacing: -0.01em;
  color: var(--accent);
}
.bl-word-apex { font-size: 22px; letter-spacing: 0.01em; }
.bl-divider {
  width: 1px; height: 56px;
  background: var(--border);
  margin: 0 2px;
  flex-shrink: 0;
}
/* Compact variant — used in topbars. Bumped up so the wordmark is legible
   (the old 20px squashed the Cars24 logo into illegibility). */
.brand-lockup.bl-sm     { gap: 10px; }
.brand-lockup.bl-sm .bl-mark-c24 img.bl-img { height: 40px; max-width: 120px; }
.brand-lockup.bl-sm .bl-mark-apex svg { width: 22px; height: 22px; }
/* Compact-variant size for the dataeze <img> mark (topbar lockups).
   The full wordmark is wider (icon + 'dataeze.ai' text), so even at
   the same height as Phitku it feels visually heavier. Drop the
   wordmark height to 20px so it reads as 'partner mark' next to
   Phitku's 24px tenant brand, not dominant. */
.brand-lockup.bl-sm .bl-mark-apex img.bl-img             { height: 24px; max-width: 28px; }
.brand-lockup.bl-sm .bl-mark-apex img.bl-img.bl-logo-full { height: 20px; max-width: none; width: auto; }
.brand-lockup.bl-sm .bl-word-apex { font-size: 16px; }
.brand-lockup.bl-sm .bl-divider   { height: 32px; }

/* Text-mark fallback — used when a tenant has not uploaded a logo yet.
   Renders display_name as a styled wordmark so the co-brand still reads
   correctly (e.g. "Phitku × dataeze"). Replaced with an <img> the moment
   the super-admin uploads a logo via /admin → Tenants. */
.bl-mark-text {
  font-family: 'DM Sans', system-ui, sans-serif;
  font-weight: 800;
  letter-spacing: -0.01em;
  color: var(--accent);
  font-size: 22px;
  line-height: 1;
  padding: 4px 0;
}
.brand-lockup.bl-sm .bl-mark-text { font-size: 17px; }

/* Inline form hints used by the Tenants editor (and reusable elsewhere). */
.form-hint {
  margin: 4px 0 0;
  font-size: 11.5px;
  color: var(--muted);
  line-height: 1.45;
}

/* Tagline shown under the lockup on login + home */
.brand-tagline {
  font-size: 10.5px;
  letter-spacing: 0.18em;
  font-weight: 600;
  color: var(--muted);
  margin-top: 8px;
  text-align: center;
}

/* ===== Login page ===== */
.login-shell {
  min-height: 100vh;
  display: grid; place-items: center;
  padding: 24px;
}
/* Login card — enterprise-grade hero. Larger surface, deeper shadow,
   subtle gradient surround, generous padding, confident type hierarchy. */
.login-body {
  background:
    radial-gradient(ellipse at top left,  rgba(91,77,255,0.07), transparent 50%),
    radial-gradient(ellipse at bottom right, rgba(124,58,237,0.05), transparent 55%),
    #f8f9fc;
}
.login-card {
  width: min(440px, 100%);
  /* Gradient border via the padding-box / border-box trick: white surface
     sits on top, indigo→purple gradient peeks through the 2px transparent
     border. Plays nicely with border-radius (border-image does not). */
  background:
    linear-gradient(#ffffff, #ffffff) padding-box,
    linear-gradient(135deg, #5B4DFF 0%, #7C3AED 100%) border-box;
  border: 2px solid transparent;
  border-radius: 24px;
  padding: 56px 48px 44px;
  box-shadow:
    0 1px 2px rgba(15, 23, 42, 0.04),
    0 12px 32px rgba(91, 77, 255, 0.08),
    0 32px 64px rgba(15, 23, 42, 0.08);
  display: flex; flex-direction: column;
  align-items: center;
  text-align: center;
  position: relative;
}
/* Login brand lockup — Cars24 × APEX, sized as a partnership mark. Both
   sides read at the same height so neither dominates; the × is a soft
   light-gray separator (not a heavy vertical bar). */
.login-card .login-lockup {
  justify-content: center;
  align-items: center;
  margin: 0 0 28px;
  gap: 16px;
}
/* Login hero — combined max-widths must fit inside the card's inner
   content area (~344px on the 440px card minus 48px side padding):
     tenant 170 + gap 16 + divider 1 + dataeze 140 = 327px  ✓
   Two-axis cap with object-fit:contain handles any aspect ratio
   (tall crest, square mark, or wide horizontal wordmark) without
   ballooning. flex-shrink:0 on dataeze so the partner mark NEVER
   gets silently clipped if a tenant logo somehow exceeds its cap. */
.login-card .bl-mark-c24 img.bl-img {
  width: auto; height: auto;
  max-height: 80px; max-width: 170px;
  object-fit: contain;
  display: block;
}
.login-card .bl-mark-apex img.bl-img.bl-logo-full {
  width: auto; height: auto;
  max-height: 40px; max-width: 140px;
  object-fit: contain;
  flex-shrink: 0;
}
/* Lockup: keep marks on a single line. No overflow:hidden — if a
   tenant uploads an oversized image we'd rather show the overrun
   visibly so the operator sees + fixes it, vs silently clip dataeze. */
.login-card .login-lockup {
  max-width: 100%;
  flex-wrap: nowrap;
  gap: 14px;
}
.login-card .bl-x {
  font-size: 22px;
  font-weight: 300;
  color: rgba(15, 23, 42, 0.22);
  line-height: 1;
  user-select: none;
}
.login-card .bl-word-apex {
  font-size: 30px;
  font-weight: 800;
  letter-spacing: 0.01em;
  color: #5B4DFF;
  line-height: 1;
}
/* Heading — large, confident, single-line welcome. */
.login-h1 {
  margin: 0 0 8px;
  font-size: 22px;
  font-weight: 700;
  letter-spacing: -0.012em;
  color: #0f172a;
}
/* Subtitle — calm, single sentence; sets up the Google button below. */
.login-sub {
  margin: 0 0 28px;
  color: rgba(15, 23, 42, 0.58);
  font-size: 14.5px;
  line-height: 1.5;
  font-weight: 400;
}
.login-sub-em { color: #0f172a; font-weight: 600; }
/* Google Sign-In wrap — full-width container, GIS button centred. */
.google-signin-wrap { width: 100%; padding: 4px 0 8px; }
.google-signin-wrap > div { max-width: 100%; display: flex !important; justify-content: center; }
/* Faint footer line for trust signals (added by JS below, optional). */
.login-card .login-foot {
  margin-top: 20px;
  font-size: 11.5px; color: rgba(15, 23, 42, 0.40);
  letter-spacing: 0.02em;
}
.login-sub-em { color: var(--text); }

/* Google-style account pill (visual stand-in — local password under the hood) */
.g-pill {
  appearance: none;
  display: flex; align-items: center; gap: 12px;
  width: 100%;
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 10px 14px 10px 8px;
  cursor: pointer;
  font-family: inherit;
  transition: background 0.15s ease, border-color 0.15s ease, box-shadow 0.2s ease;
}
.g-pill:hover {
  background: var(--surface-hover);
  border-color: var(--btn-ghost-hover-border);
  box-shadow: 0 2px 10px rgba(15,17,30,0.06);
}
.g-avatar {
  width: 32px; height: 32px;
  border-radius: 50%;
  background: linear-gradient(135deg, #16a34a 0%, #22c55e 100%);
  color: #fff;
  display: grid; place-items: center;
  font-weight: 700; font-size: 14px;
  flex-shrink: 0;
}
.g-text {
  flex: 1;
  display: flex; flex-direction: column;
  text-align: left;
  min-width: 0;
}
.g-text-line1 {
  font-size: 13.5px; font-weight: 500;
  color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.g-text-line2 {
  font-size: 11.5px; color: var(--muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.g-logo { display: inline-flex; flex-shrink: 0; }

.login-disclose {
  appearance: none; border: 0; background: transparent;
  color: var(--muted);
  cursor: pointer;
  font-family: inherit; font-size: 12.5px;
  margin-top: 18px;
  display: inline-flex; align-items: center; gap: 5px;
  padding: 4px 6px;
  border-radius: 6px;
}
.login-disclose:hover { color: var(--text); }
.login-disclose svg { transition: transform 0.2s ease; }
.login-disclose.expanded svg { transform: rotate(180deg); }

.login-form {
  width: 100%;
  display: flex; flex-direction: column; gap: 12px;
  margin-top: 14px;
  text-align: left;
}
.login-field { display: flex; flex-direction: column; gap: 6px; }
.login-field span {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--muted);
  font-weight: 500;
}
.login-field input {
  background: var(--input-bg);
  border: 1px solid var(--border);
  border-radius: 9px;
  padding: 11px 13px;
  color: var(--text);
  font-family: inherit;
  font-size: 14px;
  outline: none;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.login-field input:focus {
  border-color: rgba(72,69,255,0.55);
  box-shadow: 0 0 0 3px rgba(72,69,255,0.18);
}
.login-error {
  font-size: 13px;
  color: var(--danger-soft);
  background: rgba(248,113,113,0.08);
  border: 1px solid rgba(248,113,113,0.30);
  padding: 8px 12px;
  border-radius: 8px;
}
.login-submit {
  margin-top: 6px;
  padding: 12px;
  font-size: 14px;
}

/* =================== Popovers (workspace / dataset / model) =================== */
.popover {
  position: fixed;
  z-index: 1000;
  width: 320px;
  max-height: 420px;
  display: flex; flex-direction: column;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: 0 16px 44px rgba(0,0,0,0.55);
  overflow: hidden;
}
/* Compact variant — used for short action menus (e.g. the session row's
   kebab). Sizes to its content within sane bounds; no fixed 320px slab. */
.popover.popover-compact {
  width: auto;
  min-width: 168px;
  max-width: 240px;
  max-height: none;
}
.popover.popover-compact .popover-body { padding: 6px; }
.popover.popover-compact .popover-item { padding: 8px 10px; }
.popover-head {
  padding: 8px;
  border-bottom: 1px solid var(--border);
  background: var(--bg-2);
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.popover-title {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--muted);
  padding: 2px 4px;
}
.popover-search {
  width: 100%;
  background: var(--surface-inset);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 6px 10px;
  color: var(--text);
  font-size: 12px;
  outline: none;
  font-family: inherit;
}
.popover-search:focus { border-color: rgba(72,69,255,0.45); }
.popover-toolbar {
  display: flex; align-items: center; gap: 6px;
  padding: 0 4px;
}
.popover-count {
  flex: 1;
  font-size: 10.5px;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.popover-tool-btn {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text-soft);
  font-size: 10.5px;
  font-weight: 500;
  padding: 3px 8px;
  border-radius: 6px;
  cursor: pointer;
  font-family: inherit;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.popover-tool-btn:hover {
  background: rgba(72,69,255,0.10);
  border-color: rgba(72,69,255,0.35);
  color: var(--accent-soft);
}
.popover-body {
  overflow-y: auto;
  padding: 4px;
  display: flex; flex-direction: column; gap: 2px;
}
.popover-body::-webkit-scrollbar { width: 6px; }
.popover-body::-webkit-scrollbar-thumb { background: var(--surface-strong); border-radius: 3px; }
.popover-body .empty { padding: 14px; }

.popover-item {
  display: flex; align-items: center; gap: 8px;
  width: 100%;
  background: transparent;
  border: 1px solid transparent;
  padding: 7px 10px;
  border-radius: 6px;
  font-size: 13px;
  color: var(--text);
  cursor: pointer;
  text-align: left;
}
.popover-item:hover {
  background: rgba(72,69,255,0.10);
  border-color: rgba(72,69,255,0.20);
}
.popover-item.active {
  background: rgba(72,69,255,0.15);
  border-color: rgba(72,69,255,0.40);
  color: var(--text-strong);
}
.popover-item .nm {
  flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-family: 'DM Sans', 'Inter', sans-serif;
}
.popover-item .tag {
  font-size: 9.5px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--success-soft);
  border: 1px solid rgba(80,200,120,0.35);
  background: rgba(80,200,120,0.08);
  padding: 1px 6px;
  border-radius: 999px;
}

/* multi-select checkbox in popover */
.popover-item .ds-checkbox {
  width: 14px; height: 14px;
  border: 1.5px solid var(--border);
  border-radius: 3px;
  flex-shrink: 0;
  background: var(--surface-inset);
  position: relative;
  transition: all 0.15s ease;
}
.popover-item:hover .ds-checkbox { border-color: rgba(72,69,255,0.5); }
.popover-item.active .ds-checkbox {
  background: var(--accent); border-color: var(--accent);
}
.popover-item.active .ds-checkbox::after {
  content: "";
  position: absolute;
  left: 3px; top: 0px;
  width: 4px; height: 8px;
  border: solid var(--on-accent);
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}

/* =================== Brand link (topbar back-to-home) =================== */
.brand-link {
  text-decoration: none;
  color: inherit;
  cursor: pointer;
  border-radius: 8px;
  padding: 4px 6px;
  transition: background 0.15s ease;
}
.brand-link:hover { background: var(--surface-hover); }

/* =================== Home (post-login landing) =================== */
body.home-body {
  margin: 0;
  background: var(--bg-1);
  color: var(--text);
  font-family: 'DM Sans', 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
  min-height: 100vh;
  display: flex; flex-direction: column;
}
.home-topbar {
  display: flex; align-items: center; gap: 12px;
  padding: 14px 22px;
  border-bottom: 1px solid var(--border);
  background: var(--bg-2);
}
.home-spacer { flex: 1; }
.home-brand {
  display: flex; align-items: center; gap: 10px;
  font-weight: 700; font-size: 14px;
  letter-spacing: -0.005em;
}
.home-brand .brand-logo {
  width: 32px; height: 32px;
  border-radius: 8px;
  display: grid; place-items: center;
  background: linear-gradient(135deg, #4845ff 0%, #7a5cff 100%);
  color: #fff;
}

.home-main {
  flex: 1;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  padding: 40px 24px 80px;
}
.home-hero {
  text-align: center;
  margin-bottom: 36px;
  display: flex; flex-direction: column; align-items: center;
}
.home-hero-brand {
  display: inline-flex; align-items: center; gap: 10px;
  margin-bottom: 18px;
  color: var(--accent);
  font-weight: 800;
  letter-spacing: 0.18em;
  font-size: 15px;
  text-transform: uppercase;
}
.home-hero-mark {
  display: inline-grid; place-items: center;
  color: var(--accent);
  line-height: 0;
}
/* Hero icon when rendered as <img> (dataeze PNG). Same size as the inline
   SVG it replaced (32×32) so the hero lockup keeps its proportions. */
.home-hero-mark img { width: 32px; height: 32px; object-fit: contain; display: block; }
.home-hero-mark svg { display: block; }
.home-hero-word {
  color: var(--text-strong, var(--text));
  letter-spacing: 0.22em;
}
.home-hero h1 {
  font-size: 44px; font-weight: 800;
  margin: 0 0 10px;
  letter-spacing: -0.025em;
  line-height: 1.1;
}
.home-sub {
  margin: 0;
  color: var(--muted);
  font-size: 17px;
}
.home-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 400px));
  gap: 28px;
  width: 100%;
  max-width: 880px;
  justify-content: center;
}
/* Hero cards — large surface, confident shadow, gradient top stripe in the
   tenant accent so each card has a visible identity strip even before the
   icon. Card titles are 26px (was 17px) so they read as the primary
   call-to-action; descriptions are 16px with stronger contrast (was 13px,
   muted). Padding bumped to 36px so the content has room to breathe. */
.home-card {
  display: flex; flex-direction: column;
  gap: 14px;
  padding: 38px 34px 30px;
  background: #ffffff;
  border: 1px solid rgba(15, 23, 42, 0.06);
  border-radius: 22px;
  text-decoration: none;
  color: var(--text);
  cursor: pointer;
  transition: transform 0.18s ease, border-color 0.18s ease, box-shadow 0.22s ease;
  position: relative;
  overflow: hidden;
  box-shadow:
    0 1px 2px rgba(15, 23, 42, 0.04),
    0 8px 24px rgba(15, 23, 42, 0.05);
}
/* Top accent stripe — tenant brand colour, 4px tall. Visible even before
   the user looks at the icon, gives the card a 'product chip' identity. */
.home-card::after {
  content: "";
  position: absolute; top: 0; left: 0; right: 0;
  height: 4px;
  background: linear-gradient(90deg, var(--accent) 0%, var(--accent-2, var(--accent)) 100%);
  border-radius: 22px 22px 0 0;
  opacity: 0.95;
}
.home-card::before {
  content: "";
  position: absolute; inset: 0;
  background: radial-gradient(600px circle at 0% 0%, rgba(72,69,255,0.08), transparent 50%);
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.2s ease;
}
.home-card:hover {
  transform: translateY(-4px);
  border-color: rgba(72,69,255,0.30);
  box-shadow:
    0 1px 2px rgba(15, 23, 42, 0.04),
    0 18px 44px rgba(72, 69, 255, 0.14),
    0 8px 16px rgba(15, 23, 42, 0.06);
}
.home-card:hover::before { opacity: 1; }
/* Icon chip — bigger surface (72px) so the iconography has presence. */
.home-card-icon {
  width: 72px; height: 72px;
  border-radius: 16px;
  display: grid; place-items: center;
  margin-bottom: 10px;
  color: #fff;
}
/* Both card icons sit directly on the card surface — no coloured chip
   behind them. Power BI logo and dataeze 'dE' mark already have their
   own colour identity; a chip just adds noise. Match the Power BI
   treatment for visual consistency. */
.home-card-icon.icon-bi { background: transparent; padding: 0; color: var(--accent); }
.home-card-icon.icon-ai { background: transparent; padding: 0; }
.home-card-img { display: block; object-fit: contain; }

/* Live-data indicator: small green dot pinned to the top-right of the
   Live Dashboards icon, with a breathing pulse so it visibly signals
   'real-time'. ~2s breath cycle is unobtrusive but legible. */
.icon-bi .live-dot {
  position: absolute;
  top: 4px; right: 4px;
  width: 12px; height: 12px;
  border-radius: 50%;
  background: #22c55e;
  box-shadow: 0 0 0 2.5px #fff, 0 0 0 5px rgba(34, 197, 94, 0.20);
  animation: live-pulse 2s ease-in-out infinite;
}
@keyframes live-pulse {
  0%, 100% { box-shadow: 0 0 0 2px #fff, 0 0 0 4px rgba(34, 197, 94, 0.18); }
  50%      { box-shadow: 0 0 0 2px #fff, 0 0 0 7px rgba(34, 197, 94, 0.05); }
}
.home-card-letter {
  font-weight: 800;
  font-size: 32px;
  line-height: 1;
  color: #fff;
  letter-spacing: -0.02em;
}
/* Card type — hero-grade. Titles read as the primary action, descriptions
   keep the dataeze.ai copy voice (punchy, declarative) at a size that's
   readable at arm's length, not 'fine print'. */
.home-card-title {
  font-size: 26px; font-weight: 800;
  letter-spacing: -0.02em;
  line-height: 1.15;
  color: var(--text-strong, var(--text));
}
.home-card-desc {
  font-size: 16px;
  color: rgba(15, 23, 42, 0.72);
  line-height: 1.5;
  flex: 1;
  font-weight: 400;
}
.home-card-cta {
  font-size: 14.5px; font-weight: 700;
  color: var(--accent); letter-spacing: 0.005em;
  margin-top: 14px;
  display: inline-flex; align-items: center; gap: 6px;
}

/* =================== Dashboards page =================== */
body.dash-body {
  margin: 0;
  background: var(--bg-1);
  color: var(--text);
  font-family: 'DM Sans', 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
  /* lock to viewport so the page itself never scrolls — the embed iframe
   * and the sidebar tree are the only scroll surfaces */
  height: 100vh;
  overflow: hidden;
  display: grid;
  grid-template-columns: var(--dash-side-w, 280px) 1fr;
  grid-template-rows: 56px 1fr;
  grid-template-areas:
    "topbar topbar"
    "sidebar main";
}
body.dash-body > .topbar { grid-area: topbar; }
body.dash-body.dash-sidebar-collapsed {
  grid-template-columns: 0 1fr;
}
body.dash-body.dash-sidebar-collapsed .dash-sidebar { display: none; }

.dash-sidebar {
  grid-area: sidebar;
  border-right: 1px solid var(--border);
  background: var(--bg-2);
  display: flex; flex-direction: column;
  min-height: 0;
  overflow: hidden;
  position: relative;       /* anchor for the resize handle */
}
.dash-side-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 12px 14px 8px;
}
.dash-side-title {
  font-size: 11px; text-transform: uppercase;
  letter-spacing: 0.06em; color: var(--muted);
  font-weight: 600;
}
.dash-side-search {
  display: flex; align-items: center; gap: 8px;
  padding: 0 12px 10px;
  border-bottom: 1px solid var(--border);
}
.dash-side-search svg { color: var(--muted); flex-shrink: 0; }
.dash-side-search input {
  flex: 1;
  appearance: none; border: 0;
  background: var(--bg-1);
  border: 1px solid var(--border);
  border-radius: 7px;
  padding: 7px 9px;
  font: inherit; font-size: 12px;
  color: var(--text);
  outline: none;
}
.dash-side-search input:focus { border-color: rgba(72,69,255,0.45); }
.dash-side-scroll {
  flex: 1;
  overflow-y: auto;
  padding: 6px 6px 16px;
}
.ws-node { display: flex; flex-direction: column; }
.ws-row {
  display: flex; align-items: center; gap: 7px;
  appearance: none; border: 0; cursor: pointer;
  padding: 7px 9px;
  width: 100%;
  background: transparent;
  color: var(--text);
  font: inherit; font-size: 13px;
  border-radius: 7px;
  text-align: left;
  font-family: inherit;
}
.ws-row:hover { background: var(--surface-hover); }
.ws-caret { color: var(--muted); width: 10px; font-size: 9px; flex-shrink: 0; }
.ws-icon { color: var(--accent-soft); flex-shrink: 0; }
.ws-name { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; flex: 1; }
.ws-children { padding-left: 18px; display: flex; flex-direction: column; gap: 1px; padding-bottom: 6px; }
.rpt-row {
  display: flex; align-items: center; gap: 7px;
  appearance: none; border: 0; cursor: pointer;
  padding: 6px 8px 6px 14px;
  width: 100%;
  background: transparent;
  color: var(--text);
  font: inherit; font-size: 12.5px;
  border-radius: 6px;
  text-align: left;
  font-family: inherit;
}
.rpt-row:hover { background: var(--surface-hover); }
.rpt-row.active { background: rgba(72,69,255,0.16); color: var(--text-strong); }
.rpt-icon { color: var(--muted); flex-shrink: 0; }
.rpt-name { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; flex: 1; }
.rpt-loading, .rpt-empty, .rpt-error {
  font-size: 11.5px; color: var(--muted);
  padding: 6px 14px;
  font-style: italic;
}
.rpt-error { color: var(--danger-soft); }

.dash-main {
  grid-area: main;
  min-height: 0;
  display: flex; flex-direction: column;
  overflow: hidden;
}
.dash-empty {
  flex: 1;
  display: flex; align-items: center; justify-content: center;
  padding: 24px;
}
.dash-empty-card {
  text-align: center;
  max-width: 460px;
}
.dash-empty-icon {
  width: 76px; height: 76px;
  border-radius: 18px;
  background: rgba(72,69,255,0.12);
  border: 1px solid rgba(72,69,255,0.30);
  display: grid; place-items: center;
  color: var(--accent-soft);
  margin: 0 auto 18px;
}
.dash-empty-card h2 { margin: 0 0 8px; font-size: 22px; }
.dash-empty-card p { color: var(--muted); margin: 0; line-height: 1.6; font-size: 13.5px; }

/* The embed surface always renders in a LIGHT canvas regardless of the app
 * theme. Power BI reports are designed for white backgrounds, and showing
 * them on a near-black panel produces hard borders + flicker on rerender.
 * We isolate the embed area with explicit light tokens, then make it
 * edge-to-edge so Power BI's own chrome (titles, filters, page nav) is the
 * only chrome the user sees — no nested header / shadow / margin.
 */
.dash-embed-wrap {
  flex: 1;
  display: flex; flex-direction: column;
  min-height: 0;
  /* light token island */
  --embed-surface: #ffffff;
  --embed-border:  #e3e6ee;
  --embed-text:    #15171d;
  --embed-muted:   #5b6273;
  --embed-soft:    #f6f8fc;
  background: var(--embed-surface);
  color: var(--embed-text);
  overflow: hidden;
  border-top: 1px solid var(--embed-border);
}

/* Thin breadcrumb above the report — workspace · report. No box-shadow,
 * no extra padding; sits flush with the report iframe below. */
.dash-embed-head {
  display: flex; align-items: center; gap: 6px;
  padding: 7px 16px;
  border-bottom: 1px solid var(--embed-border);
  background: linear-gradient(180deg, #fbfcfe 0%, var(--embed-soft) 100%);
  font-size: 12px;
  line-height: 1.3;
}
.dash-embed-sub {
  color: var(--embed-muted);
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.dash-embed-sub:not(:empty)::after {
  content: "›";
  margin: 0 8px;
  color: var(--embed-muted);
  opacity: 0.55;
  font-weight: 600;
}
.dash-embed-title {
  color: var(--embed-text);
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  flex: 1;
}

.dash-embed-frame {
  flex: 1;
  min-height: 0;
  overflow: hidden;
  background: var(--embed-surface);
  position: relative;
}
.dash-embed-frame iframe {
  border: 0;
  width: 100%;
  height: 100%;
  display: block;
}

/* Fullscreen: the browser paints `:fullscreen` elements on a default BLACK
 * canvas. Force white so the report keeps its native light look — whether
 * the wrap, the frame, or the iframe itself is the fullscreen target. */
.dash-embed-wrap:fullscreen,
.dash-embed-wrap:-webkit-full-screen,
.dash-embed-frame:fullscreen,
.dash-embed-frame:-webkit-full-screen {
  background: #ffffff;
  width: 100vw;
  height: 100vh;
  padding: 0;
  margin: 0;
}
.dash-embed-wrap:fullscreen .dash-embed-head,
.dash-embed-wrap:-webkit-full-screen .dash-embed-head {
  /* Hide our breadcrumb in fullscreen — Power BI's own header is enough. */
  display: none;
}
.dash-embed-wrap:fullscreen .dash-embed-frame,
.dash-embed-wrap:-webkit-full-screen .dash-embed-frame {
  background: #ffffff;
  border: 0;
  height: 100vh;
}
iframe:fullscreen,
iframe:-webkit-full-screen {
  background: #ffffff !important;
}
/* Backdrop pseudo (the area behind a fullscreen element on some browsers). */
.dash-embed-wrap::backdrop,
.dash-embed-frame::backdrop,
iframe::backdrop {
  background: #ffffff;
}
.dash-embed-frame iframe { border: 0; width: 100%; height: 100%; display: block; }
.embed-loading, .embed-error {
  position: absolute; inset: 0;
  display: grid; place-items: center;
  padding: 28px;
  text-align: center;
  color: var(--muted);
  font-size: 13px;
}
.embed-error { color: var(--danger-soft); }
.embed-error-hint {
  display: block;
  color: var(--muted);
  font-size: 11.5px;
  margin-top: 10px;
  font-style: italic;
}

.dash-toolbar {
  display: flex; align-items: center; gap: 8px;
  margin-right: 6px;
}

/* Bookmarks popover list — width hugs the longest row (bookmark name +
   timestamp + chip + kebab) so a list of short names doesn't waste a
   wide column, and a long name doesn't get truncated. We bound it on
   both ends: a min so headings + the empty state always look right, and
   a max tied to viewport width on small screens. */
.bookmarks-pop {
  width: max-content;
  min-width: 280px;
  max-width: min(460px, calc(100vw - 32px));
}
.bm-name-text {
  /* Pair with the 18-char input cap (see saveCurrentAsBookmark / rename
     in dashboards.js). Anything longer is truncated visually too — defence
     in depth in case an older long-named row is still around. */
  max-width: 220px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.bm-list { display: flex; flex-direction: column; gap: 1px; }
.bm-item {
  display: flex; align-items: center; gap: 4px;
  padding: 0 4px 0 0;
  border-radius: 7px;
  transition: background 0.15s ease;
}
.bm-item:hover { background: var(--surface-hover); }
.bm-apply {
  flex: 1;
  appearance: none; border: 0;
  background: transparent;
  cursor: pointer;
  display: flex; flex-direction: column;
  align-items: flex-start; gap: 2px;
  padding: 8px 10px;
  font: inherit;
  color: var(--text);
  text-align: left;
  border-radius: 7px;
}
.bm-name {
  font-size: 13px; font-weight: 500;
  display: inline-flex; align-items: center; gap: 6px;
  flex-wrap: wrap;
}
.bm-name-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bm-ts { font-size: 11px; color: var(--muted); }

/* Single kebab button replacing the four legacy action icons. SVG fill is
   applied to the dots directly so it survives any container hover-color
   changes (we hit this exact bug on the chat-session kebab earlier). */
.bm-kebab {
  color: var(--muted);
  width: 26px; height: 26px;
  border-radius: 6px;
  display: inline-flex; align-items: center; justify-content: center;
  flex-shrink: 0;
  background: transparent;
  border: 0;
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.12s ease, background 0.12s ease, color 0.12s ease;
}
.bm-item:hover .bm-kebab,
.bm-kebab.is-open { opacity: 1; }
.bm-kebab:hover { color: var(--accent); background: rgba(72,69,255,0.10); }
.bm-kebab svg circle { fill: currentColor; }

/* On touch devices (no hover state) the kebab must be visible by default. */
@media (hover: none) {
  .bm-kebab { opacity: 1; }
}

/* Inline shared-with-N chip — replaces the badge that used to sit on the
   share icon button. Compact pill near the bookmark name, only when count > 0. */
.bm-share-chip {
  display: inline-flex; align-items: center; gap: 3px;
  padding: 1px 7px 1px 5px;
  border-radius: 999px;
  background: rgba(72,69,255,0.12);
  color: var(--accent);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.02em;
  font-variant-numeric: tabular-nums;
}
.bm-share-chip svg { display: block; }

.bm-shared-tag {
  display: inline-block;
  padding: 0 6px;
  font-size: 10px;
  font-weight: 600;
  color: var(--accent);
  background: rgba(72,69,255,0.12);
  border-radius: 4px;
  vertical-align: middle;
}
.bm-item.is-shared .bm-name { font-weight: 500; }

/* ----- Kebab popover menu (Share / Update / Rename / Delete) -----
 * Independent of the parent bookmarks popover so it can float over the
 * top-right corner of the row without inheriting padding or scroll
 * containment. Style mirrors the chat-session kebab menu in app.js so
 * the two interactions feel identical. */
.bm-kebab-menu {
  position: fixed;
  z-index: 10001;
  min-width: 200px;
  padding: 6px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: var(--shadow);
  display: flex; flex-direction: column;
  gap: 1px;
  animation: bmKebabIn 0.12s ease;
}
@keyframes bmKebabIn {
  from { opacity: 0; transform: translateY(-2px); }
  to   { opacity: 1; transform: translateY(0); }
}
.bm-kebab-item {
  display: flex; align-items: center; gap: 10px;
  appearance: none;
  background: transparent;
  border: 0;
  padding: 8px 10px;
  border-radius: 7px;
  font: inherit;
  font-size: 13px;
  color: var(--text);
  text-align: left;
  cursor: pointer;
  transition: background 0.1s ease, color 0.1s ease;
}
.bm-kebab-item:hover {
  background: var(--surface-hover);
  color: var(--accent);
}
.bm-kebab-item svg { flex-shrink: 0; color: currentColor; }
.bm-kebab-sep {
  height: 1px;
  background: var(--border);
  margin: 4px 2px;
}
.bm-kebab-danger { color: var(--bad, #ef4444); }
.bm-kebab-danger:hover {
  background: rgba(239,68,68,0.10);
  color: var(--bad, #ef4444);
}

/* ===== Bookmark share modal ===== */
.bm-share-modal { width: min(440px, 92vw); }
.bm-share-help {
  margin: 0 0 12px;
  font-size: 12.5px;
  color: var(--muted);
  line-height: 1.5;
}
.bm-share-search {
  width: 100%;
  padding: 8px 10px;
  background: var(--input-bg);
  border: 1px solid var(--border);
  border-radius: 8px;
  color: var(--text);
  font-size: 13px;
  margin-bottom: 8px;
}
.bm-share-search::placeholder { color: var(--placeholder); }
.bm-share-list {
  max-height: 320px;
  overflow-y: auto;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface-deep);
}
.bm-share-row {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 12px;
  border-bottom: 1px solid var(--border);
  cursor: pointer;
}
.bm-share-row:last-child { border-bottom: 0; }
.bm-share-row:hover { background: var(--surface-hover); }
.bm-share-row input[type="checkbox"] { flex-shrink: 0; }
.bm-share-meta { display: flex; flex-direction: column; gap: 2px; }
.bm-share-name { font-weight: 600; color: var(--text); font-size: 13px; }
.bm-share-sub  { font-size: 11.5px; color: var(--muted); }

/* ===== Feedback row on assistant turns ===== */
.feedback-row {
  display: flex; align-items: center; gap: 8px;
  margin-top: 10px;
  padding: 6px 0 0;
  border-top: 1px dashed var(--border);
  font-size: 12px;
  color: var(--muted);
  flex-wrap: wrap;
}
.feedback-label { font-weight: 500; }
.feedback-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px;
  border: 1px solid var(--border);
  background: transparent;
  color: var(--muted);
  border-radius: 6px;
  cursor: pointer;
  transition: color 0.12s ease, background 0.12s ease, border-color 0.12s ease;
}
.feedback-btn:hover { color: var(--accent); border-color: var(--accent); }
.feedback-btn.active { color: var(--on-accent); background: var(--accent); border-color: var(--accent); }
.fb-down.active { background: var(--bad); border-color: var(--bad); }
.feedback-comment {
  flex: 1; min-width: 200px;
  padding: 5px 9px;
  background: var(--input-bg);
  border: 1px solid var(--border);
  border-radius: 6px;
  color: var(--text);
  font-size: 12px;
  font-family: inherit;
}
.feedback-comment::placeholder { color: var(--placeholder); }
.feedback-status {
  font-size: 11px; color: var(--muted);
  font-style: italic;
  min-width: 40px;
}

/* ===== Profile pop "Admin console" link sits in the same actions stack ===== */
a.profile-pop-action { text-decoration: none; }

/* ============================================================
 * Admin console — left-rail navigation + polished page surfaces.
 * Uses the same Cars24 tokens as the analyst app (`--accent`,
 * `--panel`, `--border`, etc.) for visual continuity.
 * ============================================================ */
.admin-body {
  background: var(--bg);
  background-image: var(--bg-gradient);
  min-height: 100vh;
  margin: 0;
  color: var(--text);
  font-family: 'DM Sans', 'Inter', system-ui, -apple-system, sans-serif;
}
.admin-topbar {
  display: flex; align-items: center; gap: 14px;
  padding: 12px 22px;
  border-bottom: 1px solid var(--border);
  background: var(--topbar-bg);
  backdrop-filter: blur(10px);
  position: sticky; top: 0;
  z-index: 20;
}
.admin-topbar-title {
  font-size: 13px;
  letter-spacing: 0.06em;
  font-weight: 700;
  text-transform: uppercase;
  color: var(--muted);
  padding-left: 12px;
  border-left: 1px solid var(--border);
}

/* ----- Shell: left rail + main content ----- */
.admin-shell {
  display: grid;
  grid-template-columns: 240px 1fr;
  min-height: calc(100vh - 60px);
  align-items: stretch;
}

.admin-rail {
  border-right: 1px solid var(--border);
  background: linear-gradient(180deg, var(--panel) 0%, var(--bg-2) 100%);
  padding: 18px 12px 32px;
  display: flex; flex-direction: column;
  gap: 18px;
  position: sticky;
  top: 60px;
  height: calc(100vh - 60px);
  overflow-y: auto;
}
.admin-rail-section {
  display: flex; flex-direction: column;
  gap: 2px;
}
.admin-rail-section-label {
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: var(--muted);
  padding: 4px 10px 8px;
}
.admin-tab {
  appearance: none;
  display: flex; align-items: center; gap: 10px;
  width: 100%;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 9px;
  padding: 9px 11px;
  font-size: 13px;
  font-weight: 500;
  color: var(--text-soft);
  cursor: pointer;
  font-family: inherit;
  text-align: left;
  position: relative;
  transition: background 0.12s ease, color 0.12s ease, border-color 0.12s ease;
}
.admin-tab .admin-tab-icon { color: var(--muted); flex-shrink: 0; }
.admin-tab .admin-tab-label { flex: 1; }
.admin-tab .admin-tab-count {
  display: none;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.02em;
  background: rgba(72,69,255,0.10);
  color: var(--accent);
  padding: 2px 7px;
  border-radius: 999px;
  min-width: 20px;
  text-align: center;
}
.admin-tab .admin-tab-count:not(:empty) { display: inline-flex; align-items: center; justify-content: center; }
.admin-tab:hover {
  background: rgba(72,69,255,0.06);
  color: var(--text);
}
.admin-tab:hover .admin-tab-icon { color: var(--accent); }
.admin-tab.active {
  background: rgba(72,69,255,0.10);
  border-color: rgba(72,69,255,0.25);
  color: var(--accent);
  font-weight: 600;
}
.admin-tab.active .admin-tab-icon { color: var(--accent); }
.admin-tab.active::before {
  content: "";
  position: absolute;
  left: -12px; top: 8px; bottom: 8px;
  width: 3px;
  border-radius: 0 3px 3px 0;
  background: var(--accent-grad);
}

/* ----- Main content area ----- */
.admin-main {
  max-width: 1180px;
  width: 100%;
  margin: 0 auto;
  padding: 28px 32px 64px;
}
.admin-pane.hidden { display: none; }

/* ----- Page header (title + subtitle + actions) ----- */
.admin-page-head {
  display: flex; align-items: flex-start; gap: 24px;
  margin-bottom: 22px;
  padding-bottom: 18px;
  border-bottom: 1px solid var(--border);
}
.admin-page-title { flex: 1; min-width: 0; }
.admin-page-title h2 {
  margin: 0 0 6px;
  font-size: 22px;
  font-weight: 700;
  letter-spacing: -0.012em;
  color: var(--text-strong);
}
.admin-page-sub {
  margin: 0;
  font-size: 13px;
  line-height: 1.55;
  color: var(--text-soft);
  max-width: 70ch;
}
.admin-page-sub code {
  background: var(--code-bg);
  border: 1px solid var(--border);
  padding: 1px 6px;
  border-radius: 5px;
  font-size: 11.5px;
  font-family: 'JetBrains Mono', monospace;
  color: var(--accent-soft);
}
.admin-page-sub strong { color: var(--text-strong); font-weight: 600; }
.admin-page-actions {
  display: flex; align-items: center; gap: 8px;
  flex-shrink: 0;
}
.admin-page-actions-row { flex-wrap: wrap; justify-content: flex-end; }
.admin-page-foot {
  display: flex; align-items: center; gap: 14px;
  margin-top: 18px;
  padding: 14px 18px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 10px;
  justify-content: flex-end;
  position: sticky;
  bottom: 16px;
  box-shadow: 0 6px 20px rgba(15, 17, 30, 0.06);
}

/* ----- Cards & form surfaces ----- */
.admin-card {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: 0 4px 18px rgba(15, 17, 30, 0.04);
}
.admin-card-soft {
  padding: 18px;
}
.admin-status {
  font-size: 12.5px;
  color: var(--muted);
  flex: 1;
}

/* ----- Form controls ----- */
.admin-select {
  padding: 8px 30px 8px 12px;
  background: var(--input-bg);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 8px;
  font-size: 13px;
  font-family: inherit;
  cursor: pointer;
  transition: border-color 0.12s ease, box-shadow 0.12s ease;
  appearance: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%235b6273' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>");
  background-repeat: no-repeat;
  background-position: right 9px center;
}
.admin-select:hover { border-color: rgba(72,69,255,0.35); }
.admin-select:focus {
  outline: none;
  border-color: rgba(72,69,255,0.55);
  box-shadow: 0 0 0 3px rgba(72,69,255,0.15);
}

/* ----- Table styling ----- */
.admin-table-wrap {
  overflow: hidden;            /* clip rounded corners cleanly */
}
.admin-table-wrap > table { border-collapse: separate; border-spacing: 0; }
.admin-table {
  width: 100%;
  font-size: 13px;
  font-variant-numeric: tabular-nums;
}
.admin-table th, .admin-table td {
  text-align: left;
  padding: 12px 16px;
  border-bottom: 1px solid var(--border);
  vertical-align: middle;
}
.admin-table thead th {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--muted);
  background: var(--bg-2);
  border-bottom: 1px solid var(--border);
  position: sticky; top: 0;
}
.admin-table tbody tr:last-child td { border-bottom: 0; }
.admin-table tbody tr {
  transition: background 0.1s ease;
}
.admin-table tbody tr:hover { background: rgba(72,69,255,0.03); }
.admin-table .col-actions { white-space: nowrap; text-align: right; }
.admin-table .empty { text-align: center; color: var(--muted); padding: 32px 16px; }
.admin-table .cell-wrap { max-width: 360px; white-space: pre-wrap; word-break: break-word; }

/* ----- Empty state with icon ----- */
.admin-empty {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 10px;
  padding: 36px 16px;
  color: var(--muted);
  text-align: center;
}
.admin-empty svg { color: var(--muted); opacity: 0.55; }
.admin-empty p { margin: 0; font-size: 13.5px; max-width: 50ch; }

/* ----- Mobile / narrow viewport ----- */
@media (max-width: 840px) {
  .admin-shell { grid-template-columns: 1fr; }
  .admin-rail {
    position: static; height: auto;
    flex-direction: row; flex-wrap: wrap;
    padding: 10px 12px;
    border-right: 0; border-bottom: 1px solid var(--border);
  }
  .admin-rail-section { flex-direction: row; flex: 1; }
  .admin-rail-section-label { display: none; }
  .admin-tab.active::before { display: none; }
  .admin-main { padding: 20px 16px 48px; }
  .admin-page-head { flex-direction: column; gap: 14px; }
  .admin-page-actions { width: 100%; flex-wrap: wrap; }
}
.role-badge {
  display: inline-block;
  padding: 1px 8px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.03em;
}
.role-admin { background: rgba(72,69,255,0.14); color: var(--accent); }
.role-user  { background: var(--surface-hover); color: var(--text); }
.disabled-badge {
  display: inline-block;
  padding: 1px 7px;
  border-radius: 999px;
  font-size: 10px; font-weight: 700;
  background: rgba(239,68,68,0.12);
  color: var(--danger-soft);
}
.enabled-badge {
  display: inline-block;
  padding: 1px 7px;
  border-radius: 999px;
  font-size: 10px; font-weight: 700;
  background: rgba(34,197,94,0.10);
  color: var(--success-soft);
}
.reset-badge {
  display: inline-block;
  padding: 1px 7px;
  border-radius: 999px;
  font-size: 10px; font-weight: 700;
  background: rgba(245,158,11,0.12);
  color: var(--warn);
  margin-left: 4px;
}
.btn.btn-sm { padding: 4px 9px; font-size: 12px; }
.btn.danger { color: var(--bad); }
.btn.danger:hover { background: rgba(239,68,68,0.08); border-color: rgba(239,68,68,0.4); }

.rating-up   { color: var(--success-soft); font-weight: 600; }
.rating-down { color: var(--danger-soft);  font-weight: 600; }

/* ===== Grants editor ===== */
.grants-editor {
  display: flex; flex-direction: column; gap: 8px;
}
.grant-ws {
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--panel);
  padding: 10px 12px;
  transition: border-color 0.12s ease;
}
.grant-ws.is-granted { border-color: rgba(72,69,255,0.4); }
.grant-ws-head {
  display: flex; align-items: center; gap: 10px;
  font-weight: 600;
  font-size: 13.5px;
}
.grant-ws-toggle { flex: 0 0 auto; cursor: pointer; }
.grant-ws-name {
  flex: 0 1 auto;
  cursor: pointer;
  text-align: left;
  /* Sit right next to the checkbox; button (if present) is pushed to the
     right via its own margin-left:auto below. */
}
.grant-ws-load {
  flex: 0 0 auto;
  margin-left: auto;          /* push the load button to the right edge */
}
.grant-ws-body {
  display: flex; flex-direction: column; gap: 8px;
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px dashed var(--border);
}
.grant-ws-body[hidden] { display: none; }
/* Inline "Load datasets" button — sits on the right of the workspace
   row, only visible when the workspace is granted. Hidden via the
   [hidden] attribute when the checkbox is unchecked. */
.grant-ws-load[hidden] { display: none; }
.grant-ds-list {
  display: flex; flex-direction: column; gap: 6px;
}
.grant-ds {
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 8px 10px;
  background: var(--surface-deep);
}
.grant-ds-head {
  display: flex; align-items: center; gap: 8px;
  cursor: pointer;
  font-size: 13px;
  font-weight: 500;
}
.grant-ds-rls {
  display: grid; grid-template-columns: 1fr 1fr; gap: 8px;
  margin-top: 8px;
}
.grant-ds-rls label {
  display: flex; flex-direction: column; gap: 4px;
  font-size: 11px; color: var(--muted);
}
.grant-ds-rls input {
  padding: 5px 8px;
  background: var(--input-bg);
  border: 1px solid var(--border);
  border-radius: 6px;
  color: var(--text);
  font-size: 12.5px;
  font-family: inherit;
}
.grant-ds-rls input::placeholder { color: var(--placeholder); }
.empty-inline { font-style: italic; color: var(--muted); font-size: 12px; padding: 4px 0; }

/* ===== Per-dataset filter-rule editor ===== */
.grant-ds-filters {
  margin-top: 8px;
  display: flex; flex-direction: column; gap: 8px;
}
.grant-filters-head {
  display: flex; align-items: center; gap: 8px;
}
.grant-filters-title {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-weight: 700;
  color: var(--muted);
  flex: 1;
}
.grant-filters-help {
  margin: 0;
  font-size: 11.5px;
  color: var(--muted);
  line-height: 1.45;
}
.grant-filter-list {
  display: flex; flex-direction: column; gap: 6px;
}
.grant-filter-row {
  display: grid;
  grid-template-columns: minmax(120px, 1fr) minmax(120px, 1fr) minmax(160px, 2fr) auto auto;
  gap: 6px;
  align-items: center;
}
.grant-filter-row .admin-select {
  width: 100%;
  padding: 5px 8px;
  font-size: 12.5px;
}
.grant-filter-values-input {
  padding: 5px 8px;
  background: var(--input-bg);
  border: 1px solid var(--border);
  border-radius: 6px;
  color: var(--text);
  font-size: 12.5px;
  font-family: inherit;
  width: 100%;
}
.grant-filter-values-input::placeholder { color: var(--placeholder); }
.grant-rls-advanced {
  margin-top: 4px;
  border-top: 1px dashed var(--border);
  padding-top: 8px;
}
.grant-rls-advanced summary {
  cursor: pointer;
  font-size: 11.5px;
  color: var(--muted);
  user-select: none;
  padding: 2px 0;
}
.grant-rls-advanced[open] summary { color: var(--text); }

/* ===== Generic admin form modal ===== */
.modal-shade {
  position: fixed; inset: 0;
  background: rgba(0,0,0,0.5);
  display: grid; place-items: center;
  z-index: 9999;
  padding: 20px;
}
.modal-shade .modal {
  width: min(420px, 92vw);
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: var(--shadow);
  display: flex; flex-direction: column;
}
.modal-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 16px;
  border-bottom: 1px solid var(--border);
}
.modal-head h3 { margin: 0; font-size: 15px; font-weight: 700; }
.modal-close {
  appearance: none; background: transparent; border: 0;
  color: var(--muted); cursor: pointer; font-size: 22px; line-height: 1;
  padding: 0 4px;
}
.modal-close:hover { color: var(--text); }
.modal-body {
  padding: 16px;
  display: flex; flex-direction: column; gap: 10px;
  max-height: 60vh; overflow-y: auto;
}
.modal-field {
  display: flex; flex-direction: column; gap: 5px;
  font-size: 12px;
  color: var(--muted);
}
.modal-field-inline {
  flex-direction: row; align-items: center; gap: 8px;
  font-size: 13px; color: var(--text);
}
.modal-field input[type="text"],
.modal-field input[type="email"],
.modal-field input[type="password"],
.modal-field select {
  padding: 7px 10px;
  background: var(--input-bg);
  border: 1px solid var(--border);
  border-radius: 7px;
  color: var(--text);
  font-size: 13px;
  font-family: inherit;
}
.modal-error {
  font-size: 12px; color: var(--bad);
  min-height: 1em;
}
.modal-actions {
  display: flex; gap: 8px; justify-content: flex-end;
  padding: 12px 16px;
  border-top: 1px solid var(--border);
}

/* ===== PDF button in the feedback row =====
   Sits to the right of the thumbs row, after the optional comment box.
   `margin-left: auto` pushes it away from the rating cluster so the PDF
   action reads as a peer-level export rather than part of the rating. */
.fb-pdf {
  margin-left: auto;
  width: auto;
  padding: 0 9px;
  gap: 6px;
}
.fb-pdf .fb-pdf-label {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.04em;
}
.fb-pdf:disabled { opacity: 0.6; cursor: progress; }

/* ===== Login page: register form, SSO button, pending banner ===== */
.login-pending-banner {
  background: rgba(245,158,11,0.12);
  border: 1px solid rgba(245,158,11,0.4);
  color: #b45309;
  padding: 9px 12px;
  border-radius: 8px;
  font-size: 12.5px;
  margin: 12px 0 8px;
  line-height: 1.45;
}
.login-success {
  background: rgba(34,197,94,0.10);
  border: 1px solid rgba(34,197,94,0.35);
  color: var(--success-soft);
  padding: 8px 11px;
  border-radius: 8px;
  font-size: 12.5px;
  line-height: 1.45;
}
.login-toggle {
  appearance: none;
  background: transparent;
  border: 0;
  color: var(--muted);
  font-size: 12.5px;
  font-family: inherit;
  cursor: pointer;
  padding: 6px 0 0;
}
.login-toggle .link {
  color: var(--accent);
  font-weight: 600;
}
.login-toggle:hover .link { text-decoration: underline; }

/* ===== Admin: status badges + pending row highlight ===== */
.pending-badge {
  display: inline-block;
  padding: 1px 7px;
  border-radius: 999px;
  font-size: 10px; font-weight: 700;
  background: rgba(245,158,11,0.14);
  color: var(--warn);
}
.rejected-badge {
  display: inline-block;
  padding: 1px 7px;
  border-radius: 999px;
  font-size: 10px; font-weight: 700;
  background: rgba(239,68,68,0.10);
  color: var(--danger-soft);
}
.source-badge {
  display: inline-block;
  padding: 0 6px;
  margin-left: 4px;
  border-radius: 4px;
  font-size: 9px; font-weight: 700;
  letter-spacing: 0.05em;
  background: rgba(72,69,255,0.12);
  color: var(--accent);
  vertical-align: middle;
}
.row-pending td { background: rgba(245,158,11,0.04); }
.btn.btn-primary.btn-sm { padding: 4px 10px; }

/* ===== Admin: Dataset Training tab — per-dataset cards ===== */
.training-list {
  display: flex; flex-direction: column; gap: 12px;
}
.training-card {
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--panel);
  padding: 14px 16px;
}
.training-card-head {
  display: flex; align-items: baseline; gap: 10px;
  margin-bottom: 8px;
}
.training-card-name {
  font-size: 14px;
  font-weight: 700;
  color: var(--text-strong);
  letter-spacing: -0.005em;
}
.training-card-meta {
  font-size: 11px;
  color: var(--muted);
  font-style: italic;
}
.training-card-text {
  width: 100%;
  padding: 9px 11px;
  background: var(--input-bg);
  border: 1px solid var(--border);
  border-radius: 7px;
  color: var(--text);
  font-size: 12.5px;
  font-family: inherit;
  line-height: 1.5;
  min-height: 110px;
  resize: vertical;
  box-sizing: border-box;
}
.training-card-text::placeholder { color: var(--placeholder); }
.training-card-actions {
  display: flex; align-items: center; gap: 8px;
  justify-content: flex-end;
  margin-top: 8px;
}
.training-card-status {
  flex: 1;
  font-size: 11px;
  color: var(--muted);
  font-style: italic;
}
/* Workspace card gets the accent left-border to read as the broader scope. */
.training-card.training-card-ws {
  border-left: 3px solid var(--accent);
}
.training-card.training-card-ds {
  border-left: 3px solid var(--border);
}
.ds-scope-tag {
  display: inline-block;
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 1px 6px;
  border-radius: 4px;
  background: var(--surface-hover);
  color: var(--muted);
  margin-left: 6px;
  vertical-align: middle;
}

/* ===== User-message action: rephrase/edit toggle ===== */
/* Rephrase pill is the more interesting action — accent it even at rest so
   it stands apart from the muted Edit pill. */
.msg-action-btn span { font-size: 11.5px; font-weight: 600; letter-spacing: 0.01em; }
.msg-action-btn.rephrase-btn { color: var(--accent); border-color: rgba(72,69,255,0.4); }

/* ===== Per-visual export toolbar (charts + tables) =====
   Sits in the top-right corner of each visual card, faded by default,
   pops on hover so it doesn't compete with the data. */
.chart-card,
.table-card {
  position: relative;
}
.table-card {
  margin: 12px 0;
  border-radius: 12px;
  border: 1px solid var(--border);
  background: var(--surface-deep);
  padding: 10px 12px;
  overflow-x: auto;
}
.table-card table { margin: 0; }

/* Change / delta column conditional formatting.
   Applied by _applyChangeColumnFormatting() in app.js — every cell whose
   value looks like a signed number/percent gets wrapped in a .tbl-chg span
   so we can colour just the value (and not surrounding punctuation). */
.tbl-chg{font-variant-numeric:tabular-nums;font-weight:600;display:inline}
.tbl-chg.up   { color: #0f7a3d; }
.tbl-chg.down { color: #c5302a; }
.tbl-chg.flat { color: var(--muted); }
/* Subtle background on whole change cells for a cleaner sweep across the
   change column — matches reference screenshot where +/- is highlighted. */
.tbl-chg-cell { background: linear-gradient(90deg, transparent, rgba(0,0,0,0.015) 30%, transparent); }
.visual-actions {
  position: absolute;
  top: 8px; right: 8px;
  display: flex; gap: 4px;
  opacity: 0.45;
  transition: opacity 0.12s ease;
  z-index: 2;
}
.chart-card:hover .visual-actions,
.table-card:hover .visual-actions,
.visual-actions:focus-within { opacity: 1; }
.visual-action {
  appearance: none;
  display: inline-flex; align-items: center; gap: 4px;
  padding: 3px 8px;
  font-family: inherit;
  font-size: 11px;
  font-weight: 600;
  color: var(--muted);
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 999px;
  cursor: pointer;
  transition: color 0.12s ease, border-color 0.12s ease, background 0.12s ease;
}
.visual-action:hover {
  color: var(--accent);
  border-color: var(--accent);
  background: rgba(72,69,255,0.10);
}
.visual-action svg { display: block; }

/* ============================================================
 * Chat sharing — in-app share modal + "Shared with you" inbox.
 * Mirrors the bookmark-share modal so the visual language is
 * consistent across share interactions.
 * ============================================================ */

/* ---- Share modal (cs- = chat share) ---- */
.cs-modal { width: min(460px, 94vw); }
.cs-preview {
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface-deep);
  padding: 10px 12px;
  display: flex; flex-direction: column; gap: 2px;
}
.cs-preview-title {
  font-size: 13.5px; font-weight: 700; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cs-preview-sub { font-size: 11.5px; color: var(--muted); }
.cs-help { font-size: 12px; color: var(--muted); line-height: 1.5; }
.cs-search {
  width: 100%;
  padding: 8px 10px;
  background: var(--input-bg);
  border: 1px solid var(--border);
  border-radius: 7px;
  color: var(--text);
  font-size: 13px;
  font-family: inherit;
}
.cs-search:focus { outline: none; border-color: var(--accent); }
.cs-search::placeholder { color: var(--placeholder); }
.cs-selected-count {
  font-size: 11.5px; color: var(--muted);
  font-weight: 600; letter-spacing: 0.02em;
}
.cs-list {
  max-height: 320px;
  overflow-y: auto;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface-deep);
}
.cs-row {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 12px;
  border-bottom: 1px solid var(--border);
  cursor: pointer;
}
.cs-row:last-child { border-bottom: 0; }
.cs-row:hover { background: var(--surface-hover); }
.cs-row input[type="checkbox"] { flex-shrink: 0; accent-color: var(--accent); }
.cs-avatar {
  width: 28px; height: 28px; flex-shrink: 0;
  display: grid; place-items: center;
  border-radius: 50%;
  background: var(--accent-grad);
  color: var(--on-accent);
  font-size: 12px; font-weight: 700;
  letter-spacing: 0.02em;
}
.cs-meta { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.cs-name { font-weight: 600; color: var(--text); font-size: 13px; }
.cs-sub  { font-size: 11.5px; color: var(--muted); display: none; }
/* Email subline is hidden by default; revealed only while the user is
   actively filtering so they can disambiguate similarly-named colleagues. */
.cs-list.is-searching .cs-sub { display: block; }

/* ---- Toast confirming share went through ---- */
.cs-toast {
  position: fixed;
  bottom: 24px; left: 50%;
  transform: translateX(-50%);
  z-index: 10000;
  padding: 10px 16px;
  background: var(--text);
  color: var(--bg);
  border-radius: 999px;
  font-size: 12.5px; font-weight: 600;
  box-shadow: var(--shadow);
  opacity: 1;
  transition: opacity 0.4s ease, transform 0.4s ease;
}
.cs-toast.is-out { opacity: 0; transform: translate(-50%, 8px); }

/* ---- Topbar inbox bell + popover ----
 * The bell sits next to the profile chip and is the single entry point
 * for "Shared with you". A red dot + tiny count appears whenever there
 * are pending shares; clicking opens a popover anchored to the bell that
 * lists each shared chat with sender + timestamp.
 */
.inbox-bell {
  appearance: none;
  position: relative;
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px;
  border-radius: 9px;
  border: 1px solid var(--border);
  background: var(--panel);
  color: var(--muted);
  cursor: pointer;
  transition: color 0.12s ease, border-color 0.12s ease, background 0.12s ease;
}
.inbox-bell:hover { color: var(--accent); border-color: var(--accent); background: rgba(72,69,255,0.06); }
.inbox-bell.has-unread { color: var(--accent); border-color: var(--accent); }
.inbox-bell svg { display: block; }
.inbox-bell-badge {
  position: absolute;
  top: -4px; right: -4px;
  min-width: 16px; height: 16px;
  padding: 0 4px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 999px;
  background: var(--bad, #ef4444);
  color: #fff;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.02em;
  border: 2px solid var(--panel);
  pointer-events: none;
}
.inbox-bell-badge[hidden] { display: none; }

.popover.inbox-pop {
  width: min(360px, 92vw);
  padding: 0;
}
.inbox-pop-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 12px 14px 10px;
}
.inbox-pop-head .popover-title {
  font-size: 13px;
  font-weight: 700;
  color: var(--text);
  letter-spacing: 0.01em;
}
.inbox-pop-count {
  font-size: 11px; color: var(--muted); font-weight: 600;
}
.inbox-pop-body {
  max-height: min(420px, 70vh);
  overflow-y: auto;
  padding: 0 6px 8px;
}
.inbox-empty {
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  padding: 22px 16px 26px;
  color: var(--muted);
  text-align: center;
}
.inbox-empty p { margin: 0; font-size: 13px; color: var(--text); font-weight: 600; }
.inbox-empty-sub { font-size: 11.5px !important; font-weight: 400 !important; color: var(--muted) !important; }

.inbox-row {
  display: flex; align-items: stretch; gap: 4px;
  border-radius: 8px;
  padding: 4px;
  margin: 2px 0;
  transition: background 0.12s ease;
}
.inbox-row:hover { background: var(--surface-hover); }
.inbox-row.active { background: rgba(72,69,255,0.10); }
.inbox-open {
  flex: 1; min-width: 0;
  display: flex; align-items: flex-start; gap: 10px;
  appearance: none; background: transparent; border: 0; padding: 8px;
  text-align: left; cursor: pointer; font-family: inherit;
  color: var(--text);
}
.inbox-avatar {
  flex-shrink: 0;
  width: 30px; height: 30px;
  display: grid; place-items: center;
  border-radius: 50%;
  background: var(--accent-grad);
  color: var(--on-accent);
  font-size: 12.5px; font-weight: 700;
  letter-spacing: 0.02em;
}
.inbox-meta { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }
.inbox-title-text {
  font-size: 13px; font-weight: 600; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  line-height: 1.35;
}
.inbox-sub {
  display: flex; align-items: center; gap: 4px;
  font-size: 11px; color: var(--muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.inbox-sub b { color: var(--text); font-weight: 600; }
.inbox-dot { color: var(--border); padding: 0 1px; }
.inbox-dismiss {
  flex-shrink: 0;
  width: 26px; align-self: center;
  height: 26px;
  border-radius: 6px;
  background: transparent;
  border: 0;
  color: var(--muted);
  cursor: pointer;
  display: grid; place-items: center;
  opacity: 0;
  transition: opacity 0.12s ease, background 0.12s ease, color 0.12s ease;
}
.inbox-row:hover .inbox-dismiss { opacity: 1; }
.inbox-dismiss:hover { background: rgba(0,0,0,0.06); color: var(--bad); }

/* ---- Banner that sits above the read-only shared-chat view ---- */
.shared-banner {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; flex-wrap: wrap;
  padding: 12px 16px;
  margin: 0 0 14px;
  border: 1px solid rgba(72,69,255,0.35);
  background: linear-gradient(180deg, rgba(72,69,255,0.10), rgba(72,69,255,0.04));
  border-radius: 10px;
}
.shared-banner-body {
  display: flex; align-items: center; gap: 12px;
  min-width: 0; flex: 1;
  color: var(--accent);
}
.shared-banner-body > svg { flex-shrink: 0; }
.shared-banner-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.shared-banner-title {
  font-size: 13.5px; font-weight: 700; color: var(--text);
}
.shared-banner-sub {
  font-size: 12px; color: var(--muted); line-height: 1.45;
}
.shared-banner-actions { display: flex; gap: 8px; flex-shrink: 0; }
.shared-truncated-note {
  margin: -8px 0 12px;
  padding: 8px 12px;
  font-size: 11.5px; color: var(--muted);
  background: var(--surface-deep);
  border: 1px dashed var(--border);
  border-radius: 8px;
}

/* ---- Mobile tweaks for share modal + inbox ---- */
@media (hover: none) {
  /* Touch devices have no hover — keep dismiss buttons visible always so
     users aren't stuck looking at an item with no obvious way to clear it. */
  .inbox-dismiss { opacity: 1; }
}
@media (max-width: 480px) {
  .cs-modal { width: 96vw; }
  .cs-list { max-height: 50vh; }
  .inbox-bell { width: 32px; height: 32px; border-radius: 8px; }
  .popover.inbox-pop { width: 92vw; }
  .shared-banner { padding: 10px 12px; }
  .shared-banner-actions { width: 100%; justify-content: flex-end; }
}
.visual-action:disabled { opacity: 0.7; cursor: progress; }

/* ── Orphan check tab ──────────────────────────────────────────────────
   Card-per-orphan layout (not a table). Each card carries:
     • title row (old name + workspace pill + old GUID + status pill)
     • reference summary (small chips with counts)
     • action row (apply / purge button or candidate dropdown)
   Color-coded by match status — green spine for auto-match, amber for
   ambiguous, red for unmatchable. Dismiss animation when applied. */
.orphan-list {
  display: flex; flex-direction: column; gap: 10px;
}
.orphan-card {
  position: relative;
  background: #ffffff;
  border: 1px solid #eaecf3;
  border-radius: 12px;
  padding: 14px 16px;
  display: flex; flex-direction: column; gap: 10px;
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.03);
  transition: opacity 220ms ease, transform 220ms ease, max-height 220ms ease;
}
.orphan-card::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
  border-top-left-radius: 12px; border-bottom-left-radius: 12px;
  background: #94a3b8;
}
.orphan-card-exact_name::before { background: #059669; }
.orphan-card-ambiguous::before  { background: #d97706; }
.orphan-card-missing::before    { background: #DC2626; }
.orphan-card-dismissed {
  opacity: 0; transform: translateX(-12px);
  max-height: 0; padding: 0 16px; margin: 0; border: 0;
  pointer-events: none;
}
.orphan-card-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 12px; flex-wrap: wrap;
}
.orphan-card-titles { flex: 1; min-width: 0; }
.orphan-card-title {
  font: 700 15px/1.3 "DM Sans"; color: #0f172a; margin: 0 0 6px;
  word-break: break-word;
}
.orphan-card-meta {
  display: inline-flex; align-items: center; gap: 8px; flex-wrap: wrap;
}
.orphan-old-id {
  font-family: "JetBrains Mono", "SF Mono", Menlo, monospace;
  font-size: 11px; color: rgba(15, 23, 42, 0.50);
  background: rgba(15, 23, 42, 0.04);
  padding: 2px 6px; border-radius: 4px;
  border: 1px solid rgba(15, 23, 42, 0.06);
}
.orphan-status {
  display: inline-flex; align-items: center;
  padding: 4px 10px; border-radius: 999px;
  font: 700 11px/1 "DM Sans"; letter-spacing: 0.02em;
  white-space: nowrap;
  border: 1px solid transparent;
}
.orphan-status-exact   { background: rgba(5, 150, 105, 0.10);  color: #047857; border-color: rgba(5, 150, 105, 0.20); }
.orphan-status-amb     { background: rgba(217, 119, 6, 0.10);  color: #b45309; border-color: rgba(217, 119, 6, 0.22); }
.orphan-status-missing { background: rgba(220, 38, 38, 0.10);  color: #b91c1c; border-color: rgba(220, 38, 38, 0.22); }

.orphan-card-refs {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
  font-size: 11.5px;
  padding: 8px 0 0;
  border-top: 1px dashed #eef0f7;
}
.orphan-refs-label {
  color: rgba(15, 23, 42, 0.55);
  font-weight: 600;
  margin-right: 4px;
}
.orphan-ref-chip {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 2px 9px; border-radius: 999px;
  background: rgba(91, 77, 255, 0.06);
  color: #4338ca;
  border: 1px solid rgba(91, 77, 255, 0.14);
  font-size: 11px; font-weight: 500;
}
.orphan-ref-chip strong { font-weight: 700; }

.orphan-action {
  display: flex; align-items: center; flex-wrap: wrap; gap: 8px;
  padding: 10px 0 0;
  border-top: 1px dashed #eef0f7;
}
.orphan-action-label {
  font-size: 12.5px; font-weight: 500; color: rgba(15, 23, 42, 0.62);
}
.orphan-candidate {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 10px; border-radius: 6px;
  background: rgba(5, 150, 105, 0.08);
  color: #047857;
  border: 1px solid rgba(5, 150, 105, 0.18);
  font: 600 12px/1.2 "DM Sans";
}
.orphan-candidate code {
  font-family: "JetBrains Mono", "SF Mono", Menlo, monospace;
  font-size: 11px; opacity: 0.85;
}
.orphan-pick { min-width: 240px; }

.orphan-empty {
  display: flex; flex-direction: column; align-items: center;
  gap: 12px; padding: 60px 20px;
  text-align: center;
  color: rgba(15, 23, 42, 0.55);
}
.orphan-empty svg { color: #059669; }
.orphan-empty h3 { font: 700 16px/1.3 "DM Sans"; color: #0f172a; margin: 0; }
.orphan-empty p  { margin: 0; font-size: 13.5px; max-width: 420px; }

.orphan-scanned-at {
  width: 100%;
  text-align: right;
  font-size: 11.5px; color: rgba(15, 23, 42, 0.45);
  margin-top: -4px; padding-right: 4px;
}

/* ───────────────────────────────────────────────────────────────────────
   Admin Console v2 — User Groups, Access subject toggle, Analytics, and
   feedback merge in Chat history. Kept in one block here so the related
   styles live next to each other instead of bleeding through earlier
   sections.
   ─────────────────────────────────────────────────────────────────────── */

/* Subject toggle on the Access Management tab — User ↔ Group. Reads as a
   compact segmented control, not a primary CTA. */
.grant-subject-toggle {
  display: inline-flex; padding: 3px;
  background: #f1f3f9; border: 1px solid #e2e6ef;
  border-radius: 999px;
}
.grant-subject-btn {
  appearance: none; border: 0; background: transparent;
  padding: 6px 14px; font: inherit; font-size: 12.5px; font-weight: 600;
  color: rgba(15, 23, 42, 0.55);
  border-radius: 999px; cursor: pointer;
  transition: background 120ms ease, color 120ms ease, box-shadow 120ms ease;
}
.grant-subject-btn:hover { color: rgba(15, 23, 42, 0.78); }
.grant-subject-btn.active {
  background: #ffffff; color: #5B4DFF;
  box-shadow: 0 1px 3px rgba(15, 23, 42, 0.10);
}
.grant-subject-btn.active::before { content: ""; }

/* Users-tab toolbar — search input on the left, result count on right. */
.users-toolbar {
  display: flex; align-items: center; gap: 16px;
  margin: 0 0 14px;
  padding: 0 0 14px;
  border-bottom: 1px solid #eef0f7;
}

/* Polished search input.  Magnifier glyph on the left, an x-clear on
   the right when there's text, and a kbd hint floating on the right
   when empty.  Indigo focus glow matches the rest of the admin UI. */
.apex-search {
  position: relative;
  display: flex; align-items: center;
  flex: 1; max-width: 520px;
  height: 38px;
  background: #ffffff;
  border: 1px solid #e2e6ef;
  border-radius: 10px;
  transition: border-color 140ms ease, box-shadow 140ms ease;
}
.apex-search:hover { border-color: #cbd1de; }
.apex-search:focus-within {
  border-color: #5B4DFF;
  box-shadow: 0 0 0 4px rgba(91, 77, 255, 0.10);
}
.apex-search-icon {
  position: absolute; left: 12px; top: 50%; transform: translateY(-50%);
  color: rgba(15, 23, 42, 0.40);
  pointer-events: none;
  transition: color 140ms ease;
}
.apex-search:focus-within .apex-search-icon { color: #5B4DFF; }
.apex-search-input {
  flex: 1; height: 100%;
  background: transparent; border: 0; outline: 0;
  padding: 0 90px 0 38px;            /* room for icon + kbd hint */
  font: 500 13px/1 "DM Sans";
  color: #0f172a;
  font-family: inherit;
}
.apex-search-input::placeholder { color: rgba(15, 23, 42, 0.40); }
.apex-search-input::-webkit-search-cancel-button { display: none; } /* native ✕ replaced */
.apex-search-clear {
  position: absolute; right: 56px; top: 50%; transform: translateY(-50%);
  appearance: none; border: 0; background: rgba(15, 23, 42, 0.06);
  width: 22px; height: 22px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  color: rgba(15, 23, 42, 0.55);
  cursor: pointer;
  transition: background 100ms ease, color 100ms ease;
}
.apex-search-clear:hover { background: rgba(15, 23, 42, 0.12); color: #0f172a; }
.apex-search-clear.hidden { display: none; }

/* Keyboard shortcut hint — auto-shown when empty, hidden when typing.
   Mac users see ⌘ K; everyone else sees Ctrl K (CSS picks the right
   form via @media (platform) — fall back to client-side toggle). */
.apex-search-kbd {
  position: absolute; right: 10px; top: 50%; transform: translateY(-50%);
  display: inline-flex; align-items: center; gap: 3px;
  padding: 2px 6px;
  font: 600 10.5px/1 "DM Sans";
  color: rgba(15, 23, 42, 0.45);
  background: rgba(15, 23, 42, 0.05);
  border: 1px solid rgba(15, 23, 42, 0.08);
  border-radius: 5px;
  letter-spacing: 0.04em;
  pointer-events: none;
  transition: opacity 120ms ease;
}
.apex-search.has-value .apex-search-kbd { opacity: 0; }
.apex-search-kbd-mac { display: none; }
.apex-search-kbd-pc  { display: inline; }
@supports (-webkit-touch-callout: none) {
  /* Best-effort: iOS Safari and macOS WebKit show ⌘ */
  .apex-search-kbd-mac { display: inline; }
  .apex-search-kbd-pc  { display: none; }
}

.users-search-count {
  font: 500 12px/1 "DM Sans";
  color: rgba(15, 23, 42, 0.50);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

@media (max-width: 760px) {
  .apex-search { max-width: none; }
  .apex-search-kbd { display: none; }
  .users-search-count { display: none; }
}

/* Combined "User" cell on the Users admin table — display name (or
   username when no display name) on top, secondary identifier below.
   Collapses the previous Username + Display name + Email columns. */
.user-cell { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.user-cell-primary {
  font-weight: 600; color: #0f172a;
  font-size: 13px; line-height: 1.3;
  display: inline-flex; align-items: center; gap: 6px; flex-wrap: wrap;
}
.user-cell-sub {
  font-size: 11.5px;
  color: rgba(15, 23, 42, 0.50);
  font-weight: 500;
  word-break: break-all;
}

/* Group pills on the Users table (one per group the user belongs to). */
.group-pill-stack {
  display: inline-flex; flex-wrap: wrap; gap: 4px; max-width: 260px;
}
.group-pill {
  display: inline-block; padding: 2px 9px; border-radius: 999px;
  background: rgba(91, 77, 255, 0.08);
  color: #4338ca;
  border: 1px solid rgba(91, 77, 255, 0.18);
  font-size: 11px; font-weight: 600; letter-spacing: 0.01em;
  white-space: nowrap;
}
/* Group that grants elevated role — same shape, warmer colour, so
   admins can tell at a glance which group membership is responsible
   for a user showing up as admin. */
.group-pill-elevates {
  background: rgba(217, 70, 239, 0.10);
  color: #a21caf;
  border-color: rgba(217, 70, 239, 0.22);
}
/* "via group" annotation next to the effective role badge in the
   Users table. Quiet by default — just a hint that the role isn't a
   direct grant. */
.role-via-group {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 7px;
  border-radius: 999px;
  background: rgba(217, 70, 239, 0.08);
  color: #a21caf;
  font-size: 10.5px; font-weight: 700; letter-spacing: 0.02em;
  white-space: nowrap;
}

/* "Dashboards only" badge on the User Groups table — same visual
   weight as the role badge, distinct teal so it reads as a different
   axis (not "more privileged" but "different scope"). */
.dbo-badge {
  display: inline-block;
  margin-left: 4px;
  padding: 2px 9px;
  border-radius: 999px;
  background: rgba(13, 148, 136, 0.10);
  color: #0f766e;
  border: 1px solid rgba(13, 148, 136, 0.22);
  font: 700 10.5px/1.4 "DM Sans";
  letter-spacing: 0.02em;
  white-space: nowrap;
}

/* Toggle row inside the group form — checkbox + title + sub. Reads as
   a single tappable surface (the whole label is clickable). */
.group-form-toggle {
  display: flex; gap: 12px; align-items: flex-start;
  padding: 12px 14px;
  background: rgba(13, 148, 136, 0.04);
  border: 1px solid rgba(13, 148, 136, 0.14);
  border-radius: 10px;
  cursor: pointer;
  transition: background 120ms ease, border-color 120ms ease;
}
.group-form-toggle:hover {
  background: rgba(13, 148, 136, 0.07);
  border-color: rgba(13, 148, 136, 0.22);
}
.group-form-toggle input[type="checkbox"] {
  margin-top: 2px;
  accent-color: #0f766e;
  cursor: pointer;
}
.group-form-toggle-body { display: flex; flex-direction: column; gap: 3px; flex: 1; }
.group-form-toggle-title {
  font: 600 13px/1.3 "DM Sans"; color: #0f172a;
}
.group-form-toggle-sub {
  font: 400 11.5px/1.45 "DM Sans"; color: rgba(15, 23, 42, 0.62);
}

/* Group create/edit modal. Wider than the chat modal — has both the form
   and the member picker side by side conceptually (stacked on mobile). */
.group-modal-card { width: min(720px, 96vw); }
.group-form { display: flex; flex-direction: column; gap: 12px; }
.group-form .login-field span { font-size: 12px; }
.group-form-sep {
  margin: 16px -8px; border: 0; border-top: 1px dashed #e2e6ef;
}
.group-members { display: flex; flex-direction: column; gap: 10px; }
.group-members-search {
  width: 100%;
  height: 34px;
  margin-bottom: 8px;
  border-radius: 8px;
  font-size: 12.5px;
}
.group-members-grid {
  display: grid; gap: 4px;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  max-height: 320px; overflow-y: auto;
  padding: 4px; border: 1px solid #e2e6ef; border-radius: 10px;
  background: #fafbfd;
}
.group-member-row {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 8px; border-radius: 6px; cursor: pointer;
  font-size: 12.5px;
  transition: background 100ms ease;
}
.group-member-row:hover { background: rgba(91, 77, 255, 0.06); }
.group-member-row input[type="checkbox"] { accent-color: #5B4DFF; }
.group-member-name { font-weight: 600; color: #1a1a2e; }
.group-member-sub  {
  font-size: 11px; color: rgba(15, 23, 42, 0.50); margin-left: auto;
  max-width: 50%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* Analytics tab — KPI tiles row + two side-by-side detail tables. */
.analytics-overview {
  display: grid; gap: 12px;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  margin: 16px 0 20px;
}
.analytics-overview .kpi-card {
  background: #ffffff;
  border: 1px solid #eaecf3;
  border-radius: 12px;
  padding: 14px 16px;
  position: relative;
  display: flex; flex-direction: column; gap: 4px;
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.03);
}
.analytics-overview .kpi-card::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
  border-top-left-radius: 12px; border-bottom-left-radius: 12px;
  background: #94a3b8;
}
.analytics-overview .kpi-card.kpi-up::before    { background: #059669; }
.analytics-overview .kpi-card.kpi-down::before  { background: #DC2626; }
.analytics-overview .kpi-card.kpi-flat::before  { background: #94a3b8; }
.analytics-overview .kpi-card.kpi-slate::before { background: #5B4DFF; }
.analytics-overview .kpi-label {
  font-size: 11px; letter-spacing: 0.04em; text-transform: uppercase;
  color: rgba(15, 23, 42, 0.55); font-weight: 600;
}
.analytics-overview .kpi-value {
  font-size: 22px; font-weight: 700; color: #0f172a; line-height: 1.2;
}
.analytics-grid {
  display: grid; gap: 16px;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
}
.analytics-card { padding: 0; overflow: hidden; }
.analytics-card-head {
  display: flex; align-items: baseline; justify-content: space-between;
  padding: 12px 16px; border-bottom: 1px solid #eaecf3;
  background: linear-gradient(180deg, #fafbfd, #ffffff);
}
.analytics-card-head h3 {
  font-size: 14px; font-weight: 700; color: #1a1a2e; margin: 0;
}
.analytics-card-head .muted { font-size: 11.5px; }
.row-stale { background: rgba(220, 38, 38, 0.04); }
.row-stale td { color: rgba(15, 23, 42, 0.78); }
/* Never-active users — accounts that have never logged in or chatted.
   Different from "stale" (was active, went quiet); shouldn't read as
   alarming red. Muted gray tint instead. */
.row-never-active { background: rgba(15, 23, 42, 0.02); }
.row-never-active td { color: rgba(15, 23, 42, 0.55); }
.stale-badge {
  display: inline-block; padding: 2px 8px; border-radius: 999px;
  background: rgba(220, 38, 38, 0.10);
  color: #b91c1c;
  font-size: 11px; font-weight: 700;
}
@media (max-width: 980px) {
  .analytics-grid { grid-template-columns: 1fr; }
}

/* Inline-label control on the Analytics action row (e.g., stale threshold). */
.admin-inline-label {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 12.5px; color: rgba(15, 23, 42, 0.70); font-weight: 500;
}
.admin-input-sm { width: 60px; padding: 5px 8px; font-size: 12.5px; }

/* ── Refresh-health scope bar (above KPIs) ─────────────────────────────
   Workspace + refresh-type multi-select triggers, search, clear.
   Always pushed to top of the tab so the user sees their scope first. */
.refresh-scope-bar {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  margin: 0 0 16px;
  position: relative;
}
.ms-trigger {
  appearance: none;
  display: inline-flex; align-items: center; gap: 8px;
  background: #ffffff;
  border: 1px solid #e2e6ef;
  color: #0f172a;
  padding: 6px 10px 6px 12px;
  height: 32px;
  border-radius: 8px;
  font: 600 12.5px/1 "DM Sans";
  cursor: pointer;
  transition: border-color 120ms ease, box-shadow 120ms ease;
  white-space: nowrap;
  max-width: 240px;
}
.ms-trigger:hover { border-color: #cbd1de; }
.ms-trigger.is-open {
  border-color: #5B4DFF;
  box-shadow: 0 0 0 3px rgba(91, 77, 255, 0.10);
}
.ms-trigger-label {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  max-width: 180px;
}
.ms-trigger-caret {
  color: rgba(15, 23, 42, 0.45);
  transition: transform 120ms ease, color 120ms ease;
}
.ms-trigger.is-open .ms-trigger-caret {
  transform: rotate(180deg);
  color: #5B4DFF;
}
.refresh-search { min-width: 240px; height: 32px; border-radius: 8px; font-size: 12.5px; }
@media (max-width: 760px) {
  .refresh-search { min-width: 0; flex: 1; }
}

/* Multi-select popover */
.ms-pop {
  position: absolute;
  top: 38px; left: 0;
  z-index: 50;
  min-width: 240px; max-width: 320px;
  background: #ffffff;
  border: 1px solid #e2e6ef;
  border-radius: 10px;
  box-shadow: 0 10px 30px rgba(15, 23, 42, 0.10), 0 2px 6px rgba(15, 23, 42, 0.05);
  overflow: hidden;
}
#refreshTypePop { left: auto; }
.ms-pop-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 8px 10px;
  border-bottom: 1px solid #eef0f7;
  background: #fafbfd;
}
.ms-pop-toggle {
  appearance: none; background: transparent; border: 0;
  font: 600 11.5px/1 "DM Sans";
  color: #5B4DFF;
  cursor: pointer; padding: 4px 6px; border-radius: 5px;
  transition: background 100ms ease;
}
.ms-pop-toggle:hover { background: rgba(91, 77, 255, 0.08); }
.ms-pop-list {
  max-height: 280px; overflow-y: auto; padding: 4px;
}
.ms-pop-row {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 8px; border-radius: 6px;
  font: 500 12.5px/1.3 "DM Sans"; color: #0f172a;
  cursor: pointer;
  transition: background 100ms ease;
}
.ms-pop-row:hover { background: rgba(91, 77, 255, 0.06); }
.ms-pop-row input[type="checkbox"] { accent-color: #5B4DFF; cursor: pointer; }
.ms-pop-empty {
  padding: 12px 10px; font-size: 12px; color: rgba(15, 23, 42, 0.45);
  text-align: center;
}

/* ── Refresh-health filter bar ─────────────────────────────────────────
   Flat, single-row, GitHub-style. No segmented container, no tinted
   alert strips — the chips themselves are the entire UI. Quiet by
   default; the active chip carries the only color so the eye knows
   what's selected without scanning. */
.refresh-filter-bar {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: 8px 14px;
  margin: 0 0 12px;
}
.refresh-quick-chips {
  display: inline-flex; flex-wrap: wrap; gap: 4px;
}
.refresh-chip {
  appearance: none;
  background: transparent;
  border: 1px solid transparent;
  color: rgba(15, 23, 42, 0.65);
  padding: 5px 10px;
  font: 600 12.5px/1.2 "DM Sans";
  border-radius: 7px;
  cursor: pointer;
  display: inline-flex; align-items: center; gap: 6px;
  transition: background 120ms ease, color 120ms ease, border-color 120ms ease;
  white-space: nowrap;
}
.refresh-chip:hover {
  background: rgba(15, 23, 42, 0.04);
  color: #0f172a;
}
.refresh-chip.active {
  background: rgba(91, 77, 255, 0.10);
  color: #4338ca;
  border-color: rgba(91, 77, 255, 0.20);
}
.refresh-chip-count {
  color: rgba(15, 23, 42, 0.45);
  font-size: 11.5px; font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.refresh-chip.active .refresh-chip-count { color: #5B4DFF; }
.refresh-filter-aux {
  display: inline-flex; flex-wrap: wrap; gap: 8px; align-items: center;
  margin-left: auto;
}
.refresh-filter-aux .admin-input,
.refresh-filter-aux .admin-select {
  height: 32px;
  border-radius: 8px;
  font-size: 12.5px;
}
.refresh-filter-aux .admin-input { min-width: 220px; }
@media (max-width: 760px) {
  .refresh-filter-aux { margin-left: 0; }
  .refresh-filter-aux .admin-input { min-width: 0; flex: 1; }
}

/* ── Error-type bucket row ─────────────────────────────────────────────
   Same visual language as the top row — same chip style, same count
   styling, just a different label prefix. Reads as one continuous
   filter UI, not two stacked toolbars. */
.refresh-error-buckets {
  display: flex; align-items: center; flex-wrap: wrap; gap: 4px 10px;
  margin: 0 0 14px;
  padding: 0;
}
.refresh-bucket-label {
  font: 600 10.5px/1 "DM Sans";
  color: rgba(15, 23, 42, 0.45);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  margin-right: 4px;
}
.refresh-bucket-chips { display: inline-flex; flex-wrap: wrap; gap: 4px; }
/* Bucket chips look identical to top chips. Active state is the only
   color signal — defaults to brand indigo; per-bucket overrides keep
   the active fill matching the badge color in the Error column. */
.refresh-bucket-chip { /* inherits .refresh-chip */ }
.refresh-bucket-chip.active {
  background: rgba(220, 38, 38, 0.10);
  color: #b91c1c;
  border-color: rgba(220, 38, 38, 0.22);
}
.refresh-bucket-chip.active .refresh-chip-count { color: #b91c1c; }
.refresh-bucket-chip.refresh-bucket-auth.active        { background: rgba(220, 38, 38, 0.10);  color: #b91c1c; border-color: rgba(220, 38, 38, 0.22); }
.refresh-bucket-chip.refresh-bucket-auth.active        .refresh-chip-count { color: #b91c1c; }
.refresh-bucket-chip.refresh-bucket-permission.active  { background: rgba(217, 70, 239, 0.10); color: #a21caf; border-color: rgba(217, 70, 239, 0.22); }
.refresh-bucket-chip.refresh-bucket-permission.active  .refresh-chip-count { color: #a21caf; }
.refresh-bucket-chip.refresh-bucket-datasource.active  { background: rgba(217, 119, 6, 0.10);  color: #b45309; border-color: rgba(217, 119, 6, 0.24); }
.refresh-bucket-chip.refresh-bucket-datasource.active  .refresh-chip-count { color: #b45309; }
.refresh-bucket-chip.refresh-bucket-timeout.active     { background: rgba(245, 158, 11, 0.12); color: #92400e; border-color: rgba(245, 158, 11, 0.26); }
.refresh-bucket-chip.refresh-bucket-timeout.active     .refresh-chip-count { color: #92400e; }
.refresh-bucket-chip.refresh-bucket-schema.active      { background: rgba(91, 77, 255, 0.10);  color: #4338ca; border-color: rgba(91, 77, 255, 0.22); }
.refresh-bucket-chip.refresh-bucket-schema.active      .refresh-chip-count { color: #4338ca; }
.refresh-bucket-chip.refresh-bucket-data_format.active { background: rgba(14, 165, 233, 0.10); color: #0369a1; border-color: rgba(14, 165, 233, 0.24); }
.refresh-bucket-chip.refresh-bucket-data_format.active .refresh-chip-count { color: #0369a1; }
.refresh-bucket-chip.refresh-bucket-capacity.active    { background: rgba(244, 63, 94, 0.10);  color: #be123c; border-color: rgba(244, 63, 94, 0.24); }
.refresh-bucket-chip.refresh-bucket-capacity.active    .refresh-chip-count { color: #be123c; }
.refresh-bucket-chip.refresh-bucket-quota.active       { background: rgba(234, 88, 12, 0.10);  color: #9a3412; border-color: rgba(234, 88, 12, 0.24); }
.refresh-bucket-chip.refresh-bucket-quota.active       .refresh-chip-count { color: #9a3412; }
.refresh-bucket-chip.refresh-bucket-cancelled.active,
.refresh-bucket-chip.refresh-bucket-disabled.active,
.refresh-bucket-chip.refresh-bucket-other.active       { background: rgba(100, 116, 139, 0.10); color: #475569; border-color: rgba(100, 116, 139, 0.22); }
.refresh-bucket-chip.refresh-bucket-cancelled.active   .refresh-chip-count,
.refresh-bucket-chip.refresh-bucket-disabled.active    .refresh-chip-count,
.refresh-bucket-chip.refresh-bucket-other.active       .refresh-chip-count { color: #475569; }

/* Per-row error category badge — coloured by bucket so the eye reads
   "lots of timeouts in this workspace" without parsing the strings. */
.err-cell-stack {
  display: flex; flex-direction: column; gap: 4px; align-items: flex-start;
}
.error-bucket-badge {
  display: inline-block; padding: 2px 8px; border-radius: 999px;
  font: 700 10.5px/1.4 "DM Sans"; letter-spacing: 0.02em;
  border: 1px solid transparent; white-space: nowrap;
}
.error-bucket-auth        { background: rgba(220, 38, 38, 0.10);  color: #b91c1c; border-color: rgba(220, 38, 38, 0.20); }
.error-bucket-permission  { background: rgba(217, 70, 239, 0.10); color: #a21caf; border-color: rgba(217, 70, 239, 0.20); }
.error-bucket-datasource  { background: rgba(217, 119, 6, 0.10);  color: #b45309; border-color: rgba(217, 119, 6, 0.22); }
.error-bucket-timeout     { background: rgba(245, 158, 11, 0.12); color: #92400e; border-color: rgba(245, 158, 11, 0.25); }
.error-bucket-schema      { background: rgba(91, 77, 255, 0.10);  color: #4338ca; border-color: rgba(91, 77, 255, 0.20); }
.error-bucket-data_format { background: rgba(14, 165, 233, 0.10); color: #0369a1; border-color: rgba(14, 165, 233, 0.22); }
.error-bucket-capacity    { background: rgba(244, 63, 94, 0.10);  color: #be123c; border-color: rgba(244, 63, 94, 0.22); }
.error-bucket-quota       { background: rgba(234, 88, 12, 0.10);  color: #9a3412; border-color: rgba(234, 88, 12, 0.22); }
.error-bucket-cancelled   { background: rgba(100, 116, 139, 0.10);color: #475569; border-color: rgba(100, 116, 139, 0.20); }
.error-bucket-disabled    { background: rgba(100, 116, 139, 0.08);color: #64748b; border-color: rgba(100, 116, 139, 0.18); }
.error-bucket-other       { background: rgba(15, 23, 42, 0.06);   color: #475569; border-color: rgba(15, 23, 42, 0.10); }

/* Feedback pills — used both on the chats list ("Feedback" column) and
   inside the transcript modal feedback section. */
.fb-stack { display: inline-flex; flex-wrap: wrap; gap: 4px; }
.fb-pill {
  display: inline-block; padding: 2px 8px; border-radius: 999px;
  font-size: 11px; font-weight: 700; letter-spacing: 0.01em;
}
.fb-pill.fb-up   {
  background: rgba(5, 150, 105, 0.10); color: #047857;
  border: 1px solid rgba(5, 150, 105, 0.20);
}
.fb-pill.fb-down {
  background: rgba(220, 38, 38, 0.10); color: #b91c1c;
  border: 1px solid rgba(220, 38, 38, 0.18);
}

/* Feedback block at the bottom of the transcript modal. */
.chat-feedback-block {
  margin: 16px 0 0; padding: 14px 16px;
  background: #fafbfd; border: 1px solid #eaecf3; border-radius: 12px;
}
.chat-feedback-head {
  font-size: 12.5px; font-weight: 700; color: #1a1a2e;
  letter-spacing: 0.01em; margin-bottom: 8px;
}
.fb-entry {
  padding: 8px 10px; border: 1px solid #eaecf3; border-radius: 8px;
  margin-bottom: 6px; background: #ffffff;
}
.fb-entry:last-child { margin-bottom: 0; }
.fb-entry-head { display: flex; gap: 8px; align-items: center; font-size: 11.5px; margin-bottom: 4px; }
.fb-entry-comment { font-size: 12.5px; color: #1a1a2e; line-height: 1.45; }
.fb-entry-q       { font-size: 11.5px; color: rgba(15, 23, 42, 0.60); margin-top: 4px; }


/* =====================================================================
   /dashboards bounded eL-card loader (2026-05-28)
   Replaces the prior centered logo+spinner. Mirrors the /workspace loader
   so users get one consistent waiting experience across both routes.

   .dash-embed-stage wraps the iframe AND the loader so the loader's
   inset:0 anchors to a box sized exactly to the iframe area. Previously
   the loader pinned all the way up to the viewport because its parent
   (.dash-embed-wrap) wasn't position:relative — so the card floated
   in the middle of the whole page.
   ===================================================================== */
.dash-embed-stage {
  position: relative;
  flex: 1;
  display: flex;
  min-height: 0;
}
.dash-embed-stage > .dash-embed-frame { flex: 1; min-height: 0; }

.dash-embed-frame { position: relative; }
.pbi-loader {
  position: absolute; inset: 0;
  z-index: 50;
  display: flex; align-items: center; justify-content: center;
  padding: 32px;
  background: linear-gradient(180deg, #ffffff 0%, #fbfaf6 100%);
  border-radius: inherit;
  animation: pbi-loader-in 180ms ease-out;
  font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Inter, sans-serif;
  overflow: auto;  /* if the iframe area is shorter than the card, scroll instead of overflowing */
}
.pbi-loader[hidden] { display: none; }
.pbi-loader.is-leaving {
  animation: pbi-loader-out 280ms ease-in forwards;
  pointer-events: none;
}
@keyframes pbi-loader-in  { from { opacity: 0; } to { opacity: 1; } }
@keyframes pbi-loader-out { from { opacity: 1; } to { opacity: 0; } }

/* The eL-card lives ONLY inside .pbi-loader on this page (the chat surface
   uses its own card). Scoped to avoid stomping any other eL-* styles. */
.pbi-loader .eL-card {
  width: min(560px, 100%);
  max-height: 100%;
  display: flex; flex-direction: column; align-items: center;
  gap: 18px;
  text-align: center;
  padding: 28px 32px;
  background: #ffffff;
  border: 1px solid #e9eaef;
  border-radius: 14px;
  box-shadow: 0 12px 36px -16px rgba(15, 23, 42, 0.18), 0 2px 8px -4px rgba(15, 23, 42, 0.06);
}
.pbi-loader .eL-mark {
  display: flex; align-items: center; justify-content: center;
}

/* Brand row at the top of the loader card. Client logo (left) and
   dataeze.ai logo (right), separated by a thin divider. Subtle but
   clearly visible — this is the "your space, powered by us" beat
   while the report mints. Hides cleanly when the client logo slot is
   empty (i.e. tenant has no logo configured). */
.pbi-loader .eL-brand-row {
  display: flex; align-items: center; justify-content: center;
  gap: 14px;
  width: 100%;
  padding-bottom: 4px;
}
.pbi-loader .eL-brand-client,
.pbi-loader .eL-brand-host {
  display: inline-flex; align-items: center;
  height: 32px;
}
/* 2026-05-28 — loader brand row sizing.
   Both marks at 32px (same size) in the loader card so the
   attribution row reads balanced. No max-width cap (was crushing
   the dataeze wordmark) — let widths be intrinsic. !important
   needed to overrule the nuclear img[src*="dataeze-logo"] rule
   at the bottom of this file. */
.pbi-loader .eL-brand-client img,
.pbi-loader .eL-brand-host img,
.pbi-loader .eL-brand-row img[src*="dataeze-logo"],
.pbi-loader .eL-brand-row img.bl-img:not([src*="dataeze-logo"]) {
  height: 32px !important;
  max-height: 32px !important;
  width: auto !important;
  max-width: none !important;
  object-fit: contain !important;
  display: block !important;
  background: transparent !important;
  mix-blend-mode: multiply !important;
}
.pbi-loader .eL-brand-client.is-text {
  font-size: 13px;
  font-weight: 700;
  color: #1a1c23;
  letter-spacing: 0.01em;
}
.pbi-loader .eL-brand-client:empty { display: none; }
/* Thin centred divider between the two logos. CSS-only — easier than
   another <span> in the markup. Default: divider present (we have a
   client logo); :empty + adjacent selector strips it when the client
   slot is empty so the dataeze logo doesn't carry a dangling rule. */
.pbi-loader .eL-brand-client + .eL-brand-host {
  border-left: 1px solid #e2e5ec;
  padding-left: 14px;
}
.pbi-loader .eL-brand-client:empty + .eL-brand-host {
  border-left: 0;
  padding-left: 0;
}
.pbi-loader .eL-mark-dot {
  width: 54px; height: 54px;
  border-radius: 14px;
  background: linear-gradient(135deg, #4845ff, #7a6fff);
  color: #fff;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 6px 22px -10px rgba(91, 77, 255, 0.55);
}
.pbi-loader .eL-title {
  font-size: 17px;
  font-weight: 600;
  color: #1a1c23;
  letter-spacing: -0.01em;
}
.pbi-loader .eL-steps {
  display: flex; gap: 6px; align-items: center; flex-wrap: wrap;
  justify-content: center;
}
.pbi-loader .eL-step {
  display: inline-flex; align-items: center; gap: 7px;
  font-size: 12.5px; color: #6b7280;
  padding: 5px 10px;
  border-radius: 999px;
  background: #f4f5f8;
  border: 1px solid #e6e8ee;
}
.pbi-loader .eL-step .eL-dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: #cfd3da;
}
.pbi-loader .eL-step.active {
  color: #4845ff;
  background: rgba(72, 69, 255, 0.10);
  border-color: transparent;
}
.pbi-loader .eL-step.active .eL-dot {
  background: #4845ff;
  box-shadow: 0 0 0 4px rgba(72, 69, 255, 0.18);
  animation: pulse 1.1s ease-in-out infinite;
}
.pbi-loader .eL-step.done {
  color: #1a1c23;
  background: #eaf3ec;
  border-color: transparent;
}
.pbi-loader .eL-step.done .eL-dot { background: #3a9b56; }
.pbi-loader .eL-tip {
  margin-top: 6px;
  width: 100%;
  display: flex; gap: 10px; align-items: flex-start;
  text-align: left;
  padding: 12px 14px;
  background: #f4f5f8;
  border: 1px solid #e6e8ee;
  border-radius: 10px;
  font-size: 12.5px;
  color: #4a5161;
}
.pbi-loader .eL-tip-eyebrow {
  flex: 0 0 auto;
  font-size: 10.5px; font-weight: 700; letter-spacing: 0.06em;
  color: #4845ff;
  background: rgba(72, 69, 255, 0.10);
  padding: 3px 7px;
  border-radius: 6px;
}
.pbi-loader .eL-tip-text { flex: 1; line-height: 1.45; }
.pbi-loader .eL-foot {
  font-size: 11.5px;
  color: #8b93a0;
  font-style: italic;
  max-width: 440px;
  line-height: 1.5;
}

/* ============================================================
 * claude-fix quick-deep 2026-05-20 — Actioneer-style welcome + toggle
 * ============================================================ */
.welcome-hero {
  text-align: center;
  max-width: 720px;
  margin: 8vh auto 4vh;
  padding: 0 24px;
}
.hero-brand {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  margin-bottom: 20px;
}
.hero-mark {
  width: 48px;
  height: 48px;
  object-fit: contain;
}
.hero-label {
  font-size: 13px;
  color: #6b6b73;
  letter-spacing: 0.02em;
}
.hero-greeting {
  font-size: 28px;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: #0a0a0a;
  margin: 0 0 6px;
}
.hero-tagline {
  font-size: 14px;
  color: #6b6b73;
  margin: 0 0 28px;
  line-height: 1.55;
}
.hero-or {
  font-size: 13px;
  color: #6b6b73;
  margin: 28px 0 12px;
}
.hero-suggestions {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
}
@media (max-width: 720px) {
  .hero-suggestions { grid-template-columns: 1fr; }
}
.suggest-card {
  background: #fafaf8;
  border: 1px solid #ececec;
  border-radius: 12px;
  padding: 14px 16px;
  text-align: left;
  font-size: 13px;
  line-height: 1.45;
  color: #0a0a0a;
  cursor: pointer;
  font-family: inherit;
  transition: border-color 120ms ease, background 120ms ease;
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-height: 92px;
}
.suggest-card:hover {
  border-color: #0a0a0a;
  background: #ffffff;
}
.suggest-icon {
  font-size: 12px;
  color: #c5c5cc;
  display: inline-block;
}
.suggest-text {
  font-weight: 500;
  color: #0a0a0a;
}

/* Composer controls row — Active pill + Quick/Deep toggle */
.composer-controls {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 8px 14px 0;
  font-size: 12px;
  color: #6b6b73;
  flex-wrap: wrap;
}
.composer-status {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: rgba(22, 163, 74, 0.08);
  color: #15803d;
  font-size: 11px;
  font-weight: 600;
  padding: 3px 10px;
  border-radius: 999px;
  letter-spacing: 0;
}
.composer-status::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #22c55e;
  flex: 0 0 6px;
}
/* claude-fix mode-pill 2026-05-22: the status pill reflects the active
   Quick/Deep mode (driven by the Deep Research toggle) instead of a dead
   "Active" label. Deep = indigo, Quick = blue. */
.composer-status.mode-deep      { background: rgba(91,77,255,0.10); color: #4338ca; }
.composer-status.mode-deep::before     { background: #5B4DFF; }
.composer-status.mode-standard  { background: rgba(20,140,90,0.10); color: #14744f; }
.composer-status.mode-standard::before { background: #1f9a6d; }
.composer-status.mode-quick     { background: rgba(47,109,240,0.10); color: #1d4ed8; }
.composer-status.mode-quick::before    { background: #2f6df0; }

/* ---- 3-mode chip selector — dark capsule, proper-button look (2026-05-28)
   Uses !important on every property so any older cached rule or
   higher-specificity carryover can't override. Specs:
     container : near-black charcoal pill, slim inset border, soft shadow
     inactive  : medium grey text, semibold, no background
     hover     : white text on faint white-overlay (gives "tappable" feel)
     active    : pure white text on elevated charcoal (#2f3645) with a
                 1px inner highlight + drop shadow — looks like the pressed
                 button in a segmented action group.
   margin-left:auto + order:999 push the whole pill to the right edge of
   .composer-controls so it aligns with the right edge of the chat window. */
/* DESIGN 2026-05-28 — Quick / Standard / Depth segmented control,
   redesigned as a proper button group.

   Reference: Apple's iOS segmented control, Linear's filter pills,
   Notion's view-mode switcher. Pattern:
     · Light grey CAPSULE container (sits gracefully on the white
       composer surface instead of stamping a dark island on it)
     · Inactive chip: muted-grey TEXT, transparent bg, hover lifts
       to charcoal text + faint white wash (clearly tappable)
     · Active chip: SOLID BRAND INDIGO with white text + brand-tinted
       soft drop shadow — reads unambiguously as "the selected button"
     · Subtle 2px padding inside container so the active chip "floats"
       inside the grey track

   Cursor + transition + focus-ring all in one block so we don't
   forget the affordances.
*/
.mode-chips {
  display: inline-flex !important;
  background: #F4F5F8 !important;             /* light grey track */
  border: 1px solid #E6E8EE !important;       /* hairline edge */
  border-radius: 999px !important;
  padding: 3px !important;
  gap: 0 !important;
  margin-left: auto !important;
  order: 999 !important;
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04) !important;
}
.mode-chip {
  appearance: none !important;
  border: 0 !important;
  background: transparent !important;
  cursor: pointer;
  font: inherit;
  font-size: 13px !important;
  font-weight: 600 !important;
  color: #6B7280 !important;                  /* muted grey — inactive */
  padding: 7px 18px !important;
  border-radius: 999px !important;
  line-height: 1 !important;
  letter-spacing: 0.01em !important;
  transition: background 150ms cubic-bezier(0.4, 0, 0.2, 1),
              color 150ms cubic-bezier(0.4, 0, 0.2, 1),
              box-shadow 150ms cubic-bezier(0.4, 0, 0.2, 1) !important;
}
.mode-chip:hover:not(.active) {
  color: #1A1C23 !important;                  /* charcoal — clearer affordance */
  background: rgba(255, 255, 255, 0.65) !important;
}
.mode-chip.active {
  background: #5B4DFF !important;             /* brand indigo */
  color: #FFFFFF !important;
  box-shadow: 0 1px 3px rgba(91, 77, 255, 0.30),
              0 0 0 1px rgba(91, 77, 255, 0.08) !important;
}
.mode-chip:focus-visible {
  outline: 2px solid #5B4DFF !important;
  outline-offset: 2px !important;
}
.composer-toggle {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
  user-select: none;
  font-size: 12px;
}
.composer-toggle input {
  appearance: none;
  width: 0;
  height: 0;
  position: absolute;
  opacity: 0;
}
.composer-toggle .toggle-track {
  width: 28px;
  height: 16px;
  background: #d4d4d8;
  border-radius: 999px;
  position: relative;
  display: inline-block;
  transition: background 160ms ease;
  flex: 0 0 28px;
}
.composer-toggle .toggle-thumb {
  position: absolute;
  top: 2px;
  left: 2px;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: #ffffff;
  transition: transform 160ms ease;
  box-shadow: 0 1px 2px rgba(0,0,0,0.15);
}
.composer-toggle input:checked + .toggle-track {
  background: #0a0a0a;
}
.composer-toggle input:checked + .toggle-track .toggle-thumb {
  transform: translateX(12px);
}
.composer-toggle .toggle-label {
  color: #6b6b73;
}
.composer-toggle input:checked ~ .toggle-label {
  color: #0a0a0a;
  font-weight: 500;
}
.composer-hint-text {
  margin-left: auto;
  font-size: 11px;
  color: #94a3b8;
}


/* =====================================================================
   Chat history v2 — cleaner, more professional sidebar.
   Reference: title (regular weight) + single muted timestamp line below.
   Active = subtle grey bg + indigo left accent bar. Hover = light bg shift.
   Hides per-row token/cost & workspace/dataset chips by default; they're
   still in the DOM (so tooltip / kebab still work) but off-screen visually
   for a quieter list. Hover surfaces just the kebab.
   ===================================================================== */
.sessions-list { gap: 0; padding: 4px 6px 8px; }

.session-group-head {
  font-size: 10.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: #9aa1ad;
  padding: 14px 10px 6px;
  font-weight: 600;
}
.session-group-head:first-child { padding-top: 6px; }

.session-item {
  padding: 9px 10px 9px 14px;     /* extra left space for the accent bar */
  border-radius: 8px;
  border: 0;                       /* drop the on-hover border ring */
  gap: 3px;
  transition: background 0.12s ease;
  background: transparent;
}
.session-item::before {
  /* Indigo left accent bar — invisible by default, shown when .active.
     Anchored slightly inside the item so it reads as a notch, not a border. */
  content: "";
  position: absolute;
  left: 4px; top: 8px; bottom: 8px;
  width: 3px;
  border-radius: 999px;
  background: transparent;
  transition: background 0.12s ease;
}
.session-item:hover {
  background: rgba(15, 23, 42, 0.035);
  border-color: transparent;
}
.session-item.active {
  background: rgba(15, 23, 42, 0.05);
  border-color: transparent;
  color: var(--text-strong);
}
.session-item.active::before { background: var(--accent); }
.session-item.active .session-title { font-weight: 600; }

.session-title {
  font-size: 13px;
  font-weight: 500;
  line-height: 1.35;
  color: var(--text-strong, #1a1c23);
}

/* Single muted timestamp line under the title — show only the time chip,
   hide tokens + cost (kept in DOM for kebab/tooltip but visually quiet). */
.session-meta {
  display: inline-flex;
  padding-left: 0;
  font-size: 11.5px;
  color: #8b93a0;
  font-weight: 400;
}
.session-meta .session-meta-tok,
.session-meta .session-meta-cost,
.session-meta .session-meta-dot { display: none; }
.session-meta-time { color: #8b93a0; font-weight: 400; }

/* Workspace + dataset chips — keep them in the markup (some chats really do
   need to show WS/DS), but only reveal on hover or when active. Keeps the
   default list visually clean per the reference. */
.session-context { display: none; padding-top: 2px; }
.session-item:hover .session-context,
.session-item.active .session-context { display: flex; }

/* Streaming notch — the global .session-item.is-streaming used a left
   border which now collides with our ::before accent. Reuse the ::before
   accent (pulsing) as the canonical signal and hide the inline ● dot. */
.session-item.is-streaming { border-left: 0; padding-left: 14px; }
.session-item.is-streaming::before { background: var(--accent); animation: pulse 1.4s ease-in-out infinite; }
.session-streaming-dot { display: none; }

/* Kebab sits slightly inset so it doesn't clip past the rounded item. */
.session-kebab { right: 6px; }

/* Show-more pill at the bottom — match reference: full-width, soft border,
   centered label. Replaces the dashed dev-looking variant. */
.sessions-show-more {
  margin: 12px 8px 4px;
  padding: 9px 12px;
  background: #fff;
  border: 1px solid #e6e8ee;
  border-radius: 999px;
  color: #515767;
  font-size: 12px;
  font-weight: 500;
  text-align: center;
  width: calc(100% - 16px);
  box-shadow: 0 1px 2px rgba(10,12,20,0.03);
}
.sessions-show-more:hover {
  background: #f6f7fa;
  border-color: #dadde4;
  color: #1a1c23;
}

/* =====================================================================
   2026-05-28 — brand-lockup unification fix.
   User reported: client logo + dataeze logo render at very different
   sizes, dataeze visually dominates. Both logo PNGs also have white
   backgrounds that don't blend cleanly with light surfaces.

   This block overrides ALL earlier .bl-mark-* sizing rules so that
   client + dataeze always render at the SAME height, with widths
   intrinsic to their natural aspect ratio (no max-width crush), and
   white PNG backgrounds flattened via mix-blend-mode.

   Single source of truth — covers legacy AND v2 pages, every variant
   (default, .bl-sm, .login-card).

   Heights chosen for visual balance:
     · Login hero (default variant): 48px each
     · Topbar / sidebar (.bl-sm):    28px each
     · Login card-scoped:            36px each
   ===================================================================== */

/* Container fixes — strip backgrounds + force inline-flex alignment */
.brand-lockup .bl-mark,
.brand-lockup .bl-mark-c24,
.brand-lockup .bl-mark-apex,
[data-tenant-brand] .bl-mark,
[data-tenant-brand] .bl-mark-c24,
[data-tenant-brand] .bl-mark-apex {
  background: transparent !important;
  display: inline-flex !important;
  align-items: center !important;
  line-height: 0 !important;
}

/* DESIGN: client mark VISIBLY LARGER than dataeze. Equal heights
   looked unbalanced because dataeze's wordmark is naturally ~3× wider
   than the client crest. Standard co-brand hierarchy is "primary +
   partner attribution", so client wins on height too. Ratio ~1.6:1. */

/* DEFAULT variant (login hero) */
.brand-lockup:not(.bl-sm) .bl-mark-c24 img.bl-img {
  height: 56px !important;
  width: auto !important;
  max-width: none !important;
  max-height: 56px !important;
  object-fit: contain !important;
  background: transparent !important;
  mix-blend-mode: multiply !important;
  display: block !important;
}
.brand-lockup:not(.bl-sm) .bl-mark-apex img.bl-img,
.brand-lockup:not(.bl-sm) .bl-mark-apex img.bl-img.bl-logo-full {
  height: 28px !important;
  width: auto !important;
  max-width: none !important;
  max-height: 28px !important;
  object-fit: contain !important;
  background: transparent !important;
  mix-blend-mode: multiply !important;
  display: block !important;
}

/* COMPACT variant (.bl-sm — topbar, sidebar) */
.brand-lockup.bl-sm .bl-mark-c24 img.bl-img {
  height: 32px !important;
  width: auto !important;
  max-width: none !important;
  max-height: 32px !important;
  object-fit: contain !important;
  background: transparent !important;
  mix-blend-mode: multiply !important;
  display: block !important;
}
.brand-lockup.bl-sm .bl-mark-apex img.bl-img,
.brand-lockup.bl-sm .bl-mark-apex img.bl-img.bl-logo-full {
  height: 18px !important;
  width: auto !important;
  max-width: none !important;
  max-height: 18px !important;
  object-fit: contain !important;
  background: transparent !important;
  mix-blend-mode: multiply !important;
  display: block !important;
}

/* LOGIN CARD-scoped */
.login-card .bl-mark-c24 img.bl-img {
  height: 44px !important;
  width: auto !important;
  max-width: none !important;
  max-height: 44px !important;
  object-fit: contain !important;
  background: transparent !important;
  mix-blend-mode: multiply !important;
  display: block !important;
}
.login-card .bl-mark-apex img.bl-img,
.login-card .bl-mark-apex img.bl-img.bl-logo-full {
  height: 24px !important;
  width: auto !important;
  max-width: none !important;
  max-height: 24px !important;
  object-fit: contain !important;
  background: transparent !important;
  mix-blend-mode: multiply !important;
  display: block !important;
}

/* Divider — proportional to the smaller of the two flanking marks */
.brand-lockup:not(.bl-sm) .bl-divider {
  width: 1px !important;
  height: 36px !important;
  background: #E6E8EE !important;
  margin: 0 12px !important;
}
.brand-lockup.bl-sm .bl-divider {
  width: 1px !important;
  height: 22px !important;
  background: #E6E8EE !important;
  margin: 0 10px !important;
}
.login-card .bl-divider {
  width: 1px !important;
  height: 28px !important;
  background: #E6E8EE !important;
  margin: 0 12px !important;
}

/* Hide the bl-word text variant (used as a wordmark fallback) so we
   never get duplicate brand text alongside the IMG marks. */
.bl-word, .bl-word-apex { display: none !important; }

/* =====================================================================
   NUCLEAR OVERRIDE — attribute-selector targeting (2026-05-28 v3).
   Earlier same-height-rules with !important kept losing in the cascade
   because of source-order issues / specificity collisions / browser
   cache. Switch to img[src*="..."] selectors which match the IMG
   directly by URL — no class collisions possible. !important + image-
   attribute selector = the most specific rule combination short of
   inline style. Wins everywhere.
   ===================================================================== */

/* dataeze.ai img — small attribution mark, max 22px tall in any context */
body img[src*="dataeze-logo"],
html img[src*="dataeze-logo"] {
  height: 22px !important;
  width: auto !important;
  max-width: none !important;
  max-height: 22px !important;
  min-height: 0 !important;
  object-fit: contain !important;
  background: transparent !important;
  mix-blend-mode: multiply !important;
  display: inline-block !important;
  vertical-align: middle !important;
}

/* On the compact topbar/sidebar (.bl-sm), dataeze slightly smaller
   than the client mark but still readable. Bumped 16 → 24px on user
   request for /home where it was reading too tiny next to Phitku. */
.brand-lockup.bl-sm img[src*="dataeze-logo"] {
  height: 24px !important;
  max-height: 24px !important;
}

/* On the login hero, dataeze stays small while client jumps to 64px */
.login-card img[src*="dataeze-logo"],
.login-lockup img[src*="dataeze-logo"] {
  height: 24px !important;
  max-height: 24px !important;
}

/* TENANT (client) logos — bumped UP across all surfaces per request.
   Client should dominate the lockup at ~2× the dataeze attribution. */
body img.bl-img:not([src*="dataeze-logo"]),
html img.bl-img:not([src*="dataeze-logo"]) {
  height: 48px !important;
  width: auto !important;
  max-width: none !important;
  max-height: 48px !important;
  min-height: 0 !important;
  object-fit: contain !important;
  background: transparent !important;
  mix-blend-mode: multiply !important;
  display: inline-block !important;
  vertical-align: middle !important;
}
.brand-lockup.bl-sm img.bl-img:not([src*="dataeze-logo"]) {
  height: 40px !important;
  max-height: 40px !important;
}
.login-card img.bl-img:not([src*="dataeze-logo"]),
.login-lockup img.bl-img:not([src*="dataeze-logo"]) {
  height: 64px !important;
  max-height: 64px !important;
}

/* ============================================================
 * Reports admin tab (super-admin only) — appended 2026-06-01.
 * Local additions for the /admin Reports pane: tighter table,
 * grants list, a small form-section label. Reuses .modal,
 * .modal-card, .form-row primitives that already exist above.
 * ============================================================ */
.reports-admin-list .admin-table { width: 100%; }
.reports-admin-table th, .reports-admin-table td {
  padding: 12px 14px;
  border-bottom: 1px solid var(--border);
  font-size: 13px;
  vertical-align: middle;
}
.reports-admin-table th {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--muted, #6B7184);
  font-weight: 600;
  text-align: left;
  background: var(--bg-2, #F6F7FB);
}
.reports-admin-table td.num { text-align: right; font-variant-numeric: tabular-nums; }
.reports-admin-table td.actions {
  display: flex;
  gap: 6px;
  justify-content: flex-end;
}
.reports-admin-table .pill {
  display: inline-block;
  padding: 2px 8px;
  background: var(--accent-wash, #F4F2FF);
  color: var(--accent-soft, #3D3AE0);
  font-size: 11px;
  font-weight: 600;
  border-radius: 999px;
  letter-spacing: 0.04em;
}
.btn.btn-sm { padding: 6px 10px; font-size: 12.5px; }
.btn.btn-danger { color: #C04A33; }
.btn.btn-danger:hover { background: #FCEEEA; }

.form-section-label {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-weight: 600;
  color: var(--muted, #6B7184);
  margin: 0 0 10px;
}
.grants-list {
  list-style: none;
  padding: 0;
  margin: 0;
  max-height: 200px;
  overflow-y: auto;
}
.grants-list li {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 8px 10px;
  border-bottom: 1px solid var(--border);
  font-size: 13.5px;
}
.grants-list li:last-child { border-bottom: none; }

.form-error {
  color: #C04A33;
  font-size: 13px;
  margin: 8px 0 0;
  padding: 8px 10px;
  background: #FCEEEA;
  border-radius: 8px;
}

/* ============================================================
 * Reports admin — Manage-access modal (rebuilt 2026-06-01).
 * Replaces the native <select multiple> with a checkbox-row
 * picker + search filter + selection count. The native control
 * required Ctrl-click which non-technical admins consistently
 * missed and silently no-op'd Grant access.
 * ============================================================ */
.modal.modal-wide {
  width: min(620px, 96vw);
  max-height: 92vh;
}
.modal.modal-wide .modal-head {
  align-items: flex-start;
  padding-top: 18px;
  padding-bottom: 14px;
}
.modal.modal-wide .modal-head h3 {
  font-size: 17px;
}
/* Modal body scrolls inside the card so the picker doesn't push the
 * "Currently has access" + audit sections off the bottom. */
.modal.modal-wide .modal-body {
  max-height: calc(92vh - 80px);
}

.grants-search {
  position: relative;
  margin-bottom: 8px;
}
.grants-search svg {
  position: absolute;
  left: 10px; top: 50%;
  transform: translateY(-50%);
  color: var(--text-faint, #9AA0AE);
  pointer-events: none;
}
.grants-search input {
  width: 100%;
  padding: 8px 12px 8px 32px;
  border: 1px solid var(--border, #E3E6EE);
  border-radius: 8px;
  background: var(--input-bg, #fff);
  font: inherit;
  font-size: 13px;
  color: var(--text, #15171D);
  outline: none;
  transition: border-color .12s, box-shadow .12s;
}
.grants-search input:focus {
  border-color: var(--accent, #4845FF);
  box-shadow: 0 0 0 3px rgba(72,69,255,0.12);
}

/* Text-only picker — no avatar chip, tighter rows. */
.grants-picker {
  list-style: none;
  padding: 0;
  margin: 0;
  max-height: 240px;
  overflow-y: auto;
  border: 1px solid var(--border, #E3E6EE);
  border-radius: 10px;
  background: #fff;
}
.grants-picker-empty {
  padding: 20px 16px;
  text-align: center;
  color: var(--text-muted, #6B7184);
  font-size: 13px;
}
.grants-picker-row {
  border-bottom: 1px solid var(--border, #E3E6EE);
  cursor: pointer;
  transition: background .1s;
}
.grants-picker-row:last-child { border-bottom: none; }
.grants-picker-row:hover { background: rgba(15,17,30,0.03); }
.grants-picker-row.is-selected { background: rgba(72,69,255,0.06); }
.grants-picker-label {
  display: grid;
  grid-template-columns: 18px 1fr;
  align-items: center;
  gap: 12px;
  padding: 8px 14px;
  cursor: pointer;
  margin: 0;
}
.grants-picker-cb {
  width: 16px; height: 16px;
  accent-color: var(--accent, #4845FF);
  cursor: pointer;
}
.grants-picker-body {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.grants-picker-name {
  font-size: 13.5px;
  font-weight: 500;
  color: var(--text-strong, #0C0E15);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.grants-picker-email {
  font-size: 12px;
  color: var(--text-muted, #6B7184);
  margin-top: 1px;
}

.grants-picker-foot {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 10px;
  flex-wrap: wrap;
}
.grants-picker-count {
  flex: 1;
  font-size: 13px;
  color: var(--text-muted, #6B7184);
}
.grants-picker-foot .btn {
  padding: 7px 14px;
  font-size: 13px;
}
.grants-picker-foot .btn:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}

/* ============================================================
 * Reports admin — grants modal v2 (2026-06-01).
 * Two-section layout: "Has access" first, "Add more people"
 * second. Audit folds into a small header stat row.
 * ============================================================ */
.grants-stat-row {
  margin-top: 6px !important;
  font-size: 12px !important;
}

.grants-section { margin-top: 16px; }
.grants-section:first-of-type { margin-top: 4px; }
.grants-section-head {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 8px;
}
.grants-section-count {
  display: inline-flex;
  align-items: center;
  height: 18px;
  padding: 0 7px;
  border-radius: 999px;
  background: var(--accent-wash, #F4F2FF);
  color: var(--accent-soft, #3D3AE0);
  font-size: 11px;
  font-weight: 600;
}
/* When the count is empty/0 from the JS, hide the chip. */
.grants-section-count:empty { display: none; }

/* Override the older single-column .grants-list to be a clean
 * card-style row list matching the picker. */
.grants-list {
  list-style: none;
  padding: 0;
  margin: 0;
  border: 1px solid var(--border, #E3E6EE);
  border-radius: 10px;
  background: #fff;
  max-height: 200px;
  overflow-y: auto;
}
.grants-list-empty {
  padding: 18px 16px;
  text-align: center;
  color: var(--text-muted, #6B7184);
  font-size: 13px;
}
.grants-list-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 8px 14px;
  border-bottom: 1px solid var(--border, #E3E6EE);
  font-size: 13.5px;
}
.grants-list-row:last-child { border-bottom: none; }
.grants-list-body {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.grants-list-name {
  font-weight: 500;
  color: var(--text-strong, #0C0E15);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.grants-list-email {
  font-size: 12px;
  color: var(--text-muted, #6B7184);
  margin-top: 1px;
}
.grants-list-remove {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 5px 10px;
  border: 1px solid var(--border, #E3E6EE);
  border-radius: 7px;
  background: #fff;
  color: var(--text-muted, #6B7184);
  font-size: 12px;
  font-weight: 500;
  cursor: pointer;
  transition: background .12s, color .12s, border-color .12s;
}
.grants-list-remove:hover {
  background: #FCEEEA;
  color: #C04A33;
  border-color: rgba(192,74,51,0.3);
}

/* "Select all visible" as a subtle link, not a heavy button. */
.grants-link {
  background: none;
  border: none;
  padding: 6px 4px;
  color: var(--accent, #4845FF);
  font-size: 12.5px;
  font-weight: 500;
  cursor: pointer;
}
.grants-link:hover { text-decoration: underline; }

/* ============================================================
 * Schema cache status row inside dataset-training cards.
 * Added 2026-06-04 as part of admin button + telemetry feature.
 * ============================================================ */
.schema-cache-row {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 14px;
  padding: 10px 12px;
  background: var(--bg-2, #F6F7FB);
  border: 1px solid var(--border, #E3E6EE);
  border-radius: 8px;
  font-size: 12.5px;
  flex-wrap: wrap;
}
.schema-cache-label {
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-faint, #9AA0AE);
  padding: 2px 8px;
  background: #fff;
  border-radius: 999px;
  border: 1px solid var(--border, #E3E6EE);
  flex-shrink: 0;
}
.schema-cache-status {
  flex: 1;
  min-width: 0;
  color: var(--text-muted, #6B7184);
  line-height: 1.5;
}
.schema-cache-status b {
  color: var(--text-strong, #0C0E15);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.schema-cache-rate,
.schema-cache-stale,
.schema-cache-err,
.schema-cache-empty {
  display: inline-block;
  padding: 1px 8px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 500;
  margin-left: 6px;
}
.schema-cache-rate {
  background: rgba(26,159,98,0.10);
  color: #1A9F62;
}
.schema-cache-stale {
  background: rgba(196,122,14,0.12);
  color: #C47A0E;
}
.schema-cache-err {
  background: #FCEEEA;
  color: #C04A33;
  cursor: help;
}
.schema-cache-empty {
  background: var(--bg-2, #F6F7FB);
  color: var(--text-faint, #9AA0AE);
}
.schema-cache-spacer { flex: 1; }
.schema-cache-refresh { flex-shrink: 0; }
