/* prism — "Operator Console" design language. Instrument-grade: Geist type,
   refined cool neutrals + one sharp electric-blue accent, layered depth, tight
   radius, subtle motion. Light + dark via [data-theme] on <html>.
   Token NAMES are stable (kept from the prior theme) so every tool inherits the
   refresh; only values evolved. New tokens added at the end of each block. */

/* Self-hosted Geist (OFL) — variable, covers all weights. CSP-safe (font-src 'self'). */
@font-face {
  font-family: "Geist";
  src: url("/fonts/Geist-Variable.woff2") format("woff2");
  font-weight: 100 900; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Geist Mono";
  src: url("/fonts/GeistMono-Variable.woff2") format("woff2");
  font-weight: 100 900; font-style: normal; font-display: swap;
}

:root {
  /* Accent (constant across themes — functional) */
  --brand: #2f63ff;
  --brand-hover: #1f4fe0;
  --brand-link: #2452d6;

  /* Light theme (default) */
  --bg: #eef1f5;
  --bg-elev: #f4f6f9;
  --surface: #ffffff;
  --surface-2: #f4f6f9;
  --surface-hover: #eff2f7;
  --border: #e3e7ee;
  --border-strong: #d2d8e2;
  --text: #0b0d12;
  --text-muted: #5a6373;

  --accent: var(--brand);
  --accent-soft: rgba(47, 99, 255, 0.10);
  --accent-press: #1f4fe0;
  --accent-ring: rgba(47, 99, 255, 0.28);
  --grid-line: rgba(11, 13, 18, 0.030);

  /* Semantic (unified status colors used by .badge + tool states) */
  --ok: #0a8a4d;  --ok-soft: rgba(10, 138, 77, 0.12);
  --warn: #b4760a; --warn-soft: rgba(180, 118, 10, 0.14);
  --bad: #d23b3b; --bad-soft: rgba(210, 59, 59, 0.12);

  --shadow-1: 0 1px 2px rgba(11, 13, 18, 0.05), 0 1px 1px rgba(11, 13, 18, 0.04);
  --shadow-card: 0 1px 2px rgba(11, 13, 18, 0.04), 0 10px 26px -12px rgba(11, 13, 18, 0.20);
  --shadow-pop: 0 8px 16px -6px rgba(11, 13, 18, 0.18), 0 24px 48px -16px rgba(11, 13, 18, 0.30);

  --radius: 11px;
  --radius-sm: 8px;
  --pill: 999px;
  --font: "Geist", ui-sans-serif, -apple-system, BlinkMacSystemFont, "Helvetica Neue", system-ui, sans-serif;
  --font-mono: "Geist Mono", ui-monospace, "SF Mono", "JetBrains Mono", Menlo, monospace;

  /* Spacing scale (4px base) */
  --s1: 4px; --s2: 8px; --s3: 12px; --s4: 16px; --s5: 24px; --s6: 32px;

  /* Motion tokens — shared durations + easings (mirror anim.js defaults) */
  --motion-fast: 0.16s;
  --motion-base: 0.26s;
  --motion-slow: 0.38s;
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
  --ease-spring: cubic-bezier(0.34, 1.4, 0.5, 1);
}

[data-theme="dark"] {
  --bg: #080a0e;
  --bg-elev: #14171d;
  --surface: #14171d;
  --surface-2: #1a1e26;
  --surface-hover: #1e232c;
  --border: #262b34;
  --border-strong: #353b46;
  --text: #f3f5f9;
  --text-muted: #99a2b2;

  --brand: #5d86ff;
  --brand-hover: #4a72f5;
  --brand-link: #82a2ff;
  --accent-soft: rgba(93, 134, 255, 0.16);
  --accent-press: #4a72f5;
  --accent-ring: rgba(93, 134, 255, 0.40);
  --grid-line: rgba(255, 255, 255, 0.028);

  --ok: #2fc07e;  --ok-soft: rgba(47, 192, 126, 0.16);
  --warn: #e0a23a; --warn-soft: rgba(224, 162, 58, 0.16);
  --bad: #f2685f; --bad-soft: rgba(242, 104, 95, 0.16);

  --shadow-1: 0 1px 2px rgba(0, 0, 0, 0.4);
  --shadow-card: 0 1px 2px rgba(0, 0, 0, 0.4), 0 12px 30px -14px rgba(0, 0, 0, 0.7);
  --shadow-pop: 0 12px 28px -8px rgba(0, 0, 0, 0.6), 0 30px 60px -20px rgba(0, 0, 0, 0.8);
}

* { box-sizing: border-box; }
[hidden] { display: none !important; } /* the hidden attribute must win over display rules */
html, body { height: 100%; }

/* Global reduced-motion guard — neutralize all animation/transition for users
   who request it. Progressive enhancement: UI stays fully functional. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* Accessible keyboard focus ring (reuses brand accent) */
:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; border-radius: 4px; }

/* Skip-to-content link: visually hidden until keyboard-focused, then pinned
   top-left above the topbar. Pure CSS (CSP-safe), zero visual impact otherwise. */
.skip-link {
  position: absolute;
  left: 8px;
  top: -48px;
  z-index: 1000;
  padding: 9px 14px;
  background: var(--brand);
  color: #fff;
  text-decoration: none;
  font-size: 0.9rem;
  font-weight: 600;
  border-radius: var(--radius-sm);
  transition: top var(--motion-fast) var(--ease-out);
}
.skip-link:focus { top: 8px; }

body {
  margin: 0;
  font-family: var(--font);
  font-size: 14px;
  line-height: 1.5;
  letter-spacing: -0.006em;
  background-color: var(--bg);
  /* Atmosphere: a soft accent wash + a faint instrument grid for depth. */
  background-image:
    radial-gradient(1100px 560px at 82% -12%, var(--accent-soft), transparent 60%),
    linear-gradient(var(--grid-line, rgba(11,13,18,.030)) 1px, transparent 1px),
    linear-gradient(90deg, var(--grid-line, rgba(11,13,18,.030)) 1px, transparent 1px);
  background-size: auto, 34px 34px, 34px 34px;
  background-attachment: fixed;
  color: var(--text);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

/* Page-load entrance — subtle rise + light stagger across panels and the hero.
   CSP-safe (pure CSS, no JS) and applies to JS-inserted panels too. The global
   reduced-motion guard neutralizes it automatically. */
/* Flash-free navigation between staff pages via cross-document View Transitions. Each
   sub-page is a full document load, so without this the WHOLE shell (Prism logo + top
   bar) repaints on every click — the "whole screen flashes" jitter. With it, the browser
   holds the old frame and cross-fades to the new one (no blank repaint), and the shell —
   top bar + footer — is given a stable view-transition-name so it HOLDS IN PLACE instead
   of repainting; only the page content cross-fades.
   Support: Chromium + Safari 18+. Other browsers (e.g. Firefox) fall back to a normal
   navigation — no worse than before. prefers-reduced-motion is honoured automatically
   (the instant swap stays; the cross-fade animation drops). */
@view-transition { navigation: auto; }
.topbar { view-transition-name: prism-topbar; }
.footer { view-transition-name: prism-footer; }
::view-transition-group(root) { animation-duration: 0.18s; }

/* ── Topbar ── */
.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 14px 28px;
  border-bottom: 1px solid var(--border);
  background: var(--bg);
  position: sticky;
  top: 0;
  z-index: 10;
}

.brand { display: inline-flex; align-items: center; gap: 11px; text-decoration: none; }
.brand-mark { display: block; border-radius: 8px; }
.brand-word {
  font-size: 1.3rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--text);
}

.topbar-right { display: flex; align-items: center; gap: 8px; }

/* ── Breadcrumb (wayfinding under the topbar) ── */
.breadcrumb { width: 100%; max-width: 1080px; margin: 0 auto; padding: 14px 28px 0; }
.breadcrumb-list { list-style: none; display: flex; flex-wrap: wrap; align-items: center; gap: 4px; margin: 0; padding: 0; font-size: 0.85rem; }
.breadcrumb-item { display: inline-flex; align-items: center; gap: 4px; }
.breadcrumb-link { color: var(--text-muted); text-decoration: none; border-radius: 6px; padding: 2px 6px; transition: color 0.15s ease, background 0.15s ease; }
.breadcrumb-link:hover { color: var(--brand-link); background: var(--accent-soft); }
.breadcrumb-sep { color: var(--text-muted); opacity: 0.55; }
.breadcrumb-cur { color: var(--text); font-weight: 600; padding: 2px 6px; }

.role-chip {
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  padding: 2px 9px;
  border-radius: var(--pill);
  color: var(--brand-link);
  background: var(--accent-soft);
  border: 1px solid transparent;
  white-space: nowrap;
}
[data-theme="dark"] .role-chip { color: #9db8ff; }

/* ── Theme toggle ── */
.icon-btn {
  display: inline-grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border-radius: var(--pill);
  border: 1px solid var(--border-strong);
  background: var(--surface);
  color: var(--text-muted);
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.icon-btn:hover { color: var(--text); background: var(--surface-hover); }
.icon-sun { display: none; }
[data-theme="dark"] .icon-sun { display: block; }
[data-theme="dark"] .icon-moon { display: none; }

/* ── Staff account menu ── */
.account-menu { position: relative; display: inline-flex; }
.account-menu-trigger {
  display: inline-flex; align-items: center; gap: 9px; min-height: 44px; max-width: 260px;
  padding: 7px 10px; border: 1px solid var(--border-strong); border-radius: var(--pill);
  background: var(--surface); color: var(--text); font: inherit; cursor: pointer;
  transition: background var(--motion-fast) var(--ease-out), border-color var(--motion-fast) var(--ease-out), box-shadow var(--motion-fast) var(--ease-out);
}
.account-menu-trigger:hover, .account-menu.is-open .account-menu-trigger { background: var(--surface-hover); border-color: var(--brand); }
.account-menu-trigger:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--accent-ring); }
.account-menu-avatar { flex: none; color: var(--brand-link); }
.account-trigger-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: .9rem; font-weight: 620; }
.account-menu-chevron { flex: none; color: var(--text-muted); transition: transform var(--motion-fast) var(--ease-out); }
.account-menu.is-open .account-menu-chevron { transform: rotate(180deg); }
.account-menu-panel {
  position: absolute; top: calc(100% + 8px); right: 0; z-index: 60; width: min(320px, calc(100vw - 32px));
  padding: 8px; border: 1px solid var(--border-strong); border-radius: var(--radius);
  background: var(--surface); box-shadow: var(--shadow-pop); color: var(--text);
}
.account-menu-identity { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; padding: 10px 10px 12px; }
.account-menu-name { max-width: 100%; overflow-wrap: anywhere; font-size: .95rem; line-height: 1.3; }
.account-menu-email { max-width: 100%; overflow-wrap: anywhere; color: var(--text-muted); font-size: .82rem; line-height: 1.35; }
.account-menu-roles { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 5px; }
.account-menu-item {
  display: flex; align-items: center; gap: 10px; min-height: 44px; width: 100%; padding: 9px 10px;
  border-radius: 7px; color: var(--text); font-size: .9rem; font-weight: 540; text-decoration: none;
  transition: background var(--motion-fast) var(--ease-out), color var(--motion-fast) var(--ease-out);
}
.account-menu-item:hover, .account-menu-item:focus-visible { background: var(--surface-hover); color: var(--brand-link); }
.account-menu-item:focus-visible { outline: 2px solid var(--brand-link); outline-offset: -2px; }
.account-menu-item.is-current { color: var(--brand-link); background: var(--accent-soft); }
.account-menu-item > svg { flex: none; }
.account-menu-external { margin-left: auto; color: var(--text-muted); }
.account-menu-separator { height: 1px; margin: 6px 4px; background: var(--border); }
.account-menu-signout { color: var(--bad); }
.account-menu-signout:hover, .account-menu-signout:focus-visible { color: var(--bad); background: var(--bad-soft); }

/* ── Buttons (Coinbase pill) ── */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 0.88rem;
  font-weight: 540;
  letter-spacing: 0.005em;
  padding: 9px 16px;
  border-radius: var(--pill);
  text-decoration: none;
  border: 1px solid transparent;
  cursor: pointer;
  transition: background var(--motion-fast) var(--ease-out), border-color var(--motion-fast) var(--ease-out),
              color var(--motion-fast) var(--ease-out), box-shadow var(--motion-fast) var(--ease-out), transform .06s var(--ease-out);
}
.btn:active { transform: translateY(1px) scale(.985); }
.btn:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--accent-ring); }
.btn-primary { background: var(--brand); color: #fff; box-shadow: var(--shadow-1), inset 0 1px 0 rgba(255, 255, 255, 0.22); }
.btn-primary:hover { background: var(--accent-press); box-shadow: var(--shadow-card); }
.btn-ghost { color: var(--text); border-color: var(--border-strong); background: var(--surface); }
.btn-danger { background: var(--bad); color: #fff; border-color: transparent; }
.btn-danger:hover { background: color-mix(in srgb, var(--bad) 86%, #000); }
.btn-danger[disabled], .btn[disabled] { opacity: .45; cursor: not-allowed; }

/* Super-admin destructive panel — visually set apart from the review controls. */
.cb-danger { border-color: #e7b9a8; background: #fdf3f0; }
.cb-danger h2 { color: #912018; }
.cb-danger-input { max-width: 220px; }
.btn-ghost:hover { background: var(--surface-hover); }

/* ── Content ── */
.content { flex: 1; width: 100%; max-width: 1080px; margin: 0 auto; padding: 48px 28px 64px; }

.hero { margin-bottom: 36px; }
.hero h1 { font-size: 1.95rem; font-weight: 700; letter-spacing: -0.02em; line-height: 1.1; margin: 0 0 6px; }
.hero-sub { color: var(--text-muted); margin: 0; font-size: 1rem; }
.muted { color: var(--text-muted); }

/* ── Tool grid ── */
.tool-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 18px; }

.tool-card {
  display: flex;
  gap: 16px;
  padding: 22px;
  border-radius: var(--radius);
  background: var(--surface);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-card);
  text-decoration: none;
  color: var(--text);
  position: relative;
  overflow: hidden;
  transition: border-color 0.18s ease, transform 0.18s ease, box-shadow 0.18s ease;
}
.tool-card::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 3px;
  background: var(--brand);
  opacity: 0;
  transition: opacity 0.18s ease;
}
.tool-card:not(.is-disabled):hover {
  border-color: var(--brand);
  transform: translateY(-2px);
  box-shadow: var(--shadow-pop);
}
.tool-card:not(.is-disabled):hover::before { opacity: 1; }
.tool-card.is-disabled { opacity: 0.6; cursor: default; }

.tool-icon {
  flex: none;
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  border-radius: 11px;
  color: var(--brand);
  background: var(--accent-soft);
}

.tool-body { min-width: 0; }
.tool-head { display: flex; align-items: center; gap: 10px; margin-bottom: 6px; }
.tool-head h3 { font-size: 1.05rem; font-weight: 650; margin: 0; }
.tool-body p { margin: 0; font-size: 0.9rem; color: var(--text-muted); line-height: 1.45; }

.badge {
  font-size: 0.64rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: 3px 9px;
  border-radius: var(--pill);
  color: var(--text-muted);
  background: var(--surface-2);
  border: 1px solid var(--border);
}

/* ── Brand sections ── */
.brand-section { margin-bottom: 34px; }
.brand-section:last-child { margin-bottom: 0; }
.brand-heading {
  font-size: 0.74rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--text-muted);
  margin: 0 0 14px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--border);
}

.badge-shared {
  color: var(--brand-link);
  background: var(--accent-soft);
  border-color: transparent;
}
[data-theme="dark"] .badge-shared { color: #9db8ff; }

/* ── Empty / error ── */
.empty {
  text-align: center;
  padding: 60px 20px;
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius);
  background: var(--bg-elev);
}
.empty p { margin: 6px 0; }

/* ── What's New ──
   Content-first release timeline. Filtering is server-rendered; JS only adds a
   subtle entrance, so links/content remain complete under strict CSP or no JS. */
.content:has(.wn-hero) { max-width: 920px; }
.wn-hero { max-width: 720px; margin-bottom: 24px; }
.wn-eyebrow { margin: 0 0 8px; color: var(--brand-link); font-size: .72rem; font-weight: 750; letter-spacing: .09em; text-transform: uppercase; }
.wn-hero h1 { margin: 0 0 10px; font-size: clamp(2rem, 5vw, 3rem); line-height: 1.05; letter-spacing: -.035em; }
.wn-lead { margin: 0; max-width: 62ch; color: var(--text-muted); font-size: 1rem; line-height: 1.6; }
.wn-access { margin: 14px 0 0; color: var(--text-muted); font-size: .84rem; }
.wn-access strong { color: var(--text); }
.wn-filters { display: flex; flex-wrap: wrap; gap: 8px; padding: 14px 0 20px; border-top: 1px solid var(--border); border-bottom: 1px solid var(--border); }
.wn-filter { display: inline-flex; align-items: center; min-height: 44px; padding: 9px 15px; border: 1px solid var(--border-strong); border-radius: var(--pill); background: var(--surface); color: var(--text-muted); font-size: .86rem; font-weight: 650; text-decoration: none; transition: color .16s ease, border-color .16s ease, background .16s ease, transform .06s ease; }
.wn-filter:hover { color: var(--text); border-color: var(--brand); background: var(--surface-hover); }
.wn-filter:active { transform: translateY(1px); }
.wn-filter.is-active { color: #fff; border-color: var(--brand); background: var(--brand); box-shadow: var(--shadow-1); }
.wn-count { margin: 18px 0 14px; color: var(--text-muted); font-size: .82rem; font-weight: 650; }
.wn-timeline { position: relative; }
.wn-timeline::before { content: ''; position: absolute; top: 16px; bottom: 24px; left: 7px; width: 2px; background: var(--border); }
.wn-release { position: relative; display: grid; grid-template-columns: 16px minmax(0, 1fr); gap: 18px; padding-bottom: 18px; }
.wn-marker { position: relative; z-index: 1; width: 16px; height: 16px; margin-top: 24px; border: 4px solid var(--bg); border-radius: 50%; background: var(--brand); box-shadow: 0 0 0 1px var(--brand); }
.wn-card { min-width: 0; padding: 20px 22px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); box-shadow: var(--shadow-card); }
.wn-card h2 { margin: 10px 0 8px; font-size: 1.12rem; line-height: 1.3; letter-spacing: -.012em; }
.wn-card ul { margin: 0; padding-left: 20px; color: var(--text-muted); }
.wn-card li { margin: 5px 0; padding-left: 2px; }
.wn-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 7px; color: var(--text-muted); font-size: .76rem; }
.wn-scope, .wn-type { display: inline-flex; align-items: center; min-height: 24px; padding: 3px 9px; border-radius: var(--pill); font-size: .66rem; font-weight: 750; letter-spacing: .035em; text-transform: uppercase; }
.wn-scope { color: var(--brand-link); background: var(--accent-soft); }
.wn-type-new { color: #087443; background: rgba(5, 150, 105, .12); }
.wn-type-improvement { color: #8a5a00; background: rgba(245, 158, 11, .13); }
.wn-type-fix { color: #2459a9; background: rgba(37, 99, 235, .11); }
.wn-type-security { color: #a8321e; background: rgba(212, 56, 13, .11); }
[data-theme="dark"] .wn-type-new { color: #7ee2ad; }
[data-theme="dark"] .wn-type-improvement { color: #ffd18c; }
[data-theme="dark"] .wn-type-fix { color: #9fc0ff; }
[data-theme="dark"] .wn-type-security { color: #ffaaa0; }
.wn-version { font-variant-numeric: tabular-nums; font-weight: 700; color: var(--text); }
.wn-meta time { white-space: nowrap; }

.error-page { text-align: center; padding: 80px 20px; }
.error-code { font-size: 4.5rem; font-weight: 800; letter-spacing: -0.03em; color: var(--brand); line-height: 1; }
.error-page h1 { font-size: 1.5rem; margin: 10px 0 8px; }
.error-actions { display: flex; gap: 12px; justify-content: center; margin-top: 26px; }

/* ── Footer ── */
.footer { border-top: 1px solid var(--border); padding: 18px 28px; color: var(--text-muted); font-size: 0.82rem; text-align: center; display: flex; gap: 10px; align-items: center; justify-content: center; }
.footer-version { font: inherit; font-size: 0.72rem; font-weight: 600; padding: 2px 9px; border-radius: var(--pill); background: var(--surface-2); color: var(--text-muted); border: 1px solid transparent; cursor: pointer; }
.footer-version:hover { color: var(--text); border-color: var(--border); }
.footer-version:focus-visible { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-ring); }

/* Tool-versions modal (footer version → click). */
.version-modal { position: fixed; inset: 0; z-index: 1000; display: flex; align-items: center; justify-content: center; padding: 20px; }
.version-modal[hidden] { display: none; }
.version-modal-backdrop { position: absolute; inset: 0; background: rgba(15, 23, 42, 0.45); }
.version-modal-card { position: relative; width: 100%; max-width: 440px; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow-pop); padding: 22px 24px; }
.version-modal-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
.version-modal-title { margin: 0; font-size: 1.05rem; }
.version-modal-build { margin: 2px 0 0; font-size: 0.78rem; color: var(--text-muted); }
.version-modal-x { font: inherit; font-size: 1.4rem; line-height: 1; background: none; border: none; color: var(--text-muted); cursor: pointer; padding: 0 4px; }
.version-modal-x:hover { color: var(--text); }
.version-modal-sub { margin: 10px 0 14px; font-size: 0.85rem; color: var(--text-muted); }
.version-modal-table { width: 100%; border-collapse: collapse; }
.version-modal-table th, .version-modal-table td { text-align: left; padding: 8px 0; font-size: 0.9rem; border-bottom: 1px solid var(--border); }
.version-modal-table th { color: var(--text-muted); font-weight: 600; }
.version-modal-table th.num, .version-modal-table td.num { text-align: right; font-variant-numeric: tabular-nums; }

/* ── Admin: tabs + integrations ── */
/* Platform settings sub-tabs (progressive enhancement). No-JS: nav hidden, all panels
   show (scroll). With JS (.js-tabs): pill nav + only the active panel shown. */
.admin-subtabs { display: none; gap: 6px; flex-wrap: wrap; margin: 4px 0 20px; }
.js-tabs .admin-subtabs { display: flex; }
.admin-subtab { padding: 8px 16px; font: inherit; font-size: 0.9rem; font-weight: 600; color: var(--text-muted);
  background: var(--surface); border: 1px solid var(--border); border-radius: 999px; cursor: pointer; transition: color .12s, border-color .12s, background .12s; }
.admin-subtab:hover { color: var(--text); border-color: var(--text-muted); }
.admin-subtab.is-active { color: var(--text); border-color: var(--accent); background: var(--surface-2); }
.js-tabs .subtab-panel { display: none; }
.js-tabs .subtab-panel.is-active { display: block; }

/* Group label above a cluster of related admin panels (legacy / no-JS grouping). */
.admin-group-label { font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.09em; font-weight: 700; color: var(--text-muted); margin: 26px 0 12px; }
.admin-subhead { font-size: 0.95rem; font-weight: 650; margin: 22px 0 10px; }
/* Content-sized admin table (auto layout) — headers sit snug over their values, unlike
   the fixed-layout .audit-table tuned for the audit log's specific columns. */
.admin-table { width: 100%; border-collapse: collapse; }
.admin-table th, .admin-table td { text-align: left; padding: 8px 16px 8px 0; font-size: 0.9rem; line-height: 1.4; border-bottom: 1px solid var(--border); }
.admin-table th { color: var(--text-muted); font-weight: 600; }
.admin-table th:last-child, .admin-table td:last-child { padding-right: 0; }
.admin-table th.num, .admin-table td.num { text-align: right; font-variant-numeric: tabular-nums; }

.admin-tabs { display: flex; gap: 6px; margin-bottom: 22px; border-bottom: 1px solid var(--border); }
.admin-tab {
  padding: 9px 14px;
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--text-muted);
  text-decoration: none;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
}
.admin-tab:hover { color: var(--text); }
.admin-tab.is-active { color: var(--brand); border-bottom-color: var(--brand); }

.warn-banner {
  padding: 12px 16px;
  margin-bottom: 18px;
  border-radius: var(--radius-sm);
  font-size: 0.88rem;
  color: #8a5a00;
  background: rgba(245, 158, 11, 0.12);
  border: 1px solid rgba(245, 158, 11, 0.4);
}
[data-theme="dark"] .warn-banner { color: #ffd9a8; }

/* ── Notification outbox (admin) ──────────────────────────────────────────── */
/* Secondary sub-nav (Preferences | Outbox) beneath the main .admin-tabs — a lighter
   pill treatment so it reads as a sub-level, not a peer of the top tab bar. */
.obx-subnav { display: flex; gap: 6px; margin: 2px 0 18px; }
.obx-subnav a {
  padding: 5px 12px; font-size: 0.82rem; font-weight: 600;
  color: var(--text-muted); text-decoration: none;
  border: 1px solid var(--border); border-radius: 999px; background: var(--surface);
}
.obx-subnav a:hover { color: var(--text); border-color: var(--text-muted); }
.obx-subnav a[aria-current="page"] { color: #fff; background: var(--brand); border-color: var(--brand); }

/* Filter row — one horizontal line, label beside control, actions pinned right. */
.obx-filters { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; margin-bottom: 16px; }
.obx-filters .obx-field { display: inline-flex; align-items: center; gap: 6px; }
.obx-filters .obx-field > span { font-size: 0.8rem; font-weight: 600; color: var(--text-muted); white-space: nowrap; }
.obx-filters .input { margin: 0; width: auto; }
.obx-filters select.input { min-width: 130px; }
.obx-filters .obx-actions { margin-left: auto; display: inline-flex; gap: 8px; }

/* Explicit "Redirected" indicator — replaces the cryptic bare ↪ address. */
.badge-redirect { background: var(--accent-soft); color: var(--brand-link); }

/* Fixed layout via <colgroup> so long recipients/errors can't shove Actions off-screen. */
.obx-table { table-layout: fixed; }
.obx-table th.obx-nowrap, .obx-table td.obx-nowrap { white-space: nowrap; }
.obx-table td.obx-detail { max-width: 0; }             /* fixed-layout: cell obeys its colgroup width */
.obx-table .obx-ellip { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.obx-table td.obx-actions { white-space: nowrap; }

.search-status.is-ok { color: #0a7d33; }
[data-theme="dark"] .search-status.is-ok { color: #7ee29a; }

.panel-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 12px; }
.panel-head h2 { margin: 0; font-size: 1.05rem; font-weight: 650; }

.secret-table { width: 100%; border-collapse: collapse; }
.secret-table td { padding: 14px 0; border-bottom: 1px solid var(--border); vertical-align: middle; }
.secret-table tr:last-child td { border-bottom: none; }
.secret-meta code { font-size: 0.78rem; color: var(--text-muted); }

.source-chip {
  display: inline-block;
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  padding: 2px 9px;
  border-radius: var(--pill);
  border: 1px solid transparent;
}
.source-db { color: #0a7d33; background: rgba(16, 185, 129, 0.14); }
.source-env { color: #8a5a00; background: rgba(245, 158, 11, 0.14); }
.source-unset { color: var(--text-muted); background: var(--surface-2); }
[data-theme="dark"] .source-db { color: #7ee29a; }
[data-theme="dark"] .source-env { color: #ffd9a8; }

.secret-set { display: flex; gap: 8px; align-items: center; justify-content: flex-end; }
.secret-input {
  width: 240px;
  max-width: 42vw;
  padding: 8px 12px;
  font-size: 0.85rem;
  color: var(--text);
  background: var(--bg-elev);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  outline: none;
}
.secret-input:focus { border-color: var(--brand); }
/* Masked/plain current-value preview under the source chip. */
.secret-current { margin-top: 4px; font-family: var(--mono, monospace); font-size: 0.78rem; word-break: break-all; }
/* Secret inputs get an inline show/hide toggle so the value isn't masked while typing. */
.secret-reveal-wrap { display: inline-flex; align-items: center; gap: 4px; }
.secret-reveal { padding: 4px 8px; line-height: 1; opacity: 0.6; }
.secret-reveal.is-on { opacity: 1; }

/* ── Shared Help drawer (window.prismHelp) — consistent help UI across all tools ── */
.prism-help-root { position: fixed; inset: 0; z-index: 1000; }
.prism-help-backdrop { position: absolute; inset: 0; background: rgba(0, 0, 0, 0.35); opacity: 0; transition: opacity 0.2s ease; }
.prism-help-panel { position: absolute; top: 0; right: 0; height: 100%; width: 460px; max-width: 92vw; background: var(--bg-elev, #fff); box-shadow: -8px 0 28px rgba(0, 0, 0, 0.18); display: flex; flex-direction: column; transform: translateX(100%); transition: transform 0.2s ease; }
.prism-help-root.is-open .prism-help-backdrop { opacity: 1; }
.prism-help-root.is-open .prism-help-panel { transform: translateX(0); }
.prism-help-head { display: flex; align-items: center; justify-content: space-between; padding: 16px 20px; border-bottom: 1px solid var(--border); }
.prism-help-head h2 { margin: 0; font-size: 1.05rem; }
.prism-help-intro { padding: 12px 20px 0; margin: 0; color: var(--text-muted); font-size: 0.85rem; }
.prism-help-search { margin: 12px 20px; padding: 8px 12px; border: 1px solid var(--border-strong); border-radius: var(--radius-sm); background: var(--bg); color: var(--text); font-size: 0.85rem; outline: none; }
.prism-help-search:focus { border-color: var(--brand); }
.prism-help-body { overflow-y: auto; padding: 0 20px 24px; flex: 1; }
.prism-help-body details { border-bottom: 1px solid var(--border); }
.prism-help-body summary { cursor: pointer; padding: 12px 0; font-weight: 600; font-size: 0.9rem; list-style: revert; }
.prism-help-section { padding: 0 0 12px; font-size: 0.85rem; line-height: 1.55; color: var(--text); }
.prism-help-section p { margin: 6px 0; }
.prism-help-section ul { margin: 6px 0; padding-left: 20px; }
.prism-help-section li { margin: 4px 0; }
.prism-help-section code { background: var(--surface-2); padding: 1px 5px; border-radius: 4px; font-size: 0.82em; }
@media (max-width: 560px) { .prism-help-panel { width: 100vw; } }

/* ── Admin: users & roles ── */
.admin-panel {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-card);
  padding: 22px 24px;
  margin-bottom: 20px;
}
.admin-panel h2 { font-size: 1.05rem; font-weight: 650; margin: 0 0 16px; }

/* Settings page: each section (Notifications, …) sits under a divider. */
.settings-group { margin-top: 24px; padding-top: 20px; border-top: 1px solid var(--border); }
.settings-group > h2 { margin-bottom: 6px; }
.settings-group h3 { font-size: 0.92rem; font-weight: 650; margin: 18px 0 10px; color: var(--text-muted); }

.search-row input {
  width: 100%;
  padding: 12px 15px;
  font-size: 0.95rem;
  color: var(--text);
  background: var(--bg-elev);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  outline: none;
}
.search-row input:focus { border-color: var(--brand); }
.search-status { margin: 10px 2px 0; font-size: 0.85rem; }
.search-status.is-error { color: #d4380d; }
[data-theme="dark"] .search-status.is-error { color: #ff9a9a; }

/* Non-color status cues (R8): leading glyph so state isn't conveyed by color alone.
   Scoped to the admin status containers toggled by setStatus(); inherits color. */
#search-status.is-error::before,
#integrations-status.is-error::before { content: "\26A0\00A0"; }
#search-status.is-ok::before,
#integrations-status.is-ok::before { content: "\2713\00A0"; }

.search-results { list-style: none; margin: 14px 0 0; padding: 0; }
.result-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  margin-bottom: 8px;
  background: var(--bg-elev);
}
.result-controls { display: flex; gap: 14px; align-items: center; flex-wrap: wrap; justify-content: flex-end; }

.role-checks { display: flex; gap: 8px 12px; flex-wrap: wrap; }
.role-check {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 0.85rem;
  color: var(--text);
  cursor: pointer;
  user-select: none;
  padding: 5px 10px;
  border: 1px solid var(--border-strong);
  border-radius: var(--pill);
  background: var(--surface);
}
.role-check:hover { border-color: var(--brand); }
.role-check input { accent-color: var(--brand); cursor: pointer; }

.cell-name { font-weight: 600; font-size: 0.92rem; }
.cell-email { font-size: 0.82rem; }

.assign-table { width: 100%; border-collapse: collapse; }
.assign-table th {
  text-align: left;
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-muted);
  padding: 0 0 10px;
  border-bottom: 1px solid var(--border);
}
.assign-table td { padding: 14px 0; border-bottom: 1px solid var(--border); vertical-align: top; }
.assign-table tr:last-child td { border-bottom: none; }
/* The consultants table's own cell-date rule is scoped to [data-consultant-table], so the
   Users & roles last-login column needs its own: a bare yyyy-mm-dd otherwise wraps mid-date
   when the roles column is wide. */
.assign-table td.cell-date { white-space: nowrap; }

.chip-row { display: flex; flex-wrap: wrap; gap: 8px; }
.role-chip.removable { display: inline-flex; align-items: center; gap: 6px; padding-right: 5px; }

/* Apps & roles table: readable inter-column gutter (the base table runs columns
   flush) + body-cell text scaled to match .cell-name rather than raw body font. */
.apps-table th,
.apps-table td { padding-right: 28px; }
.apps-table th:last-child,
.apps-table td:last-child { padding-right: 0; }
/* Keep headers and app names on one line, but let first-column body text (app
   descriptions) wrap — a nowrap on the whole td forces the table wider than the
   panel and pushes the trailing columns outside the card. */
.apps-table th:first-child,
.apps-table td:first-child .cell-name { white-space: nowrap; }
.cell-text { font-size: 0.9rem; color: var(--text); line-height: 1.45; }

/* ── Audit log: filter grid + readable table ──────────────────────────────── */

/* Filter controls on a responsive grid so they share one rhythm instead of a mix
   of full-width inputs and shrink-wrapped native selects. */
.audit-filters { margin-bottom: 18px; }
.audit-filter-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 12px;
}
.audit-filter-grid > .span-all { grid-column: 1 / -1; }

.audit-filter-grid input,
.audit-filter-grid select {
  width: 100%;
  box-sizing: border-box;
  padding: 11px 13px;
  font-family: var(--font);
  font-size: 0.9rem;
  color: var(--text);
  background: var(--bg-elev);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  outline: none;
  transition: border-color var(--motion-fast) var(--ease-out);
  appearance: none;
}
.audit-filter-grid input:focus,
.audit-filter-grid select:focus { border-color: var(--brand); }
/* Native select chevron (appearance:none removes the default) */
.audit-filter-grid .select-wrap { position: relative; }
.audit-filter-grid .select-wrap::after {
  content: "";
  position: absolute;
  right: 14px;
  top: 50%;
  width: 8px; height: 8px;
  margin-top: -6px;
  border-right: 2px solid var(--text-muted);
  border-bottom: 2px solid var(--text-muted);
  transform: rotate(45deg);
  pointer-events: none;
}
.audit-filter-grid select { padding-right: 32px; }

/* Multi-select popover (native <details>; JS only enhances). Summary mirrors the
   input styling; the panel floats so it never reflows the grid. */
.multiselect { position: relative; }
.multiselect > summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 11px 13px;
  font-size: 0.9rem;
  color: var(--text);
  background: var(--bg-elev);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  transition: border-color var(--motion-fast) var(--ease-out);
}
.multiselect > summary::-webkit-details-marker { display: none; }
.multiselect > summary::after {
  content: "";
  width: 7px; height: 7px;
  border-right: 2px solid var(--text-muted);
  border-bottom: 2px solid var(--text-muted);
  transform: rotate(45deg);
  margin-top: -3px;
  flex: none;
  transition: transform var(--motion-fast) var(--ease-out);
}
.multiselect[open] > summary { border-color: var(--brand); }
.multiselect[open] > summary::after { transform: rotate(-135deg); margin-top: 2px; }
.ms-count {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 18px; height: 18px; padding: 0 5px;
  font-size: 0.72rem; font-weight: 650;
  color: #fff; background: var(--brand);
  border-radius: var(--pill);
}
.ms-panel {
  position: absolute; z-index: 20;
  top: calc(100% + 4px); left: 0; right: 0;
  max-height: 260px; overflow-y: auto;
  padding: 6px;
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-pop);
}
.ms-opt {
  display: flex; align-items: center; gap: 9px;
  padding: 8px 9px;
  font-size: 0.875rem;
  border-radius: 8px;
  cursor: pointer;
}
.ms-opt:hover { background: var(--surface-hover); }
/* Restore the native checkbox — the grid-wide `appearance:none` (for text/select
   controls) also matches these nested inputs and would blank out the checkmark. */
.ms-opt input[type="checkbox"] {
  width: 16px; height: 16px;
  margin: 0; padding: 0; flex: none;
  -webkit-appearance: auto;
  appearance: auto;
  accent-color: var(--brand);
}

.audit-actions { display: flex; gap: 10px; align-items: center; margin-top: 14px; }
.audit-export { margin: 0 0 16px; font-size: 0.85rem; color: var(--text-muted); }
.audit-export a { color: var(--brand-link); }

@media (max-width: 720px) {
  .audit-filter-grid { grid-template-columns: 1fr; }
}

/* Table: real inter-column gutters so long emails never collide with the next
   column. Fixed-ish widths keep the layout stable as values vary in length. */
.audit-table { table-layout: fixed; }
.audit-table th,
.audit-table td { padding-right: 28px; }
.audit-table th:last-child,
.audit-table td:last-child { padding-right: 0; }
.audit-table td { font-size: 0.9rem; line-height: 1.45; }

.audit-table .col-when { width: 12%; }
.audit-table .col-when .when-rel { display: block; white-space: nowrap; color: var(--text); }
.audit-table .col-when .when-abs { display: block; white-space: nowrap; font-size: 0.78rem; color: var(--text-muted); margin-top: 2px; }
.audit-table .col-user { width: 24%; word-break: break-word; }
.audit-table .col-tool { width: 15%; word-break: break-word; }
.audit-table .col-action { width: 19%; }
.audit-table .col-entity { width: 22%; word-break: break-all; color: var(--text-muted); }
.audit-table .col-link { width: 8%; text-align: right; white-space: nowrap; }
.audit-table .col-link a { color: var(--brand-link); }

/* Clickable rows */
.audit-table tr.is-clickable { cursor: pointer; }
.audit-table tbody tr.is-clickable:hover { background: var(--surface-hover); }

/* Action badges — semantic color so the log scans fast. Subtle tints, not loud. */
.action-badge {
  display: inline-block;
  padding: 3px 8px;
  font-size: 0.8rem;
  border-radius: 6px;
  white-space: nowrap;
}
.badge-positive { background: rgba(0, 82, 255, 0.10); color: var(--brand-link); }
.badge-warn     { background: rgba(214, 122, 13, 0.12); color: #b3590a; }
.badge-danger,
.badge-negative { background: rgba(212, 56, 13, 0.10); color: #c0341a; } /* -negative: legacy alias used by JS/EJS */
.badge-neutral  { background: var(--surface-2); color: var(--text-muted); }
[data-theme="dark"] .badge-warn   { color: #f0a868; }
[data-theme="dark"] .badge-danger,
[data-theme="dark"] .badge-negative { color: #ff9a8a; }

/* "Needs attention" strip atop the Consultant Billing review queue */
.cb-attention-strip { display: flex; gap: 6px; align-items: center; cursor: pointer; padding: 8px 12px; margin: 8px 0 14px; border: 1px solid color-mix(in srgb, var(--warn) 45%, transparent); border-radius: 8px; background: var(--warn-soft); color: var(--warn); font-weight: 600; }
.cb-attention-strip:hover { background: color-mix(in srgb, var(--warn) 22%, transparent); }

/* Active-filter chips */
.filter-chips { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 0 0 14px; }
.filter-chips-label { font-size: 0.8rem; color: var(--text-muted); }
.filter-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 10px;
  font-size: 0.82rem;
  color: var(--text);
  text-decoration: none;
  background: var(--accent-soft);
  border: 1px solid transparent;
  border-radius: var(--pill);
  transition: border-color var(--motion-fast) var(--ease-out);
}
.filter-chip:hover { border-color: var(--brand); }
.filter-chip-x { color: var(--text-muted); font-size: 1rem; line-height: 1; }

/* Platform settings form */
.form-banner { padding: 10px 14px; border-radius: var(--radius-sm); font-size: 0.9rem; margin: 0 0 16px; }
.form-banner.is-ok { background: var(--accent-soft); color: var(--brand-link); }
.form-banner.is-error { background: rgba(212, 56, 13, 0.10); color: #c0341a; }

.settings-form { display: flex; flex-direction: column; gap: 16px; max-width: 420px; margin-top: 8px; }
.settings-form .field { display: flex; flex-direction: column; gap: 6px; }
.settings-form .field-label { font-size: 0.85rem; font-weight: 600; color: var(--text); }
.settings-form .field input[type="number"],
.settings-form .field input[type="text"],
.settings-form .field select {
  width: 100%; box-sizing: border-box;
  padding: 11px 13px; font-size: 0.95rem; font-family: var(--font);
  color: var(--text); background: var(--bg-elev);
  border: 1px solid var(--border-strong); border-radius: var(--radius-sm); outline: none;
}
.settings-form .field input:focus,
.settings-form .field select:focus { border-color: var(--brand); }
.settings-form .field-check { flex-direction: row; align-items: center; gap: 9px; }
.settings-form .field-check input { width: 16px; height: 16px; accent-color: var(--brand); }
.settings-actions { display: flex; gap: 10px; align-items: center; margin-top: 18px; }
/* Vertically-stacked action buttons (e.g. the Manager rail actions) — content-width, left-aligned, evenly spaced. */
.cb-btn-stack { display: flex; flex-direction: column; align-items: flex-start; gap: 10px; }
.settings-meta { margin-top: 14px; font-size: 0.82rem; }

/* AP invoice-ingestion (scan-to-prefill) — upload drop zone + candidate-review table.
   Parallel to the consultant portal's .cp-drop / .cp-review styling (kept in sync). */
.cb-drop { display: flex; align-items: center; justify-content: center; gap: 8px; text-align: center;
  border: 1.5px dashed var(--border-strong); border-radius: 12px; padding: 22px 16px; margin: 6px 0 10px;
  color: var(--text-muted); cursor: pointer; transition: border-color var(--motion-fast) var(--ease-out), background var(--motion-fast) var(--ease-out); }
.cb-drop:hover, .cb-drop:focus-visible { border-color: var(--brand); background: var(--surface-hover); outline: none; }
.cb-drop.is-over { border-color: var(--brand); background: color-mix(in srgb, var(--brand) 8%, var(--surface)); }
.cb-file-list { display: flex; flex-direction: column; gap: 6px; }
.cb-file-row { display: flex; align-items: center; gap: 8px; padding: 6px 8px; border: 1px solid var(--border); border-radius: 8px; }
.cb-file-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 0.86rem; }
/* (The ingestion progress line's spacing lives with .cb-help below — it has to override it.) */
.cb-review-table th, .cb-review-table td { vertical-align: top; }
.cb-review-flag > td { background: color-mix(in srgb, #f59e0b 12%, var(--surface)); }
.cb-review-note > td { font-size: 0.8rem; padding-top: 2px; }
.cb-review-warn { color: #92400e; }
[data-theme="dark"] .cb-review-warn { color: #fbbf24; }

/* Reusable per-entity audit trail (drill-down widget) */
.trail-list { list-style: none; margin: 8px 0 0; padding: 0; }
.trail-item { border-bottom: 1px solid var(--border); }
.trail-item:last-child { border-bottom: none; }
.trail-link {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 4px;
  text-decoration: none; color: var(--text);
  border-radius: 8px;
  transition: background var(--motion-fast) var(--ease-out);
}
.trail-link:hover { background: var(--surface-hover); }
.trail-meta { font-size: 0.82rem; color: var(--text-muted); }

/* Infinite-scroll sentinel */
#audit-sentinel { padding: 18px 0 4px; text-align: center; }
.audit-loading { font-size: 0.85rem; color: var(--text-muted); }
.audit-end { text-align: center; padding-top: 16px; }

/* Status pill — positive (Live) vs neutral (everything else) on the .badge base.
   nowrap keeps "Coming soon" on one line in the narrow status column. */
.apps-table .badge { display: inline-block; white-space: nowrap; }
.badge-live { color: #0a7d33; background: rgba(10, 125, 51, 0.10); border-color: transparent; }
[data-theme="dark"] .badge-live { color: #7ee29a; background: rgba(126, 226, 154, 0.12); }
.chip-x {
  display: inline-grid;
  place-items: center;
  width: 18px;
  height: 18px;
  border: none;
  border-radius: 50%;
  cursor: pointer;
  font-size: 0.9rem;
  line-height: 1;
  color: var(--brand-link);
  background: rgba(0, 82, 255, 0.12);
}
.chip-x:hover { background: #d4380d; color: #fff; }
.chip-x:disabled { opacity: 0.4; cursor: default; }

/* ── Auth / login page ── */
.auth-topbar { display: flex; justify-content: flex-end; padding: 16px 20px; }
.auth-wrap { flex: 1; display: grid; place-items: center; padding: 16px 20px 64px; }
.auth-card {
  width: 100%;
  max-width: 400px;
  text-align: center;
  padding: 40px 32px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 20px;
  box-shadow: var(--shadow-card);
}
.auth-mark { display: block; margin: 0 auto 22px; border-radius: 12px; box-shadow: 0 8px 24px rgba(0, 82, 255, 0.28); }
.auth-title { font-size: 1.55rem; font-weight: 700; letter-spacing: -0.02em; margin: 0 0 8px; }
.auth-sub { color: var(--text-muted); font-size: 0.95rem; line-height: 1.5; margin: 0 0 28px; }

.ms-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  width: 100%;
  padding: 13px 18px;
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--text);
  background: var(--bg-elev);
  border: 1px solid var(--border-strong);
  border-radius: var(--pill);
  text-decoration: none;
  transition: border-color 0.15s ease, background 0.15s ease, transform 0.05s ease;
}
.ms-btn:hover { border-color: var(--brand); background: var(--surface-hover); }
.ms-btn:active { transform: translateY(1px); }

.auth-note { color: var(--text-muted); font-size: 0.78rem; line-height: 1.5; margin: 24px 0 0; }
.auth-footer { text-align: center; padding: 18px; color: var(--text-muted); font-size: 0.82rem; }

/* ── AVD Reporter tool ── */
.avd-search-grid { display: grid; grid-template-columns: 1fr 160px 160px auto; gap: 14px; align-items: end; }
.avd-field label { display: block; font-size: 0.78rem; font-weight: 600; color: var(--text-muted); margin-bottom: 6px; }
.avd-field input, #avd-group {
  width: 100%; padding: 9px 12px; font-size: 0.9rem; color: var(--text);
  background: var(--bg-elev); border: 1px solid var(--border-strong); border-radius: var(--radius-sm); outline: none;
}
.avd-field input:focus, #avd-group:focus { border-color: var(--brand); }
.avd-field-btn .btn { width: 100%; }
.avd-suggest-wrap { position: relative; }
.avd-suggest { display: none; position: absolute; z-index: 20; left: 0; right: 0; top: calc(100% + 4px); background: var(--surface); border: 1px solid var(--border-strong); border-radius: var(--radius-sm); box-shadow: var(--shadow-pop); max-height: 260px; overflow: auto; }
.avd-suggest.open { display: block; }
.avd-sug-item { padding: 9px 12px; font-size: 0.88rem; cursor: pointer; }
.avd-sug-item:hover { background: var(--surface-hover); }

.avd-log { list-style: none; margin: 0 0 20px; padding: 14px 16px; background: var(--bg-elev); border: 1px solid var(--border); border-radius: var(--radius-sm); max-height: 200px; overflow: auto; font-size: 0.82rem; }
.avd-log li { padding: 2px 0; color: var(--text-muted); }
.avd-log-done { color: #0a7d33; } .avd-log-warn { color: #8a5a00; } .avd-log-err { color: #d4380d; }
[data-theme="dark"] .avd-log-done { color: #7ee29a; } [data-theme="dark"] .avd-log-warn { color: #ffd9a8; } [data-theme="dark"] .avd-log-err { color: #ff9a9a; }
/* Non-color status cues (R8): leading glyph on AVD log lines; inherits color. */
.avd-log-err::before { content: "\26A0\00A0"; }
.avd-log-warn::before { content: "\26A0\00A0"; }
.avd-log-done::before { content: "\2713\00A0"; }
.avd-log-working { display: flex; align-items: center; gap: 8px; color: var(--brand-link); font-weight: 600; }
.avd-log-spinner { display: inline-block; width: 12px; height: 12px; border-radius: 50%; border: 2px solid currentColor; border-top-color: transparent; animation: prism-spin 0.6s linear infinite; }
@media (prefers-reduced-motion: reduce) { .avd-log-spinner { animation: none; } }

.avd-summary { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 16px; margin-bottom: 22px; }
.sum-card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow-card); padding: 18px 20px; }
.sum-lbl { font-size: 0.74rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-muted); font-weight: 700; }
.sum-val { font-size: 1.8rem; font-weight: 700; letter-spacing: -0.02em; margin: 6px 0 2px; }
.sum-hint { font-size: 0.78rem; color: var(--text-muted); }

.avd-results-head { flex-wrap: wrap; gap: 12px; }
.avd-results-controls { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.avd-group-label { font-size: 0.8rem; color: var(--text-muted); display: inline-flex; align-items: center; gap: 8px; white-space: nowrap; }
.avd-group-label select { padding: 6px 10px; border-radius: 8px; }
.avd-group-label .dd { width: 170px; flex: 0 0 auto; }
.avd-cols { position: relative; }
.avd-cols-pop { position: absolute; right: 0; top: calc(100% + 6px); z-index: 20; width: 230px; padding: 14px; background: var(--surface); border: 1px solid var(--border-strong); border-radius: var(--radius-sm); box-shadow: var(--shadow-pop); }
.avd-cols-pop label { display: flex; align-items: center; gap: 7px; font-size: 0.85rem; padding: 4px 0; }
.avd-preset-row { display: flex; gap: 8px; margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--border); }
.avd-preset-row .btn { flex: 1; }
.avd-export { position: relative; display: inline-block; }
.avd-export-pop { position: absolute; right: 0; top: calc(100% + 6px); z-index: 20; display: flex; flex-direction: column; gap: 6px; min-width: 130px; padding: 8px; background: var(--surface); border: 1px solid var(--border-strong); border-radius: var(--radius-sm); box-shadow: var(--shadow-pop); }
.avd-export-pop .btn { width: 100%; text-align: left; }

.avd-empty { padding: 48px 20px; text-align: center; color: var(--text-muted); border: 1px dashed var(--border-strong); border-radius: var(--radius-sm); }
.avd-table-wrap { overflow-x: auto; }
.avd-table { width: 100%; border-collapse: collapse; font-size: 0.86rem; }
.avd-table th { text-align: left; padding: 10px 12px; border-bottom: 1px solid var(--border); color: var(--text-muted); font-size: 0.74rem; text-transform: uppercase; letter-spacing: 0.03em; cursor: pointer; white-space: nowrap; }
.avd-table td { padding: 10px 12px; border-bottom: 1px solid var(--border); white-space: nowrap; }
.avd-table tbody tr:hover td { background: var(--bg-elev); }
.av-pill { display: inline-block; padding: 2px 9px; border-radius: var(--pill); font-size: 0.72rem; font-weight: 600; background: var(--surface-2); }
.av-active { color: #0a7d33; background: rgba(16,185,129,0.14); }
.av-disc { color: #8a5a00; background: rgba(245,158,11,0.14); }
.av-inactive { color: var(--text-muted); }
.av-fail { color: #d4380d; background: rgba(212,56,13,0.12); }
[data-theme="dark"] .av-active { color: #7ee29a; } [data-theme="dark"] .av-disc { color: #ffd9a8; } [data-theme="dark"] .av-fail { color: #ff9a9a; }
.av-src { font-size: 0.72rem; color: var(--text-muted); }
.avd-group td { background: var(--bg-elev); font-weight: 600; cursor: pointer; }
.avd-gc { display: inline-block; width: 12px; color: var(--brand); }
.avd-gcnt { color: var(--text-muted); font-weight: 500; font-size: 0.78rem; margin-left: 6px; }

/* a11y: keyboard-focusable suggestion highlight (combobox active option) */
.avd-sug-active { background: var(--accent-soft); }
/* a11y: real <button> sort trigger that looks exactly like the header text */
.th-sort { font: inherit; color: inherit; letter-spacing: inherit; text-transform: inherit; background: transparent; border: 0; margin: 0; padding: 0; cursor: pointer; display: inline; }
/* a11y: real <button> group toggle that looks exactly like the group row */
.avd-gbtn { font: inherit; color: inherit; background: transparent; border: 0; margin: 0; padding: 0; cursor: pointer; text-align: left; width: 100%; display: inline-flex; align-items: center; }

@media (max-width: 720px) { .avd-search-grid { grid-template-columns: 1fr; } }

/* ── Responsive ── */
@media (max-width: 640px) {
  .topbar { padding: 10px 12px; gap: 8px; }
  .brand { gap: 8px; }
  .brand-word { font-size: 1.1rem; }
  .topbar-right { gap: 4px; }
  .account-trigger-name { display: none; }
  .account-menu-trigger { gap: 4px; width: 44px; padding: 7px; justify-content: center; }
  .account-menu-chevron { display: none; }
  .account-menu-panel { position: fixed; top: 66px; right: 12px; left: 12px; width: auto; }
  .content { padding: 32px 16px 48px; }
  .breadcrumb { padding: 12px 16px 0; }
  .hero h1 { font-size: 1.5rem; }
  .tool-grid { grid-template-columns: 1fr; }
  .result-item { flex-direction: column; align-items: flex-start; }
  .result-controls { justify-content: flex-start; }
  .wn-release { gap: 12px; }
  .wn-card { padding: 17px 16px; }
  .wn-meta { gap: 6px; }
}

/* Inline busy spinner for async buttons/actions (class-based — CSP-safe) */
.is-busy { position: relative; color: transparent !important; pointer-events: none; }
.is-busy::after {
  content: ""; position: absolute; inset: 0; margin: auto;
  width: 14px; height: 14px; border-radius: 50%;
  border: 2px solid currentColor; border-top-color: transparent;
  animation: prism-spin 0.6s linear infinite;
}
@keyframes prism-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .is-busy::after { animation: none; } }

/* Visually-hidden but screen-reader accessible (labels for empty table headers/captions) */
.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* AVD History: keep row action buttons on one line with a tidy gap */
.avd-hist-actions { white-space: nowrap; text-align: right; }
.avd-hist-actions .btn { padding-top: 4px; padding-bottom: 4px; }

/* ── Toasts (window.prismToast) ── fixed bottom-right stack, theme-token styled */
.toast-stack {
  position: fixed;
  right: 20px;
  bottom: 20px;
  z-index: 1000;
  display: flex;
  flex-direction: column;
  gap: 10px;
  max-width: 360px;
  pointer-events: none; /* container ignores clicks; individual toasts re-enable */
}
.toast {
  pointer-events: auto;
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 12px 14px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 4px solid var(--brand);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-pop);
  color: var(--text);
  font-size: 0.88rem;
  line-height: 1.4;
}
.toast-ok { border-left-color: #0a7d33; }
.toast-err { border-left-color: #d4380d; }
.toast-info { border-left-color: var(--brand); }
[data-theme="dark"] .toast-ok { border-left-color: #7ee29a; }
[data-theme="dark"] .toast-err { border-left-color: #ff9a9a; }
.toast-msg { flex: 1; min-width: 0; word-break: break-word; }
.toast-x {
  flex: none;
  display: inline-grid;
  place-items: center;
  width: 20px;
  height: 20px;
  margin: -2px -4px 0 0;
  padding: 0;
  border: none;
  border-radius: 50%;
  background: transparent;
  color: var(--text-muted);
  font-size: 1.1rem;
  line-height: 1;
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease;
}
.toast-x:hover { background: var(--surface-hover); color: var(--text); }

@media (max-width: 640px) {
  .toast-stack { right: 12px; left: 12px; bottom: 12px; max-width: none; }
}

/* ── CFO Tech Invoicing ───────────────────────────────────────────────── */
/* M0 scaffold styles. The dense review grid, three-pane inspector, phase
   stepper, and status chips are added with their milestones. */
.cfo-dropzone {
  margin-top: 14px;
  padding: 28px 20px;
  border: 1.5px dashed var(--border);
  border-radius: 12px;
  text-align: center;
  color: var(--text-muted);
  background: var(--surface);
}
.cfo-dropzone[aria-disabled="true"] { opacity: 0.7; }
.cfo-dropzone p { margin: 4px 0; }
.cfo-dropzone.is-dragover { border-color: var(--brand); background: var(--surface-hover); }
.cfo-dropzone:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
.cfo-runs { margin-top: 8px; }

.linklike {
  background: none; border: none; padding: 0; margin: 0;
  color: var(--brand); cursor: pointer; font: inherit; text-decoration: underline;
}
.linklike:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; border-radius: 3px; }
.mono { font-family: var(--font-mono); font-variant-numeric: tabular-nums; letter-spacing: -0.01em; }
.num { font-variant-numeric: tabular-nums; text-align: right; }

/* Staged-file list + upload actions */
.cfo-staged { list-style: none; margin: 12px 0 0; padding: 0; display: grid; gap: 6px; }
.cfo-staged li {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 7px 10px; border: 1px solid var(--border); border-radius: 8px; background: var(--surface);
  font-size: 0.86rem;
}
.cfo-staged .cfo-staged-size { color: var(--text-muted); font-variant-numeric: tabular-nums; }
.cfo-upload-actions { display: flex; align-items: center; gap: 12px; margin-top: 14px; }

/* Runs list */
.cfo-runs table { width: 100%; border-collapse: collapse; font-size: 0.88rem; }
.cfo-runs th, .cfo-runs td { text-align: left; padding: 9px 10px; border-bottom: 1px solid var(--border); }
.cfo-runs th { font-size: 0.74rem; text-transform: uppercase; letter-spacing: 0.03em; color: var(--text-muted); }
.cfo-runs tr.cfo-run-row { cursor: pointer; }
.cfo-runs tr.cfo-run-row:hover td { background: var(--surface-hover); }
.cfo-runs .num { font-variant-numeric: tabular-nums; text-align: right; }

/* Run header + status chip */
.cfo-run-head { margin-bottom: 14px; }
.cfo-run-bar { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.cfo-run-bar h2 { margin: 0; }
.cfo-chip {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 2px 10px; border-radius: 999px; border: 1px solid var(--border);
  background: var(--surface); font-size: 0.78rem; font-weight: 600;
}
.cfo-chip.is-ok   { color: #1a7f37; }
.cfo-chip.is-warn { color: #9a6700; }
.cfo-chip.is-bad  { color: #b42318; }
.cfo-chip.is-prog { color: var(--brand); }
.cfo-chip.is-idle { color: var(--text-muted); }
[data-theme="dark"] .cfo-chip.is-ok   { color: #3fb950; }
[data-theme="dark"] .cfo-chip.is-warn { color: #d29922; }
[data-theme="dark"] .cfo-chip.is-bad  { color: #f85149; }

/* ── Unified status pills (Operator Console) ── one recipe for all three tools.
   Appended last so it overrides the per-tool base/colors above without touching
   their markup. Maps each tool's status modifiers onto the shared semantic tokens. */
.action-badge, .av-pill, .cfo-chip {
  display: inline-flex; align-items: center; gap: 6px; line-height: 1.5;
  padding: 3px 10px; font-size: 0.72rem; font-weight: 600; letter-spacing: 0.005em;
  border-radius: var(--pill); border: 1px solid var(--border);
  background: var(--surface-2); color: var(--text-muted); white-space: nowrap;
}
.action-badge.badge-positive, .av-pill.av-active, .cfo-chip.is-ok, .badge-live {
  color: var(--ok); background: var(--ok-soft); border-color: color-mix(in srgb, var(--ok) 28%, transparent);
}
.action-badge.badge-warn, .av-pill.av-disc, .cfo-chip.is-warn {
  color: var(--warn); background: var(--warn-soft); border-color: color-mix(in srgb, var(--warn) 28%, transparent);
}
.action-badge.badge-danger, .av-pill.av-fail, .cfo-chip.is-bad {
  color: var(--bad); background: var(--bad-soft); border-color: color-mix(in srgb, var(--bad) 28%, transparent);
}
.action-badge.badge-neutral, .av-pill.av-inactive, .cfo-chip.is-idle {
  color: var(--text-muted); background: var(--surface-2); border-color: var(--border);
}
.cfo-chip.is-prog {
  color: var(--accent); background: var(--accent-soft); border-color: color-mix(in srgb, var(--accent) 28%, transparent);
}
/* Override the earlier hard-coded dark chip colors (0,3,0 specificity) with the
   theme-aware tokens so dark matches light. */
[data-theme="dark"] .cfo-chip.is-ok   { color: var(--ok); }
[data-theme="dark"] .cfo-chip.is-warn { color: var(--warn); }
[data-theme="dark"] .cfo-chip.is-bad  { color: var(--bad); }

/* Progress log */
.cfo-progress { list-style: none; margin: 12px 0 0; padding: 10px 12px; max-height: 220px; overflow: auto;
  border: 1px solid var(--border); border-radius: 10px; background: var(--surface); font-size: 0.84rem; }
.cfo-progress li { display: flex; gap: 8px; padding: 3px 0; }
.cfo-progress .cfo-log-glyph { width: 1.1em; flex: none; text-align: center; }
.cfo-progress .is-ok { color: #1a7f37; } .cfo-progress .is-warn { color: #9a6700; }
.cfo-progress .is-bad { color: #b42318; } .cfo-progress .is-prog { color: var(--brand); }
[data-theme="dark"] .cfo-progress .is-ok { color: #3fb950; }
[data-theme="dark"] .cfo-progress .is-warn { color: #d29922; }
[data-theme="dark"] .cfo-progress .is-bad { color: #f85149; }

/* Workspace: archive tree + three-pane inspector */
.cfo-workspace { display: grid; grid-template-columns: 260px minmax(0, 1fr); gap: 14px; align-items: start; }
.cfo-tree { padding: 12px; max-height: 640px; overflow: auto; }
.cfo-tree-head { font-size: 0.74rem; text-transform: uppercase; letter-spacing: 0.03em; color: var(--text-muted); margin-bottom: 8px; }
.cfo-tree ul { list-style: none; margin: 0; padding: 0 0 0 12px; }
.cfo-tree > #cfo-tree-body > ul { padding-left: 0; }
.cfo-node { display: flex; align-items: center; gap: 6px; padding: 4px 6px; border-radius: 6px; font-size: 0.85rem; }
.cfo-node.cfo-group { color: var(--text-muted); font-weight: 600; }
button.cfo-node { width: 100%; text-align: left; background: none; border: none; cursor: pointer; color: var(--text); }
button.cfo-node:hover { background: var(--surface-hover); }
button.cfo-node.is-active { background: var(--surface-hover); outline: 1px solid var(--brand); }
.cfo-node .cfo-node-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cfo-node .cfo-node-status { margin-left: auto; flex: none; font-size: 0.95em; }
.cfo-node-status.is-ok { color: #1a7f37; } .cfo-node-status.is-warn { color: #9a6700; }
.cfo-node-status.is-bad { color: #b42318; } .cfo-node-status.is-prog { color: var(--brand); }
.cfo-node-status.is-idle { color: var(--text-muted); }
[data-theme="dark"] .cfo-node-status.is-ok { color: #3fb950; }
[data-theme="dark"] .cfo-node-status.is-warn { color: #d29922; }
[data-theme="dark"] .cfo-node-status.is-bad { color: #f85149; }

.cfo-panes { display: grid; grid-template-columns: 1.3fr 1fr 1fr; gap: 12px; }
.cfo-pane { border: 1px solid var(--border); border-radius: 10px; background: var(--surface); display: flex; flex-direction: column; min-width: 0; }
.cfo-pane-h { padding: 8px 12px; border-bottom: 1px solid var(--border); font-weight: 600; font-size: 0.82rem; }
.cfo-pane-sub { color: var(--text-muted); font-weight: 400; }
.cfo-pane-b { padding: 10px 12px; height: 560px; overflow: auto; font-size: 0.85rem; }
.cfo-pdf { width: 100%; height: 540px; border: none; }
.cfo-pane-b pre { white-space: pre-wrap; word-break: break-word; margin: 0; font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 0.78rem; }

/* Excel grid render */
.cfo-sheet-tabs { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 8px; }
.cfo-sheet-tab { padding: 2px 9px; border: 1px solid var(--border); border-radius: 6px; background: var(--surface); cursor: pointer; font-size: 0.8rem; }
.cfo-sheet-tab.is-active { background: var(--brand); color: #fff; border-color: var(--brand); }
.cfo-xl-grid { border-collapse: collapse; font-size: 0.76rem; }
.cfo-xl-grid th, .cfo-xl-grid td { border: 1px solid var(--border); padding: 2px 6px; max-width: 220px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cfo-xl-grid thead th, .cfo-xl-grid tbody th { background: var(--surface-hover); color: var(--text-muted); position: sticky; font-weight: 600; }
.cfo-xl-grid thead th { top: 0; z-index: 2; }
.cfo-xl-grid tbody th { left: 0; z-index: 1; }
.cfo-xl-grid td.is-formula { color: var(--brand); }
.cfo-cells { width: 100%; border-collapse: collapse; font-size: 0.78rem; }
.cfo-cells th, .cfo-cells td { text-align: left; padding: 3px 6px; border-bottom: 1px solid var(--border); vertical-align: top; }
.cfo-cells td.cfo-cell-ref { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; color: var(--text-muted); white-space: nowrap; }
.cfo-cells td.cfo-cell-formula { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; color: var(--brand); }

@media (max-width: 1080px) {
  .cfo-workspace { grid-template-columns: 1fr; }
  .cfo-panes { grid-template-columns: 1fr; }
  .cfo-pane-b { height: auto; max-height: 480px; }
}

/* Read-only review grid (M2) */
.cfo-review-wrap { margin-top: 14px; overflow-x: auto; }
.cfo-inv-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 16px 0 6px; }
.cfo-review-table { width: 100%; margin-bottom: 6px; }
.cfo-review-table th.num, .cfo-review-table td.num { text-align: right; font-variant-numeric: tabular-nums; }
.cfo-review-table td:nth-child(3) { max-width: 480px; white-space: normal; }

/* Contracts + customers (M3) */
.cfo-contract-row { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }
.cfo-contract-row input[type="text"] { flex: 1; min-width: 220px; padding: 7px 10px; border: 1px solid var(--border); border-radius: 8px; background: var(--surface); color: var(--text); }
.cfo-customers { margin-top: 12px; }
.cfo-customer-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
.cfo-customer-list li { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 7px 10px; border: 1px solid var(--border); border-radius: 8px; background: var(--surface); font-size: 0.88rem; }
.cfo-review-actions { display: flex; align-items: center; gap: 12px; }

/* Inline review-grid editors (M3-editable) */
.cfo-edit-select { font: inherit; font-size: 0.78rem; padding: 1px 4px; border: 1px solid var(--border); border-radius: 6px; background: var(--surface); color: var(--text); max-width: 170px; cursor: pointer; }
.cfo-edit-select:focus-visible { outline: 2px solid var(--brand); outline-offset: 1px; }
.cfo-edited { color: var(--brand); font-weight: 700; }

/* Customer invoice previews + consultant payables (M4) */
.cfo-outcomes-wrap { margin-top: 14px; }
.cfo-sub-h { margin: 22px 0 8px; font-size: 1rem; }
.cfo-total-row td { font-weight: 700; border-top: 2px solid var(--border-strong); }
.cfo-rate-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 6px 0 20px; }
.cfo-rate-input { width: 110px; font: inherit; font-size: 0.8rem; padding: 5px 8px; border: 1px solid var(--border); border-radius: 6px; background: var(--surface); color: var(--text); }

/* Consultant payments + RAMP dry-run (M5) */
.cfo-sub-head-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: 22px; }
.cfo-recon-warn { padding: 8px 12px; border: 1px solid var(--border); border-left: 3px solid #d29922; border-radius: 8px; background: var(--surface); margin: 8px 0; font-size: 0.86rem; }
.cfo-payload { white-space: pre-wrap; word-break: break-word; font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 0.76rem; padding: 10px 12px; border: 1px solid var(--border); border-radius: 8px; background: var(--surface); overflow: auto; max-height: 320px; }

/* Pre-flight checklist (M6) */
.cfo-preflight { margin: 8px 0 4px; }
.cfo-preflight-ok { padding: 8px 12px; border: 1px solid var(--border); border-left: 3px solid #1a7f37; border-radius: 8px; background: var(--surface); font-size: 0.86rem; }
[data-theme="dark"] .cfo-preflight-ok { border-left-color: #3fb950; }
.cfo-preflight-head { font-weight: 600; font-size: 0.86rem; margin-bottom: 4px; }
.cfo-preflight-list { list-style: none; margin: 0 0 6px; padding: 0; display: grid; gap: 4px; font-size: 0.85rem; }
.cfo-pf-bad { color: #b42318; }
.cfo-pf-warn { color: #9a6700; }
[data-theme="dark"] .cfo-pf-bad { color: #f85149; }
[data-theme="dark"] .cfo-pf-warn { color: #d29922; }

/* RAMP submit gate + env badge (M5-live) */
.cfo-env-badge { display: inline-block; padding: 3px 10px; border-radius: 999px; border: 1px solid var(--border); background: var(--surface); font-size: 0.78rem; font-weight: 600; color: var(--text-muted); margin-bottom: 8px; }
.cfo-env-badge.is-live { color: #b42318; border-color: #b42318; }
[data-theme="dark"] .cfo-env-badge.is-live { color: #f85149; border-color: #f85149; }
.cfo-submit-confirm { margin-top: 12px; padding: 12px 14px; border: 1px solid var(--border); border-left: 3px solid var(--brand); border-radius: 10px; background: var(--surface); display: grid; gap: 8px; max-width: 560px; }
.cfo-submit-confirm.is-live { border-left-color: #b42318; }
[data-theme="dark"] .cfo-submit-confirm.is-live { border-left-color: #f85149; }
.cfo-submit-head { font-weight: 700; }
.cfo-submit-confirm.is-live .cfo-submit-head { color: #b42318; }
[data-theme="dark"] .cfo-submit-confirm.is-live .cfo-submit-head { color: #f85149; }
.cfo-submit-actions { display: flex; gap: 10px; }

/* Consultant Billing (AP) — generic form input used by the review screen. */
.input {
  font: inherit;
  padding: 9px 11px;
  min-height: 38px;
  border: 1px solid var(--border-strong);
  border-radius: 8px;
  background: var(--surface);
  color: var(--text);
}
textarea.input { min-height: 56px; resize: vertical; width: 100%; max-width: 520px; }
.input:focus, .select:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-ring); }
.input { transition: border-color var(--motion-fast) var(--ease-out), box-shadow var(--motion-fast) var(--ease-out); }

/* Native <select> base (graceful fallback before prismSelect upgrades it / if JS off). */
.select { font: inherit; padding: 9px 11px; min-height: 38px; border: 1px solid var(--border-strong); border-radius: var(--radius-sm); background: var(--surface); color: var(--text); }

/* ── prismSelect — custom listbox (styled OPEN menu, theme-aware, animated) ── */
.prism-native-hidden { position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.dd { position: relative; display: block; width: 100%; }
.dd.is-disabled { opacity: .55; pointer-events: none; }
.dd-trigger { width: 100%; font: inherit; text-align: left; display: flex; align-items: center; justify-content: space-between; gap: 8px;
  background: var(--surface); color: var(--text); border: 1px solid var(--border-strong); border-radius: var(--radius-sm);
  padding: 9px 12px; min-height: 38px; cursor: pointer;
  transition: border-color var(--motion-fast) var(--ease-out), box-shadow var(--motion-fast) var(--ease-out); }
.dd-trigger:hover { border-color: var(--text-muted); }
.dd-trigger:focus-visible { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-ring); }
.dd.open .dd-trigger { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-ring); }
.dd-val { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dd-caret { flex: none; width: 8px; height: 8px; border-right: 1.6px solid var(--text-muted); border-bottom: 1.6px solid var(--text-muted);
  transform: rotate(45deg) translate(-1px, -2px); transition: transform var(--motion-base) var(--ease-out); }
.dd.open .dd-caret { transform: rotate(-135deg) translate(-1px, 0); }
/* Menu is portaled to <body> and fixed-positioned by JS so it's never clipped by a
   table scroll-wrapper or hidden behind a later panel / under a modal. */
.dd-menu { position: fixed; z-index: 950; display: none;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-sm); box-shadow: var(--shadow-pop);
  padding: 5px; max-height: 280px; overflow: auto; }
.dd-menu.is-open { display: block; }
.dd-search { position: sticky; top: 0; z-index: 1; box-sizing: border-box; width: 100%; margin-bottom: 5px; padding: 8px 10px;
  font: inherit; font-size: 0.9rem; color: var(--text); background: var(--surface);
  border: 1px solid var(--border); border-radius: 6px; }
.dd-search::placeholder { color: var(--text-muted); }
.dd-search:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-ring); }
.dd-opt { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 8px 10px; border-radius: 6px;
  cursor: pointer; font-size: 0.9rem; color: var(--text); }
.dd-opt:hover, .dd-opt.active { background: var(--surface-hover); }
.dd-opt[aria-selected="true"] { color: var(--accent); font-weight: 600; }
.dd-opt[aria-selected="true"]::after { content: "✓"; font-size: 0.8rem; }
.dd-opt[aria-disabled="true"] { opacity: .45; cursor: not-allowed; }
/* Rich options (opt-in): label + trailing badge + check on one row, wrapped description below.
   Only applies to options that declared data-badge/data-desc — plain options above are unchanged.
   Fully responsive: the row ellipsizes, the description wraps, and it lives in the same
   body-portaled, mobile-safe menu as every other prism-select. */
.dd-opt.has-rich { flex-direction: column; align-items: stretch; justify-content: flex-start; gap: 3px; }
.dd-opt.has-rich::after { content: none; } /* the check moves into .dd-opt-main */
.dd-opt-main { display: flex; align-items: center; gap: 8px; }
.dd-opt-label { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dd-opt[aria-selected="true"] .dd-opt-label { color: var(--accent); font-weight: 600; }
.dd-opt-check { flex: none; font-size: 0.8rem; color: var(--accent); visibility: hidden; }
.dd-opt.has-rich[aria-selected="true"] .dd-opt-check { visibility: visible; }
.dd-opt-badge { flex: none; font-size: 0.66rem; font-weight: 600; letter-spacing: .02em; padding: 1px 8px; border-radius: 999px;
  background: var(--surface-2); color: var(--text-muted); border: 1px solid var(--border); white-space: nowrap; }
.dd-opt-badge.tone-positive { color: #15803d; background: color-mix(in srgb, #16a34a 14%, var(--surface)); border-color: transparent; }
.dd-opt-badge.tone-warn { color: #b45309; background: color-mix(in srgb, #f59e0b 16%, var(--surface)); border-color: transparent; }
.dd-opt-desc { font-size: 0.78rem; color: var(--text-muted); line-height: 1.35; white-space: normal; }
/* Description menus (e.g. disposition): keep the list compact — cap the width so long
   descriptions wrap (not stretch the menu), hide every description, and slide open only the
   ACTIVE row's (setActive keeps exactly one .active, so moving rows collapses the previous
   and expands the next). */
.dd-menu.dd-has-desc { max-width: min(92vw, 380px); }
.dd-menu.dd-has-desc .dd-opt-desc {
  max-height: 0; opacity: 0; margin-top: 0; overflow: hidden;
  transition: max-height .18s ease, opacity .16s ease, margin-top .18s ease;
}
.dd-menu.dd-has-desc .dd-opt.active .dd-opt-desc { max-height: 160px; opacity: 1; margin-top: 3px; }
@media (prefers-reduced-motion: reduce) { .dd-menu.dd-has-desc .dd-opt-desc { transition: none; } }
/* An open dropdown/popover must float above later panels (e.g. AVD history). Elevate
   the panel that contains it above its siblings, and don't clip it. Covers the
   prismSelect menu and AVD's custom Columns/Export popovers (open = not [hidden]). */
.admin-panel:has(.dd.open),
.admin-panel:has(.avd-cols-pop:not([hidden])),
.admin-panel:has(.avd-export-pop:not([hidden])),
.admin-panel:has(.row-menu-list:not([hidden])) { position: relative; z-index: 40; overflow: visible; }

/* Consultant Billing — payload preview block. */
.cb-pre { background: var(--bg); border: 1px solid var(--border); border-radius: 8px; padding: 10px 12px; overflow: auto; max-height: 300px; font-size: .8rem; line-height: 1.4; white-space: pre; }

/* ── Consultant Billing (AP) — queue + detail ─────────────────────────────── */
.cb-toolbar { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; margin: 4px 0 16px; }
.cb-toolbar .input, .cb-toolbar .select { margin: 0; }
.cb-toolbar-spacer { flex: 1 1 auto; }

/* ── Queue chrome (Option B) ────────────────────────────────────────────────────────────────
   The header used to give five unrelated jobs the same visual weight on consecutive rows:
   navigate, create, filter, configure, and a reference key. Now it's two rows with a clear
   hierarchy — a tab row that answers "where am I?" plus the one primary action, then a single
   filter line that stays one line however many filters exist. */
/* The tab strip is a HEADER, not a scroll box: on desktop it WRAPS to a second line when the
   window is narrow — a horizontally-scrolling strip silently hid the last tabs (Archive vanished
   at ~1120px with no affordance that more existed). The swipeable strip survives only below 720px,
   where it is a legitimate touch pattern. Overflow stays visible on desktop, so the old clipping
   hazard (a container with overflow-x:auto also clips the other axis — it once ate the Settings
   popover's Save button) cannot recur. */
.cb-tabsrow { display: flex; align-items: stretch; gap: 10px; margin: 0 0 14px;
  flex-wrap: wrap; border-bottom: 1px solid var(--border); }
.cb-tabs { display: flex; align-items: stretch; gap: 2px; flex: 1 1 auto; min-width: 0;
  flex-wrap: wrap; }
@media (max-width: 720px) {
  .cb-tabs { flex-wrap: nowrap; overflow-x: auto; overflow-y: visible; scrollbar-width: thin; }
}
.cb-tab { display: inline-flex; align-items: center; gap: 6px; padding: 9px 12px; border: 0;
  background: transparent; color: var(--text-muted); font: inherit; font-size: .82rem;
  font-weight: 600; cursor: pointer; white-space: nowrap; border-bottom: 2px solid transparent;
  margin-bottom: -1px; transition: color .16s ease, border-color .16s ease; }
.cb-tab:hover { color: var(--text); }
.cb-tab[aria-current="page"] { color: var(--accent); border-bottom-color: var(--accent); }
.cb-tab:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; border-radius: 4px; }
/* Actions pinned to the row's end: the ONLY primary button, plus icon-only utilities. Sits OUTSIDE
   .cb-tabs so its popovers/menus aren't clipped by the tab strip's horizontal scroll. */
.cb-tabs-end { flex: 0 0 auto; display: flex; align-items: center; gap: 6px; padding-bottom: 4px; }

/* Single filter line: search grows, the rest are fixed-width affordances. */
.cb-filterbar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 0 0 14px; }
.cb-search-wrap { position: relative; display: inline-flex; align-items: center; flex: 1 1 260px;
  min-width: 190px; max-width: 360px; }
.cb-search-wrap .cb-search-icon { position: absolute; left: 9px; color: var(--text-muted);
  pointer-events: none; display: inline-flex; }
.cb-filterbar .cb-search { flex: 1 1 auto; max-width: none; padding-left: 30px; }
/* prismSelect wraps each <select> in a .dd sized to 100% — without this the assignee picker eats
   the whole line and pushes Filters/Legend onto a third row, which is the bug this layout fixes. */
.cb-filterbar .dd, .cb-filterbar .select { width: auto; min-width: 150px; flex: 0 0 auto; }
.cb-filterbar > .cb-pop-host, .cb-filterbar > span { flex: 0 0 auto; }
/* ...except the spacer, which must still grow so Legend is pushed to the right edge. */
.cb-filterbar > .cb-toolbar-spacer { flex: 1 1 auto; }
.cb-filterbar .cb-fchips { flex: 0 1 auto; min-width: 0; }

/* ── Focused-tab list chrome (tableView) ────────────────────────────────────────────────────
   The same filter line as the review queue, reused by RAMP / Recur360 / Vendor bills / Intake /
   Archive / Needs attention, plus click-to-sort table headers. */
.cb-tv-bar { margin: 10px 0 12px; }
.cb-tv-count { font-size: .78rem; color: var(--text-muted); white-space: nowrap; }
/* A sortable header is a real <button> so it is tab-reachable and announces itself; it inherits
   the <th>'s type so the column heading looks unchanged until you hover it. */
.cb-sort { display: inline-flex; align-items: center; gap: 5px; padding: 0; border: 0;
  background: none; font: inherit; color: inherit; cursor: pointer; text-align: inherit; }
.cb-sort:hover { color: var(--text); }
.cb-sort:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 3px; }
th.num .cb-sort { flex-direction: row-reverse; }
.cb-sort-caret { font-size: .68rem; line-height: 1; color: var(--text-muted); opacity: 0; transition: opacity .12s ease; }
.cb-sort:hover .cb-sort-caret, .cb-sort:focus-visible .cb-sort-caret { opacity: .7; }
.cb-sort-caret.is-on { opacity: 1; color: var(--accent); }
th.is-sorted { color: var(--text); }

/* Active-filter chips — today you must read seven dropdowns to know why the queue looks short. */
.cb-fchips { display: inline-flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.cb-fchip { display: inline-flex; align-items: center; gap: 4px; padding: 3px 5px 3px 9px;
  border-radius: 999px; background: var(--accent-soft); color: var(--accent);
  font-size: .72rem; font-weight: 700; white-space: nowrap; }
.cb-fchip button { border: 0; background: none; color: inherit; cursor: pointer; padding: 0 1px;
  font-size: .85rem; line-height: 1; opacity: .6; }
.cb-fchip button:hover { opacity: 1; }
.cb-fchip button:focus-visible { outline: 2px solid currentColor; outline-offset: 1px; border-radius: 50%; }
/* The count on the Filters button, so the number of active filters reads at a glance. */
.cb-fcount { background: var(--accent-soft) !important; border-color: transparent !important;
  color: var(--accent) !important; }

/* Popover shell (Filters / Period / Legend / Settings). prismSelect positions its list with
   `fixed`, so enhanced selects inside here escape this container's stacking context correctly. */
.cb-pop-host { position: relative; display: inline-flex; }
.cb-pop { position: absolute; z-index: 40; top: calc(100% + 6px); left: 0; min-width: 280px;
  padding: 13px; border: 1px solid var(--border-strong); border-radius: var(--radius);
  background: var(--surface); box-shadow: 0 12px 34px rgba(10, 14, 22, .18); }
.cb-pop.is-right { left: auto; right: 0; }
/* Wide variant for the Filters popover: two month inputs want ~154px each, and in the default
   280px shell they were squeezed to 73px — under half their natural width. */
.cb-pop.is-wide { min-width: 460px; }
.cb-pop-title { margin: 0 0 9px; font-size: .64rem; font-weight: 700; letter-spacing: .12em;
  text-transform: uppercase; color: var(--text-muted); }
.cb-pop-grid { display: grid; gap: 9px; }
.cb-pop-row { display: grid; grid-template-columns: 92px minmax(0, 1fr); align-items: center; gap: 9px; }
.cb-pop-row > label { font-size: .78rem; font-weight: 600; color: var(--text-muted); }
.cb-pop-row .select, .cb-pop-row .input, .cb-pop-row .dd { width: 100%; min-width: 0; box-sizing: border-box; }
.cb-pop-row .cb-date-filter { min-width: 0; }
.cb-pop-dates { display: flex; gap: 6px; min-width: 0; }
.cb-pop-dates > .input, .cb-pop-dates > .select, .cb-pop-dates > .dd { flex: 1 1 0; min-width: 0; }
.cb-pop-foot { display: flex; gap: 7px; margin-top: 12px; padding-top: 11px;
  border-top: 1px solid var(--border); }
.cb-pop .cb-legend { margin: 0; flex-direction: column; align-items: flex-start; gap: 8px; }
@media (max-width: 640px) {
  .cb-pop, .cb-pop.is-wide { min-width: 0; width: min(92vw, 340px); }
  .cb-pop-row { grid-template-columns: 1fr; gap: 3px; }
}

/* Filters cluster — view-only controls, sized so they don't sprawl full-width. */
.cb-filters { display: flex; flex: 1 1 100%; align-items: flex-start; gap: 8px; }
.cb-filter-fields { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; flex: 1 1 auto; min-width: 0; }
.cb-filters > .btn { flex: 0 0 auto; }                  /* Clear: pinned to the right, never its own line */
.cb-filters .dd { width: auto; min-width: 140px; }      /* override prismSelect's 100% */
.cb-date-range { display: inline-flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.cb-date-lbl { font-size: 0.8rem; font-weight: 600; color: var(--text-muted); }
.cb-date-sep { color: var(--text-muted); }
.cb-date-filter { width: auto; min-width: 150px; }
.cb-search { flex: 0 1 210px; min-width: 160px; max-width: 240px; }
.cb-cluster-label { font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.1em; font-weight: 600; color: var(--text-muted); }

/* Default-method preference — a saved change, visually set apart from the filters. */
.cb-prefs { display: flex; align-items: center; gap: 8px; padding: 6px 10px; border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--surface-2); }
.cb-prefs .dd { width: auto; min-width: 140px; }
.cb-create { display: flex; flex-wrap: wrap; gap: 8px; }
.cb-group-head { display: flex; align-items: center; gap: 8px; margin: 28px 0 0; padding-bottom: 8px; border-bottom: 1px solid var(--border); cursor: pointer; }
.cb-group-head h3 { margin: 0; font-size: .72rem; font-weight: 700; text-transform: uppercase; letter-spacing: .07em; color: var(--text-muted); }
.cb-group-count { display: inline-flex; align-items: center; justify-content: center; min-width: 20px; height: 20px; padding: 0 6px; border-radius: 10px; background: var(--surface-2); border: 1px solid var(--border); color: var(--text-muted); font-size: .72rem; font-weight: 600; }
/* Panel-level group heads use an h2 (e.g. Email intake); without a margin reset the browser's
   default h2 margins push the flex row's centerline down, so the count badge sits visibly low. */
.cb-group-head h2 { margin: 0; }
/* Intake "Dry run" chip — a simulation, not a problem: brand-tinted, distinct from skipped/neutral. */
.badge-dryrun { background: var(--accent-soft); color: var(--brand-link); }
/* Dry-run / error detail under the subject — the extraction preview (amount · inv # · dates). */
.cb-intake-note { margin-top: 2px; font-size: .78rem; color: var(--text-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Intake discard split button — primary action + caret dropdown (reuses .row-menu-list). The
   joined pair reads as one control; the menu needs the cell's overflow:visible (set above). */
.row-menu.cb-split { position: relative; display: inline-flex; align-items: stretch; }
/* The primary half may be a bare .btn OR a .btn inside a <form> (EJS pages post forms). */
.cb-split > .btn:first-child,
.cb-split > form:first-child .btn { border-top-right-radius: 0; border-bottom-right-radius: 0; height: 100%; }
.cb-split > form:first-child { display: inline-flex; }
.cb-split-caret { border-top-left-radius: 0; border-bottom-left-radius: 0; margin-left: 1px; padding-left: 10px; padding-right: 10px; }
.cb-split .row-menu-list { right: 0; left: auto; }
/* Entry-point (toolbar) count badge: neutral for pending, red for blocked/errors. */
.cb-count-badge { display: inline-flex; align-items: center; justify-content: center; min-width: 18px; height: 18px; margin-left: 6px; padding: 0 5px; border-radius: 9px; background: var(--surface-2); border: 1px solid var(--border); color: var(--text-muted); font-size: .7rem; font-weight: 700; }
.cb-count-badge.is-danger { background: color-mix(in srgb, var(--bad) 14%, var(--surface)); border-color: color-mix(in srgb, var(--bad) 45%, transparent); color: var(--bad); }
[data-theme="dark"] .cb-count-badge.is-danger { color: #f6a58f; }
.cb-group-toggle { margin-left: auto; background: none; border: 0; color: var(--text-muted); cursor: pointer; font: inherit; font-size: .8rem; }
.cb-age { color: var(--text-muted); font-variant-numeric: tabular-nums; white-space: nowrap; }
.cb-empty { color: var(--text-muted); padding: 8px 0; }

/* Queue tables (every section — Drafts / Needs action / Awaiting / Completed). Fixed layout with a
   shared <colgroup> so all sections line up column-for-column; headers align with their cells
   (text left, amounts right); nothing wraps — long free-text cells ellipsize with a title tooltip. */
/* The queue list can't push wider than its panel; a stray wide row scrolls inside it, not out. */
.cb-list { min-width: 0; max-width: 100%; overflow-x: auto; }
/* width:100% gives the fixed layout + % colgroup a width to resolve against — without it the
   nowrap cells expand the columns and the table spills past the panel. */
.audit-table.cb-queue { table-layout: fixed; width: 100%; max-width: 100%; }
.audit-table.cb-queue th { text-align: left; }
.audit-table.cb-queue th.num,
.audit-table.cb-queue td.num { text-align: right; }
/* Trim the audit-log's 28px cell gutter — far too wide across 9 fixed columns (it starved the
   pill/chip columns). Cells don't wrap; only the free-text columns ellipsize. Status/Rails hold
   badges — never clip them (overflow visible), or a stray "…" appears next to the chips. */
.audit-table.cb-queue th,
.audit-table.cb-queue td { padding-right: 12px; white-space: nowrap; vertical-align: middle; }
.audit-table.cb-queue th:last-child,
.audit-table.cb-queue td:last-child { padding-right: 0; }
/* Cells holding badges/buttons must not clip (overflow visible) — else a stray "…" or a
   cut-off button appears. Applies to the queue's Status/Rails and the intake Actions cell. */
.audit-table.cb-queue td.cb-actions { overflow: visible; }
/* Zebra banding — alternating row tint so a multi-line row (payee + sub-company) reads as one
   band and doesn't blur into its neighbour. Set on td (not tr) so it composes with the colgroup;
   the hover rule below carries the same specificity+1 so hover still wins on either stripe. */
.audit-table.cb-queue tbody tr:nth-child(even) td { background: var(--surface-2); }
.audit-table.cb-queue tbody tr.is-clickable:hover td { background: var(--surface-hover); }
/* Collapsible section header — the whole bar toggles; a caret shows open/closed state. */
.cb-group-head.cb-group-collapsible { cursor: pointer; user-select: none; }
.cb-group-caret { display: inline-block; width: 1em; color: var(--text-muted); font-size: .8rem; }
.cb-group-head.cb-group-collapsible:hover h3 { color: var(--text); }
/* ── Customizable queue columns (v0.112.0) ──────────────────────────────────────────────────
   Widths are pixels in a <colgroup> (a percentage can't express "210px because I dragged it
   there"), so the table is min-width:max-content inside a horizontally scrolling wrapper. */
/* Width is set inline from the sum of the visible column widths (see queueTable) — a
   fixed-layout table with `width: max-content` silently re-scales its columns to fit. */
.audit-table.cb-queue { min-width: 100%; }
.audit-table.cb-queue th { position: relative; }
/* Sticky identity columns: the checkbox, the glyphs and the payee stay put while the rest scrolls
   sideways, so a row never becomes an anonymous strip of numbers. `left` is set inline from the
   live widths (setStickyOffsets) because it has to survive a resize. */
.audit-table.cb-queue th.is-sticky,
.audit-table.cb-queue td.is-sticky { position: sticky; z-index: 1; background: var(--surface); }
.audit-table.cb-queue tbody tr:nth-child(even) td.is-sticky { background: var(--surface-2); }
.audit-table.cb-queue tbody tr.is-clickable:hover td.is-sticky { background: var(--surface-hover); }
/* The right edge of the sticky group, drawn only while the table is actually scrolled sideways
   (no shadow on an unscrolled table — it would read as a border that isn't there). */
.cb-table-wrap.is-scrolled .audit-table.cb-queue th.is-sticky:last-of-type,
.cb-table-wrap.is-scrolled .audit-table.cb-queue td.is-sticky:last-of-type { box-shadow: 6px 0 6px -6px rgba(0, 0, 0, .22); }
/* Sticky header. This works because .cb-table-wrap is already a real scroll viewport (overflow
   auto + max-height 62vh, below) — inside a wrapper that only scrolled horizontally it would stick
   to a box exactly as tall as its content, i.e. do nothing. The mobile breakpoint releases the
   wrapper to page flow, which correctly drops the sticky behaviour with it. */
.cb-table-wrap .audit-table.cb-queue thead th { position: sticky; top: 0; z-index: 2; background: var(--surface); }
.cb-table-wrap .audit-table.cb-queue thead th.is-sticky { z-index: 3; }
/* Resize grip — a hit area wider than the visible line, so it's grabbable without being loud. */
.cb-col-grip { position: absolute; top: 0; right: -4px; width: 9px; height: 100%; cursor: col-resize;
  display: inline-block; touch-action: none; }
.cb-col-grip::after { content: ''; position: absolute; top: 22%; bottom: 22%; left: 4px; width: 1px;
  background: var(--border); opacity: 0; transition: opacity .12s ease; }
.audit-table.cb-queue th:hover .cb-col-grip::after,
.cb-col-grip:focus-visible::after { opacity: 1; }
.cb-col-grip:focus-visible { outline: 2px solid var(--accent); outline-offset: -1px; border-radius: 2px; }
body.cb-resizing { cursor: col-resize; user-select: none; }
/* Columns popover rows. */
.cb-colpicker { display: flex; flex-direction: column; gap: 2px; max-height: 48vh; overflow: auto; min-width: 250px; }
.cb-colpick-row { display: flex; align-items: center; gap: 8px; padding: 3px 2px; border-radius: 6px;
  border-top: 2px solid transparent; /* reserved so the drop indicator can't shift the list */ }
.cb-colpick-row:hover { background: var(--surface-hover); }
/* Drag to reorder — the fast path when a column belongs several places away. The arrows remain
   for keyboard and touch, so this is an accelerator, never the only way. */
.cb-colpick-grab { cursor: grab; color: var(--text-muted); font-size: .8rem; letter-spacing: -1px; user-select: none; }
.cb-colpick-row.is-dragging { opacity: .45; }
.cb-colpick-row.is-over { border-top-color: var(--accent); }
.cb-colpick-row label { flex: 1 1 auto; font-size: .84rem; cursor: pointer; }
.cb-colpick-row.is-off label { color: var(--text-muted); }
.cb-colpick-row input[type="checkbox"] { accent-color: var(--brand); }
.cb-colpick-lock { font-size: .66rem; text-transform: uppercase; letter-spacing: .05em; color: var(--text-muted); }
.cb-colpick-move { display: inline-flex; gap: 2px; }
.cb-colpick-move .btn { padding: 1px 5px; line-height: 1.1; font-size: .7rem; }
.cb-colpick-head { margin: 8px 0 2px; font-size: .7rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: .06em; color: var(--text-muted); }
/* Tags in their own column wrap instead of stretching the row. */
.cb-cell-tags .cb-tag-row { flex-wrap: wrap; gap: 4px; }

/* Row TYPE/FLAG glyphs — one type + optional flags per row, in their own narrow column so the
   payee never wraps. A legend above the queue (and the Help drawer) name each glyph; a 500ms
   hover tooltip (.cb-tip, fixed-position on <body> so it never clips) repeats it inline. */
.cb-type-cell { white-space: nowrap; }
/* The glyphs are one flex group with a real gap rather than loose inline nodes with margins:
   a vendor bill that came in by intake AND is on hold carries three of them, which at 4px
   margins ran together and into the payee. The group WRAPS (it is the only wrapping cell in a
   nowrap row), so a future fourth flag stacks instead of colliding. */
.cb-type-cell .cb-type-glyphs { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 5px 6px; white-space: normal; }
.audit-table.cb-queue td.cb-type-cell { padding-right: 8px; }
.cb-type-icon, .cb-flag-icon { display: inline-flex; align-items: center; vertical-align: middle; }
.cb-type-icon { color: var(--text); }               /* type = primary */
.cb-flag-icon { color: var(--text-muted); }          /* flags = secondary */
/* A payment hold is a deliberate STOP, not a neutral source marker, so it reads in the negative
   colour rather than muted — the one flag that should catch the eye while scanning the queue.
   Same two values as .badge-negative so the tool has one "blocked" red per theme. Colour is never
   the only cue: the glyph shape differs and every glyph carries an aria-label + tooltip. */
.cb-flag-hold { color: #c0341a; }
[data-theme="dark"] .cb-flag-hold { color: #ff9a8a; }
/* Inline type/flag glyphs before a payee on the secondary tables (RAMP / Recur360 / Needs
   attention), which have no dedicated Type column. Same gap as the queue's glyph group. */
.cb-type-inline { display: inline-flex; align-items: center; gap: 5px; margin-right: 8px; vertical-align: middle; }
.cb-legend { display: flex; flex-wrap: wrap; align-items: center; gap: 14px; margin: 2px 0 14px; font-size: .8rem; color: var(--text-muted); }
.cb-legend-label { font-weight: 700; text-transform: uppercase; letter-spacing: .06em; font-size: .7rem; }
.cb-legend-item { display: inline-flex; align-items: center; gap: 5px; cursor: default; }
.cb-tip { position: fixed; z-index: 2000; max-width: 320px; padding: 8px 11px; font-size: .8rem; line-height: 1.45; color: var(--text); background: var(--surface); border: 1px solid var(--border); border-radius: 6px; box-shadow: 0 4px 14px rgba(0, 0, 0, .16); pointer-events: none; white-space: normal; }
.cb-tip strong { font-weight: 700; }
.cb-tip em { font-style: italic; }

/* Field-help "i" badge — replaces the paragraph that used to sit under every control, so the panel
   reads as controls again while the explanation stays one hover (or tab-stop) away. A real <button>
   on purpose: hover-only help is invisible to keyboard and touch users, so this is focusable and
   tap-toggleable, and carries the text in aria-label for screen readers. */
.cb-info { display: inline-flex; align-items: center; justify-content: center; width: 15px; height: 15px;
  margin-left: 5px; padding: 0; border-radius: 50%; border: 1px solid var(--border);
  background: transparent; color: var(--text-muted); font-size: .66rem; font-weight: 700;
  font-style: italic; font-family: Georgia, 'Times New Roman', serif; line-height: 1; cursor: help;
  vertical-align: middle; flex: 0 0 auto; }
.cb-info:hover, .cb-info:focus-visible { color: var(--text); border-color: var(--text-muted); background: var(--surface-2, transparent); }
.cb-info:focus-visible { outline: 2px solid var(--accent, #2f63ff); outline-offset: 1px; }
/* A section heading's badge sits on the baseline of a larger text run. */
.cb-group-head .cb-info, h3 .cb-info, h4 .cb-info { margin-left: 7px; }
/* ── Bill tags (Phase E Slice 2) ───────────────────────────────────────────────────────────────
   A tag is a human label, so it renders as a small TEXT chip rather than a glyph — there's no
   fixed vocabulary to learn a key for, the word is the meaning. Colour is chosen from a TOKEN
   palette (never raw hex): 8 hues that stay readable on both themes, so the queue can't turn into
   the visual sprawl the Outlook category list became. */
.cb-tag-row { display: inline-flex; flex-wrap: wrap; gap: 4px; margin-top: 3px; }
.cb-tag { display: inline-flex; align-items: center; gap: 3px; padding: 1px 7px; border-radius: 999px;
  font-size: .72rem; font-weight: 600; line-height: 1.5; white-space: nowrap; border: 1px solid transparent; }
.cb-tag-label { overflow: hidden; text-overflow: ellipsis; max-width: 16ch; }
/* A WIRED tag drives behaviour, so it is visually distinct from an inert label — an outline ring,
   never colour alone (colour is not a cue on its own). */
.cb-tag-wired { border-style: dashed; border-color: currentColor; }
.cb-tag-more { background: transparent; border-color: var(--border); color: var(--text-muted); }
/* Remove affordance inside the detail-panel chips only (queue chips pass no handler). */
.cb-tag-x { border: 0; background: none; cursor: pointer; padding: 0 0 0 2px; font-size: .95rem;
  line-height: 1; color: inherit; opacity: .55; }

/* Manage tags (Billing.Manager) — the janitorial modal. Inline confirms live in one zone at the
   top so a destructive step is always answered where the eye already is, never a native dialog. */
.cb-tagadmin-table td { vertical-align: middle; }
.cb-tagadmin-archived .cb-tag { opacity: .5; }
.cb-tagadmin-actions { display: inline-flex; flex-wrap: wrap; gap: 4px; justify-content: flex-end; }
.cb-tagadmin-edit { display: inline-flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.cb-tagadmin-edit .input { width: 15ch; }
.cb-tagadmin-confirm { border: 1px solid var(--border-strong); border-left: 3px solid var(--brand-link);
  border-radius: var(--radius-sm); background: var(--bg-elev); padding: 10px 12px; margin: 0 0 12px; }
.cb-tagadmin-confirm p { margin: 0 0 8px; font-size: .88rem; }
.cb-tagadmin-confirm-actions { display: inline-flex; gap: 6px; align-items: center; }
.cb-tag-x:hover { opacity: 1; }
.cb-tag-edit { display: flex; flex-wrap: wrap; gap: 5px; align-items: center; }

.cb-tag-slate  { background: rgba(100, 116, 139, .14); color: #475569; }
.cb-tag-blue   { background: rgba(37, 99, 235, .13);   color: #1d4ed8; }
.cb-tag-green  { background: rgba(22, 163, 74, .14);   color: #15803d; }
.cb-tag-amber  { background: rgba(217, 119, 6, .16);   color: #b45309; }
.cb-tag-red    { background: rgba(212, 56, 13, .12);   color: #c0341a; }
.cb-tag-purple { background: rgba(147, 51, 234, .13);  color: #7e22ce; }
.cb-tag-teal   { background: rgba(13, 148, 136, .14);  color: #0f766e; }
.cb-tag-pink   { background: rgba(219, 39, 119, .13);  color: #be185d; }
[data-theme="dark"] .cb-tag-slate  { background: rgba(148, 163, 184, .20); color: #cbd5e1; }
[data-theme="dark"] .cb-tag-blue   { background: rgba(96, 165, 250, .20);  color: #93c5fd; }
[data-theme="dark"] .cb-tag-green  { background: rgba(74, 222, 128, .18);  color: #86efac; }
[data-theme="dark"] .cb-tag-amber  { background: rgba(251, 191, 36, .20);  color: #fcd34d; }
[data-theme="dark"] .cb-tag-red    { background: rgba(248, 113, 113, .20); color: #ff9a8a; }
[data-theme="dark"] .cb-tag-purple { background: rgba(192, 132, 252, .20); color: #d8b4fe; }
[data-theme="dark"] .cb-tag-teal   { background: rgba(45, 212, 191, .20);  color: #5eead4; }
[data-theme="dark"] .cb-tag-pink   { background: rgba(244, 114, 182, .20); color: #f9a8d4; }

/* Bulk-assign bar — appears only once ≥1 queue row is selected, and sticks to the top of the
   scrolling list so the actions stay reachable while picking rows further down a long queue. */
.cb-bulk-bar { position: sticky; top: 0; z-index: 5; display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  margin: 0 0 12px; padding: 10px 12px; border: 1px solid var(--border); border-radius: 10px; background: var(--surface); box-shadow: 0 2px 8px rgba(0, 0, 0, .06); }
.cb-bulk-count { font-weight: 600; margin-right: 4px; }
/* Checkbox column: centred, and it must not inherit the row's pointer (the cell stops propagation
   so ticking a box never opens the bill). */
.cb-sel-cell { text-align: center; cursor: default; }
.cb-sel-cell input { cursor: pointer; }

/* Help drawer's icon key (Queue row icons section). */
.cb-help-flags { list-style: none; padding-left: 0; }
.cb-help-flags li { margin: 8px 0; }
.cb-help-flags svg { vertical-align: -3px; margin-right: 7px; color: var(--text); }
/* .settings-actions carries an 18px top margin for admin forms — drop it inside any queue table's
   action cell so the buttons center on the row (with the cell's vertical-align: middle). Applies to
   the main queue AND the RAMP / Recur360 / Needs-attention tables. */
.audit-table td.cb-actions .settings-actions { margin: 0; }
.audit-table.cb-queue td.cb-status,
.audit-table.cb-queue td.cb-rails { overflow: visible; }
.audit-table.cb-queue .cb-ellip { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Pay/Invoice rail-completion chips in the queue's Rails column. */
.cb-rail-chips { display: inline-flex; gap: 4px; }
.cb-rail-chips .action-badge { font-size: 0.72rem; padding: 1px 6px; }
/* #9 class chip on the rail queues + Needs-attention (Consultant / Vendor / Customer). */
.cb-class-chip { font-size: 0.68rem; padding: 1px 6px; margin-left: 6px; vertical-align: middle; }

/* Skeleton shimmer (none existed in platform.css). */
.cb-skel { border-radius: 8px; background: linear-gradient(90deg, rgba(0,0,0,.05) 25%, rgba(0,0,0,.09) 37%, rgba(0,0,0,.05) 63%); background-size: 400% 100%; animation: cb-shimmer 1.3s ease-in-out infinite; }
.cb-skel-row { height: 44px; margin: 8px 0; }
.cb-skel-panel { height: 120px; margin: 10px 0; }
@keyframes cb-shimmer { 0% { background-position: 100% 0; } 100% { background-position: -100% 0; } }
@media (prefers-reduced-motion: reduce) { .cb-skel { animation: none; } }
.cb-detail { display: grid; grid-template-columns: minmax(0, 1fr) minmax(300px, 360px); gap: 18px; align-items: start; }
.cb-rail { position: sticky; top: 16px; display: flex; flex-direction: column; gap: 14px; }
.cb-rail .admin-panel { margin: 0; }
.cb-detail-left { display: flex; flex-direction: column; gap: 14px; min-width: 0; }
.cb-detail-left .admin-panel { margin: 0; }
@media (max-width: 900px) {
  .cb-detail { grid-template-columns: 1fr; }
  .cb-rail { position: static; }
}

/* ── Consultant Billing (AP) — wider canvas + decision-rail form fields ──────── */
/* The AP surface (8-col queue + two-pane detail) needs more room than the default
   1080px shell; widen only this tool's page (scoped via :has, graceful fallback). */
.content:has(#cb-app) { max-width: 1320px; }

/* Decision rail controls as stacked fields: a label over a row of controls, so
   button text never wraps vertically and inputs grow to fill the column. */
.cb-field { display: flex; flex-direction: column; gap: 6px; margin-bottom: 14px; }
.cb-field-label { font-weight: 600; font-size: .82rem; color: var(--text-muted); }
.cb-field-row { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.cb-field-row .input, .cb-field-row .select { flex: 1 1 130px; min-width: 0; margin: 0; }
.cb-field-row .btn { flex: 0 0 auto; white-space: nowrap; }
/* AP lines table: auto layout so the Date never wraps and the Description column
   takes the remaining width (overrides .audit-table's fixed layout). The default
   .audit-table 28px cell gutter is far too wide across 7 columns — trim it so the
   Description keeps real room even with the Decision rail expanded. */
/* Lines scroll within their own area (tall lists) so the column header can freeze. */
.cb-table-wrap { overflow: auto; max-height: 62vh; }
/* A scroll container clips absolutely-positioned descendants in BOTH axes — an open split-button
   dropdown (e.g. intake Discard) would paint inside the frame, invisible. While a row-menu is
   open, release the clip; it restores the moment the menu closes. */
.cb-table-wrap:has(.row-menu-list:not([hidden])) { overflow: visible; max-height: none; }
/* Rail preview output (dry-run result / error) — breathe below the action buttons. */
.cb-rail-out:not(:empty) { margin-top: 12px; }
.cb-lines { table-layout: auto; min-width: 560px; }
.cb-lines thead th { position: sticky; top: 0; z-index: 1; background: var(--surface); box-shadow: 0 1px 0 var(--border); }
.cb-lines th, .cb-lines td { padding-right: 16px; }
/* Last column (usually a right-aligned amount) keeps real breathing room from the
   scroll-area edge instead of sitting flush — .audit-table's flush-right default
   reads as a cramped 0px margin inside a card. */
.cb-lines th:last-child, .cb-lines td:last-child { padding-right: 12px; }
/* Headers are short labels and must never wrap (e.g. "Bill #" splitting to "Bill" / "#"),
   so nowrap every thead cell — the .cb-table-wrap scroll area absorbs any overflow. */
.cb-lines thead th, .cb-lines .cb-c-date { white-space: nowrap; }
.cb-lines .cb-c-desc { min-width: 220px; }            /* Description gets priority (by class, not position) */
.cb-lines .cb-cell-ref { white-space: nowrap; color: var(--text-muted); }
.cb-lines .num { white-space: nowrap; }
.cb-lines .cb-line-actions { white-space: nowrap; text-align: right; }
.cb-ap-added { margin-left: 8px; }
/* Copy (⧉) button on the Item/Description cells of the Customer Invoice Preview —
   subtle by default, revealed on row hover/focus. */
.cb-copy { margin-left: 6px; padding: 0 6px; line-height: 1.4; opacity: .3; transition: opacity .12s ease; }
.cb-table-wrap tr:hover .cb-copy { opacity: .75; }
.cb-copy:hover, .cb-copy:focus-visible { opacity: 1; }
/* Section heads (Consultant lines / Customer charges) with an inline add button. */
/* Create forms (standalone invoice / on behalf) — a clean, narrow labelled form card. */
.cb-form { max-width: 540px; }
.cb-form-back { margin-bottom: 14px; }
.cb-form h2 { margin: 0 0 6px; }
.cb-form-help { color: var(--text-muted); font-size: 0.88rem; line-height: 1.5; margin: 0 0 20px; }
.cb-form-field { display: flex; flex-direction: column; gap: 6px; margin-bottom: 16px; }
.cb-form-field > label { font-size: 0.85rem; font-weight: 600; color: var(--text); }
.cb-form-actions { display: flex; justify-content: flex-end; gap: 10px; margin-top: 22px; padding-top: 16px; border-top: 1px solid var(--border); }
/* Whole-invoice actions under the Customer Invoice Preview table (Add Admin Fee / Set GL item …).
   It was a bare <p>, so the buttons sat edge-to-edge; every other button row on the platform is a
   flex row with an 8px gap, and it wraps rather than overflowing on a narrow viewport. */
.cb-bulk-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 10px 0 12px; }

.cb-lines-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; margin-bottom: 12px; }
.cb-lines-head h2 { margin: 0; }
.cb-sub { margin: 2px 0 0; font-size: 0.82rem; color: var(--text-muted); }
/* "+ New" dropdown menu (create actions) — CSP-safe popup, theme-aware via tokens. */
.cb-menu { position: relative; display: inline-block; }
.cb-menu-pop { position: absolute; top: calc(100% + 4px); right: 0; min-width: 200px; background: var(--surface); border: 1px solid var(--border); border-radius: 10px; box-shadow: var(--shadow-pop); padding: 6px; display: none; z-index: 40; }
.cb-menu.is-open .cb-menu-pop { display: block; }
.cb-menu-item { display: block; width: 100%; text-align: left; background: none; border: 0; padding: 8px 10px; border-radius: 6px; font: inherit; color: var(--text); cursor: pointer; white-space: nowrap; }
.cb-menu-item:hover, .cb-menu-item:focus { background: var(--surface-hover); outline: none; }
/* Menu items with descriptions — same accordion behaviour as the <select> menus (.dd-has-desc):
   only the hovered/focused row's description slides open, and the menu is width-capped so long
   text wraps instead of stretching it. Width cap is what keeps this responsive. */
.cb-menu-pop.cb-menu-has-desc { min-width: 300px; max-width: min(92vw, 340px); }
.cb-menu-has-desc .cb-menu-item { white-space: normal; }
.cb-menu-item-label { display: block; font-weight: 600; }
.cb-menu-desc { display: block; font-size: .78rem; color: var(--text-muted); line-height: 1.35;
  white-space: normal; max-height: 0; opacity: 0; overflow: hidden;
  transition: max-height .18s ease, opacity .18s ease, margin-top .18s ease; }
/* Driven by .is-active (set on mouseenter/focus in menuButton) rather than :hover/:focus, so a
   mouse resting on one row while the keyboard focuses another can't open two descriptions. */
.cb-menu-item.is-active .cb-menu-desc { max-height: 160px; opacity: 1; margin-top: 3px; }
@media (prefers-reduced-motion: reduce) { .cb-menu-desc { transition: none; } }

/* Detail header row: back-to-queue + the rail toggle. */
.cb-detail-head { display: flex; justify-content: space-between; align-items: center; gap: 10px; margin-bottom: 14px; }

/* Collapsed side rail → single column; the lines use the full page width. */
.cb-detail.rail-collapsed { grid-template-columns: 1fr; }
.cb-detail.rail-collapsed .cb-rail { display: none; }

/* Compact inline buttons / selects for per-line row actions. */
.btn-sm { padding: 4px 10px; font-size: .8rem; }
.select-sm { padding: 4px 8px; font-size: .85rem; }

/* Consultant view: badge marking a line AP added after submission (read-only). */
.cp-ap-added { display: inline-block; margin-left: 8px; padding: 1px 7px; border-radius: 999px; font-size: .7rem; font-weight: 600; background: var(--surface-hover, #eef0f3); color: var(--text-muted, #6b7280); vertical-align: middle; }

/* ── Bill-line edit / delete modal (centered dialog → bottom sheet on mobile) ── */
.cb-modal-overlay { position: fixed; inset: 0; background: rgba(10, 11, 13, .5); display: flex; align-items: center; justify-content: center; padding: 16px; z-index: 900; }
.cb-modal { background: var(--surface); color: var(--text); border: 1px solid var(--border); border-radius: 14px; width: 100%; max-width: 520px; max-height: 90vh; display: flex; flex-direction: column; box-shadow: var(--shadow-pop); }
.cb-modal-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 16px 18px; border-bottom: 1px solid var(--border); }
.cb-modal-head h3 { margin: 0; font-size: 1.05rem; }
.cb-modal-x { border: 0; background: transparent; color: var(--text-muted); font-size: 1.5rem; line-height: 1; cursor: pointer; width: 36px; height: 36px; border-radius: 8px; }
.cb-modal-x:hover { background: var(--surface-hover); color: var(--text); }
.cb-modal-body { padding: 16px 18px; overflow-y: auto; display: flex; flex-direction: column; gap: 14px; }
.cb-modal-foot { display: flex; justify-content: flex-end; gap: 10px; padding: 14px 18px; border-top: 1px solid var(--border); }
.cb-modal-field { display: flex; flex-direction: column; gap: 6px; }
.cb-modal-field label { font-weight: 600; font-size: .85rem; color: var(--text-muted); }
.cb-modal-field .input, .cb-modal-desc { width: 100%; margin: 0; }
.cb-modal-desc { resize: vertical; min-height: 64px; font: inherit; }

/* ── Mobile (≤560px): lines table → stacked cards; modal → bottom sheet; 44px targets ── */
@media (max-width: 560px) {
  .cb-lines { min-width: 0; }                                   /* drop the desktop scroll floor */
  .cb-table-wrap { overflow: visible; max-height: none; }
  .cb-lines thead { display: none; }
  .cb-lines, .cb-lines tbody, .cb-lines tr, .cb-lines td { display: block; width: auto; }
  .cb-lines tr { border: 1px solid var(--border); border-radius: 10px; padding: 8px 12px; margin-bottom: 10px; }
  .cb-lines td { display: flex; justify-content: space-between; align-items: center; gap: 14px; padding: 5px 0; border: 0; text-align: right; }
  .cb-lines td::before { content: attr(data-label); font-weight: 600; color: var(--text-muted); text-align: left; }
  .cb-lines .cb-c-desc { flex-direction: column; align-items: stretch; text-align: left; gap: 2px; min-width: 0; } /* Description stacks full-width */
  .cb-lines .cb-line-actions { justify-content: flex-end; gap: 8px; padding-top: 8px; margin-top: 4px; border-top: 1px solid var(--border); }
  .cb-lines .cb-line-actions::before { content: none; }
  .cb-lines .select-sm, .cb-line-actions .btn { min-height: 44px; }

  .cb-modal-overlay { padding: 0; align-items: flex-end; }
  .cb-modal { max-width: none; max-height: 92vh; border-radius: 16px 16px 0 0; }
  .cb-modal-foot { position: sticky; bottom: 0; background: var(--surface); }
  .cb-modal-foot .btn { flex: 1 1 auto; min-height: 44px; }
}

.cb-decide { margin-top: 6px; padding-top: 12px; border-top: 1px solid var(--border, #e5e7eb); display: flex; flex-direction: column; gap: 10px; }
.cb-return-note { width: 100%; min-height: 64px; margin: 0; resize: vertical; }
.cb-decide-actions { display: flex; gap: 8px; }
.cb-decide-actions .btn { flex: 1 1 0; white-space: nowrap; }

/* Inline explanation under the disposition / bill-method selectors. */
.cb-help { font-size: .8rem; color: var(--text-muted); line-height: 1.4; margin: -6px 0 14px; }
/* Ingestion progress line ("Reading “invoice.pdf” (1 of 3)…") in the upload modals. Must come
   AFTER .cb-help to beat its -6px top margin — that margin is written for help text tucked under
   a form control, and here it glued the status flush against the file list. Reserves its own
   height so appearing mid-upload doesn't shift the modal. */
.cb-upload-status { margin: 12px 0 0; min-height: 1.2em; }

/* Vendor-bill Payment panel: button + its URL caption stack with real spacing
   (the generic .cb-help negative margin pulled the URL under the pill button). */
.cb-pay-portal { display: flex; flex-direction: column; align-items: flex-start; gap: 8px; margin: 4px 0 14px; }
.cb-pay-portal .cb-pay-link { margin: 0; word-break: break-all; }

/* ── Uploaded-invoice attachment viewer (Consultant Billing) ── */
.cb-attach-list { flex-wrap: wrap !important; }
.cb-attach-chip { display: inline-flex; align-items: center; gap: 8px; max-width: 340px; }
.cb-attach-kind { font-size: .6rem; font-weight: 700; letter-spacing: .04em; color: #fff; background: var(--accent); border-radius: 4px; padding: 2px 6px; flex: none; }
.cb-attach-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cb-modal-wide { max-width: 1000px; }
.cb-viewer-body { padding: 0; }
.cb-viewer { display: flex; flex-direction: column; min-height: 0; }
.cb-viewer-frame { width: 100%; height: 74vh; border: 0; display: block; background: #fff; }
.cb-xlsx-tabs { display: flex; flex-wrap: wrap; gap: 6px; margin: 12px 16px 8px; }
.cb-xlsx-tab { border: 1px solid var(--border); background: transparent; color: var(--text-muted); border-radius: 999px; padding: 4px 12px; font-size: .82rem; cursor: pointer; }
.cb-xlsx-tab.is-active { background: var(--accent); color: #fff; border-color: var(--accent); }
.cb-xlsx-pane.is-hidden { display: none; }
.cb-xlsx-scroll { overflow: auto; max-height: 66vh; border: 1px solid var(--border); border-radius: 8px; margin: 0 16px; }
.cb-xlsx-table { border-collapse: collapse; font-size: .82rem; }
.cb-xlsx-table th, .cb-xlsx-table td { border: 1px solid var(--border); padding: 4px 8px; text-align: left; white-space: nowrap; vertical-align: top; }
.cb-xlsx-table th { background: var(--surface-hover); font-weight: 700; position: sticky; top: 0; }
.cb-xlsx-trunc { margin: 8px 16px 12px; }
/* Proposal classification note shown under the Bill method label. */
.cb-class-note { font-size: .72rem; color: var(--text-muted); margin-top: 3px; line-height: 1.35; font-style: italic; }
/* Duplicate-description line grouping. */
.cb-group-agg td { background: var(--surface-2); font-weight: 600; }
.cb-group-refs { font-size: .75rem; font-weight: 400; color: var(--text-muted); margin-top: 2px; }
.cb-sub-line td { padding-left: 24px !important; }
.cb-sub-line.cb-sub-hidden { display: none; }
/* LLM Spend summary cards. */
.cb-spend-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 14px; margin-bottom: 14px; }
.cb-spend-figure { font-size: 2rem; font-weight: 700; margin: 6px 0 4px; letter-spacing: -0.02em; }
/* RAMP payment-dates editor (pay rail). */
.cb-ramp-dates { margin: 6px 0 14px; padding: 12px; background: var(--surface-2); border: 1px solid var(--border); border-radius: 8px; }
.cb-ramp-dates .admin-subhead { margin: 0 0 8px; }

/* CFO Tech brand logo in a tool hero (e.g. Consultant Billing). */
.hero-logo { height: 30px; width: auto; display: block; margin-bottom: 10px; }

/* Consultants admin: row actions live in a kebab (⋮) overflow menu, right-aligned. */
.admin-table td.cell-actions { white-space: nowrap; text-align: right; }
.cell-hint { font-size: 0.72rem; margin-top: 4px; }

.row-menu { position: relative; display: inline-block; }
.row-menu-btn { font: inherit; line-height: 1; cursor: pointer; background: transparent; border: 1px solid var(--border-strong); color: var(--text); border-radius: 8px; padding: 3px 11px; font-size: 1.15rem; }
.row-menu-btn:hover { background: var(--surface-hover); }
.row-menu-btn:focus-visible { outline: 2px solid var(--brand-link); outline-offset: 2px; }
.row-menu-list { position: absolute; right: 0; top: calc(100% + 4px); z-index: 20; min-width: 184px; background: var(--surface); border: 1px solid var(--border); border-radius: 10px; box-shadow: var(--shadow-card); padding: 6px; display: flex; flex-direction: column; gap: 2px; text-align: left; }
.row-menu-list[hidden] { display: none; }
.row-menu-list form { display: block; margin: 0; }
.row-menu-item { width: 100%; text-align: left; font: inherit; font-size: 0.9rem; background: transparent; border: 0; color: var(--text); border-radius: 6px; padding: 8px 10px; cursor: pointer; }
.row-menu-item:hover:not([disabled]) { background: var(--surface-hover); }
.row-menu-item:focus-visible { outline: 2px solid var(--brand-link); outline-offset: -2px; }
.row-menu-item[disabled] { opacity: 0.5; cursor: not-allowed; }

/* Consultants table column tuning: headers + the date stay on one line; the
   Consultant column is capped so Company / Last sign-in get the freed width. */
[data-consultant-table] th { white-space: nowrap; }
[data-consultant-table] td.cell-date { white-space: nowrap; }
[data-consultant-table] th:first-child,
[data-consultant-table] td:first-child { width: 210px; }

/* ── Notification bell + feed dropdown (in-app, both shells) ── */
.notif-bell { position: relative; display: inline-flex; }
.notif-btn { position: relative; display: grid; place-items: center; width: 44px; height: 44px; background: none; border: 0; border-radius: var(--pill); cursor: pointer; line-height: 1; padding: 0; color: var(--text-muted); }
.notif-btn:hover { color: var(--text); background: var(--surface-hover); }
.notif-btn:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--accent-ring); }
.notif-badge { position: absolute; top: 0; right: 0; min-width: 16px; height: 16px; padding: 0 4px; border-radius: 8px; background: #d23b3b; color: #fff; font-size: 10px; line-height: 16px; text-align: center; }
.notif-panel { position: absolute; top: 110%; right: 0; width: 320px; max-height: 60vh; overflow: auto; background: var(--surface, #fff); border: 1px solid var(--border, #e2e2e2); border-radius: 12px; box-shadow: 0 10px 30px rgba(0,0,0,.18); z-index: 50; }
.notif-head { display: flex; justify-content: space-between; align-items: center; padding: 10px 14px; border-bottom: 1px solid var(--border, #eee); font-weight: 600; }
.notif-readall { background: none; border: 0; color: var(--brand, #2f63ff); cursor: pointer; font-size: 12px; }
.notif-item { display: block; padding: 10px 14px; border-bottom: 1px solid var(--border, #f0f0f0); text-decoration: none; color: inherit; }
.notif-item.is-unread { background: rgba(47,99,255,.06); }
.notif-title { font-size: 13px; }
.notif-time { font-size: 11px; color: #8a8a8a; margin-top: 2px; }
.notif-empty { padding: 18px 14px; color: #8a8a8a; font-size: 13px; }
.notif-body { cursor: pointer; }
.notif-text { font-size: 12px; color: var(--text-muted, #5a6373); margin-top: 3px; line-height: 1.4; }
.notif-ctls { display: flex; align-items: center; gap: 12px; margin-top: 8px; }
.notif-ctl { background: none; border: 0; padding: 0; cursor: pointer; font-size: 11px; color: var(--brand-link, #2452d6); }
.notif-ctl:hover { text-decoration: underline; }
.notif-view { text-decoration: none; font-weight: 600; }
.notif-dismiss { margin-left: auto; color: var(--text-muted, #8a8a8a); font-size: 13px; }
.notif-dismiss:hover { color: #d23b3b; text-decoration: none; }
