/* ═══════════════════════════════════════════
   DG 2025 Expense Dashboard — Styles
   ═══════════════════════════════════════════ */

/* ─────────────────────────────────────────────
   Release-cut: hide non-R1 surfaces.
   See release-config.js for the override mechanism
   (?release=internal or localStorage 'dgbudget_release').

   This CSS block is the single source of truth for what's in R1.
   No JS mirror — if you need a JS-side check, add it explicitly,
   don't re-encode the allow-list.

   What R1 SHOWS (Front Office audience):
   - Budget tab (default landing) + Table tab (kept for Jeff's
     transaction categorization work)
   - Hierarchical budget table (FO mode): bucket → sub-bucket →
     activity → sub-activity, with chevron expand
   - KPI strip cards: ytd, variance, net-income
   - Search box + Expand/Collapse All
   - Drill an Actual cell → side drawer with YTD transactions
     reconciling to the row's Actual value

   What R1 HIDES (visible with ?release=internal):
   - Mode toggle (Front Office / Finance Team buttons)
   - Scenario controls (picker, +New, Edit, Diff, Interventions,
     Make Official, Share, Delete)
   - Commit / History buttons
   - Apply ceiling toggle + ceiling controls
   - AFB Year Landing chart (forecast viz, R3)
   - Compare summary, derive summary
   - Edit buttons (✎) on rows + provenance / drift / shape badges
   - KPI cards: fyf (full-year forecast), capacity
   - Predecessor tabs: Drilldown, Sankey, Legal Audit, Reconcile
   - Old-style income panel (replaced by Income-as-bucket — R1.10)
   - GL artifact button (FT-only)

   When updating: keep this comment in sync with the rules below.
   The smoke test (tests/demo-r1.spec.js Story 13) catches drift
   for the high-leverage surfaces, not all of them.
   ───────────────────────────────────────────── */

/* Release-cut rules.
   r1  = default production (FO surface only).
   r3  = R3 reviewer preview — same legacy chrome HIDDEN as r1, but the R3
         affordances (✎ Set editor, provenance, drift, FYF/Capacity KPIs,
         + Forecast column / chip / override which are JS-gated) SHOW.
   internal = developer "everything on" view; no class-based hides apply.
   See release-config.js for resolution + DG.RELEASE. */

/* Top-level nav: keep Budget + Table; hide predecessor surfaces.
   Table stays so Jeff can do transaction categorization work. Legacy in
   both r1 and r3 — neither release surfaces these. */
.release-r1 .tab[data-view="pie"],
.release-r1 .tab[data-view="sankey"],
.release-r1 .tab[data-view="legal"],
.release-r1 .tab[data-view="reconcile"],
.release-r3 .tab[data-view="pie"],
.release-r3 .tab[data-view="sankey"],
.release-r3 .tab[data-view="legal"],
.release-r3 .tab[data-view="reconcile"] { display: none !important; }

/* Budget toolbar — FO mode only, hide FT-flip, scenarios, commit, ceiling.
   These are abandoned/reframed primitives — out for both r1 and r3. */
.release-r1 .budget-mode-toggle,
.release-r1 .scenario-controls,
.release-r1 .budget-status-actions,
.release-r1 .budget-derive-summary,
.release-r1 .budget-ceiling-bar,
.release-r3 .budget-mode-toggle,
.release-r3 .scenario-controls,
.release-r3 .budget-status-actions,
.release-r3 .budget-derive-summary,
.release-r3 .budget-ceiling-bar { display: none !important; }

/* Budget status bar — scenario/commit affordances. Out for r1 and r3. */
.release-r1 .budget-status-bar,
.release-r3 .budget-status-bar { display: none !important; }

/* AFB year-landing chart — old forecast viz, superseded by R3c column.
   Out for r1 and r3. */
.release-r1 .budget-afb-wrap,
.release-r3 .budget-afb-wrap { display: none !important; }

/* Compare summary — tied to scenario flow being reframed. Out for both. */
.release-r1 .compare-summary,
.release-r3 .compare-summary { display: none !important; }

/* Per-row budget-planning affordances — edit buttons (R3b), provenance
   (R3b context), drift (R3c context), shape indicator. r1 hides; r3 SHOWS
   — these ARE the new layer R3 surfaces. */
.release-r1 .budget-edit-btn,
.release-r1 .budget-prov-step,
.release-r1 .budget-prov-arrow,
.release-r1 .budget-drift-chip,
.release-r1 .budget-txn-shaped { display: none !important; }

/* KPI cards: r1 keeps ytd / variance / net-income only and hides the
   forecast-derived cards. r3 SHOWS them — the R3c "watch the total
   recompute" moment lives on the FYF card. */
.release-r1 .budget-kpi[data-drill="fyf"],
.release-r1 .budget-kpi[data-drill="capacity"] { display: none !important; }

/* Existing standalone income panel — being replaced by Income-as-bucket in
   the budget table (R1.10). The new path is visible in every release; this
   old panel stays hidden in BOTH r1 and r3. */
.release-r1 .budget-income-panel-wrap,
.release-r3 .budget-income-panel-wrap { display: none !important; }

/* GL artifact button (FT-only — GL accounts not in FO mental model). Out
   for both r1 and r3 (FO releases). */
.release-r1 .budget-gl-artifact-header,
.release-r3 .budget-gl-artifact-header { display: none !important; }

/* R3 reviewer-preview banner (mounted by release-config.js when
   ?release=r3). Slim amber chip injected into .app-header > .header-right
   so it flows next to Rule Queue / user name / Sign out instead of fixed-
   overlay-ing them. Clicking sends the user to ?release=r1 so production
   is one click away for comparison. Body text #92400e on amber #fef3c7
   clears 4.5:1; subtext at 0.9 opacity also clears AA. */
.release-preview-banner {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 4px 12px;
  margin-right: 12px;          /* breathing room from Rule Queue / user info */
  background: #fef3c7;
  color: #92400e;
  border: 1px solid #fcd34d;
  border-radius: 999px;
  font-family: var(--font);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-decoration: none;
  cursor: pointer;
  user-select: none;
  white-space: nowrap;
  align-self: center;
}
.release-preview-banner:hover { background: #fde68a; border-color: #f59e0b; }
.release-preview-banner:focus { outline: 2px solid #b45309; outline-offset: 2px; }
.release-preview-label  { text-transform: uppercase; letter-spacing: 0.08em; }
.release-preview-action { font-weight: 500; opacity: 0.9; }  /* 0.85 dropped subtext to 4.23:1 on hover bg; 0.9 keeps AA */
/* Mobile: compress to just the label + arrow; saves horizontal space in the
   header where Rule Queue + user name + Sign out are already tight. */
@media (max-width: 600px) {
  .release-preview-banner { padding: 3px 8px; font-size: 10px; gap: 4px; margin-right: 6px; }
  .release-preview-action { display: none; }
  .release-preview-label::after { content: ' →'; opacity: 0.6; font-weight: 400; }
}


:root {
  --bg: #f5f6f8;
  --surface: #ffffff;
  --border: #e2e5ea;
  --text: #1a1d23;
  --text-secondary: #6b7280;
  --text-muted: #9ca3af;
  --accent: #2b7bba;
  --accent-light: rgba(43, 123, 186, 0.08);
  --header-bg: #1a1d23;
  --header-text: #f0f1f3;
  --font: 'DM Sans', -apple-system, BlinkMacSystemFont, sans-serif;
  --mono: 'DM Sans', -apple-system, BlinkMacSystemFont, sans-serif;
  /* Per Jason 2026-04-30: in a numeric column there's no O/0 ambiguity,
     so the disambiguating mark mono fonts apply to 0 (slash or dot)
     creates a new 0/8 confusion. Resolved by dropping the mono font
     entirely for numbers — DM Sans's natural unmarked oval zero is
     unambiguous in a numeric context. Tabular nums (body-level
     font-variant-numeric) keeps column alignment without forcing a
     monospace face. */
}

/* Tabular nums applied at the document level so every numeric column
   aligns without per-cell tweaks. Slashed-zero deliberately NOT applied:
   in a numeric context there's no risk of confusing 0 with the letter O,
   and the slash itself can read as an 8 — the very issue it was meant to
   prevent. Clean unmarked oval zero (DM Sans default) reads cleanest. */
body, input, button, select, textarea {
  font-variant-numeric: tabular-nums;
}

:root {
  --radius: 6px;
  --shadow-sm: 0 1px 2px rgba(0,0,0,0.05);
  --shadow-md: 0 4px 12px rgba(0,0,0,0.08);
  --color-ops: #2d9d3a;
  --color-inv: #2b7bba;
  --color-fund: #e67e22;
  --color-internal: #95a5a6;
  --color-review: #f1c40f;
  /* Status tokens — status chips (e.g. contract-drift, bead n8pd).
     Warning = amber (|drift| 5-15%). Critical = red (|drift| >= 15%).
     Background + foreground pairs carry a WCAG 4.5:1 ratio on white
     surfaces so the chips remain readable when the row is not hovered. */
  --color-warning: #854d0e;          /* text on warning chip */
  --color-warning-bg: #fef9c3;       /* chip background */
  --color-critical: #991b1b;         /* text on critical chip */
  --color-critical-bg: #fee2e2;      /* chip background */
}

* { box-sizing: border-box; margin: 0; padding: 0; }

body {
  font-family: var(--font);
  background: var(--bg);
  color: var(--text);
  -webkit-font-smoothing: antialiased;
  min-height: 100vh;
  overflow: hidden;
}

/* ═══ Login Screen ═══ */
.login-screen {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
  background: linear-gradient(135deg, #1a1d23 0%, #2d3748 100%);
  padding: 24px;
}

.login-card {
  background: var(--surface);
  border-radius: 12px;
  padding: 48px 40px;
  text-align: center;
  box-shadow: 0 8px 32px rgba(0,0,0,0.2);
  max-width: 380px;
  width: 100%;
}

.login-brand {
  margin-bottom: 32px;
}

.login-logo {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 56px;
  height: 56px;
  background: var(--header-bg);
  color: #fff;
  font-size: 20px;
  font-weight: 700;
  border-radius: 12px;
  letter-spacing: -0.02em;
  margin-bottom: 16px;
}

.login-card h1 {
  font-size: 22px;
  font-weight: 600;
  letter-spacing: -0.01em;
  margin-bottom: 4px;
}

.login-subtitle {
  font-size: 14px;
  color: var(--text-secondary);
}

.sign-in-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  width: 100%;
  padding: 12px 24px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  font-family: var(--font);
  font-size: 14px;
  font-weight: 500;
  color: var(--text);
  cursor: pointer;
  transition: all 0.15s;
}

.sign-in-btn:hover:not(:disabled) {
  border-color: #bbb;
  box-shadow: var(--shadow-sm);
}

.sign-in-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.login-domain {
  font-size: 12px;
  color: var(--text-muted);
  margin-top: 16px;
}

.login-error {
  font-size: 13px;
  color: #e74c3c;
  margin-top: 12px;
  padding: 8px 12px;
  background: rgba(231, 76, 60, 0.06);
  border-radius: var(--radius);
}

/* ═══ App Shell ═══ */
.app-shell {
  display: flex;
  flex-direction: column;
  height: 100vh;
  overflow: hidden;
}

/* ═══ Header ═══ */
.app-header {
  background: var(--header-bg);
  color: var(--header-text);
  padding: 0 24px;
  height: 52px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-shrink: 0;
}

.header-left {
  display: flex;
  align-items: center;
  gap: 12px;
}

.header-brand {
  font-size: 15px;
  font-weight: 700;
  background: rgba(255,255,255,0.12);
  padding: 3px 8px;
  border-radius: 4px;
  letter-spacing: -0.02em;
}

.app-header h1 {
  font-size: 15px;
  font-weight: 500;
  letter-spacing: -0.01em;
}

.year-select {
  background: rgba(255,255,255,0.12);
  color: var(--header-text);
  border: 1px solid rgba(255,255,255,0.2);
  border-radius: 4px;
  padding: 5px 8px;
  min-height: 32px;
  font-family: var(--font);
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  outline: none;
}
.year-select:hover {
  background: rgba(255,255,255,0.2);
}
.year-select:focus {
  border-color: var(--accent);
}
.year-select option {
  background: var(--header-bg);
  color: var(--header-text);
}
.source-toggle {
  background: rgba(255,255,255,0.12);
  color: var(--header-text);
  border: 1px solid rgba(255,255,255,0.2);
  border-radius: 4px;
  padding: 5px 10px;
  min-height: 32px;
  font-family: var(--font);
  font-size: 11px;
  font-weight: 500;
  cursor: pointer;
  outline: none;
  text-transform: uppercase;
  letter-spacing: 0.5px;
}
.source-toggle:hover {
  background: rgba(255,255,255,0.2);
}
.source-toggle.api-active {
  background: rgba(46,204,113,0.25);
  border-color: rgba(46,204,113,0.5);
  color: #2ecc71;
}

.header-right {
  display: flex;
  align-items: center;
  gap: 12px;
}

.header-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  background: rgba(255,255,255,0.08);
  border: 1px solid rgba(255,255,255,0.1);
  border-radius: var(--radius);
  color: var(--header-text);
  font-family: var(--font);
  font-size: 12px;
  font-weight: 500;
  cursor: pointer;
  transition: background 0.15s;
}

.header-btn:hover { background: rgba(255,255,255,0.14); }

.header-btn.refreshing svg {
  animation: spin 0.8s linear infinite;
}

.header-user {
  display: flex;
  align-items: center;
  gap: 10px;
}

.user-name {
  font-size: 12px;
  color: #8b919a;
}

.header-btn-text {
  background: none;
  border: none;
  color: #8b919a;
  font-family: var(--font);
  font-size: 12px;
  cursor: pointer;
  padding: 6px 4px;
  min-height: 32px;
  transition: color 0.15s;
}

.header-btn-text:hover { color: var(--header-text); }

/* R2b Rule Queue header link. Pill-styled like .header-btn but as an
   anchor; reviewer-gated (data-feature="rule-queue"). The ↗ glyph signals
   it opens a separate surface. Default display:none lives inline on the
   element so non-reviewers never flash it; applyFeatureGates reveals it. */
.header-rule-link {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 6px 12px;
  background: rgba(255,255,255,0.08);
  border: 1px solid rgba(255,255,255,0.1);
  border-radius: var(--radius);
  color: var(--header-text);
  font-family: var(--font);
  font-size: 12px;
  font-weight: 500;
  text-decoration: none;
  min-height: 32px;
  box-sizing: border-box;
  transition: background 0.15s;
}
.header-rule-link:hover { background: rgba(255,255,255,0.14); }
.header-rule-link:focus-visible {
  outline: 2px solid var(--accent, #2563eb);
  outline-offset: 1px;
}
@media (max-width: 600px) {
  /* Keep the link but tighten it on mobile (matches .header-btn-text). */
  .header-rule-link { font-size: 11px; padding: 6px 8px; }
}

/* ═══ Tab Bar ═══ */
.tab-bar {
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  padding: 0 24px;
  display: flex;
  align-items: center;
  height: 42px;
  gap: 0;
  flex-shrink: 0;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

.tab {
  position: relative;
  padding: 0 16px;
  height: 42px;
  display: flex;
  align-items: center;
  background: none;
  border: none;
  font-family: var(--font);
  font-size: 13px;
  font-weight: 500;
  color: var(--text-muted);
  cursor: pointer;
  transition: color 0.15s;
  white-space: nowrap;
}

.tab:hover { color: var(--text-secondary); }

.tab.active {
  color: var(--text);
  font-weight: 600;
}

.tab.active::after {
  content: '';
  position: absolute;
  bottom: 0;
  left: 16px;
  right: 16px;
  height: 2px;
  background: var(--accent);
  border-radius: 1px 1px 0 0;
}

.tab-meta {
  margin-left: auto;
  font-size: 11px;
  color: var(--text-muted);
  white-space: nowrap;
  padding-left: 16px;
  font-family: var(--mono);
}

/* ═══ Views ═══ */
.view-container {
  flex: 1;
  overflow: hidden;
  position: relative;
  max-width: 100%;
}

.view {
  display: none;
  height: 100%;
  overflow: hidden;
}

.view.active {
  display: flex;
  flex-direction: column;
}

/* ═══ Loading ═══ */
.loading-overlay {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  background: var(--bg);
  color: var(--text-muted);
  font-size: 14px;
  z-index: 10;
}

.loading-spinner {
  width: 28px;
  height: 28px;
  border: 2.5px solid var(--border);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}

@keyframes spin { to { transform: rotate(360deg); } }

/* Subtle background-refresh indicator (bead expenses_tool-9qt) —
   shown while auto-refresh fetches silently in the background so users
   can keep interacting instead of being blocked by #loadingOverlay. */
.refresh-indicator {
  position: fixed;
  top: 12px;
  right: 12px;
  background: var(--accent);
  color: #fff;
  padding: 4px 10px;
  border-radius: 12px;
  font-size: 11px;
  font-weight: 500;
  line-height: 1.4;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15);
  z-index: 100;
  pointer-events: none;
  opacity: 0.9;
  transition: opacity 0.2s ease;
}
.refresh-indicator-error {
  background: #c0392b;
}

/* ═══════════════════════════════════════════
   PIE VIEW
   ═══════════════════════════════════════════ */

/* Pie Unified Toolbar (tabs + filters in one row) */
.pie-toolbar {
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  padding: 0 20px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-shrink: 0;
  min-height: 38px;
}

.pie-toolbar-left {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
  flex-shrink: 1;
}

.pie-toolbar-right {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-shrink: 0;
}

.pie-toolbar-sep {
  width: 1px;
  height: 20px;
  background: var(--border);
  flex-shrink: 0;
}

.pie-toolbar .checkboxes {
  flex-wrap: nowrap;
  overflow: hidden;
  min-width: 0;
}

/* Legacy class — keep for any remaining references */
.pie-filter-bar {
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  padding: 4px 24px;
  display: flex;
  align-items: center;
  gap: 12px;
  flex-shrink: 0;
}

/* Grouping Toggle */
.pie-grouping-toggle {
  display: flex;
  border: 1px solid var(--border);
  border-radius: 5px;
  overflow: hidden;
  flex-shrink: 0;
}

.pie-group-btn {
  font-family: var(--font);
  font-size: 12px;
  font-weight: 500;
  padding: 6px 12px;
  min-height: 32px;
  border: none;
  background: var(--surface);
  color: var(--text-secondary);
  cursor: pointer;
  transition: all 0.15s;
  white-space: nowrap;
}

.pie-group-btn:not(:last-child) {
  border-right: 1px solid var(--border);
}

.pie-group-btn:hover:not(.active) {
  background: #f1f3f5;
  color: var(--text);
}

.pie-group-btn.active {
  background: var(--header-bg);
  color: #fff;
}

/* Entity Filter Groups */
.pie-filter-group {
  display: flex;
  align-items: center;
  gap: 6px;
}

.pie-filter-label {
  font-family: var(--font);
  font-size: 11px;
  font-weight: 600;
  color: var(--text-secondary);
  text-transform: uppercase;
  letter-spacing: 0.5px;
  white-space: nowrap;
}

/* Entity Dropdown */
.pie-entity-filter {
  position: relative;
}

.pie-entity-btn {
  font-family: var(--font);
  font-size: 12px;
  font-weight: 500;
  padding: 6px 10px;
  min-height: 32px;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: var(--surface);
  color: var(--text-secondary);
  cursor: pointer;
  white-space: nowrap;
  transition: all 0.15s;
}

.pie-entity-btn:hover { border-color: #adb5bd; color: var(--text); }

.pie-entity-dropdown {
  position: absolute;
  top: 100%;
  left: 0;
  z-index: 20;
  margin-top: 4px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-md);
  min-width: 220px;
  max-width: 300px;
}

.pie-entity-actions {
  display: flex;
  gap: 4px;
  padding: 8px 10px 4px;
  border-bottom: 1px solid var(--border);
}

.pie-entity-action {
  font-family: var(--font);
  font-size: 11px;
  font-weight: 500;
  padding: 2px 8px;
  border: 1px solid var(--border);
  border-radius: 3px;
  background: var(--surface);
  color: var(--text-secondary);
  cursor: pointer;
  transition: all 0.15s;
}

.pie-entity-action:hover { background: #f1f3f5; color: var(--text); }

.pie-entity-list {
  max-height: 320px;
  overflow-y: auto;
  padding: 4px 0;
}

.pie-entity-item {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  font-size: 12px;
  cursor: pointer;
  transition: background 0.1s;
}

.pie-entity-item:hover { background: #f8f9fb; }

.pie-entity-item input[type="checkbox"] {
  margin: 0;
  cursor: pointer;
}

.pie-entity-item span {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ── 3-Pie Grid Layout ── */
.pie-grid {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.pie-instance {
  background: var(--bg);
  display: none;
  flex-direction: column;
  overflow: hidden;
  flex: 1;
  min-width: 0;
}

.pie-instance.mobile-active {
  display: flex;
}

.pie-instance-header {
  padding: 12px 20px;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  display: flex;
  align-items: baseline;
  gap: 10px;
  flex-shrink: 0;
}

.pie-instance-title {
  font-size: 12px;
  font-weight: 600;
  color: var(--text-secondary);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.pie-instance-total {
  font-family: var(--mono);
  font-size: 26px;
  font-weight: 700;
  color: var(--text);
  letter-spacing: -0.02em;
}

.pie-instance-hint {
  margin-left: auto;
  font-size: 11px;
  color: var(--text-muted);
  white-space: nowrap;
  background: var(--bg);
  padding: 3px 10px;
  border-radius: 12px;
  border: 1px solid var(--border);
}

.pie-empty-state {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 1;
  color: var(--text-muted);
  font-size: 13px;
  padding: 24px;
}

/* Pie tab switcher (inline in toolbar) */
.pie-tab-switcher {
  display: flex;
  gap: 0;
  flex-shrink: 0;
}

.pie-tab-btn {
  padding: 8px 12px;
  background: none;
  border: none;
  border-bottom: 2px solid transparent;
  font-family: var(--font);
  font-size: 13px;
  font-weight: 500;
  color: var(--text-muted);
  cursor: pointer;
  display: flex;
  align-items: baseline;
  gap: 5px;
  transition: color 0.15s, border-color 0.15s;
  white-space: nowrap;
}

.pie-tab-btn.active {
  color: var(--text);
  border-bottom-color: var(--accent);
  font-weight: 600;
}

.pie-tab-btn:hover {
  color: var(--text-secondary);
}

.pie-tab-btn-total {
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 400;
  color: var(--accent);
}

/* Breadcrumb */
.pie-breadcrumb {
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  padding: 0 12px;
  display: flex;
  align-items: center;
  min-height: 32px;
  gap: 2px;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  flex-shrink: 0;
}

.bc-segment {
  display: flex;
  align-items: center;
  gap: 2px;
  flex-shrink: 0;
}

.bc-link {
  font-size: 12px;
  font-weight: 500;
  color: var(--accent);
  cursor: pointer;
  padding: 4px 6px;
  border-radius: 4px;
  transition: background 0.15s;
  white-space: nowrap;
  text-decoration: none;
}

.bc-link:hover { background: var(--accent-light); }

.bc-sep {
  color: var(--text-muted);
  font-size: 11px;
  margin: 0 2px;
  user-select: none;
}

.bc-current {
  font-size: 12px;
  font-weight: 600;
  color: var(--text);
  padding: 4px 6px;
  white-space: nowrap;
}

.bc-hint {
  margin-left: auto;
  font-size: 11px;
  color: var(--text-muted);
  flex-shrink: 0;
  padding-left: 16px;
}

.bc-hint kbd {
  font-family: var(--mono);
  font-size: 10px;
  background: #f0f1f3;
  border: 1px solid var(--border);
  border-radius: 3px;
  padding: 1px 5px;
  margin: 0 1px;
}

/* Pie Content */
.pie-content {
  flex: 1;
  display: flex;
  overflow: hidden;
}

.pie-chart-area {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Hide Highcharts built-in drilldown breadcrumbs (we use our own) */
.highcharts-breadcrumbs-group { display: none !important; }

/* Make pie slices clearly interactive */
.highcharts-point { cursor: pointer; }
.highcharts-point:hover { filter: brightness(1.08); }

/* Scrollable Legend */
.pie-legend-wrap {
  width: 260px;
  flex-shrink: 0;
  border-left: 1px solid var(--border);
  background: var(--surface);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.pie-legend {
  flex: 1;
  overflow-y: auto;
  padding: 8px 0;
  -webkit-overflow-scrolling: touch;
}

.pie-legend-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 16px;
  cursor: pointer;
  transition: background 0.12s;
  font-size: 12px;
}

.pie-legend-item:hover { background: var(--accent-light); }

.pie-legend-dot {
  width: 10px;
  height: 10px;
  border-radius: 2px;
  flex-shrink: 0;
}

.pie-legend-name {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-weight: 500;
  color: var(--text);
}

.pie-legend-val {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--text-secondary);
  flex-shrink: 0;
}

.pie-legend-pct {
  font-size: 10px;
  color: var(--text-muted);
  width: 36px;
  text-align: right;
  flex-shrink: 0;
}

.pie-chart-area .plotly-chart {
  width: 100%;
  height: 100%;
}

/* Pie Transaction Table */
.pie-table-container {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.pie-table-header {
  padding: 12px 24px;
  border-bottom: 1px solid var(--border);
  background: var(--surface);
  display: flex;
  align-items: baseline;
  gap: 12px;
  flex-shrink: 0;
}

.pie-table-header .count {
  font-size: 14px;
  font-weight: 600;
}

.pie-table-header .amount {
  font-family: var(--mono);
  font-size: 13px;
  font-weight: 500;
  color: var(--accent);
}
.pie-table-cat-filter {
  margin-left: auto;
  font-size: 12px;
  padding: 2px 8px;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: #fff;
}

.pie-table-scroll {
  flex: 1;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

/* ═══════════════════════════════════════════
   SANKEY VIEW
   ═══════════════════════════════════════════ */

.sankey-controls-bar {
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  padding: 6px 24px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-shrink: 0;
}

.sankey-toggle-btn {
  background: none;
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 6px 10px;
  min-height: 32px;
  font-family: var(--font);
  font-size: 12px;
  font-weight: 500;
  color: var(--text-secondary);
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 4px;
  transition: all 0.15s;
}

.sankey-toggle-btn:hover { border-color: #adb5bd; color: var(--text); }

.sankey-toggle-icon { font-size: 8px; }

.sankey-controls {
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  padding: 8px 24px;
  display: flex;
  align-items: flex-start;
  gap: 20px;
  flex-wrap: wrap;
  flex-shrink: 0;
}

.control-group {
  display: flex;
  flex-direction: column;
  gap: 5px;
}

.control-group .group-label {
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--text-muted);
}

.checkboxes {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

.checkboxes label {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 12px;
  cursor: pointer;
  padding: 3px 8px;
  border-radius: 4px;
  border: 1px solid var(--border);
  background: var(--surface);
  transition: all 0.15s;
}

.checkboxes label:hover { border-color: #adb5bd; }
.checkboxes label.checked { border-color: currentColor; background: color-mix(in srgb, currentColor 8%, white); }
.checkboxes input[type="checkbox"] { display: none; }

.ctl-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  display: inline-block;
  flex-shrink: 0;
}

.btn-group {
  display: flex;
  gap: 4px;
}

.btn-sm {
  font-family: var(--font);
  font-size: 12px;
  padding: 6px 10px;
  min-height: 32px;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: var(--surface);
  color: var(--text);
  cursor: pointer;
  transition: all 0.15s;
  white-space: nowrap;
}

.btn-sm:hover { border-color: #adb5bd; background: #f1f3f5; }
.btn-sm.active { background: var(--header-bg); color: #fff; border-color: var(--header-bg); }

.threshold-row {
  display: flex;
  align-items: center;
  gap: 8px;
}

.threshold-row input[type="range"] { width: 140px; }

.threshold-val {
  font-family: var(--mono);
  font-size: 12px;
  min-width: 55px;
  color: var(--text-secondary);
}

.sankey-info {
  font-size: 11px;
  color: var(--text-muted);
  font-family: var(--mono);
}

.sankey-chart-area {
  flex: 1;
  min-height: 0;
  position: relative;
}

.sankey-hint {
  position: absolute;
  bottom: 8px;
  left: 12px;
  font-size: 11px;
  color: var(--text-muted);
  background: var(--surface);
  padding: 4px 10px;
  border-radius: 12px;
  border: 1px solid var(--border);
  opacity: 0.8;
  transition: opacity 0.2s;
  pointer-events: auto;
}

.sankey-hint:hover {
  opacity: 0;
}

/* Make sankey nodes and links interactive */
.sankey-chart-area .sankey-node { cursor: pointer; }
/* Plotly sets opacity:0 on sankey links by default (only visible on hover).
   Override to show links at rest — our rgba colors already handle transparency. */
.sankey-chart-area .sankey-link { opacity: 1 !important; }

.sankey-chart-area .plotly-chart {
  width: 100%;
  height: 100%;
}

/* ═══════════════════════════════════════════
   TABLE VIEW
   ═══════════════════════════════════════════ */

.table-toolbar {
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}

/* Primary row: always visible — search, stats, action buttons */
.toolbar-primary {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
}

/* Filter panel: collapsible, grid layout */
.toolbar-filters {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
  gap: 4px;
  padding: 0 12px 8px;
  border-top: 1px solid var(--border);
}

.toolbar-filters select,
.table-toolbar select {
  font-family: var(--font);
  font-size: 11px;
  padding: 6px 6px;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: var(--surface);
  color: var(--text);
  width: 100%;
  min-height: 32px;
  cursor: pointer;
}

.btn-filter-toggle {
  font-family: var(--font);
  font-size: 11px;
  padding: 5px 10px;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: var(--surface);
  color: var(--text-secondary);
  cursor: pointer;
  white-space: nowrap;
  min-height: 32px;
}
.btn-filter-toggle:hover { background: #f1f3f5; }
.btn-filter-toggle.active { background: #e8eaed; border-color: #adb5bd; }
.btn-filter-toggle.has-filters { color: var(--accent); border-color: var(--accent); font-weight: 600; }

.table-toolbar select:focus {
  outline: none;
  border-color: var(--accent);
}

.table-search {
  font-family: var(--font);
  font-size: 12px;
  padding: 6px 10px;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: var(--surface);
  color: var(--text);
  min-width: 120px;
  flex: 1;
  max-width: 300px;
  min-height: 32px;
}

.table-search:focus {
  outline: none;
  border-color: var(--accent);
}

.table-search::placeholder { color: var(--text-muted); }

.table-stats {
  font-size: 12px;
  color: var(--text-secondary);
  white-space: nowrap;
  display: flex;
  align-items: center;
  gap: 8px;
  margin-left: auto;
}

.table-stats .stat-count {
  font-weight: 600;
  color: var(--text);
}

.table-stats .stat-amount {
  font-family: var(--mono);
  font-weight: 500;
  color: var(--accent);
}

/* Bead expenses_tool-b6a1 — drill stats: actuals (canonical, matches Budget
   view's Actual column) plus secondary "flow" stat (ABS sum across all
   txnTypes — refunds, transfers, double-entry). Actuals reads bold/accent;
   flow reads quieter so the eye lands on the trustworthy number first. */
.table-stats .stat-actuals {
  font-weight: 700;
  color: var(--accent);
}
.table-stats .stat-actuals-label {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-secondary);
  margin-left: 2px;
}
.table-stats .stat-sep {
  color: var(--text-muted);
  margin: 0 2px;
}
.table-stats .stat-flow {
  color: var(--text-secondary);
  font-weight: 500;
}
.table-stats .stat-flow-label {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-muted);
  margin-left: 2px;
}

.btn-review-filter {
  font-family: var(--font);
  font-size: 11px;
  padding: 4px 6px;
  min-height: 28px;
  max-width: 110px;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: var(--surface);
  color: var(--text);
  cursor: pointer;
  outline: none;
}
.btn-review-filter:hover { border-color: #adb5bd; }
.btn-review-filter:focus { border-color: var(--accent); }
.btn-clear-filters {
  font-family: var(--font);
  font-size: 11px;
  padding: 4px 8px;
  min-height: 28px;
  border: 1px solid #fca5a5;
  border-radius: 4px;
  background: #fef2f2;
  color: #991b1b;
  cursor: pointer;
  white-space: nowrap;
  transition: background 0.1s;
}
.btn-clear-filters:hover { background: #fecaca; }

.btn-export {
  font-family: var(--font);
  font-size: 11px;
  padding: 5px 10px;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: var(--surface);
  color: var(--text-secondary);
  cursor: pointer;
  transition: all 0.15s;
  white-space: nowrap;
  min-height: 32px;
}

.btn-export:hover { border-color: #adb5bd; background: #f1f3f5; }
.btn-audit {
  font-family: var(--font);
  font-size: 11px;
  padding: 6px 10px;
  min-height: 32px;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: var(--surface);
  color: var(--text-secondary);
  cursor: pointer;
  white-space: nowrap;
}
.btn-audit:hover { border-color: #adb5bd; background: #f1f3f5; }

/* Audit Panel */
.audit-panel {
  position: fixed;
  right: 0; top: 0; bottom: 0;
  width: 420px;
  background: #fff;
  box-shadow: -4px 0 20px rgba(0,0,0,0.15);
  z-index: 10000;
  display: flex;
  flex-direction: column;
}
.audit-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 20px;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}
.audit-header h3 { margin: 0; font-size: 15px; font-weight: 600; }
.audit-close {
  background: none; border: none;
  font-size: 22px; color: var(--text-secondary);
  cursor: pointer; padding: 0 4px;
}
.audit-close:hover { color: var(--text-primary); }
.audit-content {
  flex: 1;
  overflow-y: auto;
  padding: 16px 20px;
}
.audit-entry {
  padding: 12px 0;
  border-bottom: 1px solid #f0f0f0;
}
.audit-entry-header {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 4px;
}
.audit-who { font-weight: 600; font-size: 13px; }
.audit-action {
  font-size: 10px; font-weight: 600;
  padding: 1px 6px; border-radius: 3px;
  text-transform: uppercase;
}
.audit-action-update { background: #dbeafe; color: #1e40af; }
.audit-action-delete { background: #fecaca; color: #991b1b; }
.audit-action-create { background: #d1fae5; color: #065f46; }
.audit-time { font-size: 11px; color: var(--text-muted); margin-left: auto; }
.audit-txn { font-size: 11px; color: var(--text-muted); font-family: var(--mono); margin-bottom: 6px; }
.audit-field { font-size: 12px; margin: 2px 0; }
.audit-field-name { font-weight: 600; color: var(--text-secondary); }
.audit-old { color: #991b1b; text-decoration: line-through; }
.audit-new { color: #065f46; font-weight: 500; }
.audit-notes { font-size: 11px; color: var(--text-muted); font-style: italic; margin-top: 4px; }
.audit-empty, .audit-loading, .audit-error { font-size: 13px; color: var(--text-muted); }
.audit-source { font-size: 10px; color: var(--text-muted); font-style: italic; }
.audit-error { color: #991b1b; }

/* Budget-edit audit entries (bead gspl) — QuickBooks/Vena field-diff
   grammar. The dollar transition is the focal line; the reason is a quote
   beneath. Distinct from transaction-correction entries (no txn-id row,
   bigger numbers). */
.audit-action-set { background: #e0e7ff; color: #3730a3; }  /* 7.4:1 on #e0e7ff */
.audit-entry-budget .audit-budget-diff {
  font-family: var(--mono, ui-monospace, SFMono-Regular, Menlo, monospace);
  font-variant-numeric: tabular-nums;
  font-size: 14px;
  margin: 6px 0 2px;
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 6px;
}
.audit-budget-old { color: var(--text-muted, #6b7280); }  /* 4.83:1 — "before" muted */
.audit-budget-new { color: var(--text, #111827); font-weight: 600; }
.audit-budget-arrow { color: var(--text-muted, #6b7280); font-family: var(--font); font-size: 12px; }
.audit-budget-baseline {
  color: var(--text-secondary, #4b5563);
  font-style: italic;
  font-family: var(--font);
  font-size: 12px;
}
.audit-entry-budget .audit-notes {
  /* Reason reads as a pull-quote — slightly larger, accented left rule. */
  font-size: 12px;
  font-style: normal;
  color: var(--text-secondary, #4b5563);
  border-left: 2px solid var(--border, #e5e7eb);
  padding-left: 8px;
  margin-top: 5px;
}
/* Baseline anchor — the bottom of the chain. Not an edit (no actor/Set
   badge), so it reads quieter: dashed top rule, muted, italic note. */
.audit-entry-baseline {
  border-top: 1px dashed var(--border, #e5e7eb);
  opacity: 0.85;
}
.audit-entry-baseline .audit-notes {
  border-left: none;
  padding-left: 0;
  font-style: italic;
  color: var(--text-muted, #6b7280);
}
/* Drill from the baseline anchor into the prior-year transactions. Link-
   styled so it reads as an action without competing with the edit entries. */
.audit-baseline-drill {
  margin-top: 6px;
  background: transparent;
  border: none;
  padding: 2px 0;
  font: inherit;
  font-size: 12px;
  color: var(--accent, #1d4ed8);  /* 7.7:1 on #fff */
  cursor: pointer;
  text-align: left;
}
.audit-baseline-drill:hover { text-decoration: underline; }
.audit-baseline-drill:focus-visible {
  outline: 2px solid var(--accent, #2563eb);
  outline-offset: 1px;
}

.table-scroll-area {
  flex: 1;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

/* Virtual scroll */
.vscroll-viewport {
  flex: 1;
  overflow: auto;
  position: relative;
  will-change: scroll-position;
  contain: layout style;
  -webkit-overflow-scrolling: touch;
}
.vscroll-table {
  table-layout: fixed;
  width: 2250px;
}
.vscroll-table thead th {
  position: sticky;
  top: 0;
  z-index: 2;
  background: #eaecef;
  box-shadow: 0 1px 0 var(--border, #e5e7eb);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* Fixed column widths — prevents resizing during virtual scroll */
/* Sized to fit longest common content without truncation */
.vscroll-table th[data-sort="date"] { width: 100px; }
.vscroll-table th[data-sort="vendor"] { width: 200px; }
.vscroll-table th[data-sort="amount"] { width: 115px; }
.vscroll-table th[data-sort="txnType"] { width: 95px; }
.vscroll-table th[data-sort="bucket"] { width: 115px; }
.vscroll-table th[data-sort="subBucket"] { width: 150px; }
.vscroll-table th[data-sort="activity"] { width: 165px; }
.vscroll-table th[data-sort="subActivity"] { width: 135px; }
.vscroll-table th[data-sort="entity"] { width: 180px; }
.vscroll-table th[data-sort="glAccount"] { width: 180px; }
.vscroll-table th[data-sort="cardMember"] { width: 130px; }
.vscroll-table th[data-sort="tags"] { width: 140px; }
.vscroll-table th[data-sort="source"] { width: 90px; }
.vscroll-table th[data-sort="description"] { width: 250px; }
.vscroll-table th:last-child { width: 65px; } /* Docs */
/* Default: no truncation, allow wrap */
.vscroll-table td { overflow: hidden; }
/* Vendor wraps naturally */
.vscroll-table td:nth-child(2) { white-space: normal; word-wrap: break-word; }
/* Entity wraps at arrow or (paid by) — not mid-name */
.vscroll-table td.entity-cell { white-space: normal; }
.entity-name { white-space: nowrap; }
.entity-arrow { margin: 0 2px; }
.acct-mask { display: block; font-size: 10px; color: var(--text-muted); white-space: nowrap; }
/* Fixed columns — short values, never truncate */
/* Bead u53b — Eren 2026-05-08: date cells were inheriting overflow-x:auto
   along with .source-cell, .num, .tags-cell. Dates are uniformly 10 chars
   so the scrollbar should never trigger, but Chrome's sub-pixel rounding
   caused a scrollbar on some rows and not others as the column width
   fluctuated by ±1px. Splitting date-cell out so it just nowraps. */
.vscroll-table td.date-cell { white-space: nowrap; }
.vscroll-table td.source-cell,
.vscroll-table td.num,
.vscroll-table td.tags-cell { white-space: nowrap; overflow-x: auto; }
.vscroll-table td.member-cell { white-space: normal; word-wrap: break-word; }
/* Scroll column — description */
.vscroll-table td.desc-cell { overflow-x: auto; white-space: nowrap; }
.vscroll-footer { flex-shrink: 0; }

/* Shared table styles (pie txn table + table view) */
.data-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}

.data-table thead { position: sticky; top: 0; z-index: 2; }

.data-table th {
  background: #f0f1f3;
  color: var(--text-secondary);
  font-weight: 600;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding: 9px 14px;
  text-align: left;
  cursor: pointer;
  user-select: none;
  white-space: nowrap;
  border-bottom: 2px solid var(--border);
  transition: color 0.15s;
}

.data-table th:hover { color: var(--text); }
.data-table th.active { color: var(--accent); }
.data-table th .sort-arrow { font-size: 10px; margin-left: 3px; }
.data-table th.num { text-align: right; }
.data-table th { position: relative; }

/* Column filter button — bead expenses_tool-fvkj.
   Always visible at low opacity so the affordance is discoverable;
   hover and active states emphasize. Previously hidden at opacity:0
   until column-header hover, which made the filter undiscoverable
   (Danielle hit this on 2026-05-05 trying to filter by date). */
.col-filter-btn {
  background: none; border: none; cursor: pointer;
  color: var(--text-muted); font-size: 10px;
  padding: 0 2px; margin-left: 2px;
  opacity: 0.45; transition: opacity 0.15s, color 0.15s;
  vertical-align: middle; line-height: 1;
}
th:hover .col-filter-btn { opacity: 0.75; }
.col-filter-btn:hover { opacity: 1; color: var(--accent); }
.col-filter-btn.active { opacity: 1; color: var(--accent); }

/* Column filter dropdown — Google Sheets style */
.col-filter-dropdown {
  position: fixed; z-index: 1000;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 8px; box-shadow: 0 8px 24px rgba(0,0,0,0.15);
  width: 240px; max-height: 380px;
  display: flex; flex-direction: column;
  font-size: 13px; text-transform: none; letter-spacing: normal;
  font-weight: 400; color: var(--text);
  cursor: default;
}
.col-filter-header {
  padding: 10px 12px 6px;
  font-size: 11px; font-weight: 600; text-transform: uppercase;
  letter-spacing: 0.04em; color: var(--text-secondary);
}
.col-filter-search {
  margin: 0 10px 6px; padding: 7px 10px;
  border: 1px solid var(--border); border-radius: 4px;
  font-family: var(--font); font-size: 13px; outline: none;
  background: var(--bg);
}
.col-filter-search:focus { border-color: var(--accent); box-shadow: 0 0 0 2px rgba(43,123,186,0.15); }
.col-filter-select-row {
  display: flex; gap: 12px; padding: 0 12px 6px;
  border-bottom: 1px solid var(--border);
}
.col-filter-link {
  font-size: 11px; color: var(--accent); cursor: pointer;
  text-decoration: none;
}
.col-filter-link:hover { text-decoration: underline; }
.col-filter-list {
  overflow-y: auto; flex: 1; min-height: 0;
  max-height: 240px; padding: 4px 0;
}
.col-filter-item {
  display: flex; align-items: center; gap: 8px;
  padding: 5px 12px; cursor: pointer;
  white-space: nowrap; transition: background 0.1s;
}
.col-filter-item:hover { background: var(--accent-light); }
.col-filter-item input[type="checkbox"] {
  margin: 0; flex-shrink: 0; cursor: pointer;
  width: 14px; height: 14px;
}
.col-filter-label { overflow: hidden; text-overflow: ellipsis; flex: 1; }
.col-filter-count { color: var(--text-muted); font-size: 11px; flex-shrink: 0; }
.col-filter-actions {
  display: flex; gap: 6px; padding: 8px 10px;
  border-top: 1px solid var(--border);
}
.col-filter-clear-btn {
  flex: 1; padding: 6px 0; border: 1px solid var(--border);
  border-radius: 4px; background: var(--surface); cursor: pointer;
  font-family: var(--font); font-size: 12px; color: var(--text-secondary);
  transition: background 0.1s;
}
.col-filter-clear-btn:hover { background: #fef2f2; color: #991b1b; border-color: #fca5a5; }
.col-filter-ok-btn {
  flex: 1; padding: 6px 0; border: 1px solid var(--accent);
  border-radius: 4px; background: var(--accent); cursor: pointer;
  font-family: var(--font); font-size: 12px; font-weight: 600; color: #fff;
  transition: opacity 0.1s;
}
.col-filter-ok-btn:hover { opacity: 0.9; }

/* Date range inputs */
.col-filter-date { padding: 6px 10px; display: flex; flex-direction: column; gap: 8px; }
.col-filter-date-row { display: flex; align-items: center; gap: 8px; }
.col-filter-date-label { font-size: 12px; color: var(--text-secondary); width: 36px; flex-shrink: 0; }
.col-filter-date-input {
  flex: 1; padding: 6px 8px; border: 1px solid var(--border);
  border-radius: 4px; font-family: var(--font); font-size: 13px; background: var(--bg);
}
.col-filter-date-input:focus { border-color: var(--accent); box-shadow: 0 0 0 2px rgba(43,123,186,0.15); }

/* Active filter indicator — highlighted header */
th:has(.col-filter-btn.active) { background: rgba(43,123,186,0.08) !important; }

.data-table td {
  padding: 8px 14px;
  border-bottom: 1px solid #f0f1f3;
  color: var(--text);
  vertical-align: top;
}

.data-table td.num {
  text-align: right;
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 500;
  white-space: nowrap;
}

.data-table td.date-cell {
  white-space: nowrap;
  color: var(--text-secondary);
  font-family: var(--mono);
  font-size: 12px;
}

.data-table td.desc-cell {
  max-width: 280px;
  overflow-x: auto;
  white-space: nowrap;
  color: var(--text-secondary);
  font-size: 12px;
}

.data-table td.member-cell {
  font-size: 11px;
  color: var(--text-muted);
  white-space: nowrap;
}

.tags-cell { white-space: nowrap; overflow-x: auto; }
.tag-pill {
  display: inline-block;
  font-size: 10px; font-weight: 500;
  background: #e0e7ff; color: #3730a3;
  padding: 1px 6px; border-radius: 10px;
  margin-right: 3px; vertical-align: middle;
}
.tag-pill .tag-remove {
  cursor: pointer; margin-left: 5px; padding: 0 4px;
  font-size: 14px; font-weight: 700; line-height: 16px;
  color: #fff; background: #991b1b; border-radius: 50%;
  display: inline-block; width: 16px; height: 16px; text-align: center;
  vertical-align: middle; opacity: 0.7;
}
.tag-pill .tag-remove:hover { opacity: 1; }
.tag-add {
  display: inline-block;
  font-size: 13px; font-weight: 600;
  background: none; border: 1px dashed #cbd5e1;
  color: #94a3b8; border-radius: 10px;
  padding: 4px 12px; min-width: 34px; min-height: 28px;
  cursor: pointer;
  vertical-align: middle;
  min-width: 24px; min-height: 24px;
  line-height: 20px;
  text-align: center;
}
.tag-add:hover { border-color: #6366f1; color: #6366f1; }

.data-table td.entity-cell {
  font-size: 12px;
  color: var(--text-secondary);
  white-space: nowrap;
}

.acct-mask {
  font-family: var(--mono);
  font-size: 10px;
  color: var(--text-muted);
}

.entity-arrow {
  color: var(--text-muted);
  font-size: 11px;
  margin: 0 2px;
}

.data-table td.source-cell {
  font-size: 11px;
  color: var(--text-muted);
  white-space: nowrap;
}

/* Status dots appear after text — minimal visual weight */
.data-table td { vertical-align: middle; }
td:has(.cat-dot) { white-space: nowrap; }
.cat-dot {
  display: inline-block;
  width: 7px; height: 7px;
  border-radius: 50%;
  vertical-align: middle;
  margin-left: 4px;
  cursor: help;
}
.cat-dot-human { background: #22c55e; }
.cat-dot-review { background: #f97316; }

/* Legacy badge classes (used by reconcile status column) */
.cat-badge {
  display: inline-block;
  font-size: 9px;
  font-weight: 700;
  width: 14px; height: 14px;
  line-height: 14px;
  text-align: center;
  border-radius: 3px;
  vertical-align: middle;
  margin-left: 4px;
}
.cat-human { background: #d1fae5; color: #065f46; }
.cat-auto { background: #fef3c7; color: #92400e; }
.cat-resolved { background: #d1fae5; color: #065f46; cursor: pointer; }
.cat-needs-review { background: #fed7aa; color: #9a3412; }
td.needs-review-field { background: rgba(254, 215, 170, 0.2); }
td.gl-mismatch { background: rgba(147, 130, 255, 0.08); }
.gl-mismatch-icon { color: #8b5cf6; font-size: 12px; cursor: help; margin-left: 2px; }
.gl-mismatch-badge {
  font-size: 10px; color: #8b5cf6; background: rgba(147, 130, 255, 0.1);
  padding: 1px 5px; border-radius: 8px; margin-left: 6px; cursor: help;
  white-space: nowrap;
}
.review-tag {
  display: inline-block;
  font-size: 9px; font-weight: 600;
  background: #fecaca; color: #991b1b;
  padding: 1px 5px; border-radius: 3px;
  vertical-align: middle; margin-left: 4px;
}
tr.needs-review { background: rgba(254, 202, 202, 0.12); }
.reset-btn {
  display: inline-block;
  font-size: 10px; font-weight: 600;
  background: #e5e7eb; color: #374151;
  border: none; border-radius: 3px;
  padding: 6px 6px; margin-left: 4px; min-height: 28px;
  cursor: pointer; vertical-align: middle;
  transition: all 0.12s;
}
.reset-btn:hover { background: #fecaca; color: #991b1b; }

td.editable-cell {
  cursor: pointer;
  position: relative;
  border-bottom: 1px dashed var(--border);
}
td.editable-cell:hover {
  background: rgba(43, 123, 186, 0.08);
  border-bottom-color: var(--accent);
}
td.editable-cell:hover::after {
  content: '\270E';
  position: absolute; right: 4px; top: 50%;
  transform: translateY(-50%);
  font-size: 12px; color: var(--accent); opacity: 0.7;
}

.inline-editor-search {
  width: 100%;
  box-sizing: border-box;
  padding: 7px 10px;
  font-family: var(--font);
  font-size: 13px;
  border: none;
  border-bottom: 1px solid var(--border);
  outline: none;
  background: var(--surface);
}
.inline-editor-search:focus { border-bottom-color: var(--accent); }
.inline-editor-list {
  max-height: 200px;
  overflow-y: auto;
}
.inline-editor-option {
  padding: 6px 10px;
  font-size: 12px;
  cursor: pointer;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.inline-editor-option:hover { background: var(--accent-light); }
.inline-editor-option.current { color: var(--accent); font-weight: 600; }
.inline-editor-option.new { color: var(--accent); font-style: italic; border-top: 1px solid var(--border); }

.inline-editor {
  font-size: 12px;
  font-family: inherit;
  border: 2px solid var(--accent);
  border-radius: 4px;
  background: #fff;
  box-shadow: 0 4px 12px rgba(0,0,0,0.15);
  padding: 2px;
  outline: none;
}
.inline-editor option { padding: 4px 8px; }
.inline-editor option:checked { background: var(--accent); color: #fff; }
.inline-editor-wrap {
  box-shadow: 0 4px 16px rgba(0,0,0,0.18);
  border-radius: 6px;
  border: 1px solid var(--border);
  background: var(--surface);
  overflow: hidden;
}
/* Bead apxf — header bar names the field being edited so users can't
   confuse Sub-Bucket with Activity (or any other pair). */
.inline-editor-header {
  font-size: 11px;
  color: var(--text-secondary);
  background: var(--surface-muted, #f8fafc);
  padding: 6px 10px;
  border-bottom: 1px solid var(--border);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.inline-editor-header strong {
  color: var(--text);
  font-weight: 600;
  text-transform: none;
  letter-spacing: 0;
}
.inline-editor-text {
  font-size: 12px;
  font-family: inherit;
  border: 2px solid var(--accent);
  border-radius: 4px;
  padding: 6px 8px;
  outline: none;
  box-shadow: none;
  display: block;
}

/* ── R3b Set editor (bead expenses_tool-60rb, pattern 10) ──
   Inline popover anchored over a Budget cell. Captures a new annual amount
   plus a required Reason field; verb is "Set" everywhere. */
/* ═══════════════════════════════════════════════════════════════════════
   R3b Set editor (bead 60rb) — editorial-finance redesign.

   Aesthetic: Bloomberg Terminal meets Stripe Dashboard. Big tabular
   numbers as the hero, small-caps section labels, hairline dividers,
   restrained palette. No rounded "card" chrome, no gradients, no stock
   icons. The Pigment-style live impact preview (.bse-impact-row) is the
   one thing the user remembers — it earns the visual weight.

   Sourced from FP&A research (2026-05-26):
   - Causal: override badge + revert affordance on overridden cells
   - Pigment: live parent-rollup preview as you type
   - QuickBooks/Vena: field-level diff visual grammar (old → new)
   - Anaplan: small inline indicator on cells WITH history (not all cells)

   Refs:
   - https://docs.causal.app/managing-models/the-causal-interface (overrides)
   - https://www.pigment.com/platform (live preview)
   - https://quickbooks.intuit.com/learn-support/.../audit-history (diff display)
═══════════════════════════════════════════════════════════════════════ */

/* Cell-level affordances: budget-set-target is the click target; the
   editor opens on click. Dotted underline + accent-tinted hover signals
   editability without competing with the row's other affordances. */
.budget-set-target {
  cursor: pointer;
  position: relative;
  text-decoration: underline;
  text-decoration-style: dotted;
  text-decoration-color: rgba(0,0,0,0.18);
  text-underline-offset: 3px;
  transition: background 0.12s ease-out;
}
.budget-set-target:hover {
  background: var(--accent-light, rgba(59,130,246,0.08));
  text-decoration-color: var(--accent, #2563eb);
}
/* Causal-pattern override marker. Tiny accent diamond inset to the left
   of the dollar amount on any cell that has a session-local edit. Hover
   exposes the tooltip with baseline/reset semantics. Sized small enough
   to not break the column's right-alignment. */
.budget-set-target.has-override {
  background: linear-gradient(90deg, rgba(37,99,235,0.07) 0, rgba(37,99,235,0.02) 24px, transparent 48px);
}
.budget-cell-override-marker {
  display: inline-block;
  width: 8px;
  height: 8px;
  margin-right: 5px;
  vertical-align: 1px;
  /* Hard-set color so the marker reads regardless of the cell's text color
     (which can shift for variance/diff states). 4.5:1 contrast on white. */
  color: var(--accent, #1d4ed8);
  font-size: 10px;
  line-height: 1;
}
/* o0ap: impacted-by-propagation marker (◇ hollow) — a row whose value
   changed because of an edit at an ancestor/descendant scope, distinct
   from the ◆ filled direct-edit marker. Muted tint, lighter than has-override. */
.budget-set-target.has-impact {
  background: linear-gradient(90deg, rgba(107,114,128,0.06) 0, rgba(107,114,128,0.02) 24px, transparent 48px);
}
.budget-cell-impact-marker {
  display: inline-block;
  margin-right: 5px;
  vertical-align: 1px;
  color: var(--text-muted, #6b7280);  /* muted vs the accent ◆ */
  font-size: 10px;
  line-height: 1;
}
.budget-cell-saved {
  background: rgba(34,197,94,0.18) !important;
  transition: background 0.6s ease-out;
}
/* o0ap: derived "Impacted" history entry in the unified drawer. */
.audit-action-impact { background: #f3f4f6; color: #4b5563; }  /* 7.5:1 on #f3f4f6 */
.audit-entry-impact { border-left: 2px solid var(--border-muted, #e5e7eb); padding-left: 8px; }
.audit-impact-by {
  font-size: 11.5px;
  color: var(--text-secondary, #4b5563);
  margin-top: 3px;
  line-height: 1.4;
}
.audit-impact-by strong { color: var(--text, #111827); font-weight: 600; }

/* ── Popover shell ──────────────────────────────────────────────────── */
.budget-set-editor {
  font-family: var(--font, inherit);
  background: var(--surface, #fff);
  border: 1px solid rgba(17, 24, 39, 0.10);
  border-radius: 6px;
  /* Stripe-style elevated shadow — assertive enough to feel like a
     decision surface, restrained enough not to feel like a modal. */
  box-shadow:
    0 1px 2px rgba(17, 24, 39, 0.04),
    0 12px 32px rgba(17, 24, 39, 0.14),
    0 24px 56px rgba(17, 24, 39, 0.06);
  overflow: hidden;
  /* Override .inline-editor-wrap defaults that don't fit this layout. */
  padding: 0;
}

/* ── Header strip ───────────────────────────────────────────────────── */
.bse-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 14px;
  border-bottom: 1px solid rgba(17, 24, 39, 0.06);
}
.bse-path {
  /* Small-caps breadcrumb — editorial finance staple. The path is
     reference metadata, not the focal point. */
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-secondary, #4b5563);  /* 8.5:1 on #fff */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  flex: 1;
  min-width: 0;
}
.bse-close {
  background: transparent;
  border: none;
  padding: 4px;
  margin: -4px;
  border-radius: 4px;
  cursor: pointer;
  color: var(--text-muted, #6b7280);  /* 4.83:1 on #fff */
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  transition: color 0.12s, background 0.12s;
}
.bse-close:hover {
  color: var(--text, #111827);
  background: var(--surface-muted, #f3f4f6);
}
.bse-close:focus-visible {
  outline: 2px solid var(--accent, #2563eb);
  outline-offset: 1px;
}

/* ── Hero: the dollar amount ────────────────────────────────────────── */
.bse-hero {
  display: flex;
  align-items: baseline;
  gap: 6px;
  padding: 20px 16px 8px;
  /* Underline draws on focus to signal active editing — replaces the
     border-box approach. Cleaner; the number reads as text, not as a
     filled form field. */
}
.bse-currency {
  font-family: var(--mono, ui-monospace, SFMono-Regular, Menlo, monospace);
  font-size: 22px;
  font-weight: 500;
  color: var(--text-secondary, #4b5563);
  line-height: 1;
}
.bse-amount-input {
  flex: 1;
  min-width: 0;
  font-family: var(--mono, ui-monospace, SFMono-Regular, Menlo, monospace);
  font-size: 32px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
  color: var(--text, #111827);  /* 16:1+ on #fff */
  background: transparent;
  border: none;
  border-bottom: 2px solid transparent;
  padding: 2px 0;
  outline: none;
  width: 100%;
  transition: border-color 0.15s ease-out;
}
.bse-amount-input:focus {
  border-bottom-color: var(--accent, #2563eb);
}
.bse-unit {
  font-family: var(--font, inherit);
  font-size: 12px;
  font-style: italic;
  color: var(--text-muted, #6b7280);  /* 4.83:1 on #fff */
  flex-shrink: 0;
  line-height: 1;
}

/* ── "Match actuals" quick-action (demo feedback 2026-05-26). Sets the
      budget to the scope's actual spend in one click → $0 remaining. Sits
      just under the hero number; subtle pill so it reads as a shortcut, not
      a primary control. ─────────────────────────────────────────────── */
.bse-match-row {
  padding: 0 16px 10px;
}
.bse-match-actuals {
  background: transparent;
  border: 1px dashed var(--border, #d1d5db);
  border-radius: 4px;
  padding: 4px 10px;
  font: inherit;
  font-size: 11.5px;
  color: var(--accent, #1d4ed8);  /* 7.7:1 on #fff */
  cursor: pointer;
  font-variant-numeric: tabular-nums;
}
.bse-match-actuals:hover {
  background: var(--accent-light, rgba(37,99,235,0.08));
  border-style: solid;
}
.bse-match-actuals:focus-visible {
  outline: 2px solid var(--accent, #2563eb);
  outline-offset: 1px;
}

/* ── Provenance row: override badge + revert (Causal) on the left,
      "View history" (gspl) on the right. Always present so the row never
      collapses; the left side toggles between override badge and the
      ca45 source label. ─────────────────────────────────────────────── */
.bse-provenance-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  padding: 4px 16px 14px;
  font-size: 11.5px;
  color: var(--text-muted, #6b7280);  /* 4.83:1 on #fff */
  line-height: 1.4;
}
.bse-prov-left { min-width: 0; flex: 1; }
.bse-prov-override[hidden],
.bse-prov-source[hidden] { display: none; }
.bse-prov-source { color: var(--text-secondary, #4b5563); }
.bse-history-link {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  background: transparent;
  border: none;
  padding: 2px 2px;
  font: inherit;
  font-size: 11px;
  color: var(--accent, #1d4ed8);  /* 7.7:1 on #fff */
  cursor: pointer;
  border-radius: 3px;
}
.bse-history-link svg { opacity: 0.85; }
.bse-history-link:hover { text-decoration: underline; }
.bse-history-link:focus-visible {
  outline: 2px solid var(--accent, #2563eb);
  outline-offset: 1px;
}
.bse-override-badge {
  color: var(--accent, #1d4ed8);
  font-size: 9px;
  line-height: 1;
  position: relative;
  top: -1px;
  flex-shrink: 0;
}
.bse-override-text {
  flex: 1;
  min-width: 0;
}
.bse-override-prefix { color: var(--text-secondary, #4b5563); }
.bse-override-baseline {
  /* Link-styled button — clickable but reads as a value. Underline only
     on hover/focus to keep the resting state quiet. */
  background: transparent;
  border: none;
  padding: 0;
  font: inherit;
  font-family: var(--mono, ui-monospace, SFMono-Regular, Menlo, monospace);
  font-variant-numeric: tabular-nums;
  color: var(--accent, #1d4ed8);  /* 7.7:1 on #fff */
  cursor: pointer;
  text-underline-offset: 2px;
}
.bse-override-baseline:hover,
.bse-override-baseline:focus-visible {
  text-decoration: underline;
  outline: none;
}
.bse-override-suffix { color: var(--text-muted, #6b7280); }

/* ── Section divider + label ────────────────────────────────────────── */
.bse-section {
  padding: 14px 16px;
  border-top: 1px solid rgba(17, 24, 39, 0.06);
}
.bse-section-label {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: var(--text-secondary, #4b5563);  /* 8.5:1 on #fff */
}

/* ── Impact preview (Pigment pattern) ───────────────────────────────── */
.bse-impact[hidden] { display: none; }
.bse-impact-row {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin-top: 6px;
}
.bse-impact-parent {
  font-size: 13px;
  font-weight: 500;
  color: var(--text, #111827);
  line-height: 1.3;
}
.bse-impact-numbers {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 8px;
  font-family: var(--mono, ui-monospace, SFMono-Regular, Menlo, monospace);
  font-variant-numeric: tabular-nums;
  font-size: 14px;
  line-height: 1.5;
}
.bse-impact-from {
  color: var(--text-muted, #6b7280);  /* 4.83:1 on #fff — "before" is muted */
}
.bse-impact-arrow {
  color: var(--text-muted, #6b7280);
  font-size: 12px;
  font-family: var(--font, inherit);  /* arrow renders cleaner in sans */
  margin: 0 -2px;
}
.bse-impact-to {
  color: var(--text, #111827);
  font-weight: 600;
}
.bse-impact-delta {
  margin-left: auto;
  font-weight: 600;
  font-size: 13px;
  padding: 1px 6px;
  border-radius: 2px;
}
.bse-impact-up .bse-impact-delta {
  /* Spending UP from baseline = budget increased. Amber, not red — neither
     a fault nor a hero. 5.45:1 on #fef3c7. */
  background: #fef3c7;
  color: #92400e;
}
.bse-impact-down .bse-impact-delta {
  /* Spending DOWN = budget cut. Green for "cost reduction". 4.59:1 on #dcfce7. */
  background: #dcfce7;
  color: #15803d;
}
.bse-impact-nochange {
  color: var(--text-muted, #6b7280);
  font-style: italic;
  font-size: 12px;
}

/* ── Reason section ─────────────────────────────────────────────────── */
.bse-reason-section .bse-section-header {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin-bottom: 8px;
}
.bse-required {
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  /* Crimson tone calls out the requirement without shouting. 7.2:1 on #fff. */
  color: #b91c1c;
}
.bse-counter {
  margin-left: auto;
  font-family: var(--mono, ui-monospace, SFMono-Regular, Menlo, monospace);
  font-variant-numeric: tabular-nums;
  font-size: 11px;
  color: var(--text-muted, #6b7280);
}
.bse-counter-val { font-weight: 600; color: var(--text-secondary, #4b5563); }
.bse-reason-input {
  width: 100%;
  box-sizing: border-box;
  font-family: var(--font, inherit);
  font-size: 13.5px;
  line-height: 1.45;
  color: var(--text, #111827);
  background: var(--surface, #fff);
  border: 1px solid rgba(17, 24, 39, 0.12);
  border-radius: 4px;
  padding: 8px 10px;
  outline: none;
  resize: none;
  transition: border-color 0.12s, box-shadow 0.12s;
}
.bse-reason-input::placeholder {
  color: var(--text-muted, #9ca3af);
  font-style: italic;
}
.bse-reason-input:focus {
  border-color: var(--accent, #2563eb);
  box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.12);
}

/* ── Actions footer ─────────────────────────────────────────────────── */
.bse-actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 8px;
  padding: 12px 16px;
  border-top: 1px solid rgba(17, 24, 39, 0.06);
  background: var(--surface-muted, #fafbfc);
  /* Sticky to the bottom of the (scrollable) popover so Cancel/Set stay
     reachable even when a short viewport forces the body to scroll. The
     wrapper is the scroll context (inline overflow-y: auto). Opaque
     background so scrolled content doesn't bleed under the buttons. */
  position: sticky;
  bottom: 0;
}
.bse-cancel,
.bse-set {
  font-family: var(--font, inherit);
  font-size: 12.5px;
  font-weight: 500;
  padding: 7px 14px;
  border-radius: 4px;
  cursor: pointer;
  min-height: 32px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  transition: background 0.12s, border-color 0.12s, color 0.12s, box-shadow 0.12s;
}
.bse-cancel {
  background: transparent;
  border: 1px solid rgba(17, 24, 39, 0.14);
  color: var(--text-secondary, #4b5563);
}
.bse-cancel:hover {
  background: var(--surface-muted, #f3f4f6);
  color: var(--text, #111827);
}
.bse-cancel:focus-visible {
  outline: 2px solid var(--accent, #2563eb);
  outline-offset: 1px;
}
.bse-set {
  background: var(--text, #111827);   /* near-black primary, not the accent — */
  border: 1px solid var(--text, #111827); /*   feels weightier, more finance-y */
  color: #fff;
  font-weight: 600;
}
.bse-set:not(:disabled):hover {
  background: #000;
  border-color: #000;
}
.bse-set:focus-visible {
  outline: 2px solid var(--accent, #2563eb);
  outline-offset: 2px;
}
.bse-set:disabled {
  background: rgba(17, 24, 39, 0.10);
  border-color: rgba(17, 24, 39, 0.10);
  color: rgba(17, 24, 39, 0.36);  /* 4.6:1 — meets AA at this small size */
  cursor: not-allowed;
}
.bse-set-kbd {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--mono, ui-monospace, SFMono-Regular, Menlo, monospace);
  font-size: 11px;
  line-height: 1;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  border: 1px solid rgba(255, 255, 255, 0.3);
  border-radius: 3px;
  color: rgba(255, 255, 255, 0.85);
  background: rgba(255, 255, 255, 0.08);
}
.bse-set:disabled .bse-set-kbd {
  border-color: rgba(17, 24, 39, 0.18);
  color: rgba(17, 24, 39, 0.36);
  background: transparent;
}

/* ── Mobile (375px and below) ───────────────────────────────────────── */
@media (max-width: 600px) {
  .bse-header { padding: 10px 12px; }
  .bse-hero {
    padding: 16px 12px 6px;
    /* Wrap the unit to a second line on very narrow widths so the number
       stays the dominant element. */
    flex-wrap: wrap;
  }
  .bse-amount-input { font-size: 26px; }
  .bse-currency { font-size: 18px; }
  .bse-override-row { padding: 4px 12px 12px; }
  .bse-section { padding: 12px; }
  .bse-impact-numbers {
    /* Stack vertically below 480px so each number is legible. */
    flex-direction: column;
    align-items: flex-start;
    gap: 2px;
  }
  .bse-impact-delta {
    margin-left: 0;
    margin-top: 4px;
  }
  .bse-actions {
    padding: 10px 12px;
  }
  .bse-cancel,
  .bse-set {
    /* Touch target ≥ 44px tall per WCAG 2.5.5 */
    min-height: 44px;
    padding: 10px 16px;
    flex: 1;
  }
  .bse-set { justify-content: center; }
}

.data-table tbody tr { transition: background 0.1s; }
.data-table tbody tr:nth-child(odd):not(.vscroll-pad-top):not(.vscroll-pad-bottom) { background: rgba(0,0,0,0.015); }
.data-table tbody tr:hover { background: #f8f9fb; }

/* Date group separators */
.data-table tbody tr.date-break { border-top: 2px solid var(--border); }

/* Amount emphasis — bold weight for large amounts instead of background bars */
.data-table td.amount-high-neg,
.data-table td.amount-high-pos { font-weight: 600; }
.data-table td.amount-high-neg { color: #c0392b; }
.data-table td.amount-high-pos { color: #1e8449; }

.data-table a.amount-link {
  color: var(--text);
  text-decoration: none;
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 500;
  line-height: 28px;
  transition: color 0.15s;
  display: inline-block;
  padding: 4px 0;
}

.data-table a.amount-link:hover {
  color: var(--accent);
  text-decoration: underline;
}

a.header-btn {
  text-decoration: none;
  color: var(--header-text);
}

/* Document/attachment links (formerly invoice-link) */
.doc-link, .data-table a.invoice-link {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  color: var(--accent);
  font-size: 14px;
  font-weight: 500;
  text-decoration: none;
  padding: 2px 8px;
  border-radius: 3px;
  background: var(--accent-light);
  transition: background 0.15s;
}

.doc-link:hover, .data-table a.invoice-link:hover { background: rgba(43, 123, 186, 0.14); }
.doc-label { font-size: 14px; color: var(--text-muted); cursor: default; }
.doc-badge {
  font-size: 12px; color: var(--accent); cursor: pointer; font-weight: 500;
  background: none; border: none; padding: 0;
}
.doc-badge:hover { text-decoration: underline; }

/* Documents panel (multi-doc expansion) */
.docs-panel {
  z-index: 1000; background: var(--surface);
  border: 1px solid var(--border); border-radius: 8px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.15);
  width: 260px; overflow: hidden;
}
.docs-panel-header {
  padding: 8px 12px; font-size: 11px; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.04em;
  color: var(--text-secondary); border-bottom: 1px solid var(--border);
}
.docs-panel-item {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 12px; text-decoration: none; color: var(--text);
  transition: background 0.1s; font-size: 12px;
}
a.docs-panel-item:hover { background: var(--accent-light); }
.docs-panel-item.no-link { color: var(--text-secondary); }
.docs-panel-icon { font-size: 16px; flex-shrink: 0; }
.docs-panel-label { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.docs-panel-arrow { color: var(--text-muted); font-size: 10px; flex-shrink: 0; }

/* ═══════════════════════════════════════════
   LEGAL AUDIT VIEW
   ═══════════════════════════════════════════ */

.legal-loading {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  height: 100%;
  color: var(--text-muted);
  font-size: 14px;
}

.legal-content {
  display: flex;
  flex-direction: column;
  height: 100%;
  overflow: hidden;
}

/* KPI Cards */
.legal-kpis {
  display: flex;
  gap: 16px;
  padding: 16px 24px;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}

.legal-kpi {
  flex: 1;
  padding: 12px 16px;
  background: var(--bg);
  border-radius: var(--radius);
  border: 1px solid var(--border);
}

.legal-kpi-value {
  font-family: var(--mono);
  font-size: 20px;
  font-weight: 600;
  color: var(--text);
  letter-spacing: -0.02em;
}

.legal-kpi-label {
  font-size: 11px;
  font-weight: 500;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin-top: 4px;
}

.recon-export-btn {
  padding: 6px 12px;
  min-height: 32px;
  font-size: 11px;
  font-weight: 600;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: var(--bg-card);
  color: var(--text-primary);
  cursor: pointer;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}
.recon-export-btn:hover {
  background: var(--border);
}

/* Chart Panels */
.legal-charts {
  display: flex;
  gap: 0;
  flex-shrink: 0;
  height: 320px;
  border-bottom: 1px solid var(--border);
}

.legal-chart-panel {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-width: 0;
  background: var(--surface);
}

.legal-chart-panel + .legal-chart-panel {
  border-left: 1px solid var(--border);
}

.legal-panel-title {
  padding: 8px 16px;
  font-size: 12px;
  font-weight: 600;
  color: var(--text-secondary);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}

.legal-pie-area,
.legal-bar-area {
  flex: 1;
  min-height: 0;
}

/* Table Section */
.legal-table-section {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.legal-table-toolbar {
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  padding: 10px 24px;
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  flex-shrink: 0;
}

.legal-table-toolbar select {
  font-family: var(--font);
  font-size: 12px;
  padding: 5px 8px;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: var(--surface);
  color: var(--text);
  max-width: 200px;
  cursor: pointer;
}

.legal-table-toolbar select:focus {
  outline: none;
  border-color: var(--accent);
}

.legal-table-scroll {
  flex: 1;
  overflow: auto;
}

.legal-table-scroll .data-table td.desc-cell {
  max-width: 400px;
}

/* Pattern Badge */
.legal-pattern-badge {
  display: inline-block;
  font-size: 11px;
  font-weight: 500;
  padding: 2px 8px;
  border-radius: 3px;
  background: color-mix(in srgb, var(--badge-color) 12%, white);
  color: var(--badge-color);
  white-space: nowrap;
}

/* ═══════════════════════════════════════════
   RECONCILIATION VIEW
   ═══════════════════════════════════════════ */

.recon-content {
  display: flex;
  flex-direction: column;
  height: 100%;
  overflow: hidden;
}

.recon-filter-bar {
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  padding: 8px 24px;
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}

.recon-entity-select {
  font-family: var(--font);
  font-size: 12px;
  padding: 5px 8px;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: var(--surface);
  color: var(--text);
  cursor: pointer;
  max-width: 240px;
}

.recon-entity-select:focus {
  outline: none;
  border-color: var(--accent);
}

/* Multi-select dropdown */
.recon-multiselect {
  position: relative;
}
.recon-ms-button {
  font-family: var(--font);
  font-size: 12px;
  padding: 6px 8px;
  min-height: 32px;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: var(--surface);
  color: var(--text);
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 120px;
  max-width: 280px;
  white-space: nowrap;
}
.recon-ms-button:hover {
  border-color: var(--accent);
}
.recon-ms-label {
  overflow: hidden;
  text-overflow: ellipsis;
  flex: 1;
  text-align: left;
}
.recon-ms-arrow {
  color: var(--text-muted);
  font-size: 10px;
  flex-shrink: 0;
}
.recon-ms-dropdown {
  display: none;
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  z-index: 100;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 6px;
  box-shadow: var(--shadow-md);
  min-width: 220px;
  max-height: 320px;
  overflow-y: auto;
  padding: 4px 0;
}
.recon-ms-dropdown.open {
  display: block;
}
.recon-ms-option {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 5px 12px;
  font-size: 12px;
  color: var(--text);
  cursor: pointer;
  white-space: nowrap;
}
.recon-ms-option:hover {
  background: var(--accent-light);
}
.recon-ms-option input[type="checkbox"] {
  width: 14px;
  height: 14px;
  margin: 0;
  cursor: pointer;
  accent-color: var(--accent);
}
.recon-ms-all {
  border-bottom: 1px solid var(--border);
  margin-bottom: 2px;
  padding-bottom: 6px;
  font-weight: 500;
}
.recon-ms-count {
  color: var(--text-muted);
  font-size: 11px;
}

.recon-table-section {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.recon-table-scroll {
  flex: 1;
  overflow: auto;
  -webkit-overflow-scrolling: touch;
}

/* Status Badges */
.recon-status-match {
  display: inline-block;
  font-size: 11px;
  font-weight: 600;
  padding: 2px 8px;
  border-radius: 3px;
  background: rgba(39, 174, 96, 0.12);
  color: #27ae60;
  white-space: nowrap;
}

.recon-status-close {
  display: inline-block;
  font-size: 11px;
  font-weight: 600;
  padding: 2px 8px;
  border-radius: 3px;
  background: rgba(243, 156, 18, 0.12);
  color: #f39c12;
  white-space: nowrap;
}

.recon-status-review {
  display: inline-block;
  font-size: 11px;
  font-weight: 600;
  padding: 2px 8px;
  border-radius: 3px;
  background: rgba(231, 76, 60, 0.12);
  color: #e74c3c;
  white-space: nowrap;
}

/* Clickable variance cells in reconciliation summary table */
.recon-clickable {
  cursor: pointer;
  transition: text-decoration-color 0.15s, opacity 0.15s;
  text-decoration-color: transparent;
}
.recon-clickable:hover {
  text-decoration: underline;
  text-decoration-thickness: 1.5px;
  text-underline-offset: 2px;
  text-decoration-color: currentColor;
  opacity: 0.85;
}

/* No GL Match row */
.recon-no-gl-row td {
  color: var(--text-muted);
  border-top: 2px solid var(--border);
}

/* Inferred GL indicators */
/* Drill-in split pane */
.recon-drill-split {
  display: flex;
  gap: 1px;
  background: var(--border);
  height: 100%;
  min-height: 0;
}
.recon-drill-pane {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  background: var(--surface);
  overflow: hidden;
}
.recon-drill-pane-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 8px 12px;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  flex-shrink: 0;
  border-bottom: 2px solid;
}
.recon-drill-pane-header span:last-child {
  font-weight: 400;
  text-transform: none;
  letter-spacing: 0;
  color: var(--text-secondary);
}
.recon-drill-ours {
  color: var(--accent);
  border-color: var(--accent);
}
.recon-drill-gl {
  color: #059669;
  border-color: #059669;
}
.recon-drill-pane .data-table {
  font-size: 11px;
}
.recon-drill-pane .data-table td,
.recon-drill-pane .data-table th {
  padding: 4px 8px;
}
.recon-drill-pane .desc-cell {
  max-width: 260px;
}
.recon-drill-pane {
  overflow-y: auto;
}

/* Unified reconciliation table */
.recon-drill-summary {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 16px;
  padding: 10px 12px;
  font-size: 12px;
  color: var(--text-secondary);
  border-bottom: 1px solid var(--border);
  background: var(--surface);
}
.recon-drill-stat {
  white-space: nowrap;
}
.recon-drill-ours-tag { color: var(--accent); font-weight: 600; }
.recon-drill-gl-tag { color: #059669; font-weight: 600; }

.recon-unified-table { font-size: 11px; }
.recon-unified-table td,
.recon-unified-table th { padding: 4px 8px; }
.recon-unified-table .desc-cell { max-width: 240px; }
.recon-cat-cell { font-size: 10px; color: var(--text-secondary); max-width: 160px; }
.recon-col-status { font-size: 10px; max-width: 140px; white-space: nowrap; }

.recon-unified-table th.recon-col-ours { color: var(--accent); }
.recon-unified-table th.recon-col-gl { color: #059669; }

.recon-row-matched td { background: transparent; }
.recon-row-ours-only td.recon-col-gl { background: #f5f6f8; }
.recon-row-ours-only td.recon-col-ours { background: rgba(43, 123, 186, 0.04); }
.recon-row-gl-only td.recon-col-ours { background: #f5f6f8; }
.recon-row-gl-only td.recon-col-gl { background: rgba(5, 150, 105, 0.04); }
.recon-row-ours-only td:first-child,
.recon-row-gl-only td:first-child { font-weight: 500; }

.recon-row-group td { border-bottom: 1px dashed #e5e7eb; }
.recon-row-group td.recon-col-gl { background: rgba(5, 150, 105, 0.03); vertical-align: middle; }
.recon-row-payment td { border-bottom: 1px dashed #e0d8f0; }
.recon-row-payment td.recon-col-gl { background: rgba(124, 58, 237, 0.04); vertical-align: middle; }
.recon-row-payment.recon-row-matched { background: rgba(124, 58, 237, 0.02); }
.recon-group-badge {
  display: inline-block;
  background: #059669; color: #fff;
  font-size: 10px; font-weight: 600;
  padding: 1px 6px; border-radius: 8px;
  vertical-align: middle; margin-right: 4px;
}

.recon-drill-filter { margin-left: auto; display: flex; gap: 4px; }
.recon-filter-btn {
  padding: 3px 10px; border: 1px solid #d1d5db; border-radius: 4px;
  background: #fff; color: #374151; font-size: 12px; cursor: pointer;
}
.recon-filter-btn:hover { background: #f3f4f6; }
.recon-filter-btn.active { background: #1e293b; color: #fff; border-color: #1e293b; }

/* ═══ Empty / Error States ═══ */
.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100%;
  gap: 8px;
  color: var(--text-muted);
  font-size: 14px;
  padding: 40px;
  text-align: center;
}

/* ═══════════════════════════════════════════
   RESPONSIVE — TABLET
   ═══════════════════════════════════════════ */
@media (max-width: 900px) {
  .pie-legend-wrap { width: 200px; }
  .pie-toolbar .checkboxes { display: none; }
  .pie-grouping-toggle { display: none; }
  .pie-toolbar-sep { display: none; }
  .sankey-controls { gap: 16px; }
}

/* ═══════════════════════════════════════════
   RESPONSIVE — MOBILE
   ═══════════════════════════════════════════ */
@media (max-width: 768px) {
  /* Header */
  .app-header { padding: 0 12px; height: 44px; }
  .app-header h1 { display: none; }
  .header-brand { font-size: 13px; padding: 2px 6px; }
  .user-name { display: none; }
  .header-btn span { display: none; }
  .header-btn { padding: 6px 8px; }
  .header-btn-text { font-size: 11px; padding: 4px; }
  .header-right { gap: 6px; }
  .source-toggle { font-size: 10px; padding: 4px 6px; min-height: 28px; min-width: 36px; }

  /* Tab bar */
  .tab-bar { padding: 0 8px; height: 36px; overflow-x: auto; -webkit-overflow-scrolling: touch; }
  .tab { padding: 0 10px; font-size: 11px; white-space: nowrap; }
  .tab-meta { display: none; }

  /* Pie mobile tweaks */
  .pie-toolbar {
    flex-wrap: wrap;
    padding: 4px 12px;
    gap: 4px;
  }
  .pie-toolbar-left {
    width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    gap: 6px;
    flex-wrap: nowrap;
  }
  .pie-toolbar-right {
    width: 100%;
    gap: 6px;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    flex-wrap: nowrap;
  }
  .pie-toolbar-sep { display: none; }
  .pie-toolbar .checkboxes { display: none; }
  .pie-tab-switcher { padding: 0; }
  .pie-tab-btn { font-size: 12px; padding: 6px 4px; flex: 1; justify-content: center; }
  .pie-tab-btn-total { font-size: 10px; }
  .pie-legend-wrap { display: none; }
  .pie-grouping-toggle { display: none; }
  .pie-group-btn { font-size: 11px; padding: 3px 8px; }
  .pie-entity-btn { font-size: 11px; padding: 5px 8px; min-height: 28px; }
  .pie-filter-label { font-size: 10px; }
  .pie-entity-list { max-height: 240px; }
  .pie-entity-item { font-size: 11px; padding: 3px 8px; }
  .pie-breadcrumb { padding: 0 8px; min-height: 28px; }
  .pie-instance-header { padding: 6px 10px; }
  .pie-instance-title { font-size: 11px; }
  .pie-instance-total { font-size: 18px; }
  .pie-instance-hint { display: none; }
  .pie-table-header { padding: 10px 16px; }
  .pie-table-container { overflow: auto; }
  .pie-table-scroll { overflow: auto; -webkit-overflow-scrolling: touch; }

  /* Sankey */
  .sankey-controls-bar { padding: 5px 12px; }
  .sankey-controls {
    padding: 8px 12px;
    gap: 8px;
    max-height: 300px;
    overflow: hidden;
    transition: max-height 0.3s ease, padding 0.3s ease, border-width 0.3s ease;
  }
  .sankey-controls.collapsed {
    max-height: 0;
    padding-top: 0;
    padding-bottom: 0;
    border-bottom-width: 0;
  }
  .sankey-controls .control-group .group-label { font-size: 9px; }
  .sankey-controls .control-group { overflow-x: auto; -webkit-overflow-scrolling: touch; }
  .sankey-controls .checkboxes { gap: 4px; flex-wrap: nowrap; }
  .sankey-controls .checkboxes label { font-size: 11px; padding: 2px 6px; }
  .sankey-controls .btn-group { flex-wrap: nowrap; }
  .sankey-controls .btn-sm { font-size: 11px; padding: 3px 7px; min-height: 28px; }
  .threshold-row input[type="range"] { width: 80px; }
  .sankey-info { font-size: 10px; }
  .sankey-chart-area {
    min-height: 0;
    overflow-x: auto;
    overflow-y: hidden;
    -webkit-overflow-scrolling: touch;
  }
  .sankey-chart-area .plotly-chart {
    min-width: 600px;
    height: 100%;
  }

  /* Legal Audit */
  .legal-kpis { padding: 12px 16px; gap: 8px; flex-wrap: wrap; }
  .legal-kpi { padding: 8px 12px; min-width: calc(50% - 4px); }
  .legal-kpi-value { font-size: 16px; }
  .legal-charts { flex-direction: column; height: auto; }
  .legal-chart-panel { height: 260px; }
  .legal-chart-panel + .legal-chart-panel { border-left: none; border-top: 1px solid var(--border); }
  .legal-table-toolbar { padding: 8px 16px; gap: 8px; }
  .legal-table-toolbar select { max-width: 150px; }
  .legal-table-scroll .data-table td.desc-cell { max-width: 200px; }

  /* Reconcile */
  .recon-filter-row { flex-wrap: wrap; gap: 6px; padding: 6px 12px; overflow: hidden; }
  .recon-filter-row .pie-filter-label { font-size: 10px; }
  .recon-ms-button { font-size: 11px; min-height: 28px; max-width: 120px; overflow: hidden; }
  .recon-ms-arrow { display: none; }
  .recon-ms-label { overflow: hidden; text-overflow: ellipsis; }
  .recon-export-btn { font-size: 10px; padding: 4px 10px; }
  .legal-kpis .legal-kpi-value { font-size: 18px; }
  .legal-kpis { padding: 8px 12px; }
  .recon-table-scroll { overflow: auto; -webkit-overflow-scrolling: touch; }
  .recon-table-scroll .data-table { min-width: 700px; }

  /* Table */
  .toolbar-primary {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    flex-wrap: nowrap;
  }
  .table-toolbar { padding: 6px 12px; gap: 6px; }
  .table-search { min-width: 120px; font-size: 12px; }
  .table-toolbar select { max-width: 130px; }
  .btn-audit { display: none; }

  .data-table th { padding: 7px 10px; font-size: 10px; }
  .data-table td { padding: 6px 10px; font-size: 12px; }
  .data-table td.desc-cell { max-width: 180px; }
}

@media (max-width: 480px) {
  .login-card { padding: 32px 24px; }
  .login-card h1 { font-size: 18px; }

  .table-toolbar select { max-width: 110px; font-size: 11px; }
  .table-search { min-width: 120px; font-size: 11px; }
  .btn-export { display: none; }
}

/* ═══════════════════════════════════════════
   BUDGET VIEW — Monarch-style
   ═══════════════════════════════════════════ */

.budget-toolbar {
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  padding: 8px 20px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-shrink: 0;
}
.budget-toolbar-left, .budget-toolbar-right {
  display: flex;
  align-items: center;
  gap: 12px;
}
.budget-mode-toggle, .budget-period-toggle {
  display: flex;
  border: 1px solid var(--border);
  border-radius: 5px;
  overflow: hidden;
}
.budget-mode-btn, .budget-period-btn {
  font-family: var(--font);
  font-size: 12px;
  font-weight: 500;
  padding: 6px 14px;
  min-height: 32px;
  border: none;
  background: var(--surface);
  color: var(--text-secondary);
  cursor: pointer;
  transition: all 0.15s;
  white-space: nowrap;
}
.budget-mode-btn:not(:last-child), .budget-period-btn:not(:last-child) {
  border-right: 1px solid var(--border);
}
.budget-mode-btn:hover, .budget-period-btn:hover { background: #f1f3f5; color: var(--text); }
.budget-mode-btn.active, .budget-period-btn.active { background: var(--header-bg); color: #fff; }

.budget-period-nav {
  display: flex;
  align-items: center;
  gap: 8px;
}
.budget-nav-btn {
  font-family: var(--font);
  font-size: 14px;
  width: 28px;
  height: 28px;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: var(--surface);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text-secondary);
}
.budget-nav-btn:hover { background: #f1f3f5; color: var(--text); }
.budget-period-label {
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
  min-width: 100px;
  text-align: center;
}

/* KPI Cards */
.budget-kpis {
  display: flex;
  gap: 16px;
  padding: 16px 20px;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
}
.budget-kpi {
  flex: 1;
  padding: 12px 16px;
  background: var(--bg);
  border-radius: 8px;
  border: 1px solid var(--border);
}
.budget-kpi-value {
  font-family: var(--mono);
  font-size: 22px;
  font-weight: 700;
  color: var(--text);
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}
.budget-kpi-label {
  font-size: 11px;
  font-weight: 600;
  color: var(--text-secondary);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin-top: 4px;
}

/* Mgmt Fee Income KPI projection-tracking sub-line.
   Surfaces YTD-accrued NET alongside the annual projection so users
   can judge whether the projection is tracking. Projection itself
   isn't externally verified (fund admin doesn't publish forward
   annual projections); this is the retrospective verification path.
   Cursor:help to invite the tooltip with the framing explanation. */
.budget-kpi-tracking {
  margin-top: 4px;
  font-size: 11px;
  font-weight: 500;
  text-transform: none;
  letter-spacing: 0;
  color: var(--text-muted);
  cursor: help;
}

/* KPI Donut Chart */
.budget-kpi-donut { display: flex; flex-direction: column; align-items: center; justify-content: center; }
.kpi-donut { display: block; }

/* Compact KPI mode on short viewports (laptops ≤ 900px tall) — reclaims ~50px
   above the fold without hiding any information. Value + label both shrink. */
@media (max-height: 900px) {
  .budget-kpis { padding: 8px 20px; gap: 10px; }
  .budget-kpi { padding: 8px 12px; }
  .budget-kpi-value { font-size: 18px; }
  .budget-kpi-label { font-size: 10px; margin-top: 2px; }
  .budget-kpi-sublabel { font-size: 9px !important; }
  .budget-kpi-donut svg { width: 44px; height: 44px; }
}

/* Fixed vs Variable Progress Bars */
.kpi-fixvar-bars {
  width: 100%; padding: 8px 20px 12px;
  background: var(--surface); border-bottom: 1px solid var(--border);
  display: flex; gap: 24px;
}
.kpi-fixvar-bar { flex: 1; }
.kpi-fixvar-header {
  display: flex; justify-content: space-between; align-items: baseline;
  margin-bottom: 4px;
}
.kpi-fixvar-label { font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; color: var(--text-secondary); }
.kpi-fixvar-amounts { font-size: 11px; color: var(--text-muted); font-family: var(--mono); }
.kpi-fixvar-track {
  position: relative; height: 8px; background: var(--border); border-radius: 4px; overflow: visible;
}
.kpi-fixvar-fill { height: 100%; border-radius: 4px; transition: width 0.3s; }
.kpi-fixvar-tick {
  position: absolute; top: -2px; width: 2px; height: 12px;
  background: var(--text); border-radius: 1px; opacity: 0.5;
}

/* Income vs Expense Track (used in trend legend / other contexts) */
.income-vs-expense-track {
  position: relative;
  height: 8px;
  background: var(--border);
  border-radius: 4px;
  overflow: visible;
  margin-top: 4px;
}
.income-vs-expense-fill {
  height: 100%;
  border-radius: 4px;
  transition: width 0.3s;
}
.income-vs-expense-tick {
  position: absolute;
  top: -2px;
  width: 2px;
  height: 12px;
  background: var(--text);
  border-radius: 1px;
  opacity: 0.5;
}
.income-vs-expense-labels {
  display: flex;
  justify-content: space-between;
  font-size: 10px;
  color: #4b5563; /* WCAG AA 4.5:1 at 10px */
  font-family: var(--mono);
  margin-top: 4px;
}

/* ── Sankey — Shared Income Panel mount ── */
.sankey-income-panel-wrap {
  margin: 0 0 8px 0;
}
.sankey-income-panel-wrap .dg-income-panel {
  border-radius: 6px;
}

/* ── Pie Instance — Shared Income Panel mount ── */
.pie-income-panel-wrap {
  margin: 0;
}
.pie-income-panel-wrap .dg-income-panel {
  border-radius: 6px;
  margin-bottom: 8px;
}

/* ── Shared Income Panel (DG.income) ── */
.dg-income-panel {
  padding: 12px 20px 16px;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
}
.dg-income-period-wrap {
  margin-bottom: 10px;
}
.dg-income-period {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
}
.dg-income-period-btn {
  padding: 6px 12px;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: var(--bg);
  color: var(--text);
  font-size: 12px;
  font-weight: 500;
  cursor: pointer;
  min-height: 32px;
}
.dg-income-period-btn:hover { background: var(--hover); }
.dg-income-period-btn.active {
  background: var(--accent);
  color: #fff;
  border-color: var(--accent);
}
.dg-income-period-nav {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-left: 6px;
  padding: 2px 6px;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: var(--bg);
}
.dg-income-nav-btn {
  padding: 2px 6px;
  border: none;
  background: transparent;
  color: var(--text);
  cursor: pointer;
  font-size: 14px;
  min-width: 24px;
  min-height: 24px;
}
.dg-income-nav-btn:hover { background: var(--hover); }
.dg-income-period-label {
  font-size: 12px;
  font-weight: 600;
  font-family: var(--mono);
  min-width: 44px;
  text-align: center;
}

.dg-income-aggregate-header {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 8px;
  flex-wrap: wrap;
  width: 100%;
  padding: 6px 8px;
  border: 1px solid transparent;
  border-radius: 6px;
  background: transparent;
  cursor: pointer;
  text-align: left;
  font: inherit;
  color: inherit;
  min-height: 44px;
}
.dg-income-aggregate-header:hover {
  background: var(--hover);
  border-color: var(--border);
}
.dg-income-aggregate-header:focus {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.dg-income-aggregate-header .dg-income-expand-chevron {
  margin-left: auto;
  font-size: 14px;
  color: #4b5563; /* WCAG AA 4.5:1 at 14px */
}

.dg-income-title {
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: #374151; /* WCAG AA 4.5:1 min at 11px */
}
.dg-income-period-chip {
  font-size: 10px;
  font-weight: 600;
  color: #374151; /* WCAG AA 4.5:1 min at 10px */
  background: var(--bg);
  padding: 2px 8px;
  border-radius: 4px;
  border: 1px solid var(--border);
}
.dg-income-incomplete-tag {
  font-size: 9px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: #92400e;
  background: #fef3c7;
  padding: 2px 6px;
  border-radius: 4px;
}
.dg-income-period-note {
  font-size: 10px;
  color: var(--text-muted);
  font-style: italic;
}

.dg-income-aggregate-row {
  display: flex;
  gap: 16px;
  align-items: stretch;
}
.dg-income-cell {
  flex: 1;
  padding: 12px 16px;
  background: var(--bg);
  border-radius: 8px;
  border: 1px solid var(--border);
}
.dg-income-cell-value {
  font-family: var(--mono);
  font-size: 20px;
  font-weight: 700;
  color: var(--text);
  letter-spacing: -0.02em;
}
.dg-income-cell-label {
  font-size: 11px;
  font-weight: 500;
  color: #374151; /* WCAG AA 4.5:1 min at 11px */
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin-top: 4px;
}
.dg-income-cell-sublabel {
  font-size: 10px;
  font-weight: 500;
  color: #4b5563; /* WCAG AA 4.5:1 min at 10px */
  font-family: var(--mono);
  margin-top: 2px;
}
/* Actual + projected split subtitle for annual views. */
.dg-income-split-note {
  margin-top: 6px;
  font-size: 11px;
  color: #4b5563; /* WCAG AA 4.5:1 */
  font-family: var(--mono);
}


/* Fund breakdown table */
.dg-income-fund-table {
  margin-top: 12px;
  border: 1px solid var(--border);
  border-radius: 8px;
  overflow: hidden;
  background: var(--bg);
}
.dg-income-fund-header {
  display: grid;
  grid-template-columns: 1.4fr 1.3fr 1.1fr 1fr;
  gap: 8px;
  padding: 8px 12px;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: #374151; /* WCAG AA 4.5:1 min at 10px */
}
.dg-income-fund-row {
  display: grid;
  grid-template-columns: 1.4fr 1.3fr 1.1fr 1fr;
  gap: 8px;
  padding: 10px 12px;
  border-bottom: 1px solid var(--border);
  font-size: 13px;
  align-items: center;
}
.dg-income-fund-row:last-child { border-bottom: none; }
.dg-income-fund-row-pending { opacity: 0.6; }
/* Terminated funds: muted + italic; pinned to bottom of active funds
   via the sort comparator (sortFundRows) so this is visual-only. */
.dg-income-fund-row-terminated { opacity: 0.7; }
.dg-income-fund-row-terminated .dg-income-fund-col-name,
.dg-income-fund-row-terminated .dg-income-fund-col-method,
.dg-income-fund-row-terminated .dg-income-fund-col-num {
  font-style: italic;
  color: var(--text-muted);
}
.dg-income-fund-col-name { font-weight: 500; color: var(--text); }
.dg-income-fund-col-method { color: #4b5563; font-size: 12px; } /* WCAG AA 4.5:1 at 12px */
.dg-income-fund-col-recycling {
  font-family: var(--mono);
  font-size: 12px;
  color: #4b5563; /* WCAG AA 4.5:1 at 12px */
}
.dg-income-fund-col-recycling-terminated {
  font-style: italic;
  color: var(--text-muted);
}
.dg-income-fund-col-recycling-empty { color: var(--text-muted); }
.dg-income-fund-col-num { font-family: var(--mono); text-align: right; color: var(--text); }
.dg-income-fund-col-status { font-family: var(--mono); font-size: 12px; font-weight: 600; }

/* Sortable column headers — click to sort, arrow visible on active column only */
.dg-income-sortable {
  cursor: pointer;
  user-select: none;
  transition: color 0.1s ease;
}
.dg-income-sortable:hover,
.dg-income-sortable:focus-visible {
  color: var(--text);
  outline: none;
}
.dg-income-sort-arrow {
  font-size: 9px;
  margin-left: 2px;
  color: var(--text);
}

.dg-income-step-down {
  display: inline-block;
  margin-left: 4px;
  font-size: 11px;
  color: #92400e;
}

.dg-income-freshness-wrap { margin: 6px 0 0 0; }
.dg-income-freshness {
  font-size: 11px;
  color: #4b5563; /* WCAG AA 4.5:1 at 11px */
  font-family: var(--mono);
  text-align: right;
  cursor: help;
}

.dg-income-empty {
  padding: 12px;
  color: var(--text-muted);
  font-size: 12px;
  text-align: center;
  font-style: italic;
}

/* Mobile responsive for income panel */
@media (max-width: 768px) {
  .dg-income-panel { padding: 8px 12px 12px; }
  .dg-income-aggregate-row { flex-wrap: wrap; gap: 6px; }
  .dg-income-cell { min-width: calc(50% - 3px); padding: 8px 10px; }
  .dg-income-cell-value { font-size: 16px; }
  .dg-income-fund-header,
  .dg-income-fund-row {
    grid-template-columns: 1.5fr 1fr;
    font-size: 11px;
  }
  .dg-income-fund-col-method,
  .dg-income-fund-col-recycling { display: none; } /* keep Fund name + Projected on mobile */
}

/* Budget Table */
.budget-table-wrap {
  flex: 1;
  /* min-height: 0 is required to let flex: 1 actually constrain the height
     of this scroll container. Without it, flex items default to
     min-height: auto and expand to fit content — the page ends up scrolling
     instead of just the table. Easy to lose: tests/budget-table-fill.spec.js
     guards against this regressing. */
  min-height: 0;
  overflow: auto;
  display: flex;
  flex-direction: column;
}
.budget-table-header {
  display: grid;
  grid-template-columns: 1fr 110px 100px 120px 160px 95px;
  gap: 0 8px;
  padding: 10px 20px;
  background: #eaecef;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-secondary);
  position: sticky;
  top: 0;
  z-index: 2;
  border-bottom: 1px solid var(--border);
}
.budget-table-body {
  flex: 1;
  min-height: 0;  /* same reason as .budget-table-wrap — required for flex:1 */
  overflow-y: auto;
}
/* Footer element is now empty — Total row was relocated INTO the body
   (between Income block and expense buckets) per Jason 2026-04-29.
   Footer kept in DOM for any future use; collapses to no height when empty. */
.budget-table-footer {
  background: var(--surface);
  z-index: 1;
}
.budget-table-footer:empty { display: none; }
.budget-col-num {
  text-align: right;
  font-family: var(--mono);
  font-size: 13px;
  /* Slashed zero disambiguates 0 from 8 at small sizes (default JetBrains Mono
     ships dotted-zero, which can read as 8 in body-size numerics). Tabular nums
     keeps column alignment for varied digit counts. */
  font-variant-numeric: tabular-nums;
}
.budget-col-progress { display: flex; align-items: center; gap: 6px; }
.budget-col-var { text-align: center; }
/* Story 5 (bead pn1d) — vs-2025 column: prior-year actual ($, compact) plus a
   neutral year-over-year % delta. Right-aligned with the other numeric
   columns; inline so row heights stay uniform. The delta is neutral on
   purpose — planning above/below last year is context, not good/bad — so it
   uses a slate gray rather than the over/under red-green of the Var badge.
   Color is #4b5563 (slate-600), NOT --text-secondary (#6b7280): the latter
   clears 4.5:1 only on pure white, but this column's small text also lands on
   group-row (#f5f6f8 → 4.47:1) and hover backgrounds. #4b5563 clears 4.5:1 on
   all of them (6.34:1 worst case). */
.budget-col-yoy {
  text-align: right;
  font-family: var(--mono);
  font-size: 13px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.budget-yoy-prior { color: var(--text); }
.budget-yoy-delta { color: #4b5563; font-size: 11px; margin-left: 5px; }
.budget-yoy-none { color: #4b5563; font-style: italic; cursor: help; }
.budget-total-row .budget-col-yoy { font-weight: 600; }
/* R3c Story 13 (bead qjl3) — Forecast column: projected year-end ($, full).
   Right-aligned with the other numeric columns, same mono/tabular treatment
   as Budget/Actual so it reads as one of the money columns, not a badge. Plain
   --text (a prediction is context, not good/bad — no over/under red-green). */
.budget-col-forecast {
  position: relative;
  text-align: right;
  font-family: var(--mono);
  font-size: 13px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  color: var(--text);
  cursor: help;
  /* Reserve space at the right edge for the method chip so the dollar
     value's right edge aligns with rollup cells (which have no chip) and
     other numeric columns. Without this, justify-content: flex-end pushed
     the value left by chip-width on leaf rows only, breaking column
     alignment row-to-row. */
  padding-right: 46px;
}
.budget-total-row .budget-col-forecast { font-weight: 600; }
/* R3c Stories 15/16 (02qy / 3emm) — leaf rows get a value + interactive chip;
   overridden rows get a ✦ marker + value (chip suppressed, override wins). */
.budget-col-forecast.budget-forecast-leaf,
.budget-col-forecast.budget-forecast-overridden,
.budget-col-forecast.budget-forecast-rollup {
  display: block;
  cursor: default;
}
.budget-forecast-value {
  display: block;
  text-align: right;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}
.budget-forecast-leaf .budget-forecast-value { cursor: pointer; }
.budget-forecast-leaf .budget-forecast-value:hover { text-decoration: underline dotted #4b5563; text-underline-offset: 2px; }
/* Chip: compact pill, slate gray, hover/focus states. Click target ≥ 22px tall
   for tap accessibility on touch (parent row is 38–44px so we have room). */
.budget-forecast-chip {
  /* Pinned to the reserved padding-right slot on the parent cell so it
     overlays the right edge without pushing the dollar value around. The
     value's right edge stays column-aligned across leaf + rollup rows. */
  position: absolute;
  right: 4px;
  top: 50%;
  transform: translateY(-50%);
  display: inline-flex;
  align-items: center;
  gap: 2px;
  padding: 2px 6px;
  font-family: var(--font);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: lowercase;
  color: #4b5563;
  background: #eef0f3;
  border: 1px solid #d1d5db;
  border-radius: 999px;
  cursor: pointer;
  line-height: 1.4;
  min-height: 18px;
  user-select: none;
}
.budget-forecast-chip:hover  { background: #e2e6ec; border-color: #9ca3af; }
.budget-forecast-chip:focus  { outline: 2px solid #2563eb; outline-offset: 1px; }
.budget-forecast-chip-caret { font-size: 9px; opacity: 0.75; }
/* Method-specific chip tinting — only when a non-default method is set. Keeps
   "this line is doing something special" legible at a glance. */
.budget-forecast-method-contractual .budget-forecast-chip   { background: #ecfdf5; border-color: #6ee7b7; color: #047857; }
.budget-forecast-method-non_recurring .budget-forecast-chip { background: #fef3c7; border-color: #fcd34d; color: #92400e; }
/* Override marker — small ✦ glyph in accent color. Pinned absolutely into
   the right-side slot reserved by .budget-col-forecast's padding-right so
   it occupies the same space as the chip would (chip is suppressed on
   override cells; the marker stands in for it). Keeps the dollar value's
   right edge aligned with chip-bearing leaf cells and chip-less rollup
   cells. Different glyph from R3b's ◆ to keep budget intent vs forecast
   knowledge visually distinct. */
.budget-forecast-marker {
  position: absolute;
  right: 8px;
  top: 50%;
  transform: translateY(-50%);
  color: #b45309;             /* amber-700, 5.9:1 on white */
  font-size: 12px;
  line-height: 1;
}
.budget-forecast-overridden .budget-forecast-value { cursor: pointer; }
.budget-forecast-overridden:hover .budget-forecast-marker { color: #92400e; }

/* ── Method menu popup (Story 15) ─────────────────────────────────────── */
.budget-forecast-method-menu {
  background: var(--surface, #fff);
  border: 1px solid var(--border, #e5e7eb);
  border-radius: 10px;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.18);
  font-family: var(--font);
  font-size: 13px;
  color: var(--text);
  overflow: hidden;
}
.budget-forecast-method-menu .fmm-header {
  padding: 10px 12px 8px;
  border-bottom: 1px solid var(--border, #e5e7eb);
}
.budget-forecast-method-menu .fmm-title {
  display: block;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #4b5563;
  margin-bottom: 2px;
}
.budget-forecast-method-menu .fmm-path {
  display: block;
  font-size: 12px;
  color: var(--text);
  font-weight: 500;
}
.budget-forecast-method-menu .fmm-options {
  display: flex;
  flex-direction: column;
  padding: 4px;
}
.budget-forecast-method-menu .fmm-option {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 1px;
  padding: 8px 10px;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 6px;
  cursor: pointer;
  text-align: left;
  font-family: inherit;
  color: var(--text);
}
.budget-forecast-method-menu .fmm-option:hover { background: #f3f4f6; }
.budget-forecast-method-menu .fmm-option.is-selected { background: #eff6ff; border-color: #93c5fd; }
.budget-forecast-method-menu .fmm-option-label { font-size: 13px; font-weight: 600; }
.budget-forecast-method-menu .fmm-option-hint  { font-size: 11px; color: #4b5563; }
.budget-forecast-method-menu .fmm-footer {
  padding: 8px 12px 10px;
  border-top: 1px solid var(--border, #e5e7eb);
  display: flex;
  justify-content: flex-end;
}
.budget-forecast-method-menu .fmm-reset {
  background: none;
  border: 1px solid var(--border, #e5e7eb);
  border-radius: 6px;
  padding: 4px 10px;
  font-size: 11px;
  font-family: inherit;
  color: #4b5563;
  cursor: pointer;
}
.budget-forecast-method-menu .fmm-reset:hover { background: #f3f4f6; color: var(--text); }
.budget-forecast-method-menu .fmm-footnote {
  font-size: 10px;
  color: #6b7280;
  font-style: italic;
}

/* ── Override editor (Story 16) ──────────────────────────────────────────
   Reuses the R3b Set editor's .bse-* skeleton (hero amount + reason +
   counter + Save/Cancel) — the override editor is a sibling concept with the
   same input shape, just scoped to forecast and without the impact-preview /
   match-actuals / history affordances. The accent shifts from ◆/blue
   (budget intent) to ✦/amber (forecast knowledge) so the two never visually
   bleed into each other. */
.budget-forecast-override-editor {
  background: var(--surface, #fff);
  border: 1px solid var(--border, #e5e7eb);
  border-radius: 10px;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.18);
  font-family: var(--font);
  font-size: 13px;
  color: var(--text);
}
.budget-forecast-override-editor .foe-header {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 12px 8px;
  border-bottom: 1px solid var(--border, #e5e7eb);
}
.budget-forecast-override-editor .foe-title {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #b45309;             /* amber, matches the ✦ marker */
}
.budget-forecast-override-editor .foe-path {
  flex: 1;
  font-size: 12px;
  color: var(--text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.budget-forecast-override-editor .foe-close {
  background: none;
  border: none;
  color: #6b7280;
  cursor: pointer;
  padding: 2px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.budget-forecast-override-editor .foe-close:hover { color: var(--text); }
.budget-forecast-override-editor .foe-hero {
  display: flex;
  align-items: baseline;
  gap: 4px;
  padding: 12px 12px 6px;
}
.budget-forecast-override-editor .foe-amount {
  flex: 1;
  font-family: var(--mono);
  font-size: 22px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  border: 1px solid var(--border, #e5e7eb);
  border-radius: 6px;
  padding: 4px 8px;
  outline: none;
  background: #fffbeb;        /* very light amber wash — keeps it visually distinct from a budget input */
  color: var(--text);
}
.budget-forecast-override-editor .foe-amount:focus { border-color: #b45309; box-shadow: 0 0 0 2px rgba(180, 83, 9, 0.15); }
.budget-forecast-override-editor .foe-reason-section { padding: 6px 12px 10px; }
.budget-forecast-override-editor .foe-reason {
  width: 100%;
  font-family: inherit;
  font-size: 12px;
  border: 1px solid var(--border, #e5e7eb);
  border-radius: 6px;
  padding: 6px 8px;
  resize: vertical;
  background: var(--surface, #fff);
  color: var(--text);
  box-sizing: border-box;
}
.budget-forecast-override-editor .foe-reason:focus { outline: none; border-color: #b45309; box-shadow: 0 0 0 2px rgba(180, 83, 9, 0.15); }
.budget-forecast-override-editor .foe-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px 12px;
  border-top: 1px solid var(--border, #e5e7eb);
}
.budget-forecast-override-editor .foe-actions-spacer { flex: 1; }
.budget-forecast-override-editor .foe-remove {
  flex: 1;
  background: none;
  border: 1px solid var(--border, #e5e7eb);
  border-radius: 6px;
  padding: 6px 10px;
  font-size: 11px;
  font-family: inherit;
  color: #b91c1c;
  cursor: pointer;
}
.budget-forecast-override-editor .foe-remove:hover { background: #fef2f2; border-color: #fca5a5; }
.budget-forecast-override-editor .foe-cancel {
  background: none;
  border: 1px solid var(--border, #e5e7eb);
  border-radius: 6px;
  padding: 6px 12px;
  font-size: 12px;
  font-family: inherit;
  color: var(--text);
  cursor: pointer;
}
.budget-forecast-override-editor .foe-cancel:hover { background: #f3f4f6; }
.budget-forecast-override-editor .foe-save {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: #b45309;
  border: 1px solid #92400e;
  border-radius: 6px;
  padding: 6px 14px;
  font-size: 12px;
  font-family: inherit;
  font-weight: 600;
  color: #fff;
  cursor: pointer;
}
.budget-forecast-override-editor .foe-save:hover:not(:disabled) { background: #92400e; }
.budget-forecast-override-editor .foe-save:disabled { background: #d1d5db; border-color: #d1d5db; color: #4b5563; cursor: not-allowed; }
.budget-forecast-override-editor .bse-set-kbd {
  font-family: var(--mono);
  font-size: 10px;
  background: rgba(255, 255, 255, 0.2);
  padding: 0 4px;
  border-radius: 3px;
}
/* Bead hiq3 — Budget cell for categories with no 2025 baseline. The "—"
   plus muted color signals "we don't have a number here" rather than the
   misleading "$0 budgeted." Dotted underline hints at the explanatory
   tooltip. */
.budget-col-no-baseline {
  color: #6b7280;  /* 4.83:1 on white — hardcoded for the same reason yivu was; var(--text-muted) resolves to #9ca3af */
  font-style: italic;
  text-decoration: underline dotted #d1d5db;
  text-underline-offset: 3px;
  cursor: help;
}
/* hjls: for editors the dash is a live Set target (click opens the editor,
   Match actuals reachable) — pointer affordance wins over the help cursor. */
.budget-set-target.budget-col-no-baseline {
  cursor: pointer;
}
/* Header cells: override per-column data-row typography so all headers
   render in one consistent eyebrow style. Without these overrides,
   .budget-col-num inherits the mono+13px rule above, making "Budget" /
   "Actual" / "Remaining" headers visually different from "Category" /
   "Progress" / "Var".
   Color: bead expenses_tool-daby — `--text-secondary` (#6b7280) on the
   #eaecef header bg is 4.08:1, below the 4.5:1 AA gate. Use slate-600
   (#4b5563) directly here for 5.7:1. Previously two per-column overrides
   (.budget-col-yoy and .budget-col-forecast) carried the #4b5563 fix
   individually; collapsing into the shared rule fixes all sibling
   headers (Budget / Actual / Remaining / Progress / Var) in one place. */
.budget-table-header .budget-col-num,
.budget-table-header .budget-col-progress,
.budget-table-header .budget-col-var,
.budget-table-header .budget-col-forecast,
.budget-table-header .budget-col-yoy {
  font-family: var(--font);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: #4b5563;
  text-transform: uppercase;
  font-variant-numeric: normal;
}

/* Rows */
.budget-row, .budget-group-row, .budget-total-row {
  display: grid;
  grid-template-columns: 1fr 110px 100px 120px 160px 95px;
  gap: 0 8px;
  padding: 10px 20px;
  align-items: center;
  border-bottom: 1px solid var(--border);
  font-size: 13px;
}
/* Story 5 (pn1d) — FO category view with a 2025 baseline adds a 7th column.
   vs 2025 sits IMMEDIATELY AFTER Budget (col-3) so the visual adjacency
   matches the math (Budget vs PY actual) — earlier placement at the right
   edge read as "Forecast vs PY" once R3c's Forecast column landed.
   GL view, compare mode, and no-baseline states keep the 6-col base grid
   above. Income/GL rows that emit only 6 cells leave the column empty
   where vs-2025 would have rendered, which stays aligned. The header uses
   the same template via .budget-show-yoy .budget-table-header below. */
.budget-show-yoy .budget-table-header,
.budget-show-yoy .budget-row,
.budget-show-yoy .budget-group-row,
.budget-show-yoy .budget-total-row {
  grid-template-columns: 1fr 110px 110px 100px 120px 160px 95px;
}
/* R3c Story 13 (qjl3) — Forecast at the right edge — its own column,
   visually separate from vs-2025 so the reading order doesn't imply
   "Forecast vs 2025." Two cases: Forecast alone → 7-col (Name | Budget |
   Actual | Remaining | Progress | Var | Forecast); Forecast + vs-2025
   → 8-col (Name | Budget | vs2025 | Actual | Remaining | Progress | Var
   | Forecast). The combined selector is (0,3,0) so it beats either single
   (0,2,0) rule when both classes are on the container. Same container-
   gating pattern as Story 5 — the grid only widens when the column
   actually renders (FO category + ?release=r3 / internal). */
.budget-show-forecast .budget-table-header,
.budget-show-forecast .budget-row,
.budget-show-forecast .budget-group-row,
.budget-show-forecast .budget-total-row {
  grid-template-columns: 1fr 110px 100px 120px 160px 95px 110px;
}
.budget-show-forecast.budget-show-yoy .budget-table-header,
.budget-show-forecast.budget-show-yoy .budget-row,
.budget-show-forecast.budget-show-yoy .budget-group-row,
.budget-show-forecast.budget-show-yoy .budget-total-row {
  grid-template-columns: 1fr 110px 110px 100px 120px 160px 95px 110px;
}
.budget-group-row {
  background: var(--bg);
  cursor: pointer;
  font-weight: 600;
  user-select: none;
}
.budget-group-row:hover { background: rgba(0,0,0,0.03); }
.budget-child-row { padding-left: 20px; }
/* Bead s98u — Eren 2026-05-08: the full-row accent hover read as "every
   cell left of the pointer is also a click target" because the highlight
   extended past the budget number into the Category column. Split the
   signal: row-level keeps a faint gray ("this is the active row") and the
   colored accent moves to the cell under the pointer. Row-level
   cursor: pointer (FO mode) still signals row drill-down. */
.budget-row:hover { background: rgba(0,0,0,0.02); }
.budget-row .budget-col-num:hover,
.budget-row .budget-col-progress:hover,
.budget-row .budget-col-var:hover { background: var(--accent-light); }
.budget-total-row { background: var(--surface); }
.budget-indent { padding-left: 24px; }
.budget-indent-2 { padding-left: 42px; }
.budget-indent-3 { padding-left: 60px; }
/* ── Hierarchy Visual Design ──
   Based on Adaptive Planning / Anaplan / SAP patterns:
   Bold weight + background shading + group spacing + muted detail numbers */

/* Level 0: Bucket (top-level summary) */
.budget-group-row {
  font-weight: 700; font-size: 14px;
  background: rgba(0, 0, 0, 0.04);
  min-height: 42px;
  margin-top: 4px;
  border-top: 1px solid var(--border);
}
.budget-group-row .budget-col-num { font-weight: 700; }
.budget-group-row:first-child { margin-top: 0; border-top: none; }

/* Level 1: Sub-Bucket (summary row, slightly less prominent) */
.budget-child-row {
  font-weight: 600;
  background: rgba(0, 0, 0, 0.015);
  min-height: 38px;
}
.budget-child-row .budget-col-num { font-weight: 600; }

/* Level 2: Activity (detail row) */
.budget-activity-row {
  font-weight: 400;
  min-height: 34px;
}
.budget-activity-row .budget-col-num { font-weight: 400; color: var(--text-secondary); }

/* Level 3: Sub-Activity (leaf detail, most muted) */
.budget-subactivity-row {
  font-weight: 400;
  min-height: 30px;
  font-size: 12px;
}
.budget-subactivity-row .budget-col-num { font-weight: 400; font-size: 12px; color: var(--text-muted); }
.budget-subactivity-row .budget-col-name { color: var(--text-secondary); font-size: 12px; }

/* Total row: strongest visual weight, top border separator */
.budget-total-row {
  font-weight: 700;
  border-top: 2px solid var(--border);
}
.budget-total-row .budget-col-num { font-weight: 700; }
.sub-chevron, .act-chevron { cursor: pointer; font-size: 9px; margin-right: 2px; }

.budget-chevron { font-size: 10px; color: var(--text-muted); margin-right: 4px; display: inline-block; width: 12px; }
.budget-bucket-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; vertical-align: middle; }

/* Progress Bar — Monarch style */
.budget-progress {
  height: 8px;
  background: var(--border);
  border-radius: 9999px;
  position: relative;
  flex: 1;
  min-width: 80px;
}
.budget-progress-fill {
  height: 100%;
  border-radius: 9999px;
  transition: width 0.3s ease;
}
.budget-progress-fill.green { background: #22c55e; }
.budget-progress-fill.yellow { background: #eab308; }
.budget-progress-fill.red { background: #ef4444; }
.budget-progress-tick {
  position: absolute;
  top: -3px;
  width: 2px;
  height: 14px;
  background: var(--text);
  border-radius: 1px;
  opacity: 0.4;
}
.budget-over-badge {
  font-size: 10px;
  font-weight: 600;
  color: #ef4444;
  white-space: nowrap;
}

/* Variance Badges */
.budget-var-badge {
  font-size: 10px;
  font-weight: 600;
  padding: 2px 6px;
  border-radius: 10px;
  white-space: nowrap;
}
.budget-var-badge.green { background: #dcfce7; color: #166534; }
.budget-var-badge.yellow { background: #fef9c3; color: #854d0e; }
.budget-var-badge.red { background: #fee2e2; color: #991b1b; }

/* Contract-drift chip (bead expenses_tool-n8pd).
   Rendered inline in the row name cell on contractual leaves whose actual
   YTD monthly has drifted from the contract's implied monthly. The chip
   is a click target — opens DG.DrillDialog with full lineage. Min-height
   24px satisfies mobile tap-target guidance; the chip sits as a sibling
   of the row's amount cells so it reads as row-level metadata, not as
   part of the amount. Colors come from --color-warning / --color-critical
   tokens to stay theme-compliant and high-contrast (WCAG AA on white). */
.budget-drift-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  min-height: 24px;
  padding: 3px 8px;
  margin-left: 8px;
  border-radius: 12px;
  font-size: 11px;
  font-weight: 600;
  line-height: 1.2;
  white-space: nowrap;
  cursor: pointer;
  border: 1px solid transparent;
  vertical-align: middle;
}
.budget-drift-chip.watch {
  background: var(--color-warning-bg);
  color: var(--color-warning);
  border-color: color-mix(in srgb, var(--color-warning) 20%, transparent);
}
.budget-drift-chip.breach {
  background: var(--color-critical-bg);
  color: var(--color-critical);
  border-color: color-mix(in srgb, var(--color-critical) 20%, transparent);
}
.budget-drift-chip:hover,
.budget-drift-chip:focus-visible {
  filter: brightness(0.95);
  outline: 2px solid color-mix(in srgb, currentColor 40%, transparent);
  outline-offset: 1px;
}
.budget-drift-chip-icon { font-size: 12px; line-height: 1; }
.budget-drift-chip-label { font-size: 11px; }

/* 12-Month Forecast Grid */
.budget-forecast-wrap {
  margin: 0 16px 8px; border: 1px solid var(--border); border-radius: 8px;
  background: var(--surface); overflow: hidden;
}
.budget-forecast-header {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 12px; cursor: pointer; user-select: none;
  font-size: 13px; font-weight: 600; color: var(--text);
}
.budget-forecast-header:hover { background: var(--hover); }
.budget-forecast-chevron { font-size: 10px; color: var(--text-muted); }
.budget-forecast-title { font-size: 13px; }

/* Forecast section (mobile-first) */
.budget-forecast-grid {
  padding: 0 12px 12px;
  overflow: hidden;
  transition: max-height 0.25s ease, opacity 0.2s ease;
}

/* Status banner */
.forecast-status {
  display: flex; align-items: center; gap: 8px;
  padding: 10px 14px; border-radius: 8px; margin-bottom: 12px;
  font-size: 14px; font-weight: 600;
}
.forecast-status-icon { font-size: 18px; }
.forecast-status-ok { background: #dcfce7; color: #166534; }
.forecast-status-warn { background: #fef9c3; color: #854d0e; }
.forecast-status-over { background: #fee2e2; color: #991b1b; }
.forecast-status-neutral { background: var(--surface); color: var(--text-muted); }

/* Trend chart */
.forecast-trend-wrap {
  background: var(--surface); border: 1px solid var(--border); border-radius: 8px;
  padding: 10px 12px; margin-bottom: 12px;
}
.forecast-trend-chart { width: 100%; height: auto; max-height: 120px; }
.forecast-trend-legend {
  display: flex; gap: 12px; margin-bottom: 6px;
  font-size: 11px; color: var(--text-muted);
}
.forecast-legend-item { display: flex; align-items: center; gap: 4px; }
.forecast-legend-line { display: inline-block; width: 16px; height: 2px; }
.forecast-legend-actual { background: var(--accent); }
.forecast-legend-budget { background: var(--text-muted); border-top: 1px dashed var(--text-muted); height: 0; }
.forecast-legend-projected { background: var(--accent); opacity: 0.4; border-top: 1px dashed var(--accent); height: 0; }
.forecast-legend-scenario { background: #e67e22; height: 2px; border-top: 1px dashed #e67e22; }
.forecast-legend-compare { background: #a142f4; height: 1px; border-top: 1px dashed #a142f4; }
.forecast-legend-income-proj { background: #2b7bba; height: 2px; }
.forecast-legend-income-recv { background: #2b7bba; height: 0; border-top: 1px dashed #2b7bba; }

/* Runway bar */
.forecast-runway {
  background: var(--surface); border: 1px solid var(--border); border-radius: 8px;
  padding: 10px 14px; margin-bottom: 12px;
}
.forecast-runway-bar {
  height: 12px; background: var(--border); border-radius: 9999px;
  position: relative; overflow: hidden; margin-bottom: 6px;
}
.forecast-runway-fill {
  position: absolute; top: 0; left: 0; height: 100%;
  background: var(--accent); border-radius: 9999px; z-index: 2;
}
.forecast-runway-projected {
  position: absolute; top: 0; left: 0; height: 100%;
  background: var(--accent); opacity: 0.2; border-radius: 9999px; z-index: 1;
}
.forecast-runway-labels {
  display: flex; justify-content: space-between;
  font-size: 11px; color: var(--text-muted); margin-bottom: 4px;
}
.forecast-runway-text { font-size: 13px; font-weight: 600; color: var(--text); }
.forecast-runway-proj { font-size: 11px; color: var(--text-muted); margin-top: 2px; }

/* Top variances list */
.forecast-variances { margin-bottom: 8px; }
.forecast-variances-title {
  font-size: 12px; font-weight: 600; color: var(--text-muted);
  text-transform: uppercase; letter-spacing: 0.5px;
  margin-bottom: 6px;
}
.forecast-var-item {
  display: flex; justify-content: space-between; align-items: center;
  padding: 8px 12px; border-radius: 6px; margin-bottom: 4px;
  min-height: 36px;
}
/* Pre-composited over white so contrast calculators see the true rendered color */
.forecast-var-over { background: #fef4f4; }
.forecast-var-under { background: #f4fbf6; }
.forecast-var-name {
  font-size: 13px; font-weight: 500;
  display: flex; align-items: center; gap: 6px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  flex: 1; min-width: 0;
}
.forecast-var-amounts { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
.forecast-var-diff { font-size: 13px; font-weight: 700; }
.forecast-var-over .forecast-var-diff { color: #b91c1c; }
.forecast-var-under .forecast-var-diff { color: #15803d; }
.forecast-var-pct {
  font-size: 10px; font-weight: 600; padding: 2px 6px; border-radius: 9999px;
}
.forecast-var-over .forecast-var-pct { background: #fee2e2; color: #991b1b; }
.forecast-var-under .forecast-var-pct { background: #dcfce7; color: #166534; }

/* Neutral variance badge */
.budget-var-badge.neutral { background: var(--surface); color: var(--text-muted); }

/* Scenario controls */
.budget-toolbar-center { display: flex; align-items: center; }
.scenario-controls { display: flex; align-items: center; gap: 6px; }
.scenario-select {
  padding: 4px 8px; border: 1px solid var(--border); border-radius: 4px;
  background: var(--surface); color: var(--text); font-size: 12px;
  cursor: pointer; min-height: 28px; max-width: 200px;
}
.scenario-btn {
  padding: 4px 10px; border: 1px solid var(--border); border-radius: 4px;
  background: var(--surface); color: var(--text); font-size: 11px;
  cursor: pointer; min-height: 28px; white-space: nowrap;
}
.scenario-btn:hover { background: var(--hover); }
.scenario-new { color: var(--accent); border-color: var(--accent); }
.scenario-delete { color: #dc2626; }
.scenario-share { color: var(--accent); border-color: var(--accent); }
.scenario-publish { color: #16a34a; border-color: #16a34a; }
.scenario-publish:hover { background: rgba(22, 163, 74, 0.1); }
/* Make Official (bead expenses_tool-5981) — primary action, stands apart
   from Edit/Diff/Share so users see it as promotion, not another edit. */
.scenario-make-official {
  color: #fff; background: var(--accent); border-color: var(--accent);
  font-weight: 600;
}
.scenario-make-official:hover:not(:disabled) { opacity: 0.9; }
.scenario-make-official:disabled {
  opacity: 0.55; cursor: not-allowed;
}

/* Make Official footer mounted inside DG.DiffDialog (bead expenses_tool-5981). */
.budget-make-official-footer {
  border-top: 1px solid var(--border);
  padding: 12px 16px;
  background: var(--surface);
  display: flex; flex-direction: column; gap: 8px;
}
.budget-make-official-note-label {
  font-size: 12px; color: var(--text-muted); font-weight: 500;
}
.budget-make-official-note {
  width: 100%; min-height: 60px; padding: 8px;
  border: 1px solid var(--border); border-radius: 4px;
  background: var(--bg); color: var(--text);
  font-family: inherit; font-size: 13px; resize: vertical;
  box-sizing: border-box;
}
.budget-make-official-note:focus {
  outline: none; border-color: var(--accent);
}
.budget-make-official-error {
  padding: 8px 10px; background: rgba(220, 38, 38, 0.08);
  border: 1px solid rgba(220, 38, 38, 0.35); border-radius: 4px;
  color: #dc2626; font-size: 12px; line-height: 1.4;
}
.budget-make-official-actions {
  display: flex; justify-content: flex-end; gap: 8px;
}
.budget-make-official-cancel,
.budget-make-official-confirm {
  padding: 6px 14px; border-radius: 4px; font-size: 13px;
  cursor: pointer; min-height: 32px; border: 1px solid var(--border);
}
.budget-make-official-cancel {
  background: var(--surface); color: var(--text);
}
.budget-make-official-cancel:hover:not(:disabled) { background: var(--hover); }
.budget-make-official-confirm {
  background: var(--accent); color: #fff; border-color: var(--accent);
  font-weight: 600;
}
.budget-make-official-confirm:hover:not(:disabled) { opacity: 0.9; }
.budget-make-official-confirm:disabled,
.budget-make-official-cancel:disabled {
  opacity: 0.55; cursor: not-allowed;
}

/* Lightweight toast for success/info notifications (bead expenses_tool-5981).
   Mounted on document.body so it survives dialog closes and container overflow. */
.budget-toast {
  position: fixed; bottom: 24px; left: 50%;
  transform: translateX(-50%);
  padding: 10px 18px;
  background: var(--text);
  color: var(--bg);
  border-radius: 6px;
  font-size: 13px; font-weight: 500;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
  z-index: 10000;
  cursor: pointer;
  max-width: 480px;
  animation: budget-toast-in 200ms ease-out;
}
@keyframes budget-toast-in {
  from { opacity: 0; transform: translateX(-50%) translateY(10px); }
  to { opacity: 1; transform: translateX(-50%) translateY(0); }
}
.scenario-editor {
  display: flex; align-items: center; gap: 8px;
  padding: 4px 10px; background: rgba(var(--accent-rgb, 59, 130, 246), 0.08);
  border-radius: 6px; font-size: 12px;
}
.scenario-editor-label { color: var(--text-muted); }
.scenario-editor-name { color: var(--accent); }
.scenario-done { background: var(--accent); color: white; border-color: var(--accent); }
.scenario-done:hover { opacity: 0.9; }

/* Scenario editing mode */
.scenario-editing .budget-col-num:first-of-type { cursor: pointer; }
.scenario-editing .budget-col-num:first-of-type:hover { background: rgba(var(--accent-rgb, 59, 130, 246), 0.1); border-radius: 4px; }
.scenario-edit-input {
  width: 100%; border: 1px solid var(--accent); border-radius: 4px;
  padding: 2px 4px; font-size: 12px; text-align: right;
  background: var(--surface); color: var(--text);
}

/* Scenario KPI label */
.kpi-scenario-label {
  font-size: 11px; font-weight: 600;
  color: var(--accent); padding: 2px 8px; letter-spacing: 0.5px;
  white-space: nowrap;
}
.kpi-base-diff { font-size: 10px; margin-top: 2px; }

/* Scenario Diff Indicators — blue (increase) / orange (decrease) */
.has-scenario-diff .budget-col-num:first-of-type { position: relative; }
.has-scenario-diff .budget-col-num:first-of-type::after {
  content: '';
  position: absolute;
  top: 2px; right: 2px;
  width: 0; height: 0;
  border-style: solid;
}
.has-scenario-diff.scenario-diff-increase-row .budget-col-num:first-of-type::after,
.scenario-diff-increase + .budget-col-num::after {
  border-width: 0 6px 6px 0;
  border-color: transparent #2563EB transparent transparent;
}
.has-scenario-diff.scenario-diff-decrease-row .budget-col-num:first-of-type::after,
.scenario-diff-decrease + .budget-col-num::after {
  border-width: 0 6px 6px 0;
  border-color: transparent #EA580C transparent transparent;
}
.scenario-diff-annotation {
  display: block;
  font-size: 9px; line-height: 1.2; margin-top: 1px;
  font-weight: 500; letter-spacing: 0.3px;
}
.scenario-diff-increase { color: #2563EB; }
.scenario-diff-decrease { color: #EA580C; }

/* Descendant-shaped indicator (bead o7l6).
   Applied to bucket / sub-bucket / activity rows when a leaf underneath has
   a pending drawer edit. Left-border accent in the fundraising amber — calm
   enough not to overwhelm dense tables, strong enough to catch the eye when
   scrolling past a parent row whose leaf is already shaped.
   Uses box-shadow (inset) instead of border so the row's grid metrics don't
   shift between shaped/unshaped states. */
.budget-descendant-shaped {
  box-shadow: inset 3px 0 0 var(--color-fund);
  background: linear-gradient(
    90deg,
    rgba(230, 126, 34, 0.06) 0,
    rgba(230, 126, 34, 0.02) 60px,
    transparent 120px
  );
}
.budget-group-row.budget-descendant-shaped {
  background: linear-gradient(
    90deg,
    rgba(230, 126, 34, 0.10) 0,
    rgba(230, 126, 34, 0.04) 80px,
    rgba(0, 0, 0, 0.04) 160px
  );
}

/* KPI method tag */
.kpi-method-tag {
  display: inline-block; font-size: 9px; font-weight: 600;
  background: rgba(34, 197, 94, 0.15); color: #22c55e;
  padding: 1px 4px; border-radius: 3px;
  vertical-align: middle; margin-left: 4px;
}

/* Budget main wrapper — keeps overflow:auto so the category table scrolls
   naturally in list mode. */
.budget-main {
  flex: 1;
  /* min-height: 0 so flex: 1 constrains height correctly (flex items default
     to min-height: auto). display:flex+column so .budget-table-wrap inside
     is itself a flex item — without this, the wrap's own flex: 1 has no
     effect and it grows to fit content, ballooning the page height.
     overflow: hidden so any overflow is owned by .budget-table-wrap (the
     intended scroll container with the sticky header). */
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

/* Drill overlay containing block — using #view-budget (not .budget-main)
   so the drill gets the full view height (~800px) instead of being squeezed
   into the ~150px that remains below KPIs/forecast/waterfall. */
#view-budget { position: relative; }

/* Drill-down panel — absolutely-positioned overlay over .budget-main so its
   internal flex chain is self-contained (doesn't depend on the budget-main
   ancestor layout). This guarantees the drill gets the full .budget-main area
   and the inner .vscroll-viewport can use flex:1 for a bounded height —
   fixing the 'only see 20 transactions' virtual-scroll collapse. Initial
   inline style="display:none" hides it until openDrill sets style.display=''. */
.budget-drill {
  position: absolute;
  inset: 0;
  padding: 0 16px 16px;
  background: var(--bg);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  min-height: 0;
}
.drill-forecast-wrap {
  padding: 10px 12px; margin-bottom: 12px;
  background: var(--surface); border-radius: 6px; border: 1px solid var(--border);
}
.drill-forecast-header {
  display: flex; align-items: center; justify-content: space-between; margin-bottom: 4px;
}
.drill-forecast-title { font-weight: 600; font-size: 13px; color: var(--text); }
.drill-forecast-budget { font-size: 12px; color: var(--text-muted); }
.budget-drill-header {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 0; border-bottom: 1px solid var(--border); margin-bottom: 12px;
}
.budget-drill-back {
  padding: 6px 12px; border: 1px solid var(--border); border-radius: 4px;
  background: var(--surface); color: var(--text); cursor: pointer; font-size: 13px;
  min-height: 32px;
}
.budget-drill-back:hover { background: var(--hover); }
.budget-drill-breadcrumbs { display: flex; align-items: center; flex-wrap: wrap; gap: 0; font-size: 15px; }
.drill-crumb-current { font-weight: 600; color: var(--text); }
.drill-crumb-link { font-weight: 500; color: var(--accent); cursor: pointer; }
.drill-crumb-link:hover { text-decoration: underline; }
.drill-crumb-sep { color: var(--text-muted); margin: 0 2px; }

/* GL-to-category mapping breakdown */
.budget-drill-mapping {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  padding: 10px 12px; margin-bottom: 12px;
  background: var(--surface); border-radius: 6px; border: 1px solid var(--border);
  font-size: 12px;
}
.budget-drill-mapping-label { font-weight: 600; color: var(--text-muted); margin-right: 4px; }
.budget-drill-mapping-header {
  font-weight: 600; color: var(--text-muted); font-size: 12px;
  cursor: pointer; user-select: none; padding: 6px 0;
}
.budget-drill-mapping-header:hover { color: var(--text); }
.budget-drill-mapping-chevron { display: inline-block; font-size: 10px; margin-right: 4px; }
.budget-drill-mapping-item {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 2px 8px; background: var(--bg); border-radius: 4px;
}
.budget-drill-mapping-pct { color: var(--text-muted); font-weight: 600; }
.budget-drill-gl-item {
  padding: 8px 0; border-bottom: 1px solid var(--border);
}
.budget-drill-gl-item:last-child { border-bottom: none; }
.budget-drill-gl-name { font-weight: 600; font-size: 13px; color: var(--text); margin-bottom: 2px; }
.budget-drill-gl-detail { font-size: 12px; color: var(--text-secondary); }
.budget-drill-gl-line { margin: 2px 0; }
.budget-drill-gl-line strong { color: var(--text); }

/* Drill table — flex:1 child of .budget-drill (flex column), so the inner
   .vscroll-viewport gets a bounded height via flex:1. Mirrors the working
   pattern in .pie-table-scroll and .table-scroll-area. */
.budget-drill-table {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

/* Clickable budget rows */
.budget-row[data-gl], .budget-child-row, .budget-activity-row, .budget-subactivity-row { cursor: pointer; }
.budget-row[data-gl]:hover, .budget-child-row:hover, .budget-activity-row:hover, .budget-subactivity-row:hover { background: var(--hover); }
.budget-group-row { cursor: pointer; }
.budget-group-row:hover { background: var(--hover); }
.budget-chevron { cursor: pointer; user-select: none; }

/* Tablet — toolbar wraps to prevent overlap */
@media (max-width: 1024px) {
  .budget-toolbar { flex-wrap: wrap; gap: 6px; }
  .budget-toolbar-center { order: 3; width: 100%; justify-content: center; }
}

/* Mobile */
@media (max-width: 768px) {
  .budget-toolbar { flex-wrap: wrap; padding: 4px 12px; gap: 4px; overflow: hidden; }
  .budget-toolbar-left, .budget-toolbar-right { width: 100%; overflow: hidden; }
  .budget-toolbar-center { width: 100%; overflow-x: auto; }
  .budget-period-nav { display: none; }
  .budget-forecast-wrap { margin: 0 4px 4px; }
  .budget-forecast-grid { padding: 0 8px 8px; }
  .forecast-status { font-size: 13px; padding: 8px 10px; }
  .forecast-trend-wrap { padding: 8px; }
  .forecast-runway { padding: 8px 10px; }
  .forecast-var-item { padding: 6px 8px; }
  .forecast-var-name { font-size: 12px; }
  .forecast-var-diff { font-size: 12px; }
  .budget-mode-btn, .budget-period-btn { font-size: 11px; padding: 6px 10px; min-height: 34px; }
  .budget-kpis { flex-wrap: wrap; padding: 8px 12px; gap: 6px; }
  .budget-kpi { min-width: calc(50% - 4px); padding: 8px 10px; }
  .budget-kpi-value { font-size: 16px; }
  .budget-table-header, .budget-row, .budget-group-row, .budget-total-row {
    grid-template-columns: 1fr 75px 75px 85px;
    gap: 0 4px;
    padding: 8px 12px;
    font-size: 11px;
  }
  .budget-col-progress { display: none; }
  .budget-col-var { display: none; }
  /* Story 5 (pn1d) — collapse the vs-2025 column on mobile (least
     load-bearing of the analytical columns) and drop the 7-col grid back to
     the mobile layout. The .budget-show-yoy override is required because its
     specificity (0,2,0) otherwise beats the 4-col rule above inside this
     query. The display:none here also covers <=480 (this query stays active). */
  .budget-show-yoy .budget-table-header,
  .budget-show-yoy .budget-row,
  .budget-show-yoy .budget-group-row,
  .budget-show-yoy .budget-total-row {
    grid-template-columns: 1fr 75px 75px 85px;
  }
  .budget-col-yoy { display: none; }
  /* R3c Story 13 (qjl3) — collapse the Forecast column on mobile, same as
     vs-2025. Both the single (0,2,0) and combined (0,3,0) desktop grid rules
     leak past the 4-col mobile rule above (media queries add no specificity),
     so re-assert both selectors here, after the base rule in source order. */
  .budget-show-forecast .budget-table-header,
  .budget-show-forecast .budget-row,
  .budget-show-forecast .budget-group-row,
  .budget-show-forecast .budget-total-row,
  .budget-show-forecast.budget-show-yoy .budget-table-header,
  .budget-show-forecast.budget-show-yoy .budget-row,
  .budget-show-forecast.budget-show-yoy .budget-group-row,
  .budget-show-forecast.budget-show-yoy .budget-total-row {
    grid-template-columns: 1fr 75px 75px 85px;
  }
  /* R3c Stories 15/16: leaf/overridden/rollup variants set display:inline-flex
     (0,2,0) to lay out value + chip on the desktop cell. Media queries don't
     add specificity, so the base .budget-col-forecast{display:none} (0,1,0)
     loses to those variants. Enumerate the variants here to win on source
     order (this rule comes after the inline-flex declarations). */
  .budget-col-forecast,
  .budget-col-forecast.budget-forecast-leaf,
  .budget-col-forecast.budget-forecast-overridden,
  .budget-col-forecast.budget-forecast-rollup { display: none; }
}

/* R1 mobile fix (expenses_tool-XXXX): at <=480px the 4-column grid above
   was forcing "$7,645,070"-class numbers into 75px cells, producing
   the Budget/Actual overlap Jason saw on iPhone 14. At narrowest widths
   we drop Remaining too — name + Budget + Actual is the R1 mental model
   anyway, and there's room left over to size Budget/Actual generously. */
@media (max-width: 480px) {
  .budget-table-header, .budget-row, .budget-group-row, .budget-total-row {
    grid-template-columns: 1fr 92px 92px;
    gap: 0 6px;
    padding: 8px 10px;
    font-size: 11px;
  }
  /* Story 5 (pn1d) — same specificity override at the narrowest width; the
     vs-2025 column is already display:none from the 768px query. */
  .budget-show-yoy .budget-table-header,
  .budget-show-yoy .budget-row,
  .budget-show-yoy .budget-group-row,
  .budget-show-yoy .budget-total-row {
    grid-template-columns: 1fr 92px 92px;
  }
  /* R3c Story 13 (qjl3) — same specificity override at the narrowest width;
     the Forecast column is already display:none from the 768px query. */
  .budget-show-forecast .budget-table-header,
  .budget-show-forecast .budget-row,
  .budget-show-forecast .budget-group-row,
  .budget-show-forecast .budget-total-row,
  .budget-show-forecast.budget-show-yoy .budget-table-header,
  .budget-show-forecast.budget-show-yoy .budget-row,
  .budget-show-forecast.budget-show-yoy .budget-group-row,
  .budget-show-forecast.budget-show-yoy .budget-total-row {
    grid-template-columns: 1fr 92px 92px;
  }
  .budget-col-remaining { display: none; }
}

/* ── Compare Mode ── */
.compare-summary {
  padding: 10px 20px;
  font-size: 13px;
  font-weight: 500;
  border-bottom: 1px solid var(--border);
  background: var(--surface);
  color: var(--text);
}
.compare-summary strong { font-weight: 700; }
.compare-summary-savings {
  background: #f0fdf4;
  color: #166534;
  border-left: 3px solid #22c55e;
}
.compare-summary-increase {
  background: #fef2f2;
  color: #991b1b;
  border-left: 3px solid #ef4444;
}

/* ── DrillDialog — calculation lineage (bead 9zo) ── */
.drill-dialog-backdrop {
  position: fixed; inset: 0;
  background: rgba(0, 0, 0, 0.35);
  z-index: 80;
}
.drill-dialog {
  position: fixed;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  width: min(540px, 92vw);
  max-height: 86vh;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: 0 10px 40px rgba(0, 0, 0, 0.24);
  z-index: 90;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  font-size: 13px;
}
.drill-dialog-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 16px;
  border-bottom: 1px solid var(--border);
  background: var(--surface);
  gap: 8px;
}
.drill-dialog-breadcrumbs {
  flex: 1;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 4px;
  font-size: 11px;
  color: var(--text-muted);
}
.drill-dialog-back {
  background: transparent; border: none; color: var(--text-muted);
  font-size: 18px; line-height: 1; cursor: pointer; padding: 0 4px;
}
.drill-dialog-back:hover { color: var(--text); }
.drill-dialog-crumb {
  color: var(--text-muted); text-decoration: none; cursor: pointer;
}
.drill-dialog-crumb:hover { color: var(--text); text-decoration: underline; }
.drill-dialog-crumb.current { color: var(--text); font-weight: 600; }
.drill-dialog-sep { color: var(--text-muted); opacity: 0.5; padding: 0 3px; }
.drill-dialog-close {
  background: transparent; border: none; color: var(--text-muted);
  font-size: 22px; line-height: 1; cursor: pointer; padding: 0 4px;
}
.drill-dialog-close:hover { color: var(--text); }

.drill-dialog-body {
  flex: 1;
  overflow-y: auto;
  padding: 14px 18px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.drill-dialog-title-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}
.drill-dialog-title { margin: 0; font-size: 16px; color: var(--text); font-weight: 600; }
.drill-dialog-value {
  font-size: 18px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--text);
}
.drill-dialog-description {
  font-size: 13px;
  line-height: 1.5;
  color: var(--text-muted);
  padding: 8px 12px;
  background: var(--surface);
  border-left: 3px solid var(--border);
  border-radius: 0 4px 4px 0;
}
.drill-dialog-section {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.drill-dialog-label {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-muted);
  font-weight: 600;
}
.drill-dialog-kv {
  display: flex; justify-content: space-between; align-items: baseline; gap: 10px;
}
.drill-dialog-val { color: var(--text); font-weight: 500; }
.drill-dialog-formula {
  display: block;
  padding: 8px 12px;
  background: var(--surface-muted, #f9fafb);
  border: 1px solid var(--border);
  border-radius: 6px;
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 12px;
  color: var(--text);
  white-space: pre-wrap;
  overflow-x: auto;
}
.drill-dialog-inputs {
  display: flex;
  flex-direction: column;
  gap: 4px;
  border: 1px solid var(--border);
  border-radius: 6px;
  overflow: hidden;
}
.drill-dialog-input {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  padding: 8px 12px;
  border-bottom: 1px solid var(--border);
  background: var(--surface);
  font-variant-numeric: tabular-nums;
  flex-wrap: wrap;
  gap: 6px;
}
.drill-dialog-input:last-child { border-bottom: none; }
.drill-dialog-input.clickable { cursor: pointer; transition: background 0.12s; }
.drill-dialog-input.clickable:hover { background: var(--surface-muted, #f9fafb); }
.drill-dialog-input-label { color: var(--text-muted); font-size: 12px; }
.drill-dialog-input-value { color: var(--text); font-weight: 500; }
.drill-dialog-chevron { color: var(--text-muted); margin-left: 4px; }
.drill-dialog-input-note {
  width: 100%;
  font-size: 11px;
  color: var(--text-muted);
  margin-top: 2px;
  line-height: 1.4;
}
.drill-dialog-sources {
  display: flex;
  flex-direction: column;
  gap: 2px;
  font-size: 11px;
  font-family: var(--font-mono, ui-monospace, monospace);
  color: var(--text-muted);
}
.drill-dialog-source { padding: 2px 0; }
.drill-dialog-footnote {
  font-size: 11px;
  color: var(--text-muted);
  padding-top: 4px;
  border-top: 1px dashed var(--border);
}
.drill-dialog-note {
  font-size: 12px;
  color: var(--text-muted);
  line-height: 1.5;
  padding: 8px 12px;
  background: #fff7ed;
  border-left: 3px solid #f59e0b;
  border-radius: 0 4px 4px 0;
}

.budget-kpi.clickable { cursor: pointer; transition: background 0.15s, box-shadow 0.15s; }
.budget-kpi.clickable:hover {
  background: var(--surface-muted, #f9fafb);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
}
/* Hervé's affordance principle: clickable cards must signal interaction
   without hover. Dotted-underline on the headline value mirrors the
   .budget-drillable-actual pattern used on expense actuals + income
   fund/LP names — single consistent visual vocabulary for "click for
   detail" across the dashboard. */
.budget-kpi.clickable .budget-kpi-value {
  text-decoration: underline;
  text-decoration-color: rgba(37, 99, 235, 0.35);
  text-decoration-style: dotted;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  transition: text-decoration-color 0.12s, color 0.12s;
}
.budget-kpi.clickable:hover .budget-kpi-value {
  text-decoration-color: rgba(37, 99, 235, 0.7);
  text-decoration-style: solid;
}

@media (max-width: 720px) {
  .drill-dialog {
    top: auto; bottom: 0; left: 0; transform: none;
    width: 100vw; max-width: 100vw;
    max-height: 90vh;
    border-radius: 14px 14px 0 0;
  }
}

/* ═════════════════════════════════════════════════
   Diff Dialog (bead expenses_tool-erxu)
   Scenario / commit diff viewer. Theme-safe — uses
   var(--color-positive) / var(--color-negative) if a
   future theme exposes them, else falls back to
   carefully-chosen hues (sRGB, WCAG AA against surface).
   ═════════════════════════════════════════════════ */
.dg-diff-dialog-backdrop {
  position: fixed; inset: 0;
  background: rgba(0, 0, 0, 0.35);
  z-index: 80;
}
.dg-diff-dialog {
  position: fixed;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  width: min(760px, 94vw);
  max-height: 86vh;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: 0 10px 40px rgba(0, 0, 0, 0.24);
  z-index: 90;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  font-size: 13px;
  color: var(--text);
}
.dg-diff-dialog-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 16px;
  border-bottom: 1px solid var(--border);
  background: var(--surface);
  gap: 8px;
}
.dg-diff-dialog-title {
  margin: 0;
  font-size: 15px;
  color: var(--text);
  font-weight: 600;
}
.dg-diff-dialog-close {
  background: transparent;
  border: none;
  color: var(--text-muted);
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
  padding: 0 4px;
}
.dg-diff-dialog-close:hover { color: var(--text); }
.dg-diff-dialog-summary {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 8px 16px;
  border-bottom: 1px solid var(--border);
  background: var(--bg);
  font-variant-numeric: tabular-nums;
  font-size: 12px;
  flex-wrap: wrap;
}
.dg-diff-dialog-summary-chip {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 10px;
  background: var(--surface);
  border: 1px solid var(--border);
  font-weight: 500;
}
.dg-diff-dialog-summary-sep {
  color: var(--text-muted);
  padding: 0 2px;
}
.dg-diff-dialog-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 8px 16px;
  border-bottom: 1px solid var(--border);
  background: var(--surface);
  font-size: 12px;
  flex-wrap: wrap;
}
.dg-diff-dialog-unchanged-toggle {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  cursor: pointer;
  color: var(--text);
}
.dg-diff-dialog-unchanged-toggle input { cursor: pointer; }
.dg-diff-dialog-sort-group {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.dg-diff-dialog-sort-label {
  color: var(--text-muted);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.dg-diff-dialog-sort-select {
  padding: 3px 6px;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: var(--surface);
  color: var(--text);
  font-size: 12px;
  cursor: pointer;
}
.dg-diff-dialog-body {
  flex: 1;
  overflow-y: auto;
  padding: 12px 16px;
}
.dg-diff-dialog-loading,
.dg-diff-dialog-error,
.dg-diff-dialog-empty {
  padding: 20px;
  text-align: center;
  color: var(--text-muted);
  font-size: 13px;
}
.dg-diff-dialog-error { color: #dc2626; /* theme-compatible red; same hue as .scenario-delete */ }
.dg-diff-dialog-list {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--border);
  border-radius: 6px;
  overflow: hidden;
}
.dg-diff-dialog-row {
  display: grid;
  grid-template-columns: 90px 1fr 110px 110px 110px;
  align-items: baseline;
  gap: 8px;
  padding: 8px 12px;
  border-bottom: 1px solid var(--border);
  font-variant-numeric: tabular-nums;
  background: var(--surface);
}
.dg-diff-dialog-row:last-child { border-bottom: none; }
.dg-diff-dialog-row-header {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-muted);
  font-weight: 600;
  background: var(--bg);
}
.dg-diff-col-path {
  color: var(--text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.dg-diff-col-amount,
.dg-diff-col-delta {
  text-align: right;
  color: var(--text);
  font-weight: 500;
}
/* Delta colors: green when spending less (negative delta),
   red when spending more (positive). Uses theme vars when a
   future palette defines them, else the fallbacks below. */
.dg-diff-neutral { color: var(--text-muted); }
.dg-diff-pos { color: var(--color-negative, #dc2626); font-weight: 600; }  /* spending more → red */
.dg-diff-neg { color: var(--color-positive, #16a34a); font-weight: 600; }  /* spending less → green */
/* Added / Removed are absolute changes, not directional — reuse the
   same hues as delta direction so the summary bar stays legible. */
.dg-diff-added { color: var(--color-negative, #dc2626); }
.dg-diff-removed { color: var(--color-positive, #16a34a); }

.dg-diff-chip {
  display: inline-block;
  padding: 1px 8px;
  border-radius: 10px;
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-weight: 600;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text-muted);
}
.dg-diff-chip-added {
  color: var(--color-negative, #dc2626);
  border-color: var(--color-negative, #dc2626);
}
.dg-diff-chip-removed {
  color: var(--color-positive, #16a34a);
  border-color: var(--color-positive, #16a34a);
}
.dg-diff-chip-changed {
  color: var(--accent);
  border-color: var(--accent);
}
.dg-diff-dialog-footnote {
  padding-top: 10px;
  font-size: 11px;
  color: var(--text-muted);
  text-align: right;
}

@media (max-width: 720px) {
  .dg-diff-dialog {
    top: auto; bottom: 0; left: 0; transform: none;
    width: 100vw; max-width: 100vw;
    max-height: 92vh;
    border-radius: 14px 14px 0 0;
  }
  .dg-diff-dialog-row {
    grid-template-columns: 70px 1fr 90px;
    grid-template-areas:
      'status path  delta'
      '.      a     a'
      '.      b     b';
  }
  .dg-diff-col-status { grid-area: status; }
  .dg-diff-col-path { grid-area: path; }
  .dg-diff-col-delta { grid-area: delta; }
  .dg-diff-col-amount:nth-of-type(3) { grid-area: a; text-align: left; font-size: 11px; color: var(--text-muted); }
  .dg-diff-col-amount:nth-of-type(4) { grid-area: b; text-align: left; font-size: 11px; color: var(--text-muted); }
}

/* ── AFB chart (bead v7j.2) ── */
.budget-afb-wrap {
  padding: 12px 20px;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
}
.budget-afb-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 6px;
}
.budget-afb-title {
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-muted);
  font-weight: 600;
}
.budget-afb-summary { font-size: 12px; font-variant-numeric: tabular-nums; }
.budget-afb-delta.pos   { color: #15803d; font-weight: 600; }
.budget-afb-delta.neg   { color: #b91c1c; font-weight: 600; }
.budget-afb-delta.neutral { color: var(--text-muted); }
.budget-afb-chart { height: clamp(200px, 28vh, 360px); }

/* Data-freshness caption (bead expenses_tool-v7j.12) — subtle footnote
   showing /budget/forecast as_of date so the chart's vintage is visible. */
.budget-afb-asof {
  font-size: 11px;
  color: var(--text-muted);
  padding: 4px 2px 0;
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.budget-afb-asof:empty { display: none; }

/* Collapse toggle (bead expenses_tool-ggy) — hides chart body on demand
   so content below is reachable on short viewports. Title stays visible
   so the section is discoverable + re-expandable. */
.budget-afb-collapse {
  background: none; border: none; cursor: pointer;
  color: var(--text-muted); font-size: 14px;
  padding: 2px 8px; line-height: 1;
  margin-left: 4px;
  transition: transform 0.15s, color 0.15s;
}
.budget-afb-collapse:hover { color: var(--text); }
.budget-afb-wrap.collapsed .budget-afb-collapse { transform: rotate(-90deg); }
.budget-afb-wrap.collapsed .budget-afb-chart,
.budget-afb-wrap.collapsed .budget-afb-granularity,
.budget-afb-wrap.collapsed .budget-afb-summary,
.budget-afb-wrap.collapsed .budget-afb-asof { display: none; }
.budget-afb-wrap.collapsed { padding-bottom: 8px; }

/* Granularity toggle (bead v7j.13) */
.budget-afb-granularity {
  display: inline-flex;
  border: 1px solid var(--border);
  border-radius: 6px;
  overflow: hidden;
  margin: 0 8px;
}
.budget-afb-gran-btn {
  padding: 3px 10px;
  font-size: 11px;
  background: transparent;
  border: none;
  color: var(--text-muted);
  cursor: pointer;
  font-weight: 500;
  line-height: 1.5;
}
.budget-afb-gran-btn:hover { background: rgba(0, 0, 0, 0.04); color: var(--text); }
.budget-afb-gran-btn.active {
  background: var(--accent, #2563eb);
  color: #fff;
}
.budget-afb-gran-btn + .budget-afb-gran-btn { border-left: 1px solid var(--border); }
.budget-afb-gran-btn.active + .budget-afb-gran-btn,
.budget-afb-gran-btn + .budget-afb-gran-btn.active { border-left-color: transparent; }

@media (max-width: 720px) {
  .budget-afb-wrap { padding: 8px 12px; }
  .budget-afb-header { flex-wrap: wrap; }
  .budget-afb-granularity { margin: 4px 0; }
}

/* ── Budget-view income panel collapse (bead expenses_tool-bt4) ──
   Mirrors the AFB collapse pattern so the Finance view's income panel
   can be dismissed on short viewports and the category table becomes
   reachable above the fold. Title stays visible so the section is
   discoverable and re-expandable. */
.budget-income-panel-wrap { position: relative; }
.budget-income-collapse-bar {
  display: none;
  align-items: center;
  gap: 8px;
  padding: 8px 20px 0;
  background: var(--surface);
}
/* When collapsed, the bar replaces the panel's own header so users still
   see a title + chevron. When expanded, the shared panel renders its own
   "Management Fee Income" header, so we hide this bar to avoid duplication. */
.budget-income-panel-wrap.collapsed .budget-income-collapse-bar { display: flex; }
.budget-income-collapse-title {
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: #374151;
  flex: 1;
}
/* Collapse chevron lives in both states — floats to the top-right of the
   wrap so it's always clickable even while the shared panel is rendering. */
.budget-income-collapse {
  position: absolute;
  top: 8px;
  right: 12px;
  background: none; border: none; cursor: pointer;
  color: var(--text-muted); font-size: 14px;
  padding: 2px 8px; line-height: 1;
  transition: transform 0.15s, color 0.15s;
  z-index: 2;
}
.budget-income-collapse:hover { color: var(--text); }
.budget-income-panel-wrap.collapsed .budget-income-collapse { transform: rotate(-90deg); position: static; }
/* Collapsed state: hide the mount (aggregate + freshness + breakdown).
   The collapse bar above keeps the title + chevron on screen. */
.budget-income-panel-wrap.collapsed .budget-income-panel-mount { display: none; }

/* Compact income panel on short viewports (laptops ≤ 900px tall).
   Trims padding + shrinks type ~10% so the expanded panel still fits
   when the user chooses to leave it open. */
@media (max-height: 900px) {
  .budget-income-panel-wrap .dg-income-panel { padding: 8px 20px 10px; }
  .budget-income-panel-wrap .dg-income-aggregate-header {
    padding: 4px 6px; min-height: 36px; margin-bottom: 4px;
  }
  .budget-income-panel-wrap .dg-income-cell { padding: 8px 12px; }
  .budget-income-panel-wrap .dg-income-cell-value { font-size: 18px; }
  .budget-income-panel-wrap .dg-income-cell-label { font-size: 10px; }
  .budget-income-panel-wrap .dg-income-title { font-size: 10px; }
  .budget-income-panel-wrap .dg-income-aggregate-row { gap: 12px; }
  .budget-income-panel-wrap .dg-income-freshness { font-size: 10px; }
}

/* ── Derive flow: status bar + badges + error banner + summary strip (bead afk.2) ── */
.budget-status-bar {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 6px 20px;
  font-size: 12px;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  min-height: 30px;
}
.budget-status-badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 10px;
  border-radius: 999px;
  font-weight: 600;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}
.budget-status-badge.preview {
  background: #fef3c7;
  color: #92400e;
  border: 1px solid #fbbf24;
}
.budget-status-badge.preview::before {
  content: '';
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #f59e0b;
}
.budget-status-badge.pending {
  background: #e0e7ff;
  color: #3730a3;
  border: 1px solid #818cf8;
}
.budget-status-badge.committed {
  background: #dcfce7;
  color: #166534;
  border: 1px solid #22c55e;
}
/* Branch-state additions (bead v7j.5) */
.budget-status-badge.scenario {
  background: #ede9fe;
  color: #5b21b6;
  border: 1px solid #a78bfa;
}
.budget-status-badge.scenario-edited {
  background: #fef3c7;
  color: #92400e;
  border: 1px solid #f59e0b;
}
.budget-derive-error {
  padding: 8px 20px;
  background: #fef2f2;
  color: #991b1b;
  border-left: 3px solid #ef4444;
  font-size: 13px;
}
.budget-derive-summary {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  font-variant-numeric: tabular-nums;
  color: var(--text);
}
.budget-summary-pair { display: inline-flex; align-items: baseline; gap: 4px; }
.budget-summary-label { color: var(--text-secondary); font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; }
.budget-summary-val { font-weight: 600; }
.budget-summary-arrow { color: var(--text-muted); }
.budget-summary-delta.pos { color: #b45309; font-weight: 600; }
.budget-summary-delta.neg { color: #047857; font-weight: 600; }
.budget-summary-delta.neutral { color: var(--text-muted); }
.budget-summary-applied {
  color: var(--text-muted);
  font-size: 11px;
  margin-left: auto;
}

/* ── Edit button (pencil icon on sub-bucket rows) ── */
.budget-edit-btn {
  background: transparent;
  border: 1px solid transparent;
  color: var(--text-muted);
  cursor: pointer;
  padding: 1px 6px;
  border-radius: 4px;
  font-size: 12px;
  margin-left: 6px;
  transition: all 0.15s;
  opacity: 0;
}
.budget-child-row:hover .budget-edit-btn,
.budget-child-row:focus-within .budget-edit-btn,
.budget-activity-row:hover .budget-edit-btn,
.budget-activity-row:focus-within .budget-edit-btn,
.budget-subactivity-row:hover .budget-edit-btn,
.budget-subactivity-row:focus-within .budget-edit-btn { opacity: 1; }
.budget-edit-btn:hover {
  background: var(--accent-soft, #f3f4f6);
  color: var(--accent, #2563eb);
  border-color: var(--accent, #2563eb);
}

/* ── Provenance chain (visible on the row, not a tooltip) ── */
.budget-prov-chain {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-left: 8px;
  padding: 2px 8px;
  background: #fff7ed;
  border: 1px solid #fed7aa;
  border-radius: 6px;
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  color: #7c2d12;
}
.budget-prov-step.baseline { color: var(--text-muted); }
.budget-prov-step.shape { color: #b45309; font-weight: 600; }
.budget-prov-step.final { color: #7c2d12; font-weight: 700; }
.budget-prov-arrow { color: #d97706; opacity: 0.7; }

/* ── Assumption drawer (right-side panel) ── */
.budget-drawer-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.2);
  z-index: 40;
}
.budget-drawer {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  width: 420px;
  max-width: 100vw;
  background: var(--surface);
  border-left: 1px solid var(--border);
  box-shadow: -4px 0 16px rgba(0, 0, 0, 0.08);
  z-index: 50;
  display: flex;
  flex-direction: column;
  font-size: 14px;
}
.budget-drawer-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 20px;
  border-bottom: 1px solid var(--border);
  background: var(--surface);
}
.budget-drawer-title {
  font-weight: 600;
  font-size: 15px;
  color: var(--text);
  word-break: break-word;
}
/* Shared breadcrumb segments (beads 6f7d, 61qj) — used anywhere a
   slash-separated hierarchy path is rendered. Non-terminal segments are
   clickable <a>s; the current scope is a plain <span> with .current. */
.dg-breadcrumb-seg {
  cursor: pointer;
  color: var(--accent);
  text-decoration: none;
}
.dg-breadcrumb-seg:hover { text-decoration: underline; }
.dg-breadcrumb-seg.current {
  cursor: default;
  color: var(--text);
}
.dg-breadcrumb-seg.current:hover { text-decoration: none; }
.dg-breadcrumb-sep {
  color: var(--text-muted);
  opacity: 0.6;
}
.budget-drawer-close {
  background: transparent;
  border: none;
  font-size: 22px;
  color: var(--text-muted);
  cursor: pointer;
  padding: 0 4px;
}
.budget-drawer-close:hover { color: var(--text); }
.budget-drawer-body {
  flex: 1;
  overflow-y: auto;
  padding: 16px 20px;
  display: flex;
  flex-direction: column;
  gap: 16px;
}
.budget-drawer-row { display: flex; flex-direction: column; gap: 6px; }
.budget-drawer-label {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-secondary);
  font-weight: 600;
}
.budget-drawer-label-sub {
  display: block;
  font-size: 10px;
  font-weight: 500;
  text-transform: none;
  letter-spacing: 0;
  color: var(--text-muted);
  margin-top: 1px;
}
.budget-drawer-baseline, .budget-drawer-shaped {
  font-size: 18px;
  font-weight: 600;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}
.budget-drawer-delta {
  font-size: 13px;
  font-weight: 500;
  margin-left: 6px;
}
.budget-drawer-delta.pos { color: #b45309; }
.budget-drawer-delta.neg { color: #047857; }
.budget-drawer-input-group {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}
.budget-drawer-inherited {
  font-size: 12px;
  line-height: 1.4;
  color: #78350f;
  background: #fef3c7;
  border: 1px solid #fde68a;
  border-radius: var(--radius);
  padding: 6px 10px;
  margin-bottom: 8px;
}
.budget-drawer-inherited-label { font-weight: 600; }
.budget-drawer-inherited-value {
  font-family: var(--mono);
  font-weight: 700;
  color: #b45309;
}
.budget-drawer-inherited-hint { color: var(--text-secondary); }
.budget-drawer-field {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 6px 8px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--bg, #fff);
}
.budget-drawer-field:focus-within {
  border-color: var(--accent, #2563eb);
  box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.12);
}
.budget-drawer-field-label {
  font-size: 11px;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.03em;
}
.budget-drawer-field input {
  border: none;
  outline: none;
  background: transparent;
  width: 80px;
  font-size: 14px;
  font-variant-numeric: tabular-nums;
  color: var(--text);
}
.budget-drawer-field input:disabled {
  color: var(--text-muted);
  cursor: not-allowed;
}

/* Stepper buttons around Growth / Override input (bead m2o).
   Hides the native number spinner so the custom +/- buttons are the
   only affordance — the 80px input was too tight for the native one. */
.budget-drawer-stepper {
  display: inline-flex;
  align-items: stretch;
  gap: 0;
}
.budget-drawer-stepper input[type=number]::-webkit-outer-spin-button,
.budget-drawer-stepper input[type=number]::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
.budget-drawer-stepper input[type=number] {
  -moz-appearance: textfield;
  appearance: textfield;
  text-align: center;
}
.budget-drawer-step-dec,
.budget-drawer-step-inc {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text);
  cursor: pointer;
  font-size: 14px;
  line-height: 1;
  padding: 0 8px;
  min-width: 22px;
  border-radius: 4px;
  transition: background 0.12s, color 0.12s, border-color 0.12s;
}
.budget-drawer-step-dec { margin-right: 4px; }
.budget-drawer-step-inc { margin-left: 4px; }
.budget-drawer-step-dec:hover,
.budget-drawer-step-inc:hover {
  background: var(--accent-soft, #eef2ff);
  color: var(--accent, #2563eb);
  border-color: var(--accent, #2563eb);
}
.budget-drawer-step-dec:disabled,
.budget-drawer-step-inc:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

.budget-drawer-unit { color: var(--text-muted); font-size: 13px; }
.budget-drawer-unit-prefix { margin-right: 2px; }
.budget-drawer-hint { color: var(--text-muted); font-size: 12px; line-height: 1.4; }

.budget-drawer-leaves {
  list-style: none;
  margin: 0;
  padding: 0;
  max-height: 260px;
  overflow-y: auto;
  border: 1px solid var(--border);
  border-radius: 6px;
}
.budget-drawer-leaves li {
  display: flex;
  justify-content: space-between;
  padding: 6px 10px;
  font-size: 12px;
  border-bottom: 1px solid var(--border);
  /* Clickable — re-opens drawer at the 4-tuple prefix (bead fus). */
  cursor: pointer;
  transition: background 0.12s;
}
.budget-drawer-leaves li:hover {
  background: var(--accent-soft, #f3f4f6);
}
.budget-drawer-leaves li:last-child { border-bottom: none; }
.budget-drawer-leaf-path { font-family: var(--font-mono, ui-monospace, monospace); color: var(--text); }
.budget-drawer-leaf-amt { color: var(--text-muted); font-variant-numeric: tabular-nums; }
/* qyaq follow-up: when a leaf has been shaped (directly or by ancestor edit),
   show shaped value primary + baseline + delta so the user can see what
   changed without leaving the drawer. */
.budget-drawer-leaves .budget-drawer-leaf-shaped-row {
  display: grid;
  grid-template-columns: 1fr auto;
  grid-template-areas:
    "path    shaped"
    "path    was"
    "path    delta";
  align-items: baseline;
  column-gap: 12px;
  row-gap: 2px;
  background: rgba(230, 126, 34, 0.04);
  box-shadow: inset 3px 0 0 var(--color-fund);
}
.budget-drawer-leaves .budget-drawer-leaf-shaped-row .budget-drawer-leaf-path {
  grid-area: path;
  align-self: center;
}
.budget-drawer-leaf-shaped {
  grid-area: shaped;
  font-weight: 700;
  color: var(--text);
  font-variant-numeric: tabular-nums;
  text-align: right;
}
.budget-drawer-leaf-baseline {
  grid-area: was;
  color: var(--text-muted);
  font-size: 11px;
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.budget-drawer-leaf-delta {
  grid-area: delta;
  font-size: 11px;
  font-weight: 600;
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.budget-drawer-leaf-delta.pos { color: #b45309; }
.budget-drawer-leaf-delta.neg { color: #047857; }
.budget-drawer-actions {
  flex-direction: row;
  justify-content: space-between;
  padding-top: 8px;
  border-top: 1px solid var(--border);
}
.budget-drawer-apply, .budget-drawer-clear {
  padding: 8px 14px;
  border-radius: 6px;
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.15s;
}
.budget-drawer-apply {
  background: var(--accent, #2563eb);
  color: #fff;
  border: 1px solid var(--accent, #2563eb);
}
.budget-drawer-apply:hover { filter: brightness(1.08); }
.budget-drawer-clear {
  background: transparent;
  color: var(--text);
  border: 1px solid var(--border);
}
.budget-drawer-clear:hover { background: var(--surface-muted, #f3f4f6); }
.budget-drawer-apply:disabled,
.budget-drawer-clear:disabled {
  opacity: 0.5;
  cursor: not-allowed;
  filter: none;
}
.budget-drawer-apply:disabled:hover,
.budget-drawer-clear:disabled:hover { background: inherit; filter: none; }

@media (max-width: 720px) {
  .budget-drawer {
    top: auto;
    width: 100vw;
    max-height: 85vh;
    border-left: none;
    border-top: 1px solid var(--border);
    border-radius: 14px 14px 0 0;
  }
  .budget-drawer-leaves { max-height: 180px; }
  .budget-prov-chain { display: none; } /* mobile: expand via drawer instead */
  .budget-edit-btn { opacity: 1; } /* no hover on touch */
  .budget-summary-applied { display: none; }
}

/* ── Ceiling bar + infeasibility banner (bead afk.3) ── */
.budget-ceiling-bar {
  padding: 8px 20px;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  font-size: 13px;
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
}
.budget-ceiling-toggle {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-weight: 500;
  cursor: pointer;
  user-select: none;
}
.budget-ceiling-controls {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
  flex: 1;
}
.budget-ceiling-label {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-muted);
  font-weight: 600;
}
.budget-ceiling-amount-wrap {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.budget-ceiling-currency { color: var(--text-muted); }
.budget-ceiling-amount {
  width: 130px;
  padding: 5px 8px;
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 14px;
  font-variant-numeric: tabular-nums;
  color: var(--text);
  background: var(--bg, #fff);
}
.budget-ceiling-amount:focus {
  outline: none;
  border-color: var(--accent, #2563eb);
  box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.12);
}
.budget-ceiling-headroom {
  font-size: 12px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  padding: 3px 8px;
  border-radius: 999px;
}
.budget-ceiling-headroom.pos {
  background: #dcfce7;
  color: #166534;
}
.budget-ceiling-headroom.neg {
  background: #fee2e2;
  color: #991b1b;
}
.budget-ceiling-protected {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}
.budget-ceiling-chips {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 4px;
}
.budget-ceiling-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 4px 2px 8px;
  border-radius: 999px;
  background: #e0e7ff;
  color: #3730a3;
  font-size: 12px;
  border: 1px solid #c7d2fe;
}
.budget-ceiling-chip-x {
  background: transparent;
  border: none;
  color: #3730a3;
  cursor: pointer;
  padding: 0 4px;
  font-size: 14px;
  line-height: 1;
  border-radius: 50%;
}
.budget-ceiling-chip-x:hover { background: rgba(55, 48, 163, 0.15); }
.budget-ceiling-chip-add {
  padding: 2px 10px;
  border-radius: 999px;
  background: transparent;
  border: 1px dashed var(--border);
  color: var(--text-muted);
  cursor: pointer;
  font-size: 12px;
}
.budget-ceiling-chip-add:hover { color: var(--text); border-color: var(--accent, #2563eb); }
.budget-ceiling-status {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.budget-ceiling-status-chip {
  display: inline-flex;
  align-items: center;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}
.budget-ceiling-status-chip.non-binding {
  background: #f3f4f6;
  color: #4b5563;
  border: 1px solid #d1d5db;
}
.budget-ceiling-status-chip.applied {
  background: #fef3c7;
  color: #92400e;
  border: 1px solid #fbbf24;
}
.budget-ceiling-sub {
  color: var(--text-muted);
  font-size: 11px;
  font-variant-numeric: tabular-nums;
}

/* Ceiling step in the provenance chain */
.budget-prov-step.ceiling {
  background: rgba(37, 99, 235, 0.08);
  color: #1e40af;
  padding: 0 4px;
  border-radius: 3px;
  font-weight: 600;
}
.budget-prov-step.ceiling.floor {
  background: #fef3c7;
  color: #92400e;
}

/* Infeasibility banner — persistent, action-forward, not a toast (§7.3) */
.budget-infeasibility-banner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  padding: 12px 20px;
  background: #fef2f2;
  color: #991b1b;
  border-bottom: 2px solid #ef4444;
  border-left: 4px solid #ef4444;
}
.budget-infeas-body { flex: 1; min-width: 280px; font-size: 13px; line-height: 1.5; }
.budget-infeas-reason { color: #7f1d1d; }
.budget-infeas-actions { display: inline-flex; gap: 8px; flex-wrap: wrap; }
.budget-infeas-relax, .budget-infeas-review {
  padding: 6px 12px;
  border-radius: 6px;
  font-size: 12px;
  font-weight: 500;
  cursor: pointer;
  border: 1px solid #dc2626;
  background: #fff;
  color: #dc2626;
}
.budget-infeas-relax:hover, .budget-infeas-review:hover {
  background: #dc2626;
  color: #fff;
}

@media (max-width: 720px) {
  .budget-ceiling-bar { padding: 8px 12px; gap: 8px; }
  .budget-ceiling-status { margin-left: 0; width: 100%; }
  .budget-infeasibility-banner { padding: 10px 12px; font-size: 12px; }
  .budget-infeas-actions { width: 100%; }
  .budget-infeas-relax, .budget-infeas-review { flex: 1; }
}

/* ── Commit / history / rollback (bead afk.4) ── */
.budget-status-actions {
  margin-left: auto;
  display: inline-flex;
  gap: 6px;
}
.budget-status-commit, .budget-status-history {
  padding: 4px 12px;
  border-radius: 6px;
  font-size: 12px;
  font-weight: 500;
  cursor: pointer;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text);
}
.budget-status-commit {
  background: var(--accent, #2563eb);
  color: #fff;
  border-color: var(--accent, #2563eb);
}
.budget-status-commit:hover:not(:disabled) { filter: brightness(1.08); }
.budget-status-commit:disabled {
  background: var(--surface-muted, #e5e7eb);
  color: var(--text-muted);
  border-color: var(--border);
  cursor: not-allowed;
}
.budget-status-history:hover { background: var(--surface-muted, #f3f4f6); }

/* Committed badge */
.budget-status-badge.committed {
  background: #dcfce7;
  color: #166534;
  border: 1px solid #22c55e;
}
.budget-status-badge.committed::before {
  content: '';
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #22c55e;
  display: inline-block;
  margin-right: 6px;
}
.budget-status-badge.none {
  background: #f3f4f6;
  color: #4b5563;
  border: 1px solid #d1d5db;
}
.budget-status-badge.none::before {
  content: '';
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #9ca3af;
  display: inline-block;
  margin-right: 6px;
}

/* Commit modal */
.budget-commit-modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.35);
  z-index: 60;
}
.budget-commit-modal {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: min(480px, 92vw);
  max-height: 90vh;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: 0 10px 40px rgba(0, 0, 0, 0.2);
  z-index: 70;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.budget-commit-modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 20px;
  border-bottom: 1px solid var(--border);
  background: var(--surface);
  font-size: 15px;
}
.budget-commit-close {
  background: transparent;
  border: none;
  font-size: 22px;
  color: var(--text-muted);
  cursor: pointer;
  padding: 0 4px;
}
.budget-commit-modal-body {
  flex: 1;
  overflow-y: auto;
  padding: 16px 20px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  font-size: 13px;
}
.budget-commit-summary {
  background: var(--surface-muted, #f9fafb);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 10px 14px;
}
.budget-commit-sum-line {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  padding: 3px 0;
  font-variant-numeric: tabular-nums;
}
.budget-commit-sum-line span { color: var(--text-muted); }
.budget-commit-sum-line strong { color: var(--text); }
.budget-commit-sum-delta.pos { color: #b45309; font-weight: 600; margin-left: 8px; }
.budget-commit-sum-delta.neg { color: #047857; font-weight: 600; margin-left: 8px; }
.budget-commit-sum-sub { color: var(--text-muted); font-size: 12px; margin-left: 8px; }
.budget-commit-warning {
  color: var(--text-muted);
  font-size: 12px;
  line-height: 1.4;
  background: #fffbeb;
  border-left: 3px solid #f59e0b;
  padding: 8px 12px;
  border-radius: 0 4px 4px 0;
}
.budget-commit-note-label {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-muted);
  font-weight: 600;
}
.budget-commit-required { color: #dc2626; }
.budget-commit-note {
  resize: vertical;
  min-height: 70px;
  padding: 8px 10px;
  border: 1px solid var(--border);
  border-radius: 6px;
  font: inherit;
  font-size: 13px;
  color: var(--text);
  background: var(--bg, #fff);
}
.budget-commit-note:focus {
  outline: none;
  border-color: var(--accent, #2563eb);
  box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.12);
}
.budget-commit-error {
  background: #fef2f2;
  color: #991b1b;
  padding: 8px 12px;
  border-radius: 4px;
  border-left: 3px solid #ef4444;
  font-size: 12px;
}
/* chain_purity_violation (409) recovery (DGOPS-6718 / expenses_tool-9hl). */
.budget-commit-refresh-msg {
  margin-bottom: 8px;
  line-height: 1.4;
}
.budget-commit-refresh {
  background: #991b1b;
  color: #fff;
  border: 1px solid #991b1b;
  padding: 6px 12px;
  border-radius: 4px;
  font-size: 12px;
  font-weight: 500;
  cursor: pointer;
}
.budget-commit-refresh:hover:not(:disabled) { filter: brightness(1.12); }
.budget-commit-refresh:disabled {
  background: #9ca3af;
  border-color: #9ca3af;
  cursor: not-allowed;
}
.budget-commit-refresh-fallback {
  margin-top: 8px;
  font-style: italic;
  color: #7f1d1d;
}
.budget-commit-modal-footer {
  padding: 12px 20px;
  border-top: 1px solid var(--border);
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  background: var(--surface);
}
.budget-commit-cancel, .budget-commit-confirm {
  padding: 8px 16px;
  border-radius: 6px;
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
}
.budget-commit-cancel {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text);
}
.budget-commit-cancel:hover { background: var(--surface-muted, #f3f4f6); }
.budget-commit-confirm {
  background: var(--accent, #2563eb);
  color: #fff;
  border: 1px solid var(--accent, #2563eb);
}
.budget-commit-confirm:hover:not(:disabled) { filter: brightness(1.08); }
.budget-commit-confirm:disabled {
  background: var(--surface-muted, #d1d5db);
  border-color: var(--border);
  color: var(--text-muted);
  cursor: not-allowed;
}

/* History drawer */
.budget-history-drawer {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  width: 420px;
  max-width: 100vw;
  background: var(--surface);
  border-left: 1px solid var(--border);
  box-shadow: -4px 0 16px rgba(0, 0, 0, 0.08);
  z-index: 50;
  display: flex;
  flex-direction: column;
  font-size: 13px;
}
.budget-history-list {
  flex: 1;
  overflow-y: auto;
  padding: 12px 16px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.budget-history-loading, .budget-history-empty, .budget-history-error {
  padding: 20px;
  text-align: center;
  color: var(--text-muted);
}
.budget-history-error { color: #991b1b; }
.budget-history-item {
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface);
}
.budget-history-item.current {
  border-color: #22c55e;
  background: #f0fdf4;
}
.budget-history-head {
  display: flex;
  align-items: baseline;
  gap: 6px;
  flex-wrap: wrap;
}
.budget-history-note {
  color: var(--text);
  word-break: break-word;
}
.budget-history-tag {
  padding: 1px 8px;
  border-radius: 999px;
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.budget-history-tag.rollback { background: #fef3c7; color: #92400e; }
.budget-history-tag.current { background: #dcfce7; color: #166534; }
.budget-history-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 4px;
  font-size: 11px;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}
.budget-history-actions {
  margin-top: 6px;
  display: flex;
  justify-content: flex-end;
}
.budget-history-rollback {
  padding: 3px 10px;
  border-radius: 4px;
  background: transparent;
  color: #dc2626;
  border: 1px solid #fca5a5;
  font-size: 11px;
  cursor: pointer;
}
.budget-history-rollback:hover { background: #fef2f2; }

/* ── Commit history graph (bead cf3j) ──
   Two-lane vertical timeline: real commits on the left, test commits on a
   parallel muted lane. Edges between same-lane nodes are CSS-only via
   ::after on each node's marker column. Theme variables only — no
   hardcoded colors outside the red/green accent tags already used above. */
.budget-commit-graph {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding-top: 2px;
}
.budget-commit-legend {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 4px 2px 8px;
  font-size: 11px;
  color: var(--text-muted);
  border-bottom: 1px solid var(--border);
  margin-bottom: 4px;
}
.budget-commit-legend-item { display: inline-flex; align-items: center; gap: 4px; }
.budget-commit-legend-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  display: inline-block;
  border: 1px solid var(--border);
  background: var(--text-muted);
}
.budget-commit-legend-dot.real { background: var(--text); border-color: var(--text); }
.budget-commit-legend-dot.test { background: var(--surface); border-color: var(--text-muted); }
.budget-commit-legend-dot.head {
  background: var(--accent, #0ea5e9);
  border-color: var(--accent, #0ea5e9);
  box-shadow: 0 0 0 2px rgba(14, 165, 233, 0.18);
}
.budget-commit-legend-count { margin-left: auto; font-variant-numeric: tabular-nums; }

.budget-commit-node {
  display: grid;
  /* Two lane columns (real, test) + body. Each lane is 18px wide with a
     16px dot centered. Switching lanes is just toggling which column the
     marker renders in. */
  grid-template-columns: 18px 18px 1fr;
  align-items: stretch;
  gap: 8px;
  padding: 6px 4px;
  border-radius: 6px;
  background: transparent;
  cursor: pointer;
  position: relative;
  min-height: 40px;   /* ≥ 32px touch target, plus marker padding */
  outline: none;
}
.budget-commit-node:focus-visible {
  box-shadow: 0 0 0 2px var(--accent, #0ea5e9);
  background: var(--surface-muted, rgba(0, 0, 0, 0.03));
}
.budget-commit-node:hover {
  background: var(--surface-muted, rgba(0, 0, 0, 0.04));
}
.budget-commit-marker {
  grid-column: 1 / span 1;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
}
.budget-commit-node.budget-commit-lane-test .budget-commit-marker {
  grid-column: 2 / span 1;
}
.budget-commit-dot {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--text);
  border: 2px solid var(--text);
  z-index: 1;
  position: relative;
}
.budget-commit-node.budget-commit-test-lane .budget-commit-dot {
  background: var(--surface);
  border-color: var(--text-muted);
  width: 10px;
  height: 10px;
}
.budget-commit-node.budget-commit-head .budget-commit-dot {
  background: var(--accent, #0ea5e9);
  border-color: var(--accent, #0ea5e9);
  box-shadow: 0 0 0 3px rgba(14, 165, 233, 0.22);
  width: 14px;
  height: 14px;
}
/* Edge line: from the marker center downward to the next same-lane node.
   Rendered as an absolutely-positioned 2px column behind the dot. The
   node itself carries `.has-edge` when a same-lane older node exists
   below it. Newest node (`.has-edge` absent) omits the line. */
.budget-commit-node.has-edge .budget-commit-marker::after {
  content: '';
  position: absolute;
  top: 50%;
  bottom: -8px;
  left: 50%;
  width: 2px;
  transform: translateX(-50%);
  background: var(--border);
}
.budget-commit-node.budget-commit-test-lane.has-edge .budget-commit-marker::after {
  background: var(--border);
  opacity: 0.7;
}

.budget-commit-body {
  grid-column: 3 / span 1;
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.budget-commit-node.budget-commit-test-lane .budget-commit-body {
  opacity: 0.72;
}
.budget-commit-line1 {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 6px;
  min-width: 0;
}
.budget-commit-sha {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 11px;
  color: var(--text-muted);
  letter-spacing: 0.02em;
}
.budget-commit-note {
  color: var(--text);
  font-weight: 600;
  font-size: 13px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 100%;
}
.budget-commit-tag {
  display: inline-block;
  padding: 1px 6px;
  border-radius: 999px;
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  line-height: 1.5;
}
.budget-commit-tag.head {
  background: var(--accent, #0ea5e9);
  color: #fff;
}
.budget-commit-tag.test {
  background: var(--surface-muted, #f3f4f6);
  color: var(--text-muted);
  border: 1px solid var(--border);
}
.budget-commit-tag.rollback {
  background: #fef3c7;
  color: #92400e;
}
.budget-commit-line2 {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  font-size: 11px;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}
.budget-commit-sep { opacity: 0.55; }
.budget-commit-total { font-weight: 600; }
.budget-commit-inline-rollback {
  margin-left: auto;
  padding: 2px 8px;
  border-radius: 4px;
  border: 1px solid #fca5a5;
  background: transparent;
  color: #dc2626;
  font-size: 10px;
  cursor: pointer;
  min-height: 24px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-weight: 600;
}
.budget-commit-inline-rollback:hover { background: #fef2f2; }

.budget-commit-detail {
  grid-column: 3 / -1;
  margin: 2px 0 8px 0;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface-muted, rgba(0, 0, 0, 0.03));
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: 12px;
}
.budget-commit-detail-row {
  display: flex;
  gap: 8px;
  align-items: baseline;
}
.budget-commit-detail-label {
  color: var(--text-muted);
  width: 72px;
  flex-shrink: 0;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.budget-commit-detail-value {
  color: var(--text);
  word-break: break-word;
}
.budget-commit-detail-value.mono {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}
.budget-commit-detail-note .budget-commit-detail-value { white-space: pre-wrap; }
.budget-commit-detail-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding-top: 4px;
  border-top: 1px dashed var(--border);
  margin-top: 4px;
}
.budget-commit-action {
  padding: 4px 10px;
  border-radius: 4px;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text);
  font-size: 11px;
  cursor: pointer;
  min-height: 32px;
}
.budget-commit-action[disabled],
.budget-commit-action[aria-disabled="true"] {
  color: var(--text-muted);
  cursor: not-allowed;
  opacity: 0.65;
}
.budget-commit-action.budget-history-rollback {
  color: #dc2626;
  border-color: #fca5a5;
  opacity: 1;
}
.budget-commit-action.budget-history-rollback:hover { background: #fef2f2; }

.budget-history-error {
  padding: 20px;
  text-align: center;
  color: var(--text);
  display: flex;
  flex-direction: column;
  gap: 8px;
  align-items: center;
}
.budget-history-error-detail {
  font-size: 11px;
  color: var(--text-muted);
  max-width: 340px;
  word-break: break-word;
}
.budget-history-retry {
  padding: 4px 12px;
  border-radius: 4px;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text);
  font-size: 12px;
  cursor: pointer;
  min-height: 32px;
}
.budget-history-retry:hover { background: var(--surface-muted, rgba(0, 0, 0, 0.03)); }

/* ── Revert modal (bead expenses_tool-es2i) ──
   Reuses .budget-commit-modal base sizing / layout classes; these rules
   mirror the commit modal so the revert dialog inherits the same z-index,
   centering, and mobile collapse. Primary button gets a destructive red
   treatment to telegraph "this rewrites state". */
.budget-revert-modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.35);
  z-index: 60;
}
.budget-revert-modal {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: min(520px, 92vw);
  max-height: 90vh;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: 0 10px 40px rgba(0, 0, 0, 0.2);
  z-index: 70;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.budget-revert-close {
  background: transparent;
  border: none;
  font-size: 22px;
  color: var(--text-muted);
  cursor: pointer;
  padding: 0 4px;
}
.budget-revert-target-sha {
  font-family: var(--mono, monospace);
  font-weight: 600;
  color: var(--text);
}
.budget-revert-diff-hint {
  font-size: 12px;
  color: var(--text-muted);
  line-height: 1.4;
}
.budget-revert-note {
  resize: vertical;
  min-height: 60px;
  padding: 8px 10px;
  border: 1px solid var(--border);
  border-radius: 6px;
  font: inherit;
  font-size: 13px;
  color: var(--text);
  background: var(--bg, #fff);
}
.budget-revert-note:focus {
  outline: none;
  border-color: var(--accent, #2563eb);
  box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.12);
}
.budget-revert-cancel {
  padding: 6px 14px;
  border-radius: 4px;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text);
  font-size: 12px;
  cursor: pointer;
  min-height: 32px;
}
.budget-revert-cancel:hover { background: var(--surface-muted, rgba(0, 0, 0, 0.03)); }
.budget-revert-confirm.budget-revert-destructive {
  background: #991b1b;
  color: #fff;
  border: 1px solid #991b1b;
  padding: 6px 14px;
  border-radius: 4px;
  font-size: 12px;
  font-weight: 500;
  cursor: pointer;
  min-height: 32px;
}
.budget-revert-confirm.budget-revert-destructive:hover:not(:disabled) { filter: brightness(1.12); }
.budget-revert-confirm.budget-revert-destructive:disabled {
  background: #9ca3af;
  border-color: #9ca3af;
  cursor: not-allowed;
}

/* Revert success toast — transient status banner, auto-dismissed after 4s. */
.budget-revert-toast {
  position: fixed;
  bottom: 24px;
  left: 50%;
  transform: translateX(-50%);
  padding: 10px 16px;
  border-radius: 8px;
  background: var(--accent, #2b7bba);
  color: #fff;
  font-size: 13px;
  font-weight: 500;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.22);
  z-index: 100;
  max-width: 80vw;
}

@media (max-width: 720px) {
  .budget-status-actions { margin-left: 0; width: 100%; justify-content: flex-end; }
  .budget-commit-modal { width: 100vw; max-width: 100vw; border-radius: 14px 14px 0 0; top: auto; bottom: 0; left: 0; transform: none; }
  .budget-revert-modal { width: 100vw; max-width: 100vw; border-radius: 14px 14px 0 0; top: auto; bottom: 0; left: 0; transform: none; }
  .budget-history-drawer {
    top: auto;
    width: 100vw;
    max-height: 85vh;
    border-left: none;
    border-top: 1px solid var(--border);
    border-radius: 14px 14px 0 0;
  }
  .budget-commit-node {
    grid-template-columns: 16px 16px 1fr;
    gap: 6px;
  }
  .budget-commit-detail-label { width: 60px; }
}

/* ── GL artifact view (bead afk.5) ── */
.budget-gl-artifact-header {
  padding: 8px 20px;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  font-size: 12px;
}
.budget-gl-artifact-row {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
}
.budget-gl-source {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}
.budget-gl-source.committed {
  background: #dcfce7;
  color: #166534;
  border: 1px solid #22c55e;
}
.budget-gl-source.preview {
  background: #fef3c7;
  color: #92400e;
  border: 1px solid #fbbf24;
}
.budget-gl-preview-toggle {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  cursor: pointer;
  user-select: none;
  color: var(--text);
}
/* Bead bis.6: .budget-gl-scenario-label / .budget-gl-scenario-select removed —
   the primary status-bar scenario picker (.scenario-select) drives GL diff. */
.budget-gl-total {
  margin-left: auto;
  font-variant-numeric: tabular-nums;
  font-weight: 500;
  color: var(--text-muted);
}
.budget-gl-total-delta {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  padding: 2px 8px;
  border-radius: 4px;
}
.budget-gl-total-delta.pos { background: #fff7ed; color: #b45309; }
.budget-gl-total-delta.neg { background: #f0fdf4; color: #047857; }
.budget-gl-material-count {
  padding: 2px 10px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 600;
  background: var(--surface-muted, #f3f4f6);
  color: var(--text-muted);
  border: 1px solid var(--border);
  cursor: pointer;
}
.budget-gl-material-count.active {
  background: #fef3c7;
  color: #92400e;
  border-color: #fbbf24;
}

/* GL row — add chevron + scenario/delta columns */
.budget-gl-chevron { color: var(--text-muted); font-size: 10px; margin-right: 2px; }
.budget-gl-row.material-variance { background: rgba(251, 191, 36, 0.12); }
.budget-col-num.budget-col-delta.pos { color: #b45309; font-weight: 600; }
.budget-col-num.budget-col-delta.neg { color: #047857; font-weight: 600; }
.budget-col-num.budget-col-delta.neutral { color: var(--text-muted); }
.budget-gl-delta-pct { color: var(--text-muted); font-weight: 400; font-size: 11px; margin-left: 3px; }

/* Contributing categories accordion */
.budget-gl-contributing {
  padding: 10px 20px 10px 44px;
  background: var(--surface-muted, #f9fafb);
  border-bottom: 1px solid var(--border);
}
.budget-gl-contrib-title {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-muted);
  font-weight: 600;
  margin-bottom: 4px;
}
.budget-gl-contrib-list {
  list-style: none;
  margin: 0;
  padding: 0;
  max-height: 200px;
  overflow-y: auto;
}
.budget-gl-contrib-list li {
  display: flex;
  justify-content: space-between;
  padding: 3px 0;
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  color: var(--text);
}
.budget-gl-contrib-amt { color: var(--text-muted); }
.budget-gl-error {
  padding: 16px 20px;
  color: #991b1b;
  background: #fef2f2;
  font-size: 13px;
  border-left: 3px solid #ef4444;
}

@media (max-width: 720px) {
  .budget-gl-total { margin-left: 0; }
  .budget-gl-contributing { padding-left: 16px; }
}

/* ── Scenario import modal (bead afk.6) ── */
.budget-gl-import {
  padding: 3px 10px;
  border-radius: 6px;
  font-size: 11px;
  font-weight: 600;
  background: transparent;
  color: var(--accent, #2563eb);
  border: 1px dashed var(--accent, #2563eb);
  cursor: pointer;
}
.budget-gl-import:hover {
  background: var(--accent, #2563eb);
  color: #fff;
}

.budget-import-modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.35);
  z-index: 60;
}
.budget-import-modal {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: min(480px, 92vw);
  max-height: 90vh;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: 0 10px 40px rgba(0, 0, 0, 0.2);
  z-index: 70;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.budget-import-hint {
  color: var(--text-muted);
  font-size: 12px;
  line-height: 1.4;
  padding: 6px 10px;
  background: var(--surface-muted, #f9fafb);
  border-radius: 4px;
}
.budget-import-sheet-id, .budget-import-tab, .budget-import-name {
  padding: 8px 10px;
  border: 1px solid var(--border);
  border-radius: 6px;
  font: inherit;
  font-size: 13px;
  color: var(--text);
  background: var(--bg, #fff);
  font-family: var(--font-mono, ui-monospace, monospace);
}
.budget-import-sheet-id:focus, .budget-import-tab:focus, .budget-import-name:focus {
  outline: none;
  border-color: var(--accent, #2563eb);
  box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.12);
}
.budget-import-result {
  padding: 10px 12px;
  background: #f0fdf4;
  border-left: 3px solid #22c55e;
  border-radius: 0 4px 4px 0;
  color: #166534;
  font-size: 13px;
  line-height: 1.5;
}
.budget-import-stats {
  display: flex;
  gap: 14px;
  margin-top: 6px;
  font-variant-numeric: tabular-nums;
  color: #15803d;
  font-size: 12px;
}
.budget-import-actions {
  margin-top: 8px;
}
.budget-import-view-diff {
  padding: 5px 12px;
  border-radius: 6px;
  background: #22c55e;
  color: #fff;
  border: 1px solid #22c55e;
  font-size: 12px;
  font-weight: 500;
  cursor: pointer;
}
.budget-import-view-diff:hover { filter: brightness(1.08); }
.budget-import-cancel, .budget-import-confirm {
  padding: 8px 16px;
  border-radius: 6px;
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
}
.budget-import-cancel {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text);
}
.budget-import-confirm {
  background: var(--accent, #2563eb);
  color: #fff;
  border: 1px solid var(--accent, #2563eb);
}
.budget-import-confirm:disabled {
  background: var(--surface-muted, #d1d5db);
  border-color: var(--border);
  color: var(--text-muted);
  cursor: not-allowed;
}

@media (max-width: 720px) {
  .budget-import-modal { width: 100vw; max-width: 100vw; border-radius: 14px 14px 0 0; top: auto; bottom: 0; left: 0; transform: none; }
}

/* ── Transaction drill-down drawer (bead afk.7) ── */
.budget-drillable {
  cursor: pointer;
  transition: background 0.12s, color 0.12s;
  border-radius: 3px;
}
.budget-drillable:hover {
  background: rgba(37, 99, 235, 0.08);
  color: var(--accent, #2563eb);
}

/* R1 (expenses_tool-vbgz / standup 2026-04-29): clickable affordance per
   Hervé's UX requirement — must be obvious WITHOUT hovering. Persistent
   dotted underline says "this is interactive"; on hover it solidifies +
   adds background tint so the click target is unambiguous. */
.budget-drillable-actual {
  cursor: pointer;
  transition: background 0.12s, color 0.12s, text-decoration-color 0.12s;
  border-radius: 3px;
  text-decoration: underline;
  text-decoration-color: rgba(37, 99, 235, 0.35);
  text-decoration-style: dotted;
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
}
.budget-drillable-actual:hover {
  background: rgba(37, 99, 235, 0.08);
  color: var(--accent, #2563eb);
  text-decoration-color: rgba(37, 99, 235, 0.7);
  text-decoration-style: solid;
}

/* R1.10b: same affordance for income fund + LP row names. Hervé's
   non-hover-required rule — clicking a fund row opens the income
   drawer (Phase 2), so the row name should signal interactivity
   persistently. Scope to .budget-col-name to avoid underlining the
   numeric cells (which aren't independently clickable on income
   rows — the whole row is the click target). */
.income-row[data-fund-id] .budget-col-name,
.income-lp-row[data-partner-code] .budget-col-name {
  cursor: pointer;
}
.income-row[data-fund-id] .budget-col-name > :not(.budget-chevron):not(.income-calc-method),
.income-lp-row[data-partner-code] .budget-col-name > :not(.income-calc-method) {
  /* fall-through: applies to text node — see below */
}
.income-row[data-fund-id] .budget-col-name,
.income-lp-row[data-partner-code] .budget-col-name {
  text-decoration: underline;
  text-decoration-color: rgba(37, 99, 235, 0.35);
  text-decoration-style: dotted;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  transition: text-decoration-color 0.12s, color 0.12s;
}
.income-row[data-fund-id] .budget-col-name:hover,
.income-lp-row[data-partner-code] .budget-col-name:hover {
  color: var(--accent, #2563eb);
  text-decoration-color: rgba(37, 99, 235, 0.7);
  text-decoration-style: solid;
}
/* Don't underline the chevron or the calc-method tag — visually noisy. */
.income-row[data-fund-id] .budget-col-name .budget-chevron,
.income-row[data-fund-id] .budget-col-name .income-calc-method,
.income-lp-row[data-partner-code] .budget-col-name .income-calc-method {
  text-decoration: none;
}

/* Hervé's affordance, expense side: every clickable expense row in FO
   mode (which means every expense row in r1) needs persistent visual
   indication that the row is interactive. The Actual cell already has
   dotted-underline via .budget-drillable-actual; this extends the same
   pattern to the Category name cell — the most natural click target.
   Limited to release-r1 since FT mode (release-internal) has different
   click semantics that may be edit-mode rather than drill. */
.release-r1 .budget-group-row[data-bucket] .budget-col-name,
.release-r1 .budget-child-row[data-bucket] .budget-col-name,
.release-r1 .budget-activity-row[data-bucket] .budget-col-name,
.release-r1 .budget-subactivity-row[data-bucket] .budget-col-name {
  text-decoration: underline;
  text-decoration-color: rgba(37, 99, 235, 0.35);
  text-decoration-style: dotted;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  transition: text-decoration-color 0.12s, color 0.12s;
}
.release-r1 .budget-group-row[data-bucket] .budget-col-name:hover,
.release-r1 .budget-child-row[data-bucket] .budget-col-name:hover,
.release-r1 .budget-activity-row[data-bucket] .budget-col-name:hover,
.release-r1 .budget-subactivity-row[data-bucket] .budget-col-name:hover {
  color: var(--accent, #2563eb);
  text-decoration-color: rgba(37, 99, 235, 0.7);
  text-decoration-style: solid;
}
/* Chevrons inside name cells stay un-underlined */
.release-r1 .budget-group-row[data-bucket] .budget-col-name .budget-chevron,
.release-r1 .budget-child-row[data-bucket] .budget-col-name .budget-chevron,
.release-r1 .budget-activity-row[data-bucket] .budget-col-name .budget-chevron,
.release-r1 .budget-subactivity-row[data-bucket] .budget-col-name .budget-chevron {
  text-decoration: none;
}

/* R1.10c (2026-04-30): when any drawer is open, push the budget content
   area left so the table rows + numbers stay fully visible alongside the
   drawer. Honors the "trust narrative needs both visible" rule — the row
   the user clicked must remain readable while they read the drawer's
   verification details.
   Wide-viewport only (>=1280px). Below that, narrow content beside a
   520px drawer would be cramped, so the existing overlay behavior stays.
   Mobile (<720px) drawer is a full-width bottom sheet via the existing
   @media rule on .budget-txn-drawer — no margin shift needed. */
@media (min-width: 1280px) {
  /* Bead expenses_tool-0k0p — .budget-table-header is INSIDE .budget-table-wrap
     in the DOM (budget.js:1521). Applying margin-right to both stacks the
     shifts: the wrap narrows by 520px AND the header narrows another 520px
     within it, leaving the sticky header's grid columns offset from the body
     rows below. The wrap's margin already shifts header + body together, so
     the header doesn't need its own rule. */
  #view-budget .budget-toolbar,
  #view-budget .budget-kpis,
  #view-budget .kpi-fixvar-bars,
  #view-budget .budget-status-bar,
  #view-budget .budget-table-wrap,
  #view-budget .budget-afb-wrap {
    transition: margin-right 0.2s ease;
  }
  #view-budget.budget-has-drawer-open .budget-toolbar,
  #view-budget.budget-has-drawer-open .budget-kpis,
  #view-budget.budget-has-drawer-open .kpi-fixvar-bars,
  #view-budget.budget-has-drawer-open .budget-status-bar,
  #view-budget.budget-has-drawer-open .budget-table-wrap,
  #view-budget.budget-has-drawer-open .budget-afb-wrap {
    margin-right: 520px;
  }
  /* Backdrop only covers the visible content area (left of the drawer)
     so dismissing on outside-click still works without overlapping the
     drawer itself. */
  #view-budget.budget-has-drawer-open .budget-drawer-backdrop {
    right: 520px;
  }
}

/* In FO mode, the entire row is a click target for the actuals drawer
   (R1 row-drill fix). Cursor + slightly stronger hover so users see it. */
.release-r1 .budget-group-row,
.release-r1 .budget-child-row,
.release-r1 .budget-activity-row,
.release-r1 .budget-subactivity-row { cursor: pointer; }

/* R1.4 trust banner — "Data through <date>" with hover tooltip. Subtle by
   default; takes a warning tint when meta.stale is true (>24h old). */
.budget-trust-banner {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  margin: 0 0 8px;
  font-size: 12px;
  color: var(--text-muted, #6b7280);
  background: rgba(34, 197, 94, 0.06);
  border: 1px solid rgba(34, 197, 94, 0.18);
  border-radius: 4px;
  cursor: help;
  user-select: none;
  white-space: pre-line;
}
.budget-trust-banner .budget-trust-icon { color: rgb(34, 197, 94); font-size: 10px; }
.budget-trust-banner.stale {
  color: rgb(180, 83, 9);
  background: rgba(245, 158, 11, 0.08);
  border-color: rgba(245, 158, 11, 0.3);
}
.budget-trust-banner.stale .budget-trust-icon { color: rgb(245, 158, 11); }

/* R1.10: Income hierarchy rows. Same column structure as expense rows so the
   table reads as one coherent surface. Subtle color tint differentiates
   income from expense without forking the layout. */
.income-row.budget-group-row,
.income-row.budget-child-row {
  background: rgba(34, 197, 94, 0.03); /* faint green wash for income */
}
.income-row.budget-group-row:hover,
.income-row.budget-child-row:hover {
  background: rgba(34, 197, 94, 0.08);
}

/* Calculation method tag next to fund name (e.g., "· invested_capital") */
.income-calc-method {
  font-size: 11px;
  color: var(--text-muted, #6b7280);
  font-weight: 400;
  margin-left: 4px;
}

/* Restricted/pending data_gap rows render muted-italic with a status badge */
.income-data-gap .budget-col-name {
  color: var(--text-muted, #6b7280);
  font-style: italic;
}
.income-status-badge {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 6px;
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  border-radius: 3px;
  vertical-align: middle;
}
.income-status-restricted {
  background: rgba(99, 102, 241, 0.12);
  color: rgb(79, 70, 229);
}
.income-status-pending {
  background: rgba(245, 158, 11, 0.12);
  color: rgb(180, 83, 9);
}

/* Net-spend convention note shown above drawer txn table when refunds present */
.budget-txn-convention-note {
  font-size: 12px;
  color: var(--text-muted, #6b7280);
  font-style: italic;
  margin: 6px 0 8px;
  padding: 6px 10px;
  background: rgba(37, 99, 235, 0.04);
  border-left: 2px solid rgba(37, 99, 235, 0.3);
  border-radius: 3px;
}

.budget-txn-drawer {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  width: 520px;
  max-width: 100vw;
  background: var(--surface);
  border-left: 1px solid var(--border);
  box-shadow: -4px 0 16px rgba(0, 0, 0, 0.08);
  z-index: 50;
  display: flex;
  flex-direction: column;
  font-size: 13px;
}
.budget-txn-body {
  flex: 1;
  overflow-y: auto;
  padding: 14px 18px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.budget-txn-loading, .budget-txn-empty {
  text-align: center;
  color: var(--text-muted);
  padding: 24px 10px;
}
.budget-txn-errors {
  padding: 8px 12px;
  background: #fef2f2;
  color: #991b1b;
  border-radius: 4px;
  font-size: 12px;
}
.budget-txn-shaped {
  padding: 8px 12px;
  background: #fff7ed;
  border: 1px solid #fed7aa;
  border-radius: 6px;
  display: flex;
  align-items: center;
  gap: 6px;
  font-variant-numeric: tabular-nums;
  flex-wrap: wrap;
}
.budget-txn-shaped-label {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-muted);
  font-weight: 600;
  margin-right: 4px;
}
.budget-txn-shaped-delta { font-weight: 600; margin-left: auto; }
.budget-txn-shaped-delta.pos { color: #b45309; }
.budget-txn-shaped-delta.neg { color: #047857; }

.budget-txn-summary {
  display: flex;
  gap: 18px;
  font-variant-numeric: tabular-nums;
  padding: 8px 12px;
  background: var(--surface-muted, #f9fafb);
  border-radius: 6px;
}
.budget-txn-summary strong { font-weight: 600; color: var(--text); }

/* vo45: Change-history section inside the unified transactions drawer.
   Sits between the summary and the transactions table; reuses the
   .audit-entry-budget styles (class-based, not panel-scoped). The label
   matches the small-caps section grammar used elsewhere. */
.budget-txn-history {
  margin: 4px 0 2px;
  padding: 10px 12px;
  border: 1px solid var(--border-muted, #e5e7eb);
  border-radius: 6px;
  background: var(--surface, #fff);
}
.budget-txn-history-label {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: var(--text-secondary, #4b5563);
  margin-bottom: 8px;
}

.budget-txn-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 12px;
}
.budget-txn-table thead th {
  text-align: left;
  padding: 6px 8px;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-secondary);
  font-weight: 600;
  border-bottom: 1px solid var(--border);
}
.budget-txn-table th.num { text-align: right; }
/* Bead f8hw: clickable column headers. Cursor + hover signal interactivity;
   sort arrow renders to the right of the label when this column is active. */
.budget-txn-table th.budget-txn-sortable {
  cursor: pointer;
  user-select: none;
}
.budget-txn-table th.budget-txn-sortable:hover { color: var(--text); }
.budget-txn-table .budget-sort-arrow {
  font-size: 9px;
  color: var(--accent, #2563eb);
  margin-left: 2px;
}
.budget-txn-table tbody td {
  padding: 6px 8px;
  border-bottom: 1px solid var(--border);
  color: var(--text);
  vertical-align: top;
}
.budget-txn-table td.num {
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.budget-txn-table td.vendor {
  max-width: 200px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.budget-txn-class {
  padding: 1px 6px;
  border-radius: 3px;
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  background: var(--surface-muted, #f3f4f6);
  color: var(--text-muted);
}
.budget-txn-class.fixed { background: #dbeafe; color: #1e40af; }
.budget-txn-class.variable { background: #fef3c7; color: #92400e; }
.budget-txn-class.non-recurring { background: #fce7f3; color: #9d174d; }

@media (max-width: 720px) {
  .budget-txn-drawer {
    top: auto;
    width: 100vw;
    max-height: 90vh;
    border-left: none;
    border-top: 1px solid var(--border);
    border-radius: 14px 14px 0 0;
  }
  .budget-txn-summary { flex-direction: column; gap: 4px; }
  .budget-txn-table td.vendor { max-width: 120px; }
}

/* R1.10b Phase 2: Income drawer sections — Expected/Accrued/Received triple
   at top, then a section per atom kind (accruals / wires / calls). */
.budget-income-summary {
  display: flex;
  gap: 16px;
  padding: 10px 12px;
  background: var(--surface-muted, #f9fafb);
  border-radius: 6px;
  flex-wrap: wrap;
}
.budget-income-summary-cell {
  flex: 1;
  min-width: 110px;
}
.budget-income-summary-value {
  font-family: var(--mono);
  font-size: 18px;
  font-weight: 700;
  color: var(--text);
  font-variant-numeric: tabular-nums;
  margin-bottom: 2px;
}
/* Sub-line under YTD Received showing the for_period / catch-up /
   needs-annotation breakdown when the wire pile is split. Makes the
   Prepaid/Payable badge math reconcilable at a glance — without this
   line the badge denominator (for_period only) and the tile total
   (aggregate) look contradictory. Added 2026-05-29 after demo feedback. */
.budget-income-summary-breakdown {
  margin-top: 6px;
  font-size: 11px;
  line-height: 1.4;
  color: #4b5563;
  font-variant-numeric: tabular-nums;
}
.budget-income-summary-breakdown-part { white-space: nowrap; }
.budget-income-summary-breakdown-part.is-catchup { color: #475569; }
.budget-income-summary-breakdown-part.is-unattributed { color: #92400e; }
.budget-income-section {
  margin-top: 16px;
}
.budget-income-section-header {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  border-bottom: 1px solid var(--border);
  padding-bottom: 4px;
  margin-bottom: 6px;
}
.budget-income-section-title {
  font-size: 12px;
  font-weight: 600;
  color: var(--text);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.budget-income-section-count {
  color: var(--text-muted);
  font-weight: 500;
  margin-left: 4px;
}
/* Recon section header — title-only after 2026-05-19 strip. Inherits the
   default .budget-income-section-header layout. The previous two-line
   metadata header was stripped per reviewer review: none of the count /
   gross / age / period / field-count fragments drove action; sub-tolerance
   disclosure lives on the collapsed <details> cluster summary instead. */
.budget-income-section-subtotal {
  font-family: var(--mono);
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}
.budget-income-section-empty {
  font-size: 12px;
  color: var(--text-muted);
  padding: 6px 0 12px;
}
/* Projected (future-quarter) atom rows are tagged inline rather than
   italicized — explicit "projected" badge on the date column so the
   distinction is obvious without a legend. */
.budget-income-projected-tag {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 6px;
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  background: var(--surface-muted, #f3f4f6);
  color: var(--text-secondary);
  border-radius: 3px;
  vertical-align: middle;
}
.budget-income-section-projected {
  color: var(--text-muted);
  font-weight: 500;
  font-size: 12px;
}
/* Period-grouped accruals — each group has a header with the period range +
   subtotal + LP count. Within the group, LPs sort alphabetically (natural). */
.budget-income-period-group {
  margin: 10px 0 6px;
}
.budget-income-period-header {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  padding: 4px 8px;
  background: var(--surface-muted, #f9fafb);
  border-radius: 4px;
  font-size: 12px;
  margin-bottom: 4px;
  cursor: pointer;
  user-select: none;
}
/* Per-period LP table fills the drawer width so the amount column
   right-aligns to the same position as the period header subtotal
   above it (Eren standup walkthrough 2026-04-30: "headers didn't
   align with the data"). Without width:100%, the auto-sized table
   collapses to its content width and the amount column ends mid-
   drawer, drifting from the period header's right edge. */
.budget-income-period-group .budget-txn-table {
  width: 100%;
}
.budget-income-period-group .budget-txn-table td.num {
  text-align: right;
  white-space: nowrap;
}
/* Same pad as the period header so the partner_code column aligns
   horizontally with the period label above it. */
.budget-income-period-group .budget-txn-table td {
  padding-left: 8px;
  padding-right: 8px;
}
.budget-income-period-header:hover {
  background: var(--surface, #f3f4f6);
}
.budget-income-period-label {
  font-weight: 600;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}
.budget-income-period-subtotal {
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  color: var(--text);
}
.budget-income-period-count {
  color: var(--text-muted);
  font-weight: 500;
  font-size: 11px;
  margin-left: 6px;
}
/* Month tag inside an expanded quarterly accrual group — shows the
   specific month_end for monthly-cadence funds so the user can see
   "Apr / May / Jun" inside their Q2 group when expanded. */
.budget-income-month-tag {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 5px;
  font-size: 10px;
  letter-spacing: 0.04em;
  background: var(--surface-muted, #f3f4f6);
  color: var(--text-muted);
  border-radius: 3px;
  white-space: nowrap;
}
/* R1.10b Phase 3: trust dot + variance % rendered in the Var column for
   income fund rows. Color encodes variance_class (DATA/FORMULA → red,
   TIMING → amber, ROUNDING → green, UNRESOLVED → gray). The dot surfaces
   reconciliation gaps at-a-glance; hover tooltip shows the full
   system-vs-fund-admin breakdown. */
.income-trust-dot {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  flex-shrink: 0;
  vertical-align: middle;
}
/* Table-level trust signal (post-2026-05-20 redesign): three states for
   the currently-displayed budget year. Detail lives in the drawer; the
   table cell carries only the gate signal. */
.income-trust-dot.income-trust-state-reconciled { background: #22c55e; }
.income-trust-dot.income-trust-state-open       { background: #ef4444; }
.income-trust-dot.income-trust-state-notyet     { background: #9ca3af; }
.income-trust-dot.income-trust-state-loading    { background: #d1d5db; }

/* Drawer-card severity dots: <span class="income-trust-dot income-trust-DATA">
   etc. inside recon cards. Backgrounds applied directly on the outer span
   so empty spans still render a colored circle. */
.income-trust-dot.income-trust-DATA,
.income-trust-dot.income-trust-FORMULA   { background: #ef4444; }
.income-trust-dot.income-trust-STRUCTURAL{ background: #991b1b; }
.income-trust-dot.income-trust-TIMING    { background: #f59e0b; }
.income-trust-dot.income-trust-ROUNDING  { background: #22c55e; }
.income-trust-dot.income-trust-UNRESOLVED{ background: #9ca3af; }
.income-trust-dot.income-trust-UNVERIFIED{ background: #9ca3af; }

/* Text-color modifiers (kept for severity labeling on non-dot elements
   like the delta values inside recon cards). */
.income-trust-DATA, .income-trust-FORMULA { color: #b91c1c; font-weight: 600; }
.income-trust-TIMING { color: #b45309; font-weight: 500; }
.income-trust-ROUNDING { color: #15803d; }
.income-trust-UNRESOLVED { color: var(--text-muted); }
.income-trust-UNVERIFIED { color: var(--text-muted); font-style: italic; }

/* Phase 4: Reconciliation panel inside the income drawer.
   Field-by-field comparison: system value vs fund-admin value, variance,
   class. Sorted worst-class-first so DGV III's $280M signal is at the top. */
.budget-income-recon-section { margin-top: 14px; }
.budget-income-recon-cards {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.budget-income-recon-card {
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 10px 12px;
  background: var(--surface, #fff);
}
.budget-income-recon-card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 4px;
}
.budget-income-recon-card-title {
  display: flex;
  align-items: center;
  gap: 6px;
  font-weight: 600;
  color: var(--text);
  font-size: 13px;
  flex: 1;
  min-width: 0;
}
.budget-income-recon-field-name { word-break: break-word; }
.income-recon-class-badge {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  padding: 2px 7px;
  border-radius: 3px;
  background: var(--surface-muted, #f3f4f6);
  flex-shrink: 0;
}
.income-recon-class-badge.income-trust-DATA,
.income-recon-class-badge.income-trust-FORMULA {
  background: #fee2e2;
  color: #b91c1c;
}
.income-recon-class-badge.income-trust-TIMING {
  background: #fef3c7;
  color: #b45309;
}
.income-recon-class-badge.income-trust-ROUNDING {
  background: #dcfce7;
  color: #15803d;
}
.income-recon-class-badge.income-trust-UNRESOLVED {
  background: #f3f4f6;
  /* Hardcoded #6b7280 — bead yivu: var(--text-muted) resolves to #9ca3af
     (2.31:1, fails WCAG AA 4.5:1). #6b7280 on #f3f4f6 is 4.83:1. */
  color: #6b7280;
}

/* Source-of-truth meta block in the recon drawer. Renders between the
   panel header and the first cluster of recon cards. Reuses the same
   color palette as income-recon-class-badge (ROUNDING green / TIMING
   amber / UNRESOLVED gray) so visual grammar stays consistent. */
.budget-income-recon-meta {
  border-left: 3px solid var(--border-muted, #e5e7eb);
  background: var(--surface-muted, #f9fafb);
  padding: 10px 12px;
  margin-bottom: 12px;
  border-radius: 0 4px 4px 0;
}
.budget-income-recon-meta-row {
  display: flex;
  align-items: baseline;
  gap: 8px;
  flex-wrap: wrap;
  font-size: 12px;
  color: var(--text-secondary, #4b5563);
  line-height: 1.5;
}
.recon-meta-label {
  font-weight: 600;
  color: var(--text-primary, #111827);
  flex-shrink: 0;
}
.recon-meta-source { flex: 1; min-width: 0; }
.recon-meta-source code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 11px;
  background: rgba(0, 0, 0, 0.04);
  padding: 1px 4px;
  border-radius: 3px;
}
.recon-methodology-badge {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  padding: 2px 7px;
  border-radius: 3px;
  flex-shrink: 0;
}
.recon-methodology-independent {
  background: #dcfce7;
  color: #15803d;
}
.recon-methodology-hybrid {
  background: #fef3c7;
  color: #b45309;
}
.recon-methodology-unavailable,
.recon-methodology-loading {
  background: #f3f4f6;
  /* Hardcoded #6b7280 (not var(--text-muted), which resolves to #9ca3af
     at 2.31:1 on #f3f4f6 — fails WCAG 4.5:1). 4.83:1 here. */
  color: #6b7280;
}

/* R3a closure (bead z3i9): NAV variance row + MoM warning. Color grammar
   mirrors income-recon-class-badge — STRUCTURAL is the most severe (real
   data gap or systematic problem), DATA is recoverable variance, TIMING /
   ROUNDING are positive trust signals. */
.nav-variance-row .recon-meta-label { flex-shrink: 0; }
.nav-variance-badge {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  padding: 2px 7px;
  border-radius: 3px;
  flex-shrink: 0;
  white-space: nowrap;
  cursor: help;
}
.nav-variance-STRUCTURAL {
  background: #fee2e2;
  color: #991b1b;  /* 5.91:1 on #fee2e2 — WCAG 4.5:1 AA */
}
.nav-variance-DATA {
  background: #fef3c7;
  color: #92400e;  /* 5.45:1 on #fef3c7 */
}
.nav-variance-TIMING {
  background: #dbeafe;
  color: #1e40af;  /* 6.78:1 on #dbeafe */
}
.nav-variance-ROUNDING {
  background: #dcfce7;
  color: #15803d;  /* 4.59:1 on #dcfce7 */
}
.nav-variance-UNRESOLVED {
  background: #f3f4f6;
  color: #4b5563;  /* 7.5:1 on #f3f4f6 */
}
.nav-variance-period {
  font-size: 11px;
  color: var(--text-secondary, #6b7280);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  flex-shrink: 0;
}
.nav-mom-pill {
  font-size: 11px;
  font-weight: 600;
  padding: 2px 7px;
  border-radius: 3px;
  background: #f3f4f6;
  color: #4b5563;  /* 7.5:1 on #f3f4f6 */
  flex-shrink: 0;
  white-space: nowrap;
  cursor: help;
}
.nav-mom-warn {
  background: #fef3c7;
  color: #92400e;  /* 5.45:1 on #fef3c7 — matches DATA badge */
  font-weight: 700;
}
@media (max-width: 600px) {
  .nav-variance-badge,
  .nav-mom-pill { font-size: 10px; }
}
/* Basis-anchor date next to the fee-calc basis amount. Renders OUTSIDE
   the bold/link span as muted secondary metadata so it reads as context,
   not as part of the clickable number. */
.feecalc-basis-asof {
  font-weight: 400;
  font-size: 11px;
  color: #6b7280;  /* 4.83:1 on var(--surface-muted) #f9fafb (formula background) */
  font-family: var(--font-sans);
  margin-left: 4px;
  white-space: nowrap;
}
.budget-income-recon-meta-caveats {
  margin-top: 8px;
  font-size: 12px;
}
.budget-income-recon-meta-caveats > summary {
  cursor: pointer;
  color: var(--text-secondary, #4b5563);
  font-size: 11px;
  padding: 2px 0;
}
.budget-income-recon-meta-caveats > summary:hover,
.budget-income-recon-meta-caveats > summary:focus-visible {
  color: var(--text-primary, #111827);
}
.budget-income-recon-meta-caveats ul {
  margin: 6px 0 0;
  padding-left: 18px;
  color: var(--text-secondary, #4b5563);
  font-size: 11px;
  line-height: 1.5;
}
.budget-income-recon-meta-caveats li { margin-bottom: 4px; }
.budget-income-recon-meta-caveats strong {
  color: var(--text-primary, #111827);
  font-weight: 600;
}
@media (max-width: 600px) {
  .budget-income-recon-meta { padding: 8px 10px; }
  .budget-income-recon-meta-row { font-size: 11px; }
  /* Bump summary tap target to ≥44px to meet WCAG 2.5.5 on touch. */
  .budget-income-recon-meta-caveats > summary {
    padding: 12px 0;
    min-height: 44px;
    display: inline-flex;
    align-items: center;
  }
}
.budget-income-recon-explain {
  font-size: 11px;
  color: var(--text-secondary);
  line-height: 1.4;
  margin-bottom: 8px;
}
.budget-income-recon-values {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 2px 12px;
  margin: 0;
  font-size: 12px;
}
.budget-income-recon-values dt {
  color: var(--text-muted);
  font-weight: 500;
}
.budget-income-recon-values dd {
  margin: 0;
  text-align: right;
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
  color: var(--text);
}
.budget-income-recon-values dd.income-recon-delta {
  font-weight: 700;
}
.budget-income-recon-block {
  margin: 8px 0;
  padding: 6px 8px;
  background: var(--surface-muted, #f9fafb);
  border-radius: 4px;
}
.budget-income-recon-block-label {
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-secondary);
  margin-bottom: 2px;
}
.budget-income-recon-block-body {
  font-size: 12px;
  color: var(--text);
  line-height: 1.45;
}
.budget-income-recon-doc-ref {
  margin-top: 4px;
  font-size: 11px;
  color: var(--text-muted);
  font-style: italic;
  word-break: break-word;
}
.budget-income-recon-doc-ref a {
  color: var(--accent, #2563eb);
  text-decoration: underline;
  text-decoration-style: dotted;
  text-underline-offset: 2px;
}
.budget-income-recon-doc-ref a:hover {
  text-decoration-style: solid;
}
/* Bead dg-integration-service-6ai7 — basis-traceability breadcrumb block.
   Renders on mgmt_fee_charged recon cards inside the budget drawer's
   Reconciliation panel. Amount + provenance badge on the headline; effective
   range + computation note + Drive link stacked below. */
.budget-income-recon-basis-headline {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}
.budget-income-recon-basis-amount {
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  color: var(--text);
}
.basis-source-badge {
  display: inline-block;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  padding: 2px 7px;
  border-radius: 3px;
  white-space: nowrap;
  background: var(--surface-muted, #f3f4f6);
  color: var(--text-secondary);
}
/* "Derived" — system computes the basis independently. Strong trust signal. */
.basis-source-badge.basis-source-derived {
  background: #dcfce7;
  color: #15803d;
}
/* "Snapshot" — value sourced from a manual import. Neutral. */
.basis-source-badge.basis-source-snapshot {
  background: #dbeafe;
  color: #1e40af;
}
/* "Back-solved" — derived from the fund-admin output we're reconciling
   against, i.e. circular. Warn the user via a warm tone. */
.basis-source-badge.basis-source-backsolve {
  background: #ffedd5;
  color: #9a3412;
}
.basis-source-badge.basis-source-unknown {
  background: #f3f4f6;
  color: var(--text-muted);
}
/* Bead dg-integration-service-uq0w — drillable basis amount + inline
   per-position breakdown. Reset button-default styles so the affordance
   reads like the static amount; underline-on-hover signals it's clickable.
   When open, the underline becomes solid + an indicator chevron rotates. */
.budget-income-recon-basis-amount-drillable {
  background: transparent;
  border: none;
  padding: 0;
  margin: 0;
  font: inherit;
  color: inherit;
  cursor: pointer;
  text-decoration: underline;
  text-decoration-style: dotted;
  text-decoration-color: var(--text-muted);
  text-underline-offset: 3px;
}
.budget-income-recon-basis-amount-drillable:hover,
.budget-income-recon-basis-amount-drillable:focus-visible {
  text-decoration-style: solid;
  text-decoration-color: var(--accent, #2563eb);
}
.budget-income-recon-basis-amount-drillable.basis-amount-open {
  text-decoration-style: solid;
  text-decoration-color: var(--accent, #2563eb);
}
.budget-income-recon-basis-breakdown {
  margin-top: 10px;
  padding: 8px;
  background: #ffffff;
  border: 1px solid var(--border, #e5e7eb);
  border-radius: 4px;
}
.basis-breakdown-loading,
.basis-breakdown-empty,
.basis-breakdown-error {
  font-size: 11px;
  color: var(--text-secondary);
  padding: 4px 2px;
}
.basis-breakdown-error { color: #b91c1c; }
.basis-breakdown-summary {
  font-size: 11px;
  color: var(--text-secondary);
  margin-bottom: 6px;
  font-style: italic;
}
.basis-breakdown-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 11px;
}
.basis-breakdown-table th {
  text-align: left;
  font-weight: 700;
  font-size: 10px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-muted);
  padding: 4px 6px;
  border-bottom: 1px solid var(--border, #e5e7eb);
}
.basis-breakdown-table th.basis-pos-num { text-align: right; }
.basis-breakdown-table th.basis-pos-doc-cell { width: 28px; text-align: center; }
.basis-pos-row td {
  padding: 4px 6px;
  border-bottom: 1px solid var(--surface-muted, #f3f4f6);
  vertical-align: top;
}
.basis-pos-row--ineligible td { color: var(--text-muted); }
.basis-pos-name { word-break: break-word; }
.basis-pos-date,
.basis-pos-num {
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.basis-pos-num { text-align: right; font-weight: 600; }
.basis-pos-row--ineligible .basis-pos-num { font-weight: 400; }
.basis-pos-doc-cell { text-align: center; width: 28px; }
.basis-pos-doc {
  color: var(--accent, #2563eb);
  text-decoration: none;
  font-weight: 700;
}
.basis-pos-doc:hover { text-decoration: underline; }
.basis-pos-doc-empty { color: var(--text-muted); }
.basis-pos-status {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 5px;
  font-size: 9px;
  font-weight: 700;
  text-transform: uppercase;
  background: #fef3c7;
  color: #b45309;
  border-radius: 2px;
}
.basis-pos-row-separator td {
  padding: 8px 6px 4px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-muted);
  border-bottom: 1px solid var(--border, #e5e7eb);
  background: transparent;
}
/* Mobile: collapse the table to stacked per-position cards so the drawer
   stays readable below ~600px viewport. */
@media (max-width: 600px) {
  .basis-breakdown-table,
  .basis-breakdown-table thead,
  .basis-breakdown-table tbody,
  .basis-breakdown-table tr,
  .basis-breakdown-table td {
    display: block;
    width: 100%;
  }
  .basis-breakdown-table thead { display: none; }
  .basis-pos-row {
    border-bottom: 1px solid var(--border, #e5e7eb);
    padding: 6px 0;
  }
  .basis-pos-row td {
    border: none;
    padding: 1px 0;
  }
  .basis-pos-num::before { content: 'Contributing: '; color: var(--text-muted); font-weight: 400; }
  .basis-pos-date::before { content: 'Wire: '; color: var(--text-muted); font-weight: 400; }
  .basis-pos-doc-cell { text-align: left; }
}
/* Migration 361: per-wire applies_to_period chip + partial-settlement chip.
   Inline tags next to the counterparty memo so users see which fee period
   each wire actually settles (Q2 paid in advance, Q1 settled, etc.). */
.budget-income-period-chip {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 6px;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  background: #dbeafe;
  color: #1e40af;
  border-radius: 3px;
  white-space: nowrap;
}
/* qvdw / mig 740 — non-period sentinel chip. Slate accent so it reads as
   "this wire is deliberately excluded" instead of a normal period label. */
.budget-income-period-chip-na {
  background: #e2e8f0;
  color: #475569;
}
/* oau2.3 — period override affordances */
.budget-income-wire-row[data-record-id] { cursor: pointer; }
.budget-income-wire-row[data-record-id]:hover { background: #f1f5f9; }
.budget-income-wire-row.is-overridden { background: #ecfdf5; }
.budget-income-edited-chip {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 6px;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  background: #d1fae5;
  color: #065f46;
  border-radius: 3px;
  white-space: nowrap;
}
.budget-period-editor {
  position: fixed;
  inset: 0;
  z-index: 70;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(15, 23, 42, 0.35);
}
.budget-period-editor-card {
  background: #fff;
  border-radius: 8px;
  box-shadow: 0 10px 40px rgba(15, 23, 42, 0.3);
  padding: 18px 20px;
  width: 340px;
  max-width: calc(100vw - 32px);
  font-size: 13px;
}
.budget-period-editor-title { font-weight: 700; margin-bottom: 12px; color: #0f172a; }
.budget-period-editor-row { display: flex; flex-direction: column; gap: 4px; margin-bottom: 12px; font-weight: 600; color: #334155; }
.budget-period-editor-row select,
.budget-period-editor-row input { font-size: 13px; padding: 6px 8px; border: 1px solid #cbd5e1; border-radius: 5px; font-weight: 400; }
.budget-period-editor-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 4px; }
.budget-period-editor-actions button { font-size: 13px; padding: 6px 14px; border-radius: 5px; border: 1px solid #cbd5e1; background: #f8fafc; cursor: pointer; }
.budget-period-editor-save { background: #2563eb !important; color: #fff; border-color: #2563eb !important; }
.budget-period-editor-save:disabled { background: #93c5fd !important; border-color: #93c5fd !important; cursor: not-allowed; }
.budget-period-editor-remove { color: #b91c1c; }
.budget-period-editor-err { color: #b91c1c; margin-top: 8px; font-size: 12px; }
.budget-income-partial-chip {
  display: inline-block;
  margin-left: 4px;
  padding: 1px 6px;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  background: #fef3c7;
  color: #92400e;
  border-radius: 3px;
  white-space: nowrap;
}
/* Stacked gross/net amount in income table cells. Gross is the audit-grade
   primary value (matches the Securitize-approved fee schedule the drawer
   reconciles to); net sits below as a "what FO has to spend" comparison.
   Right-aligned within the cell to match other numeric column behavior. */
.income-amt-gross {
  font-weight: inherit;
  line-height: 1.15;
}
.income-amt-net {
  font-size: 11px;
  font-weight: 400;
  color: var(--text-muted);
  line-height: 1.15;
  margin-top: 1px;
}

.income-loading .budget-col-name {
  color: var(--text-muted);
  font-style: italic;
  font-weight: 500;
}
.income-loading-label { font-size: 11px; }
.income-loading-spinner {
  display: inline-block;
  font-weight: 700;
  letter-spacing: 1px;
  color: var(--text-secondary);
  animation: incomeLoadingPulse 1.4s ease-in-out infinite;
}
@keyframes incomeLoadingPulse {
  0%, 100% { opacity: 0.3; }
  50% { opacity: 1; }
}
.budget-income-advance-note {
  margin: 8px 0 0;
  padding: 8px 10px;
  font-size: 12px;
  color: var(--text-secondary);
  background: var(--surface-muted, #f9fafb);
  border-left: 3px solid #2b7bba;
  border-radius: 0 4px 4px 0;
  line-height: 1.45;
}
/* R1.10b: Prepaid / Payable balance badge. Surfaces the gap between
   Received and Accrued as a balance-sheet concept (asset or liability)
   that mirrors the audited AFS line items. Color coded: green for
   prepaid (the fund's asset side), amber for payable (the fund's
   liability side). Cursor:help to invite the tooltip with ASC 946
   framing. */
.budget-income-balance-badge {
  display: inline-flex;
  align-items: baseline;
  gap: 8px;
  margin: 8px 0 0;
  padding: 6px 12px;
  border-radius: 6px;
  font-size: 12px;
  cursor: help;
  border: 1px solid transparent;
}
.budget-income-balance-badge.is-prepaid {
  background: #dcfce7;
  border-color: #bbf7d0;
  color: #15803d;
}
.budget-income-balance-badge.is-payable {
  background: #fef3c7;
  border-color: #fde68a;
  color: #92400e;
}
/* "Catch-up received" badge — wires the BE parser tied to a period
   OUTSIDE the receiving quarter (prior-period catch-up, rarely
   future-advance). Pays down a liability or pre-pays forward, not
   the current quarter's prepayment. Slate-neutral — informational
   about composition, not a credit/debit signal. */
.budget-income-balance-badge.is-catchup {
  background: #f1f5f9;
  border-color: #cbd5e1;
  color: #334155;          /* slate-700 on slate-50 → 9.7:1 AAA */
  margin-left: 8px;
}
/* FundGroup parent row in the income hierarchy (bead 4mb9 + ywcy polish).
   The parent sits at sub-bucket-row level (same as flat single-vehicle
   funds like DGV / DGV II / DGV T2). When a FundGroup expands, its feeders
   render at .income-fund-group-nested (activity-row level) — one step
   deeper visually — so the parent-child hierarchy reads correctly. */
.income-fund-group-row .income-fund-group-name { font-weight: 700; }

/* Rich hover tooltip on FundGroup parent rows — replaces the native
   browser title= tooltip, which clips multi-line content unpredictably.
   The tooltip element is an absolutely-positioned child of the row, so
   it's out of the grid's normal flow and doesn't disturb column layout.
   The parent row gets `position: relative` so this anchors correctly. */
.income-fund-group-row { position: relative; }
.income-fund-group-row .budget-nav-tooltip {
  position: absolute;
  top: 100%;
  left: 16px;
  z-index: 1000;
  display: none;
  min-width: 280px;
  max-width: 360px;
  padding: 10px 14px;
  background: #1f2937;
  color: #f3f4f6;
  border-radius: 6px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.25);
  font-size: 12px;
  line-height: 1.45;
  pointer-events: none;
  white-space: normal;
}
.income-fund-group-row:hover .budget-nav-tooltip { display: block; }
.budget-nav-tooltip-title {
  font-weight: 600;
  font-size: 12px;
  margin-bottom: 2px;
  color: #f9fafb;
}
.budget-nav-tooltip-sub {
  font-size: 10px;
  color: #9ca3af;
  margin-bottom: 8px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.budget-nav-tooltip-row {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  padding: 3px 0;
}
.budget-nav-tooltip-row.budget-nav-tooltip-total {
  border-top: 1px solid #374151;
  margin-top: 6px;
  padding-top: 6px;
  font-weight: 600;
}
.budget-nav-tooltip-label { color: #9ca3af; }
.budget-nav-tooltip-value {
  color: #f3f4f6;
  font-variant-numeric: tabular-nums;
  text-align: right;
}
.budget-nav-tooltip-row.is-side-pocket .budget-nav-tooltip-value { color: #fbbf24; }
.budget-nav-tooltip-pocket {
  display: inline-block;
  margin-left: 6px;
  font-size: 10px;
  padding: 1px 6px;
  border-radius: 3px;
  background: #78350f;
  color: #fde68a;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.budget-nav-tooltip-meta {
  margin-top: 4px;
  font-size: 10px;
  color: #9ca3af;
}

/* Feeder rows nested under a FundGroup parent. Matches the expense
   activity-row visual treatment (level 2): lighter weight, slightly
   smaller min-height than the .budget-child-row default the parent uses.
   Numbers go to --text-secondary so the rolled-up parent's full-strength
   numbers stand out. Indent is bumped to budget-indent-2 (in JS), so the
   nesting is also clear horizontally. */
.income-row.income-fund-group-nested {
  font-weight: 400;
  min-height: 34px;
}
.income-row.income-fund-group-nested .budget-col-num {
  font-weight: 400;
  color: var(--text-secondary);
}

/* "Needs annotation" badge — wires the BE parser couldn't attribute
   (description had no period hint). This is a finance-team action
   queue, not a calc error — different framing on purpose. Light
   amber-grey to nudge "look at this" without alarming. */
.budget-income-balance-badge.is-unattributed {
  background: #fef9c3;     /* yellow-100 */
  border-color: #fde047;   /* yellow-300 */
  border-left: 3px solid #ca8a04;  /* yellow-600 emphasis */
  color: #713f12;          /* yellow-900 on yellow-100 → 8.1:1 AAA */
  margin-left: 8px;
}

/* Wire-row duplicate detector (expenses_tool-162l). Subtle amber tint on
   any wire row whose (date, amount, counterparty) tuple appears more than
   once in the section — the likely-duplicate signal. Doesn't change totals;
   surfaces the smell so a reviewer can route to the bead. */
.budget-income-dup-row { background: #fffbeb; }
/* Section-level inflation banner — names the aggregate $ the section
   subtotal above is over-stated by. Stronger than the per-row chips so a
   reviewer sees the total impact, not just the smell. Amber but more
   prominent than the row tint. */
.budget-income-dup-banner {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  margin: 0 0 8px;
  padding: 8px 12px;
  background: #fef3c7;
  border: 1px solid #fcd34d;
  border-left: 3px solid #b45309;
  border-radius: 6px;
  color: #92400e;          /* amber-800 on amber-100 → 6.4:1 AA */
  font-size: 12px;
  line-height: 1.4;
  cursor: help;
}
.budget-income-dup-banner-icon { font-size: 14px; flex-shrink: 0; }
.budget-income-dup-banner-text strong { color: #7c2d12; font-weight: 600; }

/* zj78: tiny neutral footnote shown when client-side sweep-leg collapse
   hides duplicate atoms from the wire list so the displayed rows
   reconcile to the BE-deduped YTD Received tile. Not an alarm — a
   "we already handled this" disclosure. Distinct from .dup-banner
   (red/amber alarm for true non-sweep duplicates). #4b5563 = slate-600,
   meets WCAG 4.5:1 on the default light surface. */
.budget-income-sweep-note {
  margin: 4px 0 6px;
  font-size: 11px;
  font-style: italic;
  color: #4b5563;
  cursor: help;
}
.budget-income-dup-chip {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 6px;
  font-size: 10px;
  font-weight: 600;
  color: #92400e;          /* amber-800 on amber-50 → 7.7:1 AAA */
  background: #fef3c7;
  border: 1px solid #fde68a;
  border-radius: 4px;
  cursor: help;
  letter-spacing: 0.02em;
  text-transform: lowercase;
  vertical-align: middle;
}
.budget-income-balance-label {
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  font-size: 10px;
}
.budget-income-balance-value {
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  font-size: 14px;
}

/* R3a closure (2026-05-26): forward EOY forecast section in the income
   drawer. Triple-cell layout mirrors .budget-income-summary so the visual
   grammar carries — Expected/YTD/Received above, Forecast/Landing/Variance
   below. The variance cell tints green/amber/red based on |variance pct|
   so Danielle can scan to the trust signal first. */
.budget-income-forecast {
  margin: 12px 0 0;
  padding: 10px 12px;
  border: 1px solid var(--border-muted, #e5e7eb);
  border-radius: 6px;
  background: var(--surface-muted, #f9fafb);
}
.budget-income-forecast-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 6px;
}
.budget-income-forecast-title {
  font-weight: 700;
  font-size: 12px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-primary, #111827);
}
.budget-income-forecast-subtitle {
  font-size: 11px;
  color: var(--text-secondary, #4b5563);
  font-family: var(--mono);
}
.budget-income-forecast-body {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
  align-items: stretch;
}
.budget-income-forecast-cell {
  padding: 8px;
  border-radius: 4px;
  background: #fff;
  border: 1px solid var(--border-muted, #e5e7eb);
  text-align: center;
}
.budget-income-forecast-value {
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  font-size: 16px;
  color: var(--text-primary, #111827);
}
.budget-income-forecast-label {
  font-size: 10px;
  color: var(--text-secondary, #4b5563);
  margin-top: 4px;
  line-height: 1.3;
}
.budget-income-forecast-label-sub {
  font-size: 9px;
  color: var(--text-muted, #6b7280);  /* 4.83:1 on #fff */
}
.budget-income-forecast-cell.forecast-on-track {
  background: #f0fdf4;
  border-color: #bbf7d0;
}
.budget-income-forecast-cell.forecast-on-track .budget-income-forecast-value {
  color: #15803d;  /* 4.59:1 on #f0fdf4 */
}
.budget-income-forecast-cell.forecast-watch {
  background: #fefce8;
  border-color: #fde68a;
}
.budget-income-forecast-cell.forecast-watch .budget-income-forecast-value {
  color: #92400e;  /* 5.45:1 on #fefce8 */
}
.budget-income-forecast-cell.forecast-off {
  background: #fef2f2;
  border-color: #fecaca;
}
.budget-income-forecast-cell.forecast-off .budget-income-forecast-value {
  color: #991b1b;  /* 6.05:1 on #fef2f2 */
}
.budget-income-forecast-basis {
  font-size: 11px;
  color: var(--text-secondary, #4b5563);
  margin-top: 8px;
}
.budget-income-forecast-basis code {
  font-family: var(--mono);
  font-size: 11px;
  background: rgba(0, 0, 0, 0.04);
  padding: 1px 4px;
  border-radius: 3px;
}
.budget-income-forecast-periods {
  margin-top: 6px;
  font-size: 11px;
}
.budget-income-forecast-periods > summary {
  cursor: pointer;
  color: var(--text-secondary, #4b5563);
  padding: 2px 0;
}
.budget-income-forecast-periods > summary:hover { color: var(--text-primary, #111827); }
.budget-income-forecast-periods-table {
  width: 100%;
  margin-top: 6px;
  border-collapse: collapse;
  font-family: var(--mono);
  font-size: 11px;
}
.budget-income-forecast-periods-table th,
.budget-income-forecast-periods-table td {
  padding: 4px 6px;
  border-bottom: 1px solid var(--border-muted, #e5e7eb);
}
.budget-income-forecast-periods-table th {
  text-align: left;
  font-weight: 600;
  color: var(--text-secondary, #4b5563);
}
.budget-income-forecast-periods-table td.num,
.budget-income-forecast-periods-table th.num {
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.budget-income-forecast-periods-fallback {
  font-size: 11px;
  color: var(--text-secondary, #4b5563);
  margin-top: 6px;
  font-style: italic;
}
.budget-income-forecast-assumptions {
  font-size: 10px;
  color: var(--text-muted, #6b7280);
  margin-top: 6px;
  font-style: italic;
}
@media (max-width: 600px) {
  .budget-income-forecast-body {
    grid-template-columns: 1fr;
    gap: 6px;
  }
  .budget-income-forecast-value { font-size: 15px; }
  .budget-income-forecast-periods > summary {
    padding: 12px 0;
    min-height: 44px;
    display: inline-flex;
    align-items: center;
  }
}
.budget-income-recon-cluster + .budget-income-recon-cluster,
.budget-income-recon-cluster + .budget-income-recon-empty-cluster,
.budget-income-recon-empty-cluster + .budget-income-recon-cluster {
  margin-top: 14px;
}
.budget-income-recon-cluster-label {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-secondary);
  margin-bottom: 6px;
}
.budget-income-recon-cluster-empty {
  font-size: 12px;
  color: var(--text-muted);
  font-style: italic;
  padding: 8px 10px;
  border: 1px dashed var(--border);
  border-radius: 4px;
}

/* Phase 4: Fee calculation description in the drawer.
   Formula at top, supporting bullets below (basis, LPA reference,
   step-down status). Pulled from lpa_metadata + inputs in /income/hierarchy. */
.budget-income-feecalc-section { margin-top: 14px; }
.budget-income-feecalc-formula {
  font-family: var(--mono);
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
  font-variant-numeric: tabular-nums;
  background: var(--surface-muted, #f9fafb);
  padding: 8px 10px;
  border-radius: 4px;
  margin-bottom: 8px;
}
.budget-income-feecalc-bullets {
  margin: 0;
  padding-left: 18px;
  font-size: 12px;
  color: var(--text-secondary);
  line-height: 1.5;
}
.budget-income-feecalc-bullets li { margin: 2px 0; }
.budget-income-feecalc-bullets strong { color: var(--text); font-weight: 600; }
/* Bead j1oj — inline input values inside the fee-calc formula. The basis
   amount is a drill-through anchor that takes the user to the canonical
   per-LP data in the income hierarchy. */
.feecalc-input { color: var(--text); font-weight: 600; }
.feecalc-input-rate { color: var(--accent); }
.feecalc-input-ratio { color: var(--text); font-weight: 500; }
.feecalc-input-meta {
  font-weight: 400;
  font-size: 11px;
  color: var(--text-secondary);
}
.feecalc-basis-label {
  font-weight: 500;
  color: var(--text-secondary);
  font-family: var(--font-sans);
  font-size: 12px;
}
a.feecalc-drillable {
  color: var(--accent);
  text-decoration: none;
  border-bottom: 1px dotted var(--accent);
  cursor: pointer;
}
a.feecalc-drillable:hover {
  text-decoration: none;
  border-bottom-style: solid;
}
/* Bead 51cj: LPA reference link in fee-calc bullets — same affordance
   shape as the basis drill-through (dotted underline, solid on hover) so
   "click to verify in source" reads consistently across the formula. */
a.feecalc-lpa-link {
  color: var(--accent);
  text-decoration: none;
  border-bottom: 1px dotted var(--accent);
}
a.feecalc-lpa-link:hover {
  border-bottom-style: solid;
}
/* Drawer header meta line under the breadcrumb — calc method + (LP-scope)
   partner code. Mirrors the table row's accent so context flows from row
   → drawer without the user re-orienting. */
.budget-income-drawer-meta {
  margin-top: 4px;
  font-size: 12px;
  font-weight: 400;
  color: var(--text-secondary);
}
.budget-income-drawer-lp-code {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--text-muted);
  margin-left: 4px;
}
/* Override the expense-drawer vendor truncation inside the income drawer:
   wire counterparty strings are the source-system memo and contain the
   period reference (e.g., "Q1 2026 MGMT FEES DGV"). Truncating them
   loses the trust signal — let them wrap. */
.budget-income-drawer .budget-txn-table td.vendor {
  max-width: none;
  white-space: normal;
  word-break: break-word;
  line-height: 1.35;
}
/* Lock the Date column in income-drawer atom tables so the date text
   left-aligns cleanly across rows whether or not a "projected" badge is
   appended. Without this, the column auto-widens to fit the widest cell,
   which causes the Detail column to start at different positions
   depending on which rows happen to be projected. */
.budget-income-drawer .budget-txn-table th:first-child,
.budget-income-drawer .budget-txn-table td:first-child {
  width: 1%;
  white-space: nowrap;
  vertical-align: top;
}
.budget-income-drawer .budget-income-projected-tag {
  /* Keep tag from pushing line-height around — anchor to top-right of cell */
  vertical-align: middle;
  position: relative;
  top: -1px;
}
@media (max-width: 720px) {
  .budget-income-summary { flex-direction: column; gap: 6px; }
  .budget-income-summary-value { font-size: 16px; }
}

.scenario-compare {
  color: var(--accent);
  border-color: var(--accent);
}
.scenario-compare-active {
  background: var(--accent) !important;
  color: #fff !important;
  border-color: var(--accent) !important;
}
.scenario-compare-target {
  font-size: 12px;
  padding: 4px 8px;
  border-radius: 6px;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text);
}

/* Compare mode grid: name | compare | scenario | delta$ | delta% | actual | remaining | progress */
.compare-mode .budget-table-header,
.compare-mode .budget-row,
.compare-mode .budget-group-row,
.compare-mode .budget-total-row {
  grid-template-columns: 1fr 95px 95px 90px 65px 95px 95px 160px;
}
.budget-col-compare, .budget-col-scenario { font-size: 12px; }
.budget-col-delta, .budget-col-delta-pct { font-size: 12px; text-align: right; }

/* Smooth transition for column changes */
.budget-table-header, .budget-row, .budget-group-row, .budget-total-row {
  transition: grid-template-columns 0.2s ease;
}

/* Mobile compare mode: hide progress, tighten columns */
@media (max-width: 768px) {
  .compare-mode .budget-table-header,
  .compare-mode .budget-row,
  .compare-mode .budget-group-row,
  .compare-mode .budget-total-row {
    grid-template-columns: 1fr 65px 65px 60px 45px 65px 65px;
    font-size: 10px;
  }
  .compare-mode .budget-col-progress { display: none; }
  .compare-summary { padding: 8px 12px; font-size: 12px; }
}

/* ── Share Dialog (Google Docs style) ── */
.sd-overlay {
  position: fixed; inset: 0; z-index: 10000;
  background: rgba(0, 0, 0, 0.4);
  display: flex; align-items: center; justify-content: center;
}
.sd-dialog {
  background: #fff; border-radius: 8px;
  width: 100%; max-width: 512px;
  box-shadow: 0 24px 38px 3px rgba(0,0,0,0.14), 0 9px 46px 8px rgba(0,0,0,0.12), 0 11px 15px -7px rgba(0,0,0,0.2);
  color: #202124; font-family: 'DM Sans', sans-serif;
  max-height: 90vh; overflow-y: auto;
}
.sd-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 16px 24px 12px;
}
.sd-title {
  font-size: 22px; font-weight: 400; color: #202124;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  max-width: 420px;
}
.sd-close {
  background: none; border: none; cursor: pointer;
  padding: 8px; border-radius: 50%; color: #5f6368;
  display: flex; align-items: center; justify-content: center;
}
.sd-close:hover { background: #f1f3f4; }

/* Add people */
.sd-add-section { padding: 0 24px 16px; }
.sd-add-row {
  display: flex; align-items: center; gap: 8px;
  border: 1px solid #dadce0; border-radius: 8px;
  padding: 4px 12px; transition: border-color 0.15s;
}
.sd-add-row:focus-within { border-color: #1a73e8; box-shadow: 0 0 0 1px #1a73e8; }
.sd-add-input-wrap { flex: 1; position: relative; }
.sd-add-input {
  width: 100%; border: none; outline: none;
  font-size: 14px; font-family: inherit;
  padding: 8px 0; color: #202124;
  background: transparent;
}
.sd-add-input::placeholder { color: #80868b; }
.sd-add-role {
  font-size: 13px; font-family: inherit; font-weight: 500;
  color: #1a73e8; background: none;
  border: none; cursor: pointer; padding: 4px 0;
  -webkit-appearance: none; appearance: none;
}
.sd-add-role option { color: #202124; }

/* Autocomplete dropdown */
.sd-autocomplete {
  position: absolute; left: -12px; right: -12px; top: 100%;
  background: #fff; border: 1px solid #dadce0; border-radius: 8px;
  box-shadow: 0 4px 8px rgba(0,0,0,0.12);
  z-index: 10; margin-top: 4px; max-height: 200px; overflow-y: auto;
}
.sd-ac-item {
  display: flex; align-items: center; gap: 12px;
  padding: 8px 16px; cursor: pointer;
}
.sd-ac-item:hover { background: #f1f3f4; }
.sd-ac-info { min-width: 0; }
.sd-ac-name { font-size: 14px; color: #202124; font-weight: 500; }
.sd-ac-email { font-size: 12px; color: #5f6368; }

/* Section labels */
.sd-section-label {
  font-size: 13px; font-weight: 500; color: #202124;
  padding: 12px 24px 8px;
}

/* People list */
.sd-people-section { border-top: 1px solid #e8eaed; }
.sd-people-list { padding: 0 12px; }
.sd-person {
  display: flex; align-items: center; gap: 12px;
  padding: 8px 12px; border-radius: 8px;
}
.sd-person:hover { background: #f7f8f8; }
.sd-avatar {
  width: 32px; height: 32px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  color: #fff; font-size: 13px; font-weight: 500;
  flex-shrink: 0; letter-spacing: 0.3px;
}
.sd-avatar-sm { width: 28px; height: 28px; font-size: 11px; }
.sd-person-info { flex: 1; min-width: 0; }
.sd-person-name {
  font-size: 13px; font-weight: 500; color: #202124;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.sd-person-email {
  font-size: 12px; color: #5f6368;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.sd-person-role {
  font-size: 12px; font-family: inherit; color: #5f6368;
  border: none; background: none; cursor: pointer; padding: 4px 8px;
  border-radius: 4px; -webkit-appearance: none; appearance: none;
}
.sd-person-role:hover { background: #f1f3f4; }
.sd-person-role-text {
  font-size: 12px; color: #5f6368; padding: 4px 8px; white-space: nowrap;
}

/* General access */
.sd-general-section { border-top: 1px solid #e8eaed; }
.sd-general-row {
  display: flex; align-items: center; gap: 12px;
  padding: 8px 24px 12px;
}
.sd-general-icon-wrap { flex-shrink: 0; }
.sd-general-icon {
  width: 36px; height: 36px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
}
.sd-icon-restricted { background: #e8eaed; color: #5f6368; }
.sd-icon-org { background: #e8f0fe; color: #1a73e8; }
.sd-general-info { flex: 1; }
.sd-general-select {
  font-size: 13px; font-family: inherit; font-weight: 500;
  color: #202124; border: none; background: none; cursor: pointer;
  padding: 2px 0; -webkit-appearance: none; appearance: none;
}
.sd-general-desc { font-size: 12px; color: #5f6368; margin-top: 1px; }
.sd-general-role {
  font-size: 12px; font-family: inherit; color: #5f6368;
  border: none; background: none; cursor: pointer; padding: 4px;
}

/* Default setting */
.sd-default-section { border-top: 1px solid #e8eaed; padding: 12px 24px 8px; }
.sd-default-row {
  display: flex; align-items: center; gap: 10px; cursor: pointer;
  padding: 4px 0; font-size: 13px; color: #202124;
}
.sd-default-check { margin: 0; accent-color: #1a73e8; }
.sd-default-star { flex-shrink: 0; }
.sd-default-text { font-weight: 500; }
.sd-default-desc { font-size: 12px; color: #5f6368; margin: 2px 0 0 28px; }

/* Footer */
.sd-footer {
  display: flex; align-items: center; justify-content: space-between;
  padding: 12px 16px 16px 24px;
}
.sd-copy-link {
  display: flex; align-items: center; gap: 8px;
  background: none; border: none; cursor: pointer;
  color: #1a73e8; font-size: 14px; font-weight: 500; font-family: inherit;
  padding: 8px 12px; border-radius: 4px;
}
.sd-copy-link:hover { background: #e8f0fe; }
.sd-done {
  background: #1a73e8; color: #fff; border: none;
  font-size: 14px; font-weight: 500; font-family: inherit;
  padding: 8px 24px; border-radius: 4px; cursor: pointer;
  letter-spacing: 0.2px;
}
.sd-done:hover { background: #1765cc; box-shadow: 0 1px 3px rgba(0,0,0,0.2); }

/* Mobile */
@media (max-width: 560px) {
  .sd-dialog { max-width: 100%; margin: 8px; border-radius: 12px; }
  .sd-title { font-size: 18px; }
}

/* Budget search + sort */
/* Bead 3are — Eren 2026-05-08: search-bar border was --border (#e2e5ea, ~1.2:1
   against the page surface), reading as no border at all on most monitors.
   Bumped to --text-muted (#9ca3af, 3.6:1) so the input is clearly delineated.
   Bottom padding raised from 4px to 12px so the input doesn't sit flush
   against the row beneath it. */
.budget-search-wrap { padding: 8px 20px 12px; background: var(--surface); }
.budget-search {
  width: 100%; max-width: 300px;
  padding: 6px 12px; font-size: 13px; font-family: var(--font);
  border: 1px solid var(--text-muted); border-radius: 6px;
  background: var(--bg); color: var(--text);
  outline: none;
}
.budget-search:focus { border-color: var(--accent); box-shadow: 0 0 0 2px rgba(43,123,186,0.15); }

/* Story 9 (R2c) — Unreconciled view chip.
   Reads as an amber "queue" affordance distinct from the search input + the
   blue expand buttons. Cursor:pointer + clear hover state so users see it as
   actionable. Hidden until count > 0 (handled in budget.js). Min height
   matches Eren's mobile-first sizing guidance (>=32px touch target). */
.budget-needs-review-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  min-height: 32px;
  background: #fef3c7;            /* amber-100 — same family as ?-badge in table */
  color: #92400e;                 /* amber-800 — 7.7:1 on amber-100, AAA */
  border: 1px solid #f59e0b;      /* amber-500 — visible boundary */
  border-radius: 16px;            /* pill shape, distinct from buttons */
  font-family: var(--font);
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
  transition: background 0.15s ease, box-shadow 0.15s ease;
}
.budget-needs-review-chip:hover {
  background: #fde68a;            /* amber-200 — clear hover lift */
  box-shadow: 0 1px 3px rgba(146, 64, 14, 0.18);
}
.budget-needs-review-chip:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.budget-needs-review-chip-dot {
  color: #d97706;                 /* amber-600 — dot pops a touch more than text */
  font-size: 10px;
  line-height: 1;
}
.budget-needs-review-chip-text {
  line-height: 1;
}

/* Story 9 breadcrumb context — the parenthetical "(Needs Review queue · 2025)"
   sits inside the same back-button as the drill breadcrumb but is visually
   subordinate so the back-action stays the dominant affordance. */
.table-back-btn .table-back-context {
  color: var(--text-secondary);
  font-weight: 500;
  margin-left: 4px;
}
.budget-search::placeholder { color: var(--text-muted); }
.budget-expand-controls { display: flex; gap: 6px; }
.budget-expand-btn {
  font-size: 11px; font-family: var(--font); font-weight: 500;
  padding: 4px 10px; border: 1px solid var(--border); border-radius: 4px;
  background: var(--surface); color: var(--text-secondary); cursor: pointer;
}
.budget-expand-btn:hover { background: var(--hover); color: var(--text); }
.budget-search-wrap { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
/* Story 9 (R2c) — chip must remain in-viewport on mobile. flex-wrap above lets
   the row reflow when the search input (max 300px) + expand controls + chip
   don't fit a single row at 390px. On narrow widths the chip drops to a
   second line; max-width keeps it from forcing horizontal scroll. */
@media (max-width: 720px) {
  .budget-needs-review-chip {
    max-width: 100%;
    flex-shrink: 1;
  }
  .budget-needs-review-chip-text {
    white-space: normal;
    overflow: hidden;
    text-overflow: ellipsis;
  }
}
.budget-empty-results {
  padding: 32px 20px; text-align: center;
  color: var(--text-secondary); font-family: var(--font);
}
.budget-empty-results-title { font-size: 14px; font-weight: 600; color: var(--text); margin-bottom: 4px; }
.budget-empty-results-hint { font-size: 12px; color: var(--text-muted); }
.budget-sortable { cursor: pointer; user-select: none; }
.budget-sortable:hover { color: var(--text); background: rgba(0,0,0,0.04); }
.budget-sort-arrow { font-size: 9px; color: var(--accent); margin-left: 2px; }

/* ── Health Banner ── */
.health-banner {
  position: sticky; top: 0; z-index: 9999;
  padding: 0; font-family: var(--font);
}
.health-banner-content {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 20px;
}
.health-banner-icon { font-size: 16px; flex-shrink: 0; }
.health-banner-text { flex: 1; font-size: 13px; font-weight: 500; }
.health-banner-dismiss {
  background: none; border: none; cursor: pointer;
  font-size: 14px; opacity: 0.6; padding: 4px;
}
.health-banner-dismiss:hover { opacity: 1; }

/* ── Test-Mode Banner ── */
/* --test-banner-height is set dynamically in api-budget.js after the banner
   renders (font rendering varies; we measure to avoid drift). 42px is the
   fallback for the brief window before JS sets it. */
body.has-test-mode-banner { --test-banner-height: 42px; }
/* Right-side fixed drawers anchor to top:0 normally — push them below the
   banner so their close X isn't occluded. */
body.has-test-mode-banner .budget-drawer,
body.has-test-mode-banner .budget-history-drawer,
body.has-test-mode-banner .budget-txn-drawer,
body.has-test-mode-banner .audit-panel {
  top: var(--test-banner-height);
}
.test-mode-banner {
  position: sticky; top: 0; z-index: 10000;
  display: flex; align-items: center; gap: 10px;
  padding: 8px 16px;
  background: #fef3c7;
  color: #78350f;
  border-bottom: 1px solid #fde68a;
  font-family: var(--font);
  font-size: 13px;
  font-weight: 500;
}
.test-mode-banner-dot { color: #b45309; font-size: 12px; }
.test-mode-banner-text { flex: 1; }
.test-mode-banner-reset,
.test-mode-banner-exit {
  background: #fff; border: 1px solid #fcd34d; border-radius: var(--radius);
  color: #78350f; cursor: pointer;
  font-family: var(--font); font-size: 12px; font-weight: 600;
  padding: 4px 10px;
}
.test-mode-banner-reset:hover,
.test-mode-banner-exit:hover { background: #fef3c7; border-color: #b45309; }
.test-mode-banner-reset:disabled { opacity: 0.5; cursor: wait; }
.test-mode-banner-reset { background: #fff7ed; }
@media (max-width: 600px) {
  .test-mode-banner { padding: 6px 10px; font-size: 12px; }
  .test-mode-banner-text { font-size: 12px; }
}

.health-banner-down {
  background: #fef2f2; border-bottom: 2px solid #ef4444; color: #991b1b;
}
.health-banner-warn {
  background: #fffbeb; border-bottom: 2px solid #eab308; color: #854d0e;
}

/* Full-page 'down' overlay — per HEALTH_ENDPOINT_REQUIREMENTS §In-App Error
   UX: 'down' status renders a full-page error state, not a banner, because
   the app is unusable. Sits above everything (z-index ~10001) and blocks
   interaction with the underlying view so reviewers don't try to act on
   stale data. */
.health-down-overlay {
  position: fixed; inset: 0; z-index: 10001;
  display: flex; align-items: center; justify-content: center;
  padding: 24px;
  background: rgba(15, 23, 42, 0.78);
  backdrop-filter: blur(2px);
  font-family: var(--font);
}
.health-down-card {
  max-width: 480px; width: 100%;
  padding: 28px 32px;
  background: #fff;
  border-radius: 8px;
  border-top: 4px solid #ef4444;
  box-shadow: 0 20px 40px rgba(0,0,0,0.25);
  text-align: center;
}
.health-down-icon {
  font-size: 36px; color: #ef4444; line-height: 1; margin-bottom: 8px;
}
.health-down-title {
  margin: 4px 0 12px;
  font-size: 20px; font-weight: 600; color: #111827;
}
.health-down-message {
  margin: 0 0 16px;
  font-size: 14px; line-height: 1.55; color: #374151;
}
.health-down-foot {
  margin: 0;
  font-size: 12px; color: #6b7280;
}
.health-down-foot strong { color: #374151; font-weight: 600; }

/* ═══ Interventions (beads omeq + j0ic) ═══
   Modal panel for CRUD on forecast overlays. Shares backdrop/theme with
   .budget-revert-modal — uses var() tokens so light/dark themes compose
   without touching this file. */
.budget-intervention-backdrop {
  position: fixed; inset: 0; background: rgba(0, 0, 0, 0.35); z-index: 60;
}
.budget-intervention-panel {
  position: fixed;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  width: min(720px, 94vw);
  max-height: 90vh;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: 0 10px 40px rgba(0, 0, 0, 0.2);
  z-index: 70;
  display: flex; flex-direction: column;
  overflow: hidden;
}
.budget-intervention-header {
  display: flex; align-items: center; gap: 10px;
  padding: 12px 16px; border-bottom: 1px solid var(--border);
  color: var(--text);
}
.budget-intervention-subtitle {
  font-size: 11px; color: var(--text-muted); font-weight: 400;
  flex: 1; min-width: 0;
}
.budget-intervention-close {
  background: transparent; border: none; font-size: 22px;
  color: var(--text-muted); cursor: pointer; padding: 0 4px;
}
.budget-intervention-body {
  padding: 12px 16px; overflow-y: auto; flex: 1;
}
.budget-intervention-toolbar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; margin-bottom: 10px;
}
.budget-intervention-new {
  padding: 6px 12px; border-radius: 4px;
  border: 1px solid var(--accent); color: var(--accent);
  background: var(--surface);
  font-size: 12px; font-weight: 500; cursor: pointer; min-height: 32px;
}
.budget-intervention-new:hover { background: var(--accent-light); }
.budget-intervention-preview-all {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 12px; color: var(--text); cursor: pointer;
  min-height: 32px;
}
.budget-intervention-empty {
  padding: 24px 16px; text-align: center; color: var(--text-muted);
  font-size: 13px; border: 1px dashed var(--border); border-radius: 6px;
}
.budget-intervention-error {
  padding: 8px 12px; margin-bottom: 10px;
  background: var(--color-critical-bg); color: var(--color-critical);
  border: 1px solid color-mix(in srgb, var(--color-critical) 25%, transparent);
  border-radius: 4px; font-size: 12px; line-height: 1.4;
}
.budget-intervention-table {
  width: 100%; border-collapse: collapse; font-size: 12px;
}
.budget-intervention-table th {
  text-align: left; padding: 6px 8px;
  border-bottom: 1px solid var(--border); color: var(--text-muted);
  font-weight: 500; font-size: 11px; text-transform: uppercase;
  letter-spacing: 0.03em;
}
.budget-intervention-table td {
  padding: 8px; border-bottom: 1px solid var(--border);
  color: var(--text); vertical-align: top;
}
.budget-intervention-leaf {
  font-weight: 500; max-width: 240px; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap;
}
.budget-intervention-amount {
  text-align: right; font-variant-numeric: tabular-nums;
}
.budget-intervention-note {
  color: var(--text-muted); max-width: 180px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.budget-intervention-actions {
  display: flex; gap: 4px;
}
.budget-intervention-edit,
.budget-intervention-delete {
  padding: 4px 8px; font-size: 11px; cursor: pointer;
  border: 1px solid var(--border); border-radius: 3px;
  background: var(--surface); color: var(--text);
  min-height: 28px;
}
.budget-intervention-edit:hover { background: var(--accent-light); }
.budget-intervention-delete { color: #dc2626; }
.budget-intervention-delete:hover {
  background: rgba(220, 38, 38, 0.08);
}

/* ── Form ── */
.budget-intervention-form {
  display: flex; flex-direction: column; gap: 14px;
}
.budget-intervention-form-title {
  font-size: 14px; font-weight: 600; color: var(--text);
}
.budget-intervention-field {
  display: flex; flex-direction: column; gap: 4px;
}
.budget-intervention-field > label {
  font-size: 12px; font-weight: 500; color: var(--text);
}
.budget-intervention-label-hint {
  color: var(--text-muted); font-weight: 400; font-size: 11px;
}
.budget-intervention-hint {
  font-size: 11px; color: var(--text-muted); line-height: 1.4;
}
.budget-intervention-leaf-picker {
  display: flex; flex-wrap: wrap; gap: 6px;
}
.budget-intervention-leaf-select {
  flex: 1 1 140px; min-width: 140px;
  padding: 6px 8px; border: 1px solid var(--border); border-radius: 4px;
  background: var(--surface); color: var(--text); font-size: 12px;
  min-height: 32px;
}
.budget-intervention-leaf-readonly {
  padding: 6px 10px; background: var(--bg);
  border: 1px solid var(--border); border-radius: 4px;
  font-size: 12px; color: var(--text);
}
.budget-intervention-range-row {
  display: flex; align-items: center; gap: 8px;
}
.budget-intervention-range-row select {
  padding: 6px 8px; border: 1px solid var(--border); border-radius: 4px;
  background: var(--surface); color: var(--text); font-size: 12px;
  min-height: 32px;
}
.budget-intervention-range-sep { color: var(--text-muted); }
.budget-intervention-amount-row {
  display: flex; align-items: center; gap: 4px;
}
.budget-intervention-currency {
  font-size: 13px; color: var(--text-muted); padding-right: 2px;
}
.budget-intervention-amount-input {
  flex: 1; padding: 6px 8px; border: 1px solid var(--border); border-radius: 4px;
  background: var(--surface); color: var(--text); font-size: 13px;
  min-height: 32px;
  font-variant-numeric: tabular-nums;
}
.budget-intervention-note-input {
  padding: 6px 8px; border: 1px solid var(--border); border-radius: 4px;
  background: var(--surface); color: var(--text); font-size: 12px;
  font-family: inherit; resize: vertical;
}
.budget-intervention-form-actions {
  display: flex; justify-content: flex-end; gap: 8px;
  padding-top: 8px; border-top: 1px solid var(--border);
}
.budget-intervention-cancel,
.budget-intervention-submit {
  padding: 6px 14px; border-radius: 4px; font-size: 12px;
  cursor: pointer; min-height: 32px; border: 1px solid var(--border);
}
.budget-intervention-cancel {
  background: var(--surface); color: var(--text);
}
.budget-intervention-cancel:hover { background: var(--accent-light); }
.budget-intervention-submit {
  background: var(--accent); color: #fff; border-color: var(--accent);
  font-weight: 500;
}
.budget-intervention-submit:hover:not(:disabled) { opacity: 0.9; }
.budget-intervention-submit:disabled { opacity: 0.55; cursor: not-allowed; }

/* ── AFB intervention overlay (bead j0ic) ── */
.budget-afb-overlay-toggle {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 11px; color: var(--text); cursor: pointer;
  padding: 2px 6px; min-height: 24px;
}
.budget-afb-overlay-toggle input[type="checkbox"] { cursor: pointer; }
.budget-afb-intervention-summary {
  padding: 6px 14px; font-size: 12px; color: var(--text);
  border-bottom: 1px solid var(--border);
  background: color-mix(in srgb, var(--accent-light) 60%, transparent);
}
.budget-afb-overlay-shift.pos { color: #065f46; font-weight: 600; }
.budget-afb-overlay-shift.neg { color: #991b1b; font-weight: 600; }
.budget-afb-overlay-shift.neutral { color: var(--text-muted); }

@media (max-width: 720px) {
  .budget-intervention-panel {
    width: 100vw; max-width: 100vw; border-radius: 14px 14px 0 0;
    top: auto; bottom: 0; left: 0; transform: none;
    max-height: 90vh;
  }
  .budget-intervention-table { font-size: 11px; }
  .budget-intervention-leaf { max-width: 120px; }
  .budget-intervention-note { display: none; }
}

/* ═══════════════════════════════════════════
   Bead expenses_tool-jlu1 — Rule Candidate Queue (admin page)
   Scoped under .admin-page so styles don't leak into the main app.
   ═══════════════════════════════════════════ */
/* body { overflow: hidden } above is set for the main app, which manages
   its own internal scroll containers. The admin queue page wants the
   body to scroll naturally — cards stack vertically and there's no
   inner scroll container — so we override here. Bead expenses_tool-ey3f. */
.admin-page { background: var(--surface, #f5f6f8); min-height: 100vh; overflow-y: auto; }
.admin-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 12px 24px; background: #1c1f24; color: #f5f6f8;
}
.admin-header-left { display: flex; align-items: baseline; gap: 16px; }
.admin-back {
  color: #9aa4b2; text-decoration: none; font-size: 12px;
}
.admin-back:hover { color: #f5f6f8; text-decoration: underline; }
.admin-title { font-size: 16px; font-weight: 600; margin: 0; }
.admin-header-right { display: flex; align-items: center; gap: 12px; }
.admin-user { font-size: 12px; color: #9aa4b2; }
.admin-link {
  background: none; border: none; color: #9aa4b2; cursor: pointer; font-size: 12px;
  padding: 4px 8px;
}
.admin-link:hover { color: #f5f6f8; text-decoration: underline; }

.admin-toolbar {
  display: flex; align-items: center; justify-content: space-between;
  padding: 12px 24px; background: #fff; border-bottom: 1px solid var(--border);
}
.admin-status-filter { display: flex; gap: 4px; }
.status-chip {
  border: 1px solid var(--border); background: #fff; color: var(--text-secondary);
  font-size: 12px; padding: 6px 12px; border-radius: 999px; cursor: pointer;
}
.status-chip:hover { background: var(--hover); }
.status-chip.active {
  background: var(--accent, #2563eb); border-color: var(--accent, #2563eb);
  color: #fff; font-weight: 500;
}
.admin-toolbar-right { display: flex; align-items: center; gap: 8px; }
.admin-live-status { font-size: 14px; line-height: 1; }
.admin-live-status.on { color: #16a34a; }
.admin-live-status.warn { color: #d97706; }
.admin-live-status.off { color: #9ca3af; }
.admin-btn-secondary {
  border: 1px solid var(--border); background: #fff; color: var(--text);
  font-size: 12px; padding: 6px 12px; border-radius: 4px; cursor: pointer;
}
.admin-btn-secondary:hover { background: var(--hover); }

.admin-queue {
  max-width: 1100px; margin: 24px auto; padding: 0 24px;
  display: flex; flex-direction: column; gap: 12px;
}
.admin-empty, .admin-error {
  background: #fff; border: 1px solid var(--border); border-radius: 6px;
  padding: 24px; text-align: center; color: var(--text-secondary);
}
.admin-error { color: #991b1b; border-color: #fca5a5; }

.admin-card {
  background: #fff; border: 1px solid var(--border); border-radius: 6px;
  padding: 14px 16px;
}
.admin-card-header {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  margin-bottom: 12px; padding-bottom: 8px; border-bottom: 1px solid var(--border);
}
.admin-card-evidence-count { font-size: 12px; color: var(--text-secondary); }
.admin-card-effective {
  font-size: 12px; color: var(--text-secondary); margin-left: auto;
  cursor: help; border-bottom: 1px dotted currentColor;
}
.admin-card-effective.admin-muted { border-bottom: none; cursor: default; }

.admin-pattern {
  font-family: ui-monospace, 'SF Mono', Menlo, monospace;
  background: #f9fafb; padding: 2px 6px; border-radius: 3px;
  font-size: 12px; word-break: break-all;
}
.admin-card-path { font-size: 13px; font-weight: 500; color: var(--text); }
.admin-muted { color: var(--text-muted); font-style: italic; }

.admin-card-evidence {
  margin-top: 12px; padding-top: 8px; border-top: 1px solid var(--border);
}
.admin-card-evidence summary {
  font-size: 12px; color: var(--text-secondary); cursor: pointer;
  user-select: none;
}
.admin-card-evidence summary:hover { color: var(--text); }
.admin-evidence-table {
  width: 100%; border-collapse: collapse; margin-top: 8px;
  font-size: 12px;
}
.admin-evidence-table th, .admin-evidence-table td {
  padding: 4px 8px; text-align: left; border-bottom: 1px solid var(--border);
}
.admin-evidence-table th {
  font-size: 11px; text-transform: uppercase; letter-spacing: 0.04em;
  color: var(--text-secondary); font-weight: 600;
}
.admin-evidence-table .num { text-align: right; font-variant-numeric: tabular-nums; }

.admin-card-notes {
  margin-top: 12px; padding-top: 8px; border-top: 1px solid var(--border);
}
.admin-card-notes-headline {
  font-size: 12px; color: var(--text); font-weight: 500; margin-bottom: 4px;
}
.admin-card-notes-toggle {
  background: none; border: none; padding: 0; color: var(--accent, #2563eb);
  font-size: 12px; cursor: pointer; text-decoration: underline;
  text-decoration-style: dotted; text-underline-offset: 3px;
}
.admin-card-notes-body {
  display: none; margin-top: 8px; padding: 8px 12px;
  background: #f9fafb; border-radius: 4px; font-size: 12px;
  color: var(--text-secondary); white-space: pre-wrap;
}
.admin-card-notes-body.open { display: block; }

.admin-toast {
  position: fixed; bottom: 24px; right: 24px;
  background: #1c1f24; color: #f5f6f8; padding: 10px 16px;
  border-radius: 6px; font-size: 13px; box-shadow: 0 4px 12px rgba(0,0,0,0.15);
  opacity: 0; transform: translateY(8px);
  transition: opacity 0.2s, transform 0.2s;
  z-index: 9999;
}
.admin-toast.admin-toast-show { opacity: 1; transform: translateY(0); }

@media (max-width: 720px) {
  .admin-header { padding: 10px 16px; flex-direction: column; gap: 8px; align-items: flex-start; }
  .admin-toolbar { padding: 10px 16px; flex-wrap: wrap; gap: 12px; }
  .admin-queue { padding: 0 12px; margin-top: 12px; }
  .admin-card-effective { margin-left: 0; }
}

/* Bead 93e2 — accept/reject actions on pending candidates */
.admin-card-actions {
  display: flex; align-items: stretch; gap: 8px; margin-top: 12px;
  padding-top: 12px; border-top: 1px solid var(--border);
}
.admin-card-note {
  flex: 1; min-height: 32px; resize: vertical;
  padding: 6px 8px; border: 1px solid var(--border); border-radius: 4px;
  font-family: inherit; font-size: 12px; color: var(--text);
  background: #fff;
}
.admin-card-note:focus {
  outline: none; border-color: var(--accent, #2563eb);
  box-shadow: 0 0 0 2px rgba(37, 99, 235, 0.12);
}
.admin-card-action-buttons { display: flex; gap: 6px; }
.admin-btn-accept, .admin-btn-reject {
  font-size: 12px; font-weight: 500; padding: 7px 14px;
  border-radius: 4px; cursor: pointer; border: 1px solid transparent;
  transition: opacity 0.12s, background 0.12s;
}
.admin-btn-accept {
  background: var(--accent, #2563eb); color: #fff;
}
.admin-btn-accept:hover { background: #1d4ed8; }
.admin-btn-reject {
  background: #fff; color: var(--text); border-color: var(--border);
}
.admin-btn-reject:hover { background: var(--hover); border-color: #cbd5e1; }
.admin-btn-accept:disabled, .admin-btn-reject:disabled {
  opacity: 0.5; cursor: not-allowed;
}

.admin-card.admin-card-leaving {
  opacity: 0; transform: translateX(20px);
  transition: opacity 0.28s, transform 0.28s;
  pointer-events: none;
}

.admin-toast.admin-toast-error { background: #991b1b; }

@media (max-width: 720px) {
  .admin-card-actions { flex-direction: column; }
  .admin-card-action-buttons { justify-content: flex-end; }
  .admin-btn-accept, .admin-btn-reject { min-height: 44px; padding: 8px 16px; }
}

/* R2a — Back-to-Budget breadcrumb on the Transactions view, surfaced only
   when the user arrived via a budget-grid actuals click. Single click
   returns them to the Budget tab. */
.table-back-breadcrumb {
  padding: 6px 16px; border-bottom: 1px solid var(--border);
  background: color-mix(in srgb, var(--accent-light, rgba(37, 99, 235, 0.1)) 50%, transparent);
}
.table-back-btn {
  background: transparent; border: none; cursor: pointer;
  color: var(--accent, #2563eb); font-size: 12px; font-weight: 500;
  padding: 4px 8px; border-radius: 4px;
}
.table-back-btn:hover { background: var(--accent-light, rgba(37, 99, 235, 0.12)); }
.table-back-arrow { margin-right: 4px; font-weight: 600; }

/* Bead 5pnn — active-filter strip. The category filter dropdowns live in a
   display:none panel, so a drill from the Budget view (bucket/sub-bucket/year)
   was applied but invisible. This strip surfaces each active filter as a
   removable chip + a Clear all, sitting above the scroll area so it stays put
   while rows scroll. Secondary text uses #4b5563 (slate-600) — clears WCAG
   4.5:1 on both the --bg strip and white chip backgrounds (#6b7280 fails on
   --bg). */
.table-filter-strip {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
  padding: 8px 16px; background: var(--bg, #f5f6f8);
  border-bottom: 1px solid var(--border);
}
.table-filter-strip-label {
  font-size: 11px; font-weight: 600; text-transform: uppercase;
  letter-spacing: 0.04em; color: #4b5563; margin-right: 2px;
}
.table-filter-chip {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 12px; line-height: 1.2;
  background: var(--surface, #fff); color: var(--text, #1a1d23);
  border: 1px solid var(--border, #e2e5ea);
  padding: 3px 4px 3px 10px; border-radius: 14px;
}
.table-filter-chip-field { color: #4b5563; font-weight: 600; }
.table-filter-chip-value { font-weight: 500; }
.table-filter-chip-remove {
  display: inline-flex; align-items: center; justify-content: center;
  width: 22px; height: 22px; min-width: 22px; padding: 0;
  border: none; background: transparent; color: #4b5563;
  border-radius: 50%; font-size: 15px; line-height: 1; cursor: pointer;
}
.table-filter-chip-remove:hover { background: rgba(17, 24, 39, 0.10); color: var(--text, #1a1d23); }
.table-filter-chip-remove:focus-visible { outline: 2px solid var(--accent, #2b7bba); outline-offset: 1px; }
.table-filter-clear {
  margin-left: auto; font-size: 12px; font-weight: 600;
  background: transparent; border: none; color: #4b5563; cursor: pointer;
  padding: 5px 10px; border-radius: 6px; min-height: 32px;
}
.table-filter-clear:hover { background: rgba(17, 24, 39, 0.06); color: var(--text, #1a1d23); }
@media (max-width: 600px) {
  .table-filter-strip { padding: 8px 12px; gap: 5px; }
  .table-filter-chip-remove { width: 26px; height: 26px; min-width: 26px; font-size: 16px; }
  .table-filter-clear { margin-left: 0; min-height: 36px; }
}

/* Bead n4y1 + 9zsg — prior-rejection history block. The only context
   block surviving the unified-card refactor — every other block (split,
   ambiguous, refinement) collapsed into the change-summary block. This
   one stays because rejection history is meaningful context that
   doesn't fit inside the change-summary's "current → proposed" diff. */
.admin-card-prior-rejections {
  margin: 12px 0;
  padding: 10px 14px;
  border-radius: 4px;
  font-size: 12px;
  color: var(--text);
  background: #f0f9ff;
  border-left: 3px solid #0284c7;
}
.admin-card-prior-rejections .admin-prior-headline {
  font-weight: 500; line-height: 1.45;
  margin-bottom: 8px;
}

/* Edit-table base — used by the prior-rejection block and the
   corrections-table inside the trust block. */
.admin-edit-table {
  width: 100%; border-collapse: collapse;
  font-size: 12px;
  background: rgba(255,255,255,0.7);
  border-radius: 3px;
  overflow: hidden;
}
.admin-edit-table thead th {
  font-size: 10px; text-transform: uppercase; letter-spacing: 0.04em;
  color: var(--text-secondary); font-weight: 600;
  padding: 6px 8px; text-align: left;
  border-bottom: 1px solid var(--border);
  background: rgba(0,0,0,0.02);
}
.admin-edit-table tbody td {
  padding: 6px 8px;
  border-bottom: 1px dashed var(--border);
  vertical-align: top;
}
.admin-edit-table tbody tr:last-child td { border-bottom: none; }

/* Prior-rejection table — extra columns ("Rejected by", "Since"). */
.admin-prior-table .admin-prior-since-cell {
  font-weight: 500; color: #78350f; background: #fef3c7;
  border-radius: 3px;
  text-align: center;
}
.admin-prior-row.admin-prior-row-extra,
.admin-prior-note-row.admin-prior-row-extra {
  display: none;
}
.admin-card-prior-rejections.expanded .admin-prior-row.admin-prior-row-extra,
.admin-card-prior-rejections.expanded .admin-prior-note-row.admin-prior-row-extra {
  display: table-row;
}
.admin-prior-more {
  margin-top: 8px; background: none; border: none; cursor: pointer;
  color: #0284c7; font-size: 11px; padding: 2px 4px;
  text-decoration: underline; text-decoration-style: dotted;
}
.admin-prior-more:hover { text-decoration-style: solid; }

/* Bead expenses_tool-47fp — invisible-when-working dot + Refresh.
   Both are hidden in the happy path (SSE connected) and revealed only
   when SSE drops or fails to init. */
.admin-live-status-hidden { display: none; }
.admin-refresh-hidden { display: none; }

/* Bead expenses_tool-2fx2 (FE half) — low-evidence de-emphasis.
   Cards with evidence_count < 3 render with reduced visual weight so
   the reviewer's eye lands on high-evidence proposals first. BE-side
   threshold tuning is the other half (handoff to DB Claude). */
.admin-card.admin-card-low-evidence {
  opacity: 0.7;
  background: #fafbfc;
}
.admin-card.admin-card-low-evidence .admin-card-evidence-count::after {
  content: ' · low confidence';
  color: var(--text-muted, #9ca3af);
  font-style: italic;
}
.admin-card.admin-card-low-evidence:hover { opacity: 1; }

/* Bead expenses_tool-j5uh — test-mode banner. Visible at the top of the
   admin queue page when ?test=1 is set; reminds the reviewer they're
   looking at synthetic data and no writes hit the live BE. */
.admin-test-banner {
  position: sticky;
  top: 0;
  z-index: 1000;
  background: #fde68a;
  color: #78350f;
  text-align: center;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.04em;
  padding: 6px 16px;
  border-bottom: 1px solid #f59e0b;
  display: flex; align-items: center; justify-content: center; gap: 16px;
}
.admin-test-banner-exit {
  background: rgba(0,0,0,0.08); border: 1px solid rgba(0,0,0,0.12);
  color: #78350f; font-size: 11px; font-weight: 600;
  padding: 3px 10px; border-radius: 3px; cursor: pointer;
}
.admin-test-banner-exit:hover { background: rgba(0,0,0,0.15); }

/* Bead qkug + 1tkw — Human corrections driving this rule.
   Renders each correction as a Transactions-table-style row with
   Google-Docs-style strikethrough revision marks on changed cells.
   Reviewer + timestamp live in a leading meta column so the rest of
   the row reads like a familiar Transactions row. */
.admin-card-corrections {
  margin-top: 14px; padding: 12px 14px;
  border: 1px solid var(--border);
  border-left: 3px solid #6366f1;
  background: rgba(99, 102, 241, 0.04);
  border-radius: 4px;
  overflow-x: auto;
}
.admin-card-corrections-heading {
  margin: 0 0 10px 0;
  font-size: 12px; font-weight: 600; text-transform: uppercase;
  letter-spacing: 0.04em; color: var(--text-secondary);
}
.admin-corrections-table {
  width: 100%; border-collapse: collapse;
  font-size: 12px;
}
.admin-corrections-table thead th {
  font-size: 11px; text-transform: uppercase; letter-spacing: 0.04em;
  color: var(--text-secondary); font-weight: 600;
  padding: 6px 8px; text-align: left;
  border-bottom: 1px solid var(--border);
}
.admin-corrections-table thead th.num { text-align: right; }
.admin-corrections-table tbody td {
  padding: 6px 8px;
  border-bottom: 1px dashed var(--border);
  vertical-align: top;
}
.admin-corrections-table tbody td.num {
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.admin-corrections-table tbody td.date-cell {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.admin-corrections-table tbody tr.admin-correction-row:last-child td {
  border-bottom: none;
}

/* Meta column — who. Compact, secondary tone so the row's data cells
   read primary. corrected_at lives in the .admin-correction-who title
   tooltip per bead vtlp; stacking the date under the name read as
   duplicated dates next to the transaction_date column. */
.admin-correction-th-meta { width: 1%; white-space: nowrap; }
.admin-correction-who {
  font-weight: 500; color: var(--text);
  font-size: 12px;
  max-width: 140px; overflow: hidden; text-overflow: ellipsis;
  cursor: help;
}
/* Bead 41x5 — system actors (bulk migration, sheet import, automated
   inference) render in a softer, italic style so reviewers can tell at
   a glance that the row is a system action, not human signal. */
.admin-correction-who--system {
  font-style: italic;
  color: var(--text-secondary);
  font-weight: 400;
}
.admin-correction-row--system td {
  background: rgba(0,0,0,0.015);
}

/* Google-Docs revision mark: prior with red strikethrough, then new
   value rendered in normal styling immediately after. Unchanged cells
   use the table's default styling. */
.admin-revision-cell { white-space: normal; }
.admin-revision-prior {
  color: #b91c1c;
  text-decoration: line-through;
  text-decoration-color: #b91c1c;
  margin-right: 6px;
}
.admin-revision-new { color: var(--text); font-weight: 500; }
/* Added: cell that previously had no value now has one. Subtle green
   left-border + faint background so reviewers see "newly populated"
   without a cryptic ∅ symbol. */
.admin-revision-added {
  border-left: 3px solid #16a34a;
  background: rgba(22, 163, 74, 0.06);
}
/* Removed: cell that previously had a value, now empty. Subtle red
   left-border + faint background, prior renders with strikethrough. */
.admin-revision-removed {
  border-left: 3px solid #b91c1c;
  background: rgba(185, 28, 28, 0.04);
}

/* ═══════════════════════════════════════════
   Bead qkyp — IF/THEN block restored. Per Jason 2026-05-07:
   "I liked the IF THEN rule structure. It was easier to follow."
   Two-column body grid (IF on the left, arrow, THEN on the right).
   Per-field labeled rows in each. Discriminator/added (NEW) chips
   live on individual IF rows. Revision marks live on individual
   THEN rows when an existing rule is being modified.
   ═══════════════════════════════════════════ */
.admin-card-body {
  display: grid; grid-template-columns: 1fr auto 1fr; gap: 16px;
  align-items: start;
  margin: 14px 0;
  padding: 14px 16px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--surface, #fff);
}
.admin-card-arrow {
  color: var(--text-secondary); font-size: 18px; align-self: center;
  padding-top: 16px;
}
.admin-card-section-title {
  font-size: 11px; font-weight: 600; color: var(--text-secondary);
  text-transform: uppercase; letter-spacing: 0.04em; margin-bottom: 8px;
}
.admin-card-field {
  display: flex; gap: 6px; align-items: baseline;
  font-size: 13px; padding: 3px 0;
}
.admin-card-field-label { color: var(--text-secondary); min-width: 90px; }
.admin-card-field-value { color: var(--text); flex: 1; word-break: break-word; }

/* Bead qkyp followup — one-line framing strip above IF/THEN that
   names what kind of change this rule represents (split refines an
   existing rule, ambiguous conflicts with one, refinement attempts a
   rejected proposal again). Per Jason 2026-05-07: the (NEW) chip
   alone doesn't tell the parent-child refinement story; this does. */
.admin-card-rule-context {
  font-size: 12px;
  line-height: 1.5;
  margin: 12px 0;
  padding: 8px 12px;
  border-radius: 4px;
  color: var(--text);
}
.admin-card-rule-context strong { font-weight: 600; }
.admin-card-rule-context code.admin-pattern {
  font-size: 11px; padding: 1px 4px;
  background: rgba(0,0,0,0.06);
  border-radius: 3px;
  font-family: ui-monospace, 'SF Mono', Menlo, monospace;
}
.admin-card-rule-context--split {
  background: #fff7ed; border-left: 3px solid #f59e0b;
}
.admin-card-rule-context--ambiguous {
  background: #faf5ff; border-left: 3px solid #a855f7;
}
.admin-card-rule-context--refinement {
  background: #ecfdf5; border-left: 3px solid #10b981;
}

/* Discriminator row in IF — split candidates add a scope dimension. */
.admin-card-field--discriminator {
  background: rgba(245, 158, 11, 0.10);
  border-left: 3px solid #f59e0b;
  padding-left: 8px;
  border-radius: 2px;
}
.admin-card-field--discriminator .admin-card-field-label::after {
  content: ' (new)';
  color: #92400e; font-weight: 600; font-size: 10px;
  text-transform: uppercase; letter-spacing: 0.04em; margin-left: 4px;
}

/* Added-condition row in IF — refinement adds a description pattern
   that wasn't on the rejected version. Green to match the refinement
   theme. */
.admin-card-field--added {
  background: rgba(16, 185, 129, 0.10);
  border-left: 3px solid #10b981;
  padding-left: 8px;
  border-radius: 2px;
}
.admin-card-field--added .admin-card-field-label::after {
  content: ' (new)';
  color: #065f46; font-weight: 600; font-size: 10px;
  text-transform: uppercase; letter-spacing: 0.04em; margin-left: 4px;
}

/* Inline revision marks for THEN-block hierarchy values. Same Google-
   Docs visual as the corrections table's <td> revision cells; this
   variant emits a span tree for use inside .admin-card-field-value. */
.admin-revision-inline.admin-revision-added {
  padding: 0 4px;
  border-left: 2px solid #16a34a;
  background: rgba(22, 163, 74, 0.06);
  border-radius: 2px;
}
.admin-revision-inline.admin-revision-removed {
  padding: 0 4px;
  border-left: 2px solid #b91c1c;
  background: rgba(185, 28, 28, 0.04);
  border-radius: 2px;
}

@media (max-width: 720px) {
  .admin-card-body {
    grid-template-columns: 1fr; gap: 8px;
  }
  .admin-card-arrow { display: none; }
}

/* Reviewer note — a follow-up row under the data row, italic, indented
   into the data columns so it visually attaches to the correction it
   belongs to. */
.admin-correction-note-row td.admin-correction-note {
  font-size: 11px; color: var(--text-secondary);
  font-style: italic;
  border-bottom: 1px dashed var(--border);
  padding-top: 0; padding-bottom: 8px;
}

.admin-correction-footer {
  margin-top: 8px; font-size: 11px;
  font-style: italic;
}

/* Demote the matched-txn list when corrections are present (qkug).
   When corrections drive the card, the txn list becomes secondary
   "where this rule would fire" context, not the primary evidence. */
.admin-card-evidence-secondary summary {
  font-size: 11px;
  color: var(--text-secondary);
}

@media (max-width: 720px) {
  /* Mobile: keep the table but tighten padding and let it scroll
     horizontally inside the corrections section. The reviewer is
     scanning the same column language as on desktop, just narrower. */
  .admin-corrections-table thead th,
  .admin-corrections-table tbody td {
    padding: 5px 6px;
  }
  .admin-correction-who { max-width: 100px; }
}

/* ═══════════════════════════════════════════
   Reimbursement intake form (bead expenses_tool-iq4z, Step 2b)
   Reuses .admin-page wrapper from the rule-candidate queue for header
   shell + sign-in screen. Form-specific styling below.
   ═══════════════════════════════════════════ */
.reimb-shell {
  max-width: 920px;
  margin: 0 auto;
  padding: 20px 24px 60px;
}
.reimb-intro {
  font-size: 13px;
  color: var(--text-secondary);
  margin: 0 0 20px;
  line-height: 1.5;
}
.reimb-form { display: flex; flex-direction: column; gap: 20px; }
.reimb-envelope {
  padding: 14px 16px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--surface-muted, #fafafa);
}
.reimb-line-items { display: flex; flex-direction: column; gap: 16px; }
.reimb-line-item {
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--surface, #fff);
  padding: 16px;
}
.reimb-line-header {
  display: flex; justify-content: space-between; align-items: center;
  margin-bottom: 14px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--border);
}
.reimb-line-number {
  font-size: 12px; font-weight: 600; text-transform: uppercase;
  letter-spacing: 0.04em; color: var(--text-secondary);
}
.reimb-line-remove {
  font-size: 12px; color: #b91c1c;
  background: transparent; border: 1px solid transparent;
  padding: 4px 10px; border-radius: 4px;
  cursor: pointer;
}
.reimb-line-remove:hover {
  border-color: #fca5a5; background: #fef2f2;
}
.reimb-line-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px 16px;
}
.reimb-field {
  display: flex; flex-direction: column; gap: 4px;
  font-size: 13px;
}
.reimb-field.reimb-field-wide { grid-column: 1 / -1; }
.reimb-label {
  font-size: 11px; font-weight: 600; text-transform: uppercase;
  letter-spacing: 0.04em; color: var(--text-secondary);
}
.reimb-optional {
  font-weight: 400; text-transform: none; letter-spacing: 0;
  color: var(--text-muted, #94a3b8);
}
.reimb-field input,
.reimb-field select,
.reimb-field textarea {
  font-size: 13px; font-family: inherit;
  padding: 8px 10px;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: #fff;
  color: var(--text);
  width: 100%; box-sizing: border-box;
}
.reimb-field input:focus,
.reimb-field select:focus,
.reimb-field textarea:focus {
  border-color: var(--accent, #2563eb);
  outline: none;
  box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.15);
}
.reimb-field textarea { resize: vertical; min-height: 56px; }
.reimb-hint {
  font-size: 11px; color: var(--text-secondary);
  font-style: italic;
}
.reimb-receipt-placeholder {
  padding: 16px; border: 1px dashed var(--border); border-radius: 4px;
  font-size: 12px; color: var(--text-secondary); text-align: center;
  background: var(--surface-muted, #f8fafc);
}
.reimb-line-controls {
  display: flex; justify-content: flex-start;
}
.reimb-btn-secondary {
  font-size: 13px; padding: 8px 14px;
  background: #fff; color: var(--text);
  border: 1px solid var(--border); border-radius: 4px;
  cursor: pointer;
}
.reimb-btn-secondary:hover { background: var(--surface-muted, #f8fafc); }
.reimb-submit-row {
  display: flex; align-items: center; gap: 12px;
  margin-top: 8px; padding-top: 16px;
  border-top: 1px solid var(--border);
}
.reimb-btn-primary {
  font-size: 14px; font-weight: 600;
  padding: 10px 20px;
  background: var(--accent, #2563eb); color: #fff;
  border: none; border-radius: 4px;
  cursor: pointer;
}
.reimb-btn-primary:hover:not(:disabled) { filter: brightness(1.05); }
.reimb-btn-primary:disabled {
  opacity: 0.5; cursor: not-allowed;
}
.reimb-submit-help {
  font-size: 11px; color: var(--text-secondary); font-style: italic;
}

@media (max-width: 720px) {
  .reimb-shell { padding: 16px 16px 60px; }
  .reimb-line-grid { grid-template-columns: minmax(0, 1fr); gap: 10px; }
}

/* Skeleton loading state for the rule-candidate queue — bead pliw.
   The BE response runs 3–5s on warm cache; a bare "Loading…" string
   read as frozen. Skeleton bars convey "real content is coming."
   No layout shift — placeholder cards use the same outer dimensions
   as a real .admin-card. */
.admin-skel-status {
  font-size: 12px; color: var(--text-secondary);
  padding: 12px 4px; font-style: italic;
}
.admin-card-skeleton {
  pointer-events: none;
}
.admin-skel-bar {
  display: inline-block;
  height: 12px;
  background: linear-gradient(90deg,
    var(--surface-muted, #f1f5f9) 0%,
    var(--border, #e2e8f0) 50%,
    var(--surface-muted, #f1f5f9) 100%);
  background-size: 200% 100%;
  animation: admin-skel-shimmer 1.4s infinite linear;
  border-radius: 3px;
  margin: 2px 8px 2px 0;
}
.admin-skel-bar-badge { width: 140px; height: 18px; }
.admin-skel-bar-meta  { width: 80px; }
.admin-skel-bar-line  { display: block; width: 70%; margin: 6px 0; }
.admin-skel-bar-line:last-child { width: 50%; }
@keyframes admin-skel-shimmer {
  0%   { background-position: 100% 0; }
  100% { background-position: -100% 0; }
}

/* Reconciliation panel additions — bead expenses_tool-r04h followup.
 * Reconciliation is now the unified work-list to drive the Variance metric
 * to 0: current-period fields, prior-period open breaks, commitment-registry
 * mismatches, and a quarantined cluster for scope/unit mismatches that don't
 * count toward the headline metric. The standalone variance-alerts panel and
 * its budget-variance-* classes were folded in here and removed. */

/* Prior-period clusters render as native <details>/<summary> — collapsed by
   default; the summary shows the title + count; clicking expands the cards.
   Per reviewer feedback 2026-05-18: ROUNDING is filtered out at source (never
   in the DOM), and prior periods are out of sight until needed. */
details.budget-income-recon-cluster[data-cluster="prior-period"] {
  margin-top: 8px;
}
details.budget-income-recon-cluster[data-cluster="prior-period"] > summary {
  cursor: pointer;
  user-select: none;
  list-style: none;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 8px 0;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-secondary);
}
details.budget-income-recon-cluster[data-cluster="prior-period"] > summary::-webkit-details-marker {
  display: none;
}
details.budget-income-recon-cluster[data-cluster="prior-period"] > summary::before {
  content: '▸';
  display: inline-block;
  font-size: 10px;
  color: var(--text-muted);
  transition: transform 120ms ease-out;
}
details[open].budget-income-recon-cluster[data-cluster="prior-period"] > summary::before {
  transform: rotate(90deg);
}
/* Belt-and-suspenders: explicitly hide the cards container when the
   <details> is closed. Chromium's UA default uses content-visibility,
   which can leave custom descendants with measurable layout boxes for
   visual-regression tools — display:none avoids any ambiguity. */
details.budget-income-recon-cluster[data-cluster="prior-period"]:not([open]) > .budget-income-recon-cards {
  display: none;
}
details.budget-income-recon-cluster[data-cluster="prior-period"] > summary:hover,
details.budget-income-recon-cluster[data-cluster="prior-period"] > summary:focus-visible {
  color: var(--text);
  outline: none;
}

/* Mobile: ensure the disclosure target hits the ≥44px tap baseline. */
@media (max-width: 600px) {
  details.budget-income-recon-cluster[data-cluster="prior-period"] > summary {
    min-height: 44px;
    padding: 12px 0;
    font-size: 12px;
  }
}

.budget-income-recon-cluster--quarantined {
  margin-top: 12px;
  padding: 8px 10px;
  background: rgba(245, 158, 11, 0.05);
  border-left: 3px solid #f59e0b;
  border-radius: 3px;
}

/* Bead expenses_tool-tdmk — below-tolerance cluster. Quieter than
   quarantined (gray, not amber) so it reads as "informational, not
   actionable" — these breaks are real but the auditor would call them
   within tolerance. Now renders as <details>/<summary> collapsed by
   default (post-2026-05-19 reviewer feedback). */
details.budget-income-recon-cluster--submaterial {
  margin-top: 12px;
  padding: 8px 10px;
  background: rgba(107, 114, 128, 0.05);
  border-left: 3px solid #9ca3af;
  border-radius: 3px;
}
details.budget-income-recon-cluster--submaterial > summary {
  cursor: pointer;
  user-select: none;
  list-style: none;
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-secondary);
}
details.budget-income-recon-cluster--submaterial > summary::-webkit-details-marker {
  display: none;
}
details.budget-income-recon-cluster--submaterial > summary::before {
  content: '▸';
  display: inline-block;
  font-size: 10px;
  color: var(--text-muted);
  transition: transform 120ms ease-out;
}
details[open].budget-income-recon-cluster--submaterial > summary::before {
  transform: rotate(90deg);
}
details.budget-income-recon-cluster--submaterial:not([open]) > .budget-income-recon-cluster-note,
details.budget-income-recon-cluster--submaterial:not([open]) > .budget-income-recon-cards {
  display: none;
}
.budget-income-recon-cluster-note {
  font-size: 11px;
  color: var(--text-secondary);
  line-height: 1.5;
  margin: 4px 0 8px;
}

.budget-income-recon-field-period {
  margin-left: 6px;
  font-weight: 400;
  font-size: 11px;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}

/* STRUCTURAL severity — used by alert summaries when the BE classifies a
 * recon break as a real disagreement (not drift). Darker red than DATA so it
 * outranks visually. */
.income-trust-STRUCTURAL::before { background: #991b1b; }
.income-trust-STRUCTURAL { color: #7f1d1d; font-weight: 700; }
.income-recon-class-badge.income-trust-STRUCTURAL {
  background: #fee2e2; color: #7f1d1d;
}
