/* ── Reset & Base ──────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; background: #f0f2f5; color: #1a1a2e; font-size: 14px; min-width: 1080px; overflow-x: auto; }

/* ── Non-production environment banner ──────────────────────────────────────
   Sits ABOVE the sticky header (higher z-index, also sticky) when populated
   by app.js from /api/auth/me's `envLabel`. Hidden on prod (empty label).
   Color varies by env so local and staging are distinguishable at a glance:
     local   → blue/info  (this machine, harmless)
     staging → amber/warn (non-prod data, real OAuth, be careful)
     other   → amber/warn (default for any unknown non-prod label) */
.env-banner { position: sticky; top: 0; z-index: 200; width: 100%; padding: 0.4rem 1rem; text-align: center; font-size: 0.85rem; font-weight: 700; letter-spacing: 0.06em; background: #fef3c7; color: #92400e; border-bottom: 2px solid #f59e0b; }
.env-banner[hidden] { display: none; }
.env-banner[data-env="local"] { background: #dbeafe; color: #1e3a8a; border-bottom-color: #3b82f6; }
/* When the banner is visible, app.js sets `.header { top: <banner-height>px }`
   inline so the header pins flush beneath the banner with no gap. Measured at
   runtime to survive font/padding changes. */

/* ── Header ───────────────────────────────────────────────────────────────── */
.header { display: flex; justify-content: space-between; align-items: center; padding: 0 1.5rem; height: 56px; background: #312556; color: white; position: sticky; top: 0; z-index: 100; }
.header-left { display: flex; align-items: center; gap: 2rem; }
.header-right { display: flex; align-items: center; gap: 1.5rem; }
.logo { font-size: 1.1rem; font-weight: 700; letter-spacing: -0.02em; display: flex; align-items: center; gap: 0.5rem; }
.logo-icon { width: 24px; height: 24px; }
.nav-tabs { display: flex; gap: 0; }
.nav-tab { background: none; border: none; color: rgba(255,255,255,0.6); padding: 0.5rem 1rem; cursor: pointer; font-size: 0.85rem; border-bottom: 2px solid transparent; transition: all 0.2s; border-radius: 0; width: auto; height: auto; }
.nav-tab:hover { color: rgba(255,255,255,0.9); }
.nav-tab.active { color: white; border-bottom-color: #00e68a; }
/* "More ⋯" overflow menu — utility tabs (How It Works / History / Admin) live here
   to keep the primary nav from overflowing now that Channels was added. */
.nav-more { position: relative; display: flex; align-items: stretch; }
/* `.nav-more{display:flex}` (0,1,0) would override the UA `[hidden]` rule, so
   re-assert it — this is what gates the whole control to editor/admin. */
.nav-more[hidden] { display: none; }
.nav-more-toggle { background: none; border: none; color: rgba(255,255,255,0.6); padding: 0.5rem 1rem; cursor: pointer; font-size: 0.85rem; border-bottom: 2px solid transparent; transition: all 0.2s; font-family: inherit; display: inline-flex; align-items: center; gap: 0.3rem; }
.nav-more-toggle:hover { color: rgba(255,255,255,0.9); }
.nav-more-toggle.active { color: white; border-bottom-color: #00e68a; }
.nav-more-toggle[aria-expanded="true"] { color: #fff; }
.nav-more-caret { font-size: 0.7rem; opacity: 0.8; line-height: 1; }
.nav-more-menu { position: absolute; left: 0; top: calc(100% + 6px); min-width: 168px; background: white; border: 1px solid #e5e7eb; border-radius: 8px; box-shadow: 0 8px 24px rgba(0,0,0,0.12); z-index: 150; overflow: hidden; padding: 0.25rem 0; }
.nav-more-menu[hidden] { display: none; }
/* Scoped under .nav-more-menu so these beat the (0,2,0) `.nav-tab.active` rule
   the items still inherit from carrying the `nav-tab` class. */
.nav-more-menu .nav-more-item { display: block; width: 100%; text-align: left; color: #1a1a2e; border-bottom: none; padding: 0.5rem 0.85rem; font-size: 0.82rem; white-space: nowrap; }
.nav-more-menu .nav-more-item:hover { background: #f3f1fa; color: #312556; }
.nav-more-menu .nav-more-item.active { background: #f3f1fa; color: #312556; font-weight: 600; border-bottom: none; box-shadow: inset 3px 0 0 #00e68a; }
.scenario-selector { display: flex; align-items: center; gap: 0.5rem; }
.scenario-selector label { font-size: 0.8rem; opacity: 0.7; }
.scenario-selector select { background: rgba(255,255,255,0.1); border: 1px solid rgba(255,255,255,0.2); color: white; padding: 0.25rem 0.5rem; border-radius: 4px; font-size: 0.85rem; }
/* Sync status — a compact pill; full detail on hover/focus via a white popover card. */
.sync-status { position: relative; display: inline-flex; align-items: center; gap: 0.4rem; font-size: 0.78rem; padding: 0.25rem 0.65rem; border-radius: 999px; background: rgba(255,255,255,0.08); border: 1px solid rgba(255,255,255,0.14); color: rgba(255,255,255,0.85); cursor: default; }
.sync-status:hover, .sync-status:focus-visible { background: rgba(255,255,255,0.15); outline: none; }
.sync-dot { width: 8px; height: 8px; border-radius: 50%; background: #00e68a; flex: none; }
.sync-dot.error { background: #ff6b6b; }
.sync-popover { display: none; position: absolute; top: calc(100% + 8px); right: 0; min-width: 240px; background: #fff; color: #1a1a2e; border: 1px solid #e5e7eb; border-radius: 8px; box-shadow: 0 8px 24px rgba(0,0,0,0.18); padding: 0.7rem 0.85rem; z-index: 9999; text-align: left; line-height: 1.55; cursor: default; }
.sync-status:hover .sync-popover, .sync-status:focus-within .sync-popover { display: block; }
.sync-popover-title { font-weight: 700; color: #312556; margin-bottom: 0.4rem; }
.sync-popover-row { display: flex; justify-content: space-between; gap: 1.5rem; }
.sync-popover-row .k { color: #888; }
.sync-popover-row .v { color: #1a1a2e; font-weight: 600; white-space: nowrap; }
.user-info { font-size: 0.8rem; position: relative; }
.user-menu-trigger { display: inline-flex; align-items: center; gap: 0.35rem; background: transparent; border: 1px solid transparent; color: rgba(255,255,255,0.85); font-size: 0.8rem; font-family: inherit; padding: 0.3rem 0.6rem; border-radius: 6px; cursor: pointer; transition: background 0.15s, border-color 0.15s, color 0.15s; }
.user-menu-trigger:hover { background: rgba(255,255,255,0.08); color: #fff; }
.user-menu-trigger[aria-expanded="true"] { background: rgba(255,255,255,0.12); border-color: rgba(255,255,255,0.2); color: #fff; }
.user-menu-trigger:focus-visible { outline: 2px solid #00e68a; outline-offset: 2px; }
.user-menu-email { max-width: 220px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.user-menu-caret { font-size: 0.7rem; opacity: 0.8; line-height: 1; }
.user-menu { position: absolute; right: 0; top: calc(100% + 6px); min-width: 220px; background: white; border: 1px solid #e5e7eb; border-radius: 8px; box-shadow: 0 8px 24px rgba(0,0,0,0.12); z-index: 150; overflow: hidden; }
.user-menu-header { padding: 0.6rem 0.85rem; border-bottom: 1px solid #eee; }
.user-menu-email-full { font-size: 0.8rem; color: #1a1a2e; font-weight: 600; word-break: break-all; }
.user-menu-role { font-size: 0.7rem; color: #888; margin-top: 0.15rem; text-transform: uppercase; letter-spacing: 0.03em; }
.user-menu-item { display: block; padding: 0.6rem 0.85rem; font-size: 0.85rem; color: #1a1a2e; text-decoration: none; transition: background 0.1s; }
.user-menu-item:hover, .user-menu-item:focus { background: #f8f9fa; outline: none; }

/* ── Views ────────────────────────────────────────────────────────────────── */
.view { display: none; }
.view.active { display: block; }

/* ── App Layout ──────────────────────────────────────────────────────────── */
.app-layout { display: grid; grid-template-columns: 1fr 280px; gap: 1.5rem; padding: 1.5rem; position: relative; }
.app-content { min-width: 0; }
/* When filters panel is hidden, content takes full width */
.app-layout:has(.filters-panel[style*="display: none"]) { grid-template-columns: 1fr; }
.app-layout:has(.filters-panel[style*="display:none"]) { grid-template-columns: 1fr; }
.filters-panel { background: white; border-radius: 8px; padding: 1.25rem; box-shadow: 0 1px 3px rgba(0,0,0,0.08); height: fit-content; position: sticky; top: 72px; }
.filters-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 1rem; }
.filters-header h2 { font-size: 1rem; color: #333; margin: 0; }
.filters-close { background: none; border: none; font-size: 1.2rem; color: #999; cursor: pointer; padding: 0.1rem 0.3rem; border-radius: 4px; line-height: 1; }
.filters-close:hover { color: #333; background: rgba(0,0,0,0.05); }
/* Header filters toggle button */
.filters-toggle { background: rgba(255,255,255,0.1); border: 1px solid rgba(255,255,255,0.2); border-radius: 4px; cursor: pointer; font-size: 0.8rem; color: rgba(255,255,255,0.7); padding: 0.25rem 0.65rem; transition: all 0.15s; line-height: 1.2; white-space: nowrap; }
.filters-toggle:hover { background: rgba(255,255,255,0.15); color: white; }
.filters-toggle.active { background: rgba(78,205,196,0.2); border-color: rgba(78,205,196,0.4); color: #4ecdc4; }
.filter-group { margin-bottom: 1rem; }
.filter-group label { display: block; font-size: 0.8rem; font-weight: 600; color: #555; margin-bottom: 0.25rem; }
.filter-group input[type="month"], .filter-group select, .filter-group textarea { width: 100%; padding: 0.4rem 0.5rem; border: 1px solid #ddd; border-radius: 4px; font-size: 0.85rem; }
.month-picker { display: flex; gap: 0.4rem; }
.month-picker select { flex: 1; padding: 0.4rem 0.5rem; border: 1px solid #ddd; border-radius: 4px; font-size: 0.85rem; }
.filter-group textarea { font-family: inherit; resize: vertical; }
.filter-hint { display: block; font-size: 0.7rem; color: #888; margin-top: 0.2rem; font-weight: 400; }
/* Live Model–specific filter hint: only shown when the body is on the Live Model view. */
.filter-hint-live-model { display: none; color: #4ecdc4; font-style: italic; }
body.body-view-model .filter-hint-live-model { display: block; }
/* Live Model view forces revenueType=MRR and revenueStreams=all three. Disable those
   two filter sections visually so users see what's actually in effect. */
body.body-view-model .filter-group-mrr-basis,
body.body-view-model .filter-group-streams {
  opacity: 0.55;
  pointer-events: none;
  background: #f8f9fa;
  padding: 0.5rem;
  border-radius: 4px;
  border: 1px dashed #d4cee0;
}
body.body-view-model .filter-group-mrr-basis .filter-hint:not(.filter-hint-live-model),
body.body-view-model .filter-group-streams .filter-hint:not(.filter-hint-live-model) {
  display: none;
}
/* ARR Bridge view (issue #50): two soundness conditions on the classifier.
     - dealTypes locked to all 3. Visually disable the whole group, mirroring
       Live Model's pattern. (See applyBridgeFilterOverlay() in app.js for
       the JS state mutation that force-checks all 3.)
     - forecastCategories must INCLUDE "Closed", but other categories are
       user-controlled. The Closed checkbox alone is `disabled` via JS;
       browser default styling communicates the lock for that one box. The
       group itself stays fully active so users can toggle the other 4. */
.filter-hint-bridge { display: none; color: #4ecdc4; font-style: italic; }
body.body-chart-bridge .filter-hint-bridge { display: block; }
body.body-chart-bridge .filter-group-deal-types {
  opacity: 0.55;
  pointer-events: none;
  background: #f8f9fa;
  padding: 0.5rem;
  border-radius: 4px;
  border: 1px dashed #d4cee0;
}
body.body-chart-bridge .filter-group-deal-types .filter-hint:not(.filter-hint-bridge) {
  display: none;
}
/* Legacy .tooltip-trigger replaced by .info-icon pattern */
.checkbox-group { display: flex; flex-direction: column; gap: 0.25rem; }
.checkbox-group label { font-weight: 400; display: flex; align-items: center; gap: 0.4rem; cursor: pointer; }
.checkbox-group input[type="checkbox"] { margin: 0; }
.slip-inputs { display: flex; flex-direction: column; gap: 0.25rem; }
.slip-input-row { display: flex; align-items: center; gap: 0.5rem; }
.slip-input-row span { font-size: 0.8rem; flex: 1; }
.slip-input-row input { width: 50px; padding: 0.2rem 0.4rem; border: 1px solid #ddd; border-radius: 4px; text-align: center; }
.filter-actions { display: flex; gap: 0.5rem; margin-top: 1rem; }

/* ── Buttons ──────────────────────────────────────────────────────────────── */
.btn { padding: 0.5rem 1rem; border: none; border-radius: 6px; cursor: pointer; font-size: 0.85rem; font-weight: 500; transition: all 0.2s; width: auto; height: auto; }
.btn-primary { background: #312556; color: white; }
.btn-primary:hover { background: #2d2d4a; }
.btn-secondary { background: #e8e8e8; color: #333; }
.btn-secondary:hover { background: #ddd; }
.btn-danger { background: #ff6b6b; color: white; }
.btn-danger:hover { background: #ff5252; }
.btn-sm { padding: 0.3rem 0.6rem; font-size: 0.75rem; }
.btn-export { background: transparent; border: 1px solid #d0d5dd; color: #555; font-size: 0.72rem; padding: 0.25rem 0.55rem; border-radius: 4px; display: inline-flex; align-items: center; gap: 0.3rem; }
.btn-export:hover { background: #f5f5f5; border-color: #aaa; color: #333; }

/* ── Summary Cards ────────────────────────────────────────────────────────── */
.summary-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 1rem; margin-bottom: 1.5rem; }
.summary-card { background: white; border-radius: 8px; padding: 1rem 1.25rem; box-shadow: 0 1px 3px rgba(0,0,0,0.08); position: relative; }
.summary-label { font-size: 0.75rem; color: #888; text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 0.25rem; }
/* Shared info icon + tooltip pattern */
.info-icon, .card-info-icon { position: relative; font-size: 0.85rem; color: #bbb; cursor: help; transition: color 0.15s; font-style: normal; line-height: 1; }
.info-icon:hover, .card-info-icon:hover { color: #4ecdc4; }
.info-icon[data-tooltip]:hover::after, .card-info-icon[data-tooltip]:hover::after { content: attr(data-tooltip); position: absolute; top: calc(100% + 6px); left: 50%; transform: translateX(-50%); background: #312556; color: #fff; font-size: 0.75rem; font-weight: 400; text-transform: none; letter-spacing: normal; text-align: left; padding: 0.5rem 0.75rem; border-radius: 6px; white-space: normal; width: max-content; max-width: 260px; z-index: 100; line-height: 1.4; box-shadow: 0 4px 12px rgba(0,0,0,0.15); pointer-events: none; }
.info-icon[data-tooltip]:hover::before, .card-info-icon[data-tooltip]:hover::before { content: ""; position: absolute; top: calc(100% - 2px); left: 50%; transform: translateX(-50%); border: 6px solid transparent; border-bottom-color: #312556; z-index: 100; pointer-events: none; }
/* Suppress CSS tooltips inside scroll containers — JS tooltip handles these */
th .info-icon[data-tooltip]:hover::after,
th .info-icon[data-tooltip]:hover::before,
td .info-icon[data-tooltip]:hover::after,
td .info-icon[data-tooltip]:hover::before { display: none; }
/* JS-powered tooltip that renders on <body> to escape overflow clipping */
.js-tooltip { position: fixed; background: #312556; color: #fff; font-size: 0.75rem; font-weight: 400; text-align: left; padding: 0.5rem 0.75rem; border-radius: 6px; white-space: normal; width: max-content; max-width: 260px; z-index: 9999; line-height: 1.4; box-shadow: 0 4px 12px rgba(0,0,0,0.15); pointer-events: none; }
/* Card info icon positioned top-right */
.card-info-icon { position: absolute; top: 0.6rem; right: 0.75rem; font-size: 1rem; }
.summary-value { font-size: 1.4rem; font-weight: 700; color: #1a1a2e; }
.summary-value.positive { color: #0cce6b; }
.summary-value.negative { color: #ff6b6b; }

/* ── Charts ───────────────────────────────────────────────────────────────── */
.chart-container { background: white; border-radius: 8px; padding: 1.25rem; box-shadow: 0 1px 3px rgba(0,0,0,0.08); margin-bottom: 1.5rem; height: 350px; }
.chart-container canvas { width: 100% !important; height: 100% !important; }
.model-charts { margin-bottom: 1.5rem; }
.model-charts-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }
.model-chart-box { margin-bottom: 0; position: relative; }
.model-chart-box .chart-title { font-size: 1rem; font-weight: 600; color: #1a1a2e; margin-bottom: 0.5rem; display: flex; align-items: center; gap: 0.5rem; }
.model-chart-box canvas { height: calc(100% - 1.5rem) !important; }
/* Chart download button (PNG export for PowerPoint/Slides) */
.chart-download-btn {
  margin-left: auto;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 4px;
  font-size: 0.95rem;
  cursor: pointer;
  color: #888;
  padding: 0.15rem 0.4rem;
  font-family: inherit;
  line-height: 1;
  transition: all 0.15s;
}
.chart-download-btn:hover { background: #f0f2f5; color: #312556; border-color: #d0c8de; }
.chart-download-btn:active { background: #e2dcef; }
@media print { .chart-download-btn { display: none !important; } }

/* ── Data Tables ──────────────────────────────────────────────────────────── */
.table-container { background: white; border-radius: 8px; box-shadow: 0 1px 3px rgba(0,0,0,0.08); overflow-x: auto; }
.table-actions { display: flex; justify-content: flex-end; padding: 0.25rem 0.5rem; gap: 0.35rem; }
.btn-sm { font-size: 0.75rem; padding: 0.25rem 0.6rem; }
.data-table { width: 100%; border-collapse: collapse; font-size: 0.85rem; }
.data-table th { background: #f8f9fa; padding: 0.6rem 1rem; text-align: right; font-weight: 600; color: #555; border-bottom: 2px solid #eee; position: sticky; top: 0; }
.data-table th:first-child { text-align: left; }
.data-table td { padding: 0.5rem 1rem; text-align: right; border-bottom: 1px solid #f0f0f0; }
.data-table td:first-child { text-align: left; font-weight: 500; }
.data-table tr:hover { background: #f8f9fa; }
.cell-positive { color: #0cce6b; }
.cell-negative { color: #ff6b6b; }

/* ── Live Model ───────────────────────────────────────────────────────────── */
.model-container { background: white; border-radius: 8px; box-shadow: 0 1px 3px rgba(0,0,0,0.08); overflow: hidden; }
.model-toolbar { padding: 1rem 1.25rem; border-bottom: 1px solid #eee; display: flex; align-items: center; gap: 1rem; flex-wrap: wrap; }
.model-toolbar .btn-export:first-of-type { margin-left: auto; }
.model-title { font-size: 1.1rem; font-weight: 700; }
.model-subtitle { font-size: 0.85rem; color: #888; }
.view-scenario-subtitle { font-size: 0.82rem; color: #888; margin-bottom: 0.5rem; padding: 0 0.25rem; }
/* Horizontal scroll inside for the wide month columns; vertical lets the table
   render at its full natural height (page scrolls if needed). */
.model-scroll { overflow-x: auto; overflow-y: visible; }
.model-scroll-top { overflow-x: auto; overflow-y: hidden; height: 14px; border-bottom: 1px solid #eee; background: #fafbfc; }
.model-scroll-top-inner { height: 1px; }

.model-year-tabs { display: flex; gap: 0.25rem; }
.model-year-tab { padding: 0.3rem 0.65rem; border: 1px solid #ddd; border-radius: 4px; background: white; cursor: pointer; font-size: 0.8rem; color: #555; font-family: inherit; }
.model-year-tab:hover { background: #f5f5f5; }
.model-year-tab.active { background: #312556; color: white; border-color: #312556; }

.btn-jump-today { padding: 0.3rem 0.7rem; border: 1px solid #4ecdc4; border-radius: 4px; background: white; color: #3bb3aa; cursor: pointer; font-size: 0.8rem; font-family: inherit; font-weight: 600; }
.btn-jump-today:hover { background: #e8fbf9; }

.model-table { width: 100%; border-collapse: collapse; font-size: 0.85rem; }
.model-table thead th { background: #f8f9fa; padding: 0.5rem 0.75rem; text-align: right; font-weight: 600; color: #555; border-bottom: 2px solid #eee; white-space: nowrap; min-width: 110px; position: sticky; top: 0; z-index: 15; }
.model-table thead th:first-child { text-align: left; position: sticky; left: 0; top: 0; background: #f8f9fa; z-index: 25; min-width: 180px; }
/* Floating thead clone — pinned to viewport when scrolled past the original.
   See setupFloatingModelThead() in app.js. Subtle shadow so the divide between
   the clone and the table rows below it reads as a layer, not a duplicate. */
.model-thead-floating { box-shadow: 0 2px 4px rgba(0,0,0,0.05); }
.model-thead-floating-table { border-collapse: collapse; }
@media print { .model-thead-floating { display: none !important; } }
.model-table td { padding: 0.5rem 0.75rem; text-align: right; border-bottom: 1px solid #f0f0f0; white-space: nowrap; }
.model-table tbody td:first-child { text-align: left; font-weight: 600; position: sticky; left: 0; background: white; z-index: 10; }
.model-table tr:hover td { background: #f8f9fa; }
.model-table tr:hover td:first-child { background: #f0f2f5; }
/* Editable cells: light yellow background, pointer cursor */
.model-table .editable { background: #fffde7; cursor: pointer; transition: background 0.15s; }
.model-table .editable:hover { background: #fff9c4; }
.model-table .editable:focus { outline: 2px solid #4ecdc4; outline-offset: -2px; background: #fff9c4; }
/* Cells with a manual override: blue left border indicator */
.model-table .has-override { box-shadow: inset 3px 0 0 #4ecdc4; font-weight: 600; }
/* Inline input when editing a cell */
.model-table .cell-input { width: 100%; border: none; background: white; text-align: right; font-size: 0.85rem; font-family: inherit; padding: 0; outline: none; font-weight: 500; }
.model-table .cell-input::placeholder { color: #bbb; font-weight: 400; font-style: italic; }
/* Sub-row styling for AR Adjustment and R2.1 OpEx detail rows */
.model-table .row-sub td:first-child { padding-left: 1.5rem; font-weight: 400; font-size: 0.8rem; color: #888; }
/* Revenue sub-sub-row (e.g. Modeled MRR Additions under Platform MRR) — extra indent */
.model-table .revenue-sub-sub td:first-child { padding-left: 2.5rem; font-size: 0.78rem; font-style: italic; }
/* R2.1: OpEx collapse/expand toggle */
.opex-collapse-toggle { cursor: pointer; display: inline-block; color: #94a3b8; font-size: 0.7rem; width: 1rem; text-align: center; transition: color 0.15s; user-select: none; }
.opex-collapse-toggle:hover { color: #1a1a2e; }
/* R2.1: hide OpEx sub-rows when collapsed */
.model-table tbody.opex-collapsed .opex-sub { display: none; }
/* R2.2: % of Total Revenue toggle button */
.pct-toggle {
  cursor: pointer; display: inline-block; font-size: 0.65rem; font-weight: 700;
  padding: 1px 4px; border-radius: 3px; margin-left: 4px; user-select: none;
  transition: background 0.15s, color 0.15s; vertical-align: middle;
  border: 1px solid #94a3b8; color: #94a3b8; background: transparent;
}
.pct-toggle.pct-active { background: #312556; color: #fff; border-color: #312556; }
.pct-toggle:hover { border-color: #1a1a2e; color: #1a1a2e; }
/* R2.2: % rows — small, gray, italic, extra indent, subordinate to dollar row */
.model-table .pct-row td:first-child {
  padding-left: 3rem; font-size: 0.75rem; color: #888; font-style: italic; font-weight: 400;
}
.model-table .pct-row td { color: #888; font-size: 0.75rem; font-style: italic; }
/* R2.2: hide % rows when pct-collapsed */
.model-table tbody.pct-collapsed .pct-row { display: none; }
/* R3: Revenue / Funding collapse toggles — mirror the OpEx chevron pattern */
.revenue-collapse-toggle,
.funding-collapse-toggle {
  cursor: pointer; display: inline-block; color: #94a3b8; font-size: 0.7rem;
  width: 1rem; text-align: center; transition: color 0.15s; user-select: none;
}
.revenue-collapse-toggle:hover,
.funding-collapse-toggle:hover { color: #1a1a2e; }
/* R3: hide Revenue / Funding sub-rows when collapsed */
.model-table tbody.revenue-collapsed .revenue-sub { display: none; }
.model-table tbody.funding-collapsed .funding-sub { display: none; }
/* R2.2: forecast-default cells — italicized, muted color */
.model-table td.forecast-default { color: #999; font-style: italic; }
.model-table .row-header { font-weight: 700; color: #1a1a2e; }
.model-table .row-computed { color: #333; }
.model-table .row-burn { font-weight: 700; color: #1a1a2e; background: #f8f9fa; }
.model-table .row-burn td { border-top: 2px solid #312556; border-bottom: 1px solid #d0c8de; }
.model-table .row-cash { font-weight: 700; color: #1a1a2e; }
.model-table .row-runway { font-weight: 700; color: #1a1a2e; }
.model-table .row-runway td { border-top: 2px solid #312556; }
/* Section dividers — heavy top border on rows that start a new logical section */
.model-table .row-section-start td { border-top: 2px solid #c4bdd1; }
.model-table .value-negative { color: #ff6b6b; }
.model-table .value-positive { color: #0cce6b; }
/* Negative cash is a critical signal — make it unmistakable on the bold Cash row.
   The default light coral gets washed out at row-cash's font-weight 700, so override
   with a deeper red + pale-pink background so insolvent months pop on screen + print. */
.model-table .row-cash td.value-negative {
  color: #c53030;
  background-color: #fef2f2;
}
.model-table .value-warning { color: #ff9f43; font-weight: 700; }
/* Legend for model editing */
.model-legend { padding: 0.5rem 1.25rem; border-top: 1px solid #eee; display: flex; gap: 1.5rem; font-size: 0.75rem; color: #888; }
.model-legend-item { display: flex; align-items: center; gap: 0.35rem; }
.model-legend-swatch { width: 14px; height: 14px; border-radius: 2px; border: 1px solid #ddd; }
.model-legend-swatch.swatch-editable { background: #fffde7; }
.model-legend-swatch.swatch-override { background: #fffde7; border-left: 3px solid #4ecdc4; }
.model-legend-swatch.swatch-inherited { background: #f5f5f5; border-left: 3px dotted #aaa; }
.model-legend-inherited { display: none; } /* shown only on non-default scenarios */
body.scenario-non-default .model-legend-inherited { display: flex; }

/* Inherited cells: a value derived from the default scenario at read time
   (the user can edit to create a scenario-specific override). Visually
   distinct from "manual override" (teal border) and "no override" (yellow
   editable bg) so users can see at a glance which fields the active
   scenario has explicitly customized vs. inherited unchanged. */
.model-table td.is-inherited {
  background: #f5f5f5; /* slightly darker than editable yellow — visually "borrowed" */
  color: #555;
  font-style: italic;
}
.model-table td.is-inherited::before {
  content: "↪ "; /* subtle hint that the value comes from elsewhere */
  color: #aaa;
  margin-right: 1px;
  font-style: normal;
}

/* Inheritance banner above the model table — only shown on non-default scenarios. */
.model-inheritance-banner {
  background: #fef9e7;
  border-left: 3px solid #d4a017;
  padding: 0.5rem 1rem;
  font-size: 0.8rem;
  color: #6c5a18;
  line-height: 1.45;
  margin: 0 1rem 0.25rem;
  border-radius: 0 4px 4px 0;
}
.model-inheritance-banner strong { color: #4a3e10; }
/* #81: warning banner shown on the Live Model when ALL sales channels are
   deselected (channels:[]) — SF revenue is excluded and only the manual MRR
   layer remains, which would otherwise silently zero the flagship model. */
.model-channels-empty-banner {
  background: #fff4e5;
  border-left: 3px solid #e07b00;
  padding: 0.5rem 1rem;
  font-size: 0.8rem;
  color: #7a4a00;
  line-height: 1.45;
  margin: 0 1rem 0.25rem;
  border-radius: 0 4px 4px 0;
}

/* ── Admin ────────────────────────────────────────────────────────────────── */
.admin-layout { display: flex; flex-direction: column; gap: 1.5rem; }
.admin-section { background: white; border-radius: 8px; padding: 1.25rem; box-shadow: 0 1px 3px rgba(0,0,0,0.08); }
.admin-section h2 { font-size: 1rem; margin-bottom: 0.5rem; }
.admin-section-desc { font-size: 0.85rem; color: #555; margin-bottom: 1rem; }
/* B4: Hygiene report opp sub-row styling */
.hygiene-opp-section td { padding: 0; }
.hygiene-opp-subrow td { padding: 0.3rem 0.5rem; }
.admin-toolbar { margin-bottom: 1rem; }
.admin-sync { display: flex; align-items: center; gap: 1rem; margin-bottom: 1rem; }
.sync-result { font-size: 0.85rem; padding: 0.5rem 1rem; border-radius: 4px; }
.sync-result.success { background: #e8f5e9; color: #2e7d32; }
.sync-result.error { background: #fef2f2; color: #991b1b; }
.sync-log-info { font-size: 0.85rem; color: #666; }

/* ── Modal ────────────────────────────────────────────────────────────────── */
.modal-overlay { position: fixed; inset: 0; background: rgba(0,0,0,0.5); z-index: 200; display: flex; align-items: center; justify-content: center; }
#opp-detail-modal { z-index: 210; background: rgba(0,0,0,0.3); }
.modal { background: white; border-radius: 8px; width: 90vw; max-width: 1100px; min-width: 600px; max-height: 85vh; display: flex; flex-direction: column; box-shadow: 0 8px 32px rgba(0,0,0,0.2); }

/* ── Confirmation modal (replaces native confirm() across the app) ─────── */
.confirm-overlay {
  position: fixed; inset: 0;
  background: rgba(0,0,0,0.5);
  z-index: 1000; /* above all other modals so it's always on top */
  display: flex; align-items: center; justify-content: center;
  animation: confirm-fade-in 0.12s ease-out;
}
@keyframes confirm-fade-in { from { opacity: 0; } to { opacity: 1; } }
.confirm-modal {
  background: white;
  border-radius: 8px;
  padding: 1.25rem 1.5rem 1rem;
  max-width: 480px;
  min-width: 320px;
  box-shadow: 0 8px 32px rgba(0,0,0,0.25);
}
.confirm-title {
  font-size: 1rem;
  font-weight: 700;
  color: #1a1a2e;
  margin: 0 0 0.6rem;
  line-height: 1.4;
}
.confirm-message {
  font-size: 0.875rem;
  color: #4a5568;
  margin: 0 0 1.25rem;
  line-height: 1.5;
  white-space: pre-line; /* preserve \n in message strings */
}
/* Optional secondary callout, used to draw extra attention to a caveat
   (e.g., set-default's "each swap is one-way" warning). Visually distinct
   from .confirm-message: subtle border + label, neutral color so it
   informs rather than alarms. */
.confirm-note {
  display: flex;
  gap: 0.6rem;
  align-items: flex-start;
  padding: 0.7rem 0.85rem;
  margin: 0 0 1.25rem;
  background: #f7f6fb;
  border-left: 3px solid #6b5b95;
  border-radius: 4px;
}
.confirm-note-label {
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: #6b5b95;
  flex-shrink: 0;
  padding-top: 0.05rem;
}
.confirm-note-body {
  font-size: 0.8rem;
  color: #4a5568;
  line-height: 1.45;
}
.confirm-actions {
  display: flex;
  gap: 0.5rem;
  justify-content: flex-end;
}
.confirm-actions .btn {
  min-width: 80px;
}
/* Prompt form fields (used inside .confirm-modal for promptForm()) */
.prompt-fields { margin-bottom: 1.25rem; display: flex; flex-direction: column; gap: 0.85rem; }
.prompt-field { display: flex; flex-direction: column; gap: 0.3rem; }
.prompt-label { font-size: 0.8rem; font-weight: 600; color: #4a5568; }
.prompt-input {
  width: 100%;
  padding: 0.5rem 0.65rem;
  border: 1px solid #cbd5e0;
  border-radius: 4px;
  font-size: 0.9rem;
  font-family: inherit;
  background: white;
  color: #1a1a2e;
  outline: none;
  transition: border-color 0.15s, box-shadow 0.15s;
}
.prompt-input:focus {
  border-color: #312556;
  box-shadow: 0 0 0 3px rgba(49, 37, 86, 0.12);
}
#drilldown-modal .modal, #opp-overrides-modal .modal { max-width: 1400px; }
.modal-header { display: flex; justify-content: space-between; align-items: center; padding: 1rem 1.25rem; border-bottom: 1px solid #eee; }
.modal-header h2 { font-size: 1.1rem; font-weight: 700; }
.modal-close { background: none; border: none; font-size: 1.5rem; cursor: pointer; color: #888; padding: 0 0.25rem; line-height: 1; width: auto; height: auto; }
.modal-close:hover { color: #333; }
.modal-summary { padding: 0.75rem 1.25rem; background: #f8f9fa; display: flex; gap: 2rem; font-size: 0.85rem; border-bottom: 1px solid #eee; }
.modal-summary .summary-item { display: flex; flex-direction: column; }
.modal-summary .summary-item .label { font-size: 0.7rem; color: #888; text-transform: uppercase; letter-spacing: 0.04em; }
.modal-summary .summary-item .value { font-weight: 700; font-size: 1rem; }
.modal-body { overflow: auto; padding: 0; flex: 1 1 auto; min-height: 0; }
.modal-body .data-table { font-size: 0.8rem; }
.modal-body .data-table th { font-size: 0.75rem; position: sticky; top: 0; z-index: 1; }
.modal-body .data-table td { padding: 0.4rem 0.75rem; }
.modal-body .data-table td:first-child, .modal-body .data-table th:first-child { max-width: 160px; overflow: hidden; text-overflow: ellipsis; }

/* Clickable month headers in model table */
.model-table th.clickable { cursor: pointer; transition: color 0.15s; }
.model-table th.clickable:hover { color: #4ecdc4; }

/* ── Account Selector ────────────────────────────────────────────────────── */
.account-selector { border: 1px solid #ddd; border-radius: 4px; overflow: hidden; }
.account-search { width: 100%; padding: 0.4rem 0.5rem; border: none; border-bottom: 1px solid #eee; font-size: 0.8rem; outline: none; box-sizing: border-box; }
.account-search:focus { border-bottom-color: #4ecdc4; }
.account-list { max-height: 160px; overflow-y: auto; padding: 0.25rem 0; }
.account-list label { display: flex; align-items: center; gap: 0.4rem; padding: 0.2rem 0.5rem; font-size: 0.8rem; cursor: pointer; transition: background 0.1s; }
.account-list label:hover { background: #f5f5f5; }
.account-list label.hidden { display: none; }
.account-list input[type="checkbox"] { margin: 0; flex-shrink: 0; }
.account-list .no-results { padding: 0.5rem; font-size: 0.8rem; color: #999; text-align: center; }
.account-list label.account-selected { background: #fff3e0; border-left: 2px solid #ff9800; font-weight: 500; }
.account-list label.account-selected:hover { background: #ffe0b2; }
.account-count { display: block; font-size: 0.7rem; color: #e65100; font-weight: 600; padding: 0.2rem 0.5rem; background: #fff8e1; border-bottom: 1px solid #ffe082; }
.account-count:empty { display: none; }

/* ── Scenario Management ─────────────────────────────────────────────────── */
.btn-icon { background: none; border: none; color: rgba(255,255,255,0.6); cursor: pointer; font-size: 1.1rem; padding: 0.15rem 0.35rem; border-radius: 4px; transition: all 0.15s; line-height: 1; width: auto; height: auto; }
.btn-icon:hover { color: white; background: rgba(255,255,255,0.1); }
.scenario-card { border: 1px solid #eee; border-radius: 6px; padding: 0.75rem 1rem; margin-bottom: 0.75rem; display: flex; justify-content: space-between; align-items: center; transition: border-color 0.15s; }
.scenario-card:hover { border-color: #ccc; }
.scenario-card.is-default { border-left: 3px solid #4ecdc4; }
.scenario-card-info { flex: 1; }
.scenario-card-name { font-weight: 600; font-size: 0.95rem; }
.scenario-card-meta { font-size: 0.75rem; color: #888; margin-top: 0.2rem; }
.scenario-card-actions { display: flex; gap: 0.4rem; align-items: center; }
.scenario-badge { display: inline-block; font-size: 0.65rem; text-transform: uppercase; letter-spacing: 0.04em; padding: 0.15rem 0.4rem; border-radius: 3px; background: #4ecdc4; color: white; font-weight: 600; margin-left: 0.5rem; }

/* ── Drill-down Links ────────────────────────────────────────────────────── */
.drilldown-link { color: #1a1a2e; text-decoration: none; border-bottom: 1px dashed #aaa; transition: all 0.15s; }
.drilldown-link:hover { color: #4ecdc4; border-bottom-color: #4ecdc4; }

/* ── Drill-down Table Alignment ──────────────────────────────────────────── */
#drilldown-table td { text-align: left; }
#drilldown-table .cell-num { text-align: right; }
#drilldown-table a { color: #1a6fb5; text-decoration: none; }
#drilldown-table a:hover { color: #4ecdc4; text-decoration: underline; }
#drilldown-table th.sortable { user-select: none; }
#drilldown-table th.sortable:hover { color: #4ecdc4; }

/* ── Loading ──────────────────────────────────────────────────────────────── */
.loading { text-align: center; padding: 2rem; color: #888; }
.spinner { display: inline-block; width: 24px; height: 24px; border: 3px solid #eee; border-top-color: #312556; border-radius: 50%; animation: spin 0.8s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }

/* ── Projection Settings ─────────────────────────────────────────────────── */
.projection-section { border-top: 1px solid #e5e7eb; padding-top: 0.75rem; margin-top: 0.5rem; }
.projection-toggle { font-weight: 600; font-size: 0.85rem; }
.projection-options { margin-top: 0.5rem; padding-left: 0.25rem; }
.projection-option { margin-bottom: 0.6rem; }
.projection-option label { display: block; font-size: 0.8rem; margin-bottom: 0.2rem; }
.projection-input { width: 100%; padding: 0.35rem 0.5rem; border: 1px solid #ddd; border-radius: 4px; font-size: 0.8rem; }

/* ── Projection Banner ───────────────────────────────────────────────────── */
.projection-banner { background: linear-gradient(135deg, #eef6ff 0%, #f0f0ff 100%); border: 1px solid #c3d8f0; border-left: 4px solid #4a90d9; border-radius: 6px; padding: 0.75rem 1rem; margin-bottom: 1rem; font-size: 0.82rem; line-height: 1.5; }
.projection-banner-title { font-weight: 700; color: #2c5282; margin-bottom: 0.25rem; display: flex; align-items: center; gap: 0.4rem; }
.projection-banner-title::before { content: "📈"; }
.projection-banner-details { color: #4a5568; }
.projection-banner-detail { display: inline-block; margin-right: 1.2rem; }
.projection-banner-detail strong { color: #2d3748; }
/* R1.3: Live Model override notice inside the projection banner */
/* Small caption line under the main projection-details — sources / origin. */
.projection-banner-meta { font-size: 0.72rem; color: #718096; margin-top: 0.15rem; font-style: italic; }
/* Notice sections inside the banner: only show the top separator when there's
   a preceding sibling. Without this, an orphan separator line appears at the
   top of the banner when only one notice fires (Jake spotted this 2026-05-20). */
.projection-banner-override-notice { color: #2d3748; }
/* B3: Renewal projection notice inside the projection banner */
.projection-banner-renewal-notice { color: #234e52; }
/* Sibling-combinator separators: only apply when a notice section is NOT
   the first child of the banner. Defeats the orphan-line issue. */
.projection-banner > * + .projection-banner-override-notice {
  margin-top: 0.5rem;
  padding-top: 0.5rem;
  border-top: 1px solid #c3d8f0;
}
.projection-banner > * + .projection-banner-renewal-notice {
  margin-top: 0.5rem;
  padding-top: 0.5rem;
  border-top: 1px solid #b2f5ea;
}

/* ── Actual Row Indicators (Dashboard) ──────────────────────────────────── */
.row-actual { background: #f0faf5 !important; }
.actual-badge { display: inline-block; font-size: 0.6rem; text-transform: uppercase; letter-spacing: 0.04em; padding: 0.1rem 0.3rem; border-radius: 3px; background: #38a169; color: white; font-weight: 600; margin-left: 0.35rem; vertical-align: middle; }
.actual-divider td { border-top: 2px solid #38a169 !important; }

/* ── Projected Row Indicators (Dashboard) ──────────────────────────────── */
.row-projected { background: #f0f6ff !important; }
.row-projected td:first-child { position: relative; }
.projected-badge { display: inline-block; font-size: 0.6rem; text-transform: uppercase; letter-spacing: 0.04em; padding: 0.1rem 0.3rem; border-radius: 3px; background: #4a90d9; color: white; font-weight: 600; margin-left: 0.35rem; vertical-align: middle; }
.projected-divider td { border-top: 2px dashed #4a90d9 !important; }

/* ── R1.3: Live Model Override Row Indicators (Dashboard) ─────────────── */
/* Override months share the projected row background (forward-looking, not SF data)
   but use a distinct teal badge to signal "manually entered in Live Model". */
.row-mrr-override { background: #f0f6ff !important; }
.override-badge { display: inline-block; font-size: 0.6rem; text-transform: uppercase; letter-spacing: 0.04em; padding: 0.1rem 0.3rem; border-radius: 3px; background: #4ecdc4; color: white; font-weight: 600; margin-left: 0.35rem; vertical-align: middle; cursor: help; }

/* ── Actual columns in Live Model ──────────────────────────────────────── */
.model-table th.col-actual { background: #e6f7ed; color: #22543d; position: relative; }
.model-table th.col-actual::after { content: "actual"; display: block; font-size: 0.55rem; text-transform: uppercase; letter-spacing: 0.05em; color: #38a169; font-weight: 500; }
.model-table td.col-actual { background: rgba(56, 161, 105, 0.04); }

/* ── Projected columns in Live Model ─────────────────────────────────────── */
.model-table th.col-projected { background: #e8f0fe; color: #2c5282; position: relative; }
.model-table th.col-projected::after { content: "projected"; display: block; font-size: 0.55rem; text-transform: uppercase; letter-spacing: 0.05em; color: #4a90d9; font-weight: 500; }
.model-table td.col-projected { background: rgba(74, 144, 217, 0.04); }

/* ── How It Works Page ──────────────────────────────────────────────────── */
.help-page { max-width: 800px; margin: 0 auto; }
.help-page h2 { font-size: 1.4rem; margin-bottom: 0.5rem; color: #1a1a2e; }
.help-intro { color: #555; margin-bottom: 2rem; line-height: 1.6; }
.help-section { background: white; border-radius: 8px; padding: 1.25rem 1.5rem; margin-bottom: 1rem; box-shadow: 0 1px 3px rgba(0,0,0,0.08); }
.help-section h3 { font-size: 1rem; color: #1a1a2e; margin-bottom: 0.5rem; }
.help-section p { font-size: 0.9rem; color: #444; line-height: 1.6; margin-bottom: 0.5rem; }
.help-section ul { margin: 0.5rem 0 0.5rem 1.5rem; font-size: 0.9rem; color: #444; line-height: 1.8; }
.help-formula-table { width: 100%; border-collapse: collapse; margin: 0.75rem 0; font-size: 0.85rem; }
.help-formula-table td { padding: 0.4rem 0.75rem; border-bottom: 1px solid #eee; }
.help-formula-table td:first-child { width: 160px; white-space: nowrap; }

/* ── Projected Drilldown ─────────────────────────────────────────────────── */
.projection-drilldown-info { text-align: center; padding: 2rem; color: #4a5568; }
.projection-drilldown-info h3 { color: #2c5282; margin-bottom: 0.75rem; }
.projection-formula { background: #f0f6ff; border: 1px solid #c3d8f0; border-radius: 6px; padding: 1rem; margin: 1rem auto; max-width: 500px; font-family: 'SF Mono', monospace; font-size: 0.85rem; }
.projection-formula .formula-label { font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.05em; color: #718096; margin-bottom: 0.25rem; }
.projection-formula .formula-value { color: #2c5282; font-weight: 600; }

/* ── Chart Tabs ────────────────────────────────────────────────────────────── */
.chart-tabs { display: flex; gap: 0; margin-bottom: -1px; background: white; border-radius: 8px 8px 0 0; padding: 0.5rem 1rem 0; box-shadow: 0 1px 3px rgba(0,0,0,0.08); position: relative; z-index: 1; }
.chart-tab { background: none; border: none; color: #718096; padding: 0.5rem 1rem; cursor: pointer; font-size: 0.82rem; font-weight: 500; border-bottom: 2px solid transparent; transition: all 0.2s; }
.chart-tab:hover { color: #2d3748; }
.chart-tab.active { color: #1a1a2e; border-bottom-color: #4ecdc4; }

/* ── ARR Bridge ────────────────────────────────────────────────────────────── */
.bridge-metrics-banner { background: white; border-radius: 8px; padding: 1rem 1.25rem; box-shadow: 0 1px 3px rgba(0,0,0,0.08); margin-bottom: 1rem; }
.bridge-metrics-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 0.75rem; }
.bridge-metric { text-align: center; padding: 0.5rem; }
.bridge-metric-label { font-size: 0.65rem; text-transform: uppercase; letter-spacing: 0.05em; color: #718096; margin-bottom: 0.2rem; }
.bridge-metric-value { font-size: 1.1rem; font-weight: 700; color: #1a1a2e; }
.bridge-metric-value.positive { color: #38a169; }
.bridge-metric-value.negative { color: #e53e3e; }
.bridge-metric-sub { font-size: 0.7rem; color: #a0aec0; margin-top: 0.1rem; }

.bridge-methodology { background: white; border-radius: 8px; padding: 0 1.25rem; box-shadow: 0 1px 3px rgba(0,0,0,0.08); margin-bottom: 1rem; }
.bridge-methodology details { padding: 0.75rem 0; }
.bridge-methodology summary { font-size: 0.82rem; font-weight: 600; color: #4a5568; cursor: pointer; user-select: none; }
.bridge-methodology summary:hover { color: #2d3748; }
.methodology-content { padding: 0.75rem 0; font-size: 0.8rem; line-height: 1.6; color: #4a5568; }
.methodology-content p { margin-bottom: 0.5rem; }
.methodology-content ul { margin: 0.5rem 0 0.5rem 1.5rem; }
.methodology-content li { margin-bottom: 0.3rem; }
.methodology-content code { background: #f0f2f5; padding: 0.15rem 0.4rem; border-radius: 3px; font-size: 0.75rem; }
.method-color { display: inline-block; width: 12px; height: 12px; border-radius: 2px; vertical-align: middle; margin-right: 0.3rem; }
.method-new { background: #38a169; }
.method-expansion { background: #4299e1; }
.method-contraction { background: #ed8936; }
.method-churn { background: #e53e3e; }

/* Bridge table coloring */
#bridge-table .col-positive { color: #38a169; }
#bridge-table .col-negative { color: #e53e3e; }
#bridge-table td.cell-new { color: #38a169; font-weight: 500; }
#bridge-table td.cell-expansion { color: #4299e1; font-weight: 500; }
#bridge-table td.cell-contraction { color: #ed8936; font-weight: 500; }
#bridge-table td.cell-churn { color: #e53e3e; font-weight: 500; }
#bridge-table td.cell-prob-adj { color: #805ad5; font-weight: 500; }
#bridge-table td.cell-net-positive { color: #38a169; font-weight: 600; }
#bridge-table td.cell-net-negative { color: #e53e3e; font-weight: 600; }
#bridge-table td.cell-ending { font-weight: 700; }
#bridge-table { min-width: 1100px; }
#bridge-table th, #bridge-table td { white-space: nowrap; padding: 0.6rem 0.75rem; font-size: 0.8rem; }
#bridge-table th:first-child, #bridge-table td:first-child { position: sticky; left: 0; background: white; z-index: 1; }
#bridge-table th:first-child { background: #f8f9fa; }

/* Clickable bridge cells */
#bridge-table td.bridge-clickable { cursor: pointer; position: relative; }
#bridge-table td.bridge-clickable:hover { text-decoration: underline; filter: brightness(0.85); }
#bridge-table td.bridge-clickable .bridge-cell-inner { pointer-events: none; }

/* Clickable month names in bridge table */
.bridge-month-link { cursor: pointer; color: #4299e1; text-decoration: none; }
.bridge-month-link:hover { text-decoration: underline; }

/* Bridge detail sub-rows for multi-opp accounts */
.bridge-detail-opp-row td { border-top: none !important; padding-top: 0.15rem !important; padding-bottom: 0.15rem !important; font-size: 0.78rem; }
.bridge-detail-opp-row td:first-child { border-top: none !important; }
.bridge-detail-account-row td { border-bottom: none !important; padding-bottom: 0.25rem !important; }

/* ── Desktop-App Responsiveness (Issue #25) ─────────────────────────────── */
/* Global min-width on body (1080px) prevents layout collapse; horizontal
   scroll on small viewports follows the same pattern as Jira/Linear/Figma.
   Two breakpoints handle "half-screen on a computer" comfort. */

@media (max-width: 1280px) {
  /* Header: reclaim space */
  .header-left { gap: 1rem; }
  .header-right { gap: 0.75rem; }
  .nav-tab, .nav-more-toggle { padding: 0.5rem 0.65rem; font-size: 0.8rem; }
  .scenario-selector label { display: none; }
  /* Keep the trigger visible so logout stays reachable — hide the email text, keep caret */
  .user-menu-email { max-width: 0; padding: 0; opacity: 0; }
  .user-menu-trigger::before { content: "\1F464"; font-size: 0.95rem; line-height: 1; }

  /* Layout: reduce padding, shrink sidebar */
  .app-layout { grid-template-columns: 1fr 240px; gap: 1rem; padding: 1rem; }
  .filters-panel { padding: 1rem; }

  /* Charts: stack model chart grid vertically */
  .model-charts-grid { grid-template-columns: 1fr; }
  .chart-container { padding: 1rem; margin-bottom: 1rem; }

  /* Modals: tighten summary spacing */
  .modal-summary { gap: 1rem; flex-wrap: wrap; }
}

@media (max-width: 1100px) {
  /* Sidebar becomes a floating overlay so content gets full width,
     but the filters toggle button stays visible and functional. */
  .app-layout { grid-template-columns: 1fr !important; }
  .filters-panel {
    position: fixed;
    top: 56px;
    right: 0;
    bottom: 0;
    width: 300px;
    z-index: 99;
    border-radius: 0;
    box-shadow: -4px 0 16px rgba(0,0,0,0.15);
    overflow-y: auto;
    /* JS toggle still controls display via inline style */
  }
}

/* Chunked Live Model tables: only visible during print (injected by JS). */
.print-chunked-tables { display: none; }

/* Print header element is inserted into the DOM by buildPrintHeader() during
   beforeprint and removed on afterprint. While the print dialog is open the
   on-screen body still renders the inserted element — without an explicit
   screen-mode rule the Harper SVG logo renders at its natural size (huge).
   Hide it on screen; @media print below restores it. */
.print-header { display: none; }
.customers-print-methodology { display: none; }

/* ── Print / PDF Export ──────────────────────────────────────────────────── */
@media print {
  /* Hide non-content elements */
  .header, .filters-panel, .nav-tabs, .table-actions, .model-toolbar .btn-export,
  .chart-tabs, .btn-export-pdf, .model-legend, .filters-toggle,
  .model-scroll-top, .model-year-tabs, .btn-jump-today,
  .scenario-selector, .sync-status, .user-info, .bridge-methodology { display: none !important; }

  /* Show charts in print — Chart.js canvas re-rendered at high DPR via beforeprint hook.
     Sizing math (designed to fit BOTH A4 and Letter landscape on one page):
       A4 landscape content area:    18.5cm tall (210mm − 2.5cm margins)
       Letter landscape content area: 19.1cm tall (216mm − 2.5cm margins)
       A4 is the tighter constraint (18.5cm available)
       Print header:                  ~1cm
       Available for charts:          ~17.5cm (using A4)
       2 rows × chart + 1 gap:        2H + 0.3cm = 17.5cm  →  H ≈ 8.6cm (≈325px)
     Setting max-height: 320px (~8.46cm) gives ~17.2cm total chart grid + 1cm header
     + 0.3cm bottom margin = ~18.5cm. Fits A4 exactly; comfortable on Letter. Going
     bigger (e.g. 350px → 9.26cm) overflows A4 by ~0.5cm and creates a phantom page 2.

     Visual treatment: drop the screen-mode box-shadow (Chrome's print engine
     renders shadows inconsistently across boxes — fuzzy, asymmetric, sometimes
     missing on one corner). Replace with a thin neutral border for visual
     separation; cleaner and more consistent in PDF. Also flatten the border-
     radius slightly for a more polished print look. */
  .chart-container, #chart-bridge-container {
    break-inside: avoid;
    margin-bottom: 0.3cm;
    max-height: 320px;
    box-shadow: none !important;
    border: 1px solid #e2e8f0 !important;
    border-radius: 4px !important;
    background: white !important;
  }
  .chart-container canvas, #chart-bridge-container canvas {
    max-width: 100% !important;
    max-height: 270px !important;  /* container 320px − title (~16px) − padding (~30px) */
    width: auto !important;
    height: auto !important;
    image-rendering: -webkit-optimize-contrast;
    image-rendering: crisp-edges;
  }
  /* 2-up grid for the Live Model charts. Lock the whole grid so it can't split
     across pages — the dashboard belongs on page 1, the table chunks on later pages. */
  .model-charts-grid {
    display: grid !important;
    grid-template-columns: 1fr 1fr !important;
    gap: 0.3cm !important;
    page-break-inside: avoid !important;
    break-inside: avoid !important;
  }
  .model-charts {
    page-break-inside: avoid !important;
    break-inside: avoid !important;
  }

  /* Bridge metrics banner — same clean-outline treatment as chart-container
     (drop screen box-shadow, replace with border, flatten radius). Chrome's
     print engine renders box-shadows inconsistently; a thin neutral border
     is sharper and more uniform across pages. */
  #bridge-metrics-banner {
    break-inside: avoid;
    margin-bottom: 0.3cm;
    padding: 0.3cm !important;
    box-shadow: none !important;
    border: 1px solid #e2e8f0 !important;
    border-radius: 4px !important;
    background: white !important;
  }
  /* Customers chart and table get the same clean-outline + page-break-avoid
     treatment as the dashboard. Hide the toggle (mode is fixed at print time
     to whatever the user selected). */
  body.printing.body-view-customers .customers-toggle,
  body.printing.body-view-customers .customers-truncate-banner,
  body.printing.body-view-channels .customers-toggle,
  body.printing.body-view-channels .customers-truncate-banner { display: none !important; }
  body.printing.body-view-customers .customers-header { margin-bottom: 0.3cm; }
  body.printing.body-view-customers .customers-title { font-size: 14px !important; }
  /* Print sizing: bigger than the dashboard charts because the Customers
     chart is the hero element of the page — bars + legend (~50 customers in
     'All' mode) need vertical room to read. Sized so the chart still leaves
     space below for the forecast banner + the first ~5 rows of the
     concentration table on page 1. */
  body.printing.body-view-customers .customers-chart-container,
  body.printing.body-view-channels .customers-chart-container { max-height: 540px !important; }
  body.printing.body-view-customers .customers-chart-container canvas,
  body.printing.body-view-channels .customers-chart-container canvas { max-height: 470px !important; }
  body.printing.body-view-customers .customers-table-container,
  body.printing.body-view-channels .customers-table-container {
    page-break-before: auto !important;
    page-break-inside: auto !important;
  }
  body.printing.body-view-customers .customers-table-container table,
  body.printing.body-view-channels .customers-table-container table { page-break-inside: auto !important; }
  body.printing.body-view-customers .customers-table-container thead,
  body.printing.body-view-channels .customers-table-container thead { display: table-header-group !important; }
  body.printing.body-view-customers .customers-table-container tr,
  body.printing.body-view-channels .customers-table-container tr { page-break-inside: avoid !important; }

  /* Summary cards for print — same clean-outline treatment as chart-container. */
  .summary-cards { break-inside: avoid; margin-bottom: 0.3cm; gap: 0.3cm !important; }
  .summary-cards .summary-card {
    padding: 0.3cm !important;
    font-size: 9px !important;
    box-shadow: none !important;
    border: 1px solid #e2e8f0 !important;
    border-radius: 4px !important;
    background: white !important;
  }
  .summary-cards .summary-card .summary-value { font-size: 14px !important; }
  .card-info-icon, .info-icon { display: none !important; }

  /* Reset layout */
  body { background: white !important; font-size: 11px !important; }
  .app-layout { display: block !important; padding: 0 !important; }
  .view { display: none !important; }
  .view.active { display: block !important; }

  /* Print header with title and date */
  body.printing::before {
    content: attr(data-print-title);
    display: block;
    font-size: 18px;
    font-weight: 700;
    color: #1a1a2e;
    padding: 0.5cm 0 0.15cm;
  }
  body.printing::after {
    content: "Generated " attr(data-print-date);
    display: block;
    font-size: 9px;
    color: #718096;
    margin-bottom: 0.4cm;
    padding-bottom: 0.3cm;
    border-bottom: 1px solid #e2e8f0;
  }

  /* Table formatting for print */
  .data-table, .model-table { width: 100% !important; font-size: 9px !important; border-collapse: collapse; }
  .data-table th, .data-table td, .model-table th, .model-table td {
    padding: 3px 6px !important; border: 1px solid #d0d0d0 !important;
    white-space: nowrap !important;
  }
  .data-table th, .model-table th { background: #f0f2f5 !important; font-weight: 600; color: #1a1a2e !important; }
  /* Preserve section dividers and result-row emphasis in print (override the
     uniform 1px cell border above with stronger top borders) */
  .model-table .row-section-start td { border-top: 2px solid #888 !important; }
  .model-table .row-burn td { border-top: 2.5px solid #312556 !important; background: #f4f0f9 !important; }
  .model-table .row-runway td { border-top: 2.5px solid #312556 !important; }
  .model-table .row-burn td:first-child, .model-table .row-runway td:first-child { font-weight: 700 !important; }
  /* Negative cash emphasis preserved in print */
  .model-table .row-cash td.value-negative {
    color: #c53030 !important;
    background-color: #fef2f2 !important;
  }

  /* Model table: remove scroll, show ALL columns (critical for PDF) */
  .model-scroll { overflow: visible !important; max-height: none !important; max-width: none !important; }
  /* Disable sticky positioning in print so headers/labels don't clip or stack oddly */
  .model-table thead th, .model-table thead th:first-child, .model-table tbody td:first-child { position: static !important; }
  /* PDF reflects the on-screen Total Operating Expense view: if sub-rows are
     collapsed, they stay hidden; if % rows are hidden, they stay hidden. The
     screen-side rules (.opex-collapsed .opex-sub { display: none }, etc.)
     apply naturally — no force-expand. The toggle controls themselves are
     hidden in print so the PDF looks clean. */
  .opex-collapse-toggle { display: none !important; }
  .pct-toggle { display: none !important; }
  .revenue-collapse-toggle { display: none !important; }
  .funding-collapse-toggle { display: none !important; }
  .model-container {
    background: none !important; box-shadow: none !important; border: none !important; overflow: visible !important;
  }
  /* Push the table to its own page(s) so it's not squeezed below the charts.
     Only applies when the chunked-tables system is NOT active (legacy / non-Live-Model
     prints). When .print-chunked-active is on the container, the container is hidden
     via display:none and the per-chunk page-break-before below handles pagination —
     applying both rules would create a blank page (one for the hidden container, one
     for the first chunk). */
  .model-container:not(.print-chunked-active) {
    page-break-before: always !important;
    break-before: page !important;
  }
  .model-table { table-layout: auto !important; width: 100% !important; font-size: 10px !important; }
  .model-table th, .model-table td { min-width: 0 !important; padding: 4px 6px !important; }
  .model-table th:first-child, .model-table td:first-child { position: static !important; min-width: 0 !important; }

  /* Keep table rows intact across page breaks and repeat the header on
     each printed page (for both the original and the chunked slices). */
  .model-table { page-break-inside: auto !important; break-inside: auto !important; }
  .model-table thead { display: table-header-group !important; }
  .model-table tfoot { display: table-footer-group !important; }
  .model-table tr { page-break-inside: avoid !important; break-inside: avoid !important; page-break-after: auto !important; }

  /* When chunked slices are active (see buildPrintChunkedModelTable), hide
     the original wide table and render each 12-month slice on its own page. */
  .model-container.print-chunked-active { display: none !important; }
  /* The wrapper itself starts on a new page — this puts the dashboard
     charts alone on page 1 and the first year chunk on page 2. We do NOT
     also page-break-before each chunk inside the wrapper, because Chrome's
     print engine generates a spurious blank page when both the wrapper and
     its first child have page-break-before. The chunk-to-chunk rule below
     handles pagination between years 2 and 3 etc. */
  .print-chunked-tables {
    display: block !important;
    page-break-before: always !important;
    break-before: page !important;
  }
  .print-chunked-table { width: 100% !important; margin-bottom: 0.4cm; }
  .print-chunked-table + .print-chunked-table {
    page-break-before: always !important;
    break-before: page !important;
  }

  /* Bridge table: remove sticky columns */
  #bridge-table th:first-child, #bridge-table td:first-child { position: static !important; }

  /* Table containers: remove scroll */
  .table-container { overflow: visible !important; }

  /* Model toolbar: show just the title */
  .model-toolbar { border: none !important; padding: 0 !important; }
  .model-title { display: none !important; } /* Title is in the print header now */
  .model-subtitle { display: none !important; }

  /* Actual column styling for print */
  .model-table th.col-actual { background: #e6f7ed !important; }
  .model-table td.col-actual { background: rgba(56, 161, 105, 0.06) !important; }
  .actual-badge { font-size: 7px !important; padding: 1px 3px !important; }

  /* Projected column styling for print */
  .model-table th.col-projected { background: #fef3cd !important; }

  /* ── Branded header (logo + scenario/section title) ─────────────────────── */
  .print-header {
    display: flex !important;
    align-items: center;
    gap: 0.4cm;
    padding: 0 0 0.25cm 0 !important;
    margin: 0 0 0.3cm 0 !important;
    border-bottom: 2px solid #312556 !important;
  }
  .print-header-logo {
    height: 0.9cm !important;
    width: auto !important;
    flex-shrink: 0;
  }
  .print-header-text {
    flex: 1;
    line-height: 1.15;
  }
  /* Brand line owns the top of every page — outweighs chart-titles below. */
  .print-header-brand {
    font-size: 20px !important;
    font-weight: 700 !important;
    color: #1a1a2e !important;
    letter-spacing: -0.005em;
    line-height: 1.1 !important;
  }
  .print-header-title {
    font-size: 12px !important;
    font-weight: 500 !important;
    color: #312556 !important;
    letter-spacing: 0.01em;
    margin-top: 0.05cm;
  }
  .print-header-section { color: #312556 !important; font-weight: 500; }
  .print-header-date {
    font-size: 9px !important;
    color: #718096 !important;
    margin-top: 0.05cm;
  }
  /* Time-travel exports carry an amber accent on the date line so the
     printed PDF is unmistakably historical. */
  .print-header-snapshot .print-header-date {
    color: #b45309 !important;
    font-weight: 600 !important;
  }
  /* The old pseudo-element title is no longer used — print-header replaces it. */
  body.printing::before, body.printing::after { content: none !important; }

  /* ── Hide all-zero rows in print (marked by markZeroRowsForPrint) ───────── */
  .print-hide-row { display: none !important; }

  /* ── Normalize label-column fonts in print ──────────────────────────────────
     Screen uses smaller/lighter sub-row labels (.row-sub) as visual hierarchy,
     but in PDF the size+color shifts read as inconsistent. Print normalizes
     to one size + one color in the label column while preserving indentation
     and the bold weight on result rows (row-burn, row-cash, row-runway). */
  .model-table .row-sub td:first-child {
    font-size: inherit !important;
    color: inherit !important;
    font-weight: 400 !important;
  }
  .model-table .pct-row td:first-child {
    font-size: inherit !important;
    color: inherit !important;
    font-weight: 400 !important;
    /* % rows stay italic — they're derived metrics, distinct from $-amount sub-rows */
  }
  .model-table .pct-row td {
    font-size: inherit !important;
    color: inherit !important;
  }

  /* ── Cash Runway footnote on the Live Model print ───────────────────────── */
  body.printing.body-view-model .model-container::after,
  body.printing.body-view-model .print-chunked-tables::after {
    content: "Cash Burn = Net Burn (Accrual) + Linode Expense − Linode Payment Plan. Cash Runway = months until cash runs out: 0 when out of money (cash ≤ $0); the months to the projected cash-zero crossing when the model foresees one; otherwise cash ÷ trailing-3-month avg Cash Burn (projected past the model). ∞ = cash-flow positive — adding cash each month, no runout. Forecast Operating Expense = prior non-Linode OpEx + 30% × non-Akamai net-MRR delta (floored at $0) — projected OpEx scales with modeled revenue.";
    display: block !important;
    font-size: 8px !important;
    color: #555 !important;
    font-style: italic;
    margin-top: 0.3cm !important;
    padding-top: 0.15cm;
    border-top: 1px solid #e2e8f0;
    page-break-inside: avoid !important;
  }

  /* ── Customers methodology footnote ─────────────────────────────────────── */
  /* CSS-only footnote on the Customers print, parallel to the Bridge + Live
     Model footnotes. Explains the chart + table semantics for an investor
     reader who hasn't seen the live tool. */
  /* Methodology footnote — visible between chart and table on page 1 (was
     previously a ::after on table-container, which placed it after the entire
     concentration table on page 3 where it got buried after the churned-customer
     rows). The dedicated <p class="customers-print-methodology"> element in the
     HTML is hidden on screen and only displayed in print. */
  body.printing.body-view-customers .customers-print-methodology,
  body.printing.body-view-channels .customers-print-methodology {
    display: block !important;
    font-size: 8px !important;
    color: #555 !important;
    font-style: italic;
    margin: 0.2cm 0 0.3cm 0 !important;
    padding: 0.15cm 0.25cm;
    border-top: 1px solid #e2e8f0;
    border-bottom: 1px solid #e2e8f0;
    page-break-inside: avoid !important;
    line-height: 1.4;
  }

  /* ── ARR Bridge methodology footnote on the Bridge print ────────────────── */
  /* Mirrors the Live Model footnote pattern. Bridge view especially benefits
     because the realized-ARR + dealTypes locks are non-obvious to a reader.
     Shown only when the printed view is the ARR Bridge. */
  body.printing.body-chart-bridge #table-bridge-container::after {
    content: "ARR Bridge: realized-ARR walk per standard SaaS reporting convention (10-Q ARR walks, KeyBanc SaaS Survey, a16z/Bessemer benchmarks). Closed forecast category is always included as the realized-ARR baseline; additional categories layer in forward-looking forecasts. Deal Types are always all three (New / Expansion / Renewal) — partial subsets break the classifier. Classifications use unweighted month-over-month account-level Platform MRR transitions. NDR and Gross Retention are computed on unweighted movements.";
    display: block !important;
    font-size: 8px !important;
    color: #555 !important;
    font-style: italic;
    margin-top: 0.3cm !important;
    padding: 0.15cm 0.25cm 0;
    border-top: 1px solid #e2e8f0;
    page-break-inside: avoid !important;
  }

  /* ── Page footer on every page (Confidential, Generated date, page X of Y) ─ */
  /* @bottom-* margin boxes don't accept attr() or arbitrary dynamic content
     from the page body, so the section name can't be inserted dynamically.
     We keep the footer generic ("Operating Model") because the print-header
     at the top of every page already shows the section (Live Model / ARR
     Bridge / MRR Dashboard) — duplicating it in the footer adds no info. */
  @page {
    size: landscape;
    margin: 1cm 1cm 1.5cm 1cm;
    @bottom-left {
      content: "Confidential — Harper, Inc.";
      font-size: 8pt;
      color: #888;
    }
    @bottom-center {
      content: "Operating Model";
      font-size: 8pt;
      color: #888;
    }
    @bottom-right {
      content: "Page " counter(page) " of " counter(pages);
      font-size: 8pt;
      color: #888;
    }
  }

  /* ── Print-only glossary (Live Model) ───────────────────────────────────── */
  .print-glossary {
    display: block !important;
    page-break-before: always !important;
    break-before: page !important;
    page-break-inside: auto;
    margin-top: 0;
  }
  .print-glossary-title {
    font-size: 16pt !important;
    color: #312556 !important;
    margin: 0 0 4pt !important;
    font-weight: 700 !important;
  }
  .print-glossary-intro {
    font-size: 9pt !important;
    color: #555 !important;
    font-style: italic;
    margin: 0 0 8pt !important;
  }
  .print-visual-encoding {
    margin: 0 0 6pt !important;
    padding: 4pt 6pt !important;
    background: #f7fafc !important;
    border-left: 2pt solid #4a90d9 !important;
    border-radius: 2pt !important;
    page-break-inside: avoid;
  }
  .print-visual-encoding-title {
    font-size: 8pt !important;
    font-weight: 700 !important;
    color: #2d3748 !important;
    margin: 0 0 2pt !important;
    text-transform: uppercase;
    letter-spacing: 0.04em;
  }
  .print-visual-encoding-list {
    margin: 0 !important;
    padding-left: 12pt !important;
    font-size: 7.5pt !important;
    line-height: 1.3 !important;
  }
  .print-visual-encoding-list li {
    margin: 0 0 1pt !important;
    color: #2d3748 !important;
  }
  .print-glossary-table {
    width: 100% !important;
    border-collapse: collapse !important;
    font-size: 8.5pt !important;
  }
  .print-glossary-table thead {
    display: table-header-group; /* repeat header on continuation pages */
  }
  .print-glossary-table th {
    text-align: left !important;
    border-bottom: 1.5px solid #312556 !important;
    padding: 4pt 8pt !important;
    font-weight: 700 !important;
    color: #312556 !important;
    background: #f4f0f9 !important;
  }
  .print-glossary-table td {
    padding: 3pt 8pt !important;
    border-bottom: 1px solid #e0e0e0 !important;
    vertical-align: top !important;
    line-height: 1.25 !important;
  }
  .print-glossary-table tr {
    page-break-inside: avoid !important;
    break-inside: avoid !important;
  }
  .print-glossary-table .print-glossary-term {
    font-weight: 600 !important;
    width: 22% !important;
    color: #1a1a2e !important;
  }

  /* Color adjustments */
  * { -webkit-print-color-adjust: exact !important; print-color-adjust: exact !important; color-adjust: exact !important; }
}

/* Hidden on screen — only appears in print */
.print-glossary { display: none; }

/* ── Opportunity Probability Override (drilldown read-only indicators) ──── */
.prob-cell { position: relative; }
.prob-cell.has-override { background: #fffde7; }
.prob-cell .prob-override-badge { display: inline-block; font-size: 0.55rem; text-transform: uppercase; letter-spacing: 0.03em; padding: 1px 4px; border-radius: 3px; background: #4ecdc4; color: white; font-weight: 600; margin-left: 0.25rem; vertical-align: middle; }
.prob-cell .prob-sf-value { font-size: 0.65rem; color: #a0aec0; text-decoration: line-through; margin-right: 0.3rem; }

/* ── Opportunity Overrides Modal ──────────────────────────────────────── */
.do-open-btn { background: #f7fafc; border: 1px solid #e2e8f0; border-radius: 6px; padding: 0.4rem 0.75rem; font-size: 0.82rem; cursor: pointer; display: inline-flex; align-items: center; gap: 0.5rem; color: #4a5568; transition: all 0.15s; }
.do-open-btn:hover { background: #edf2f7; border-color: #cbd5e0; }
.do-badge { display: inline-block; background: #e2e8f0; color: #718096; font-size: 0.7rem; font-weight: 700; padding: 1px 6px; border-radius: 10px; min-width: 18px; text-align: center; }
.do-badge.has-overrides { background: #4ecdc4; color: white; }
.do-filter-tabs { display: inline-flex; border: 1px solid #e2e8f0; border-radius: 5px; overflow: hidden; flex-shrink: 0; }
.do-filter-tab { background: #f7fafc; border: none; padding: 0.3rem 0.6rem; font-size: 0.75rem; font-family: inherit; cursor: pointer; color: #718096; transition: all 0.15s; border-right: 1px solid #e2e8f0; }
.do-filter-tab:last-child { border-right: none; }
.do-filter-tab:hover { background: #edf2f7; }
.do-filter-tab.active { background: #4ecdc4; color: white; font-weight: 600; }
.do-search { width: 100%; border: 1px solid #e2e8f0; border-radius: 4px; padding: 0.35rem 0.6rem; font-size: 0.82rem; font-family: inherit; outline: none; }
.do-search:focus { border-color: #4ecdc4; box-shadow: 0 0 0 2px rgba(78,205,196,0.15); }
.do-renewals-toggle { display: inline-flex; align-items: center; gap: 0.4rem; font-size: 0.82rem; color: #4a5568; cursor: pointer; padding: 0.3rem 0.6rem; background: #f7fafc; border: 1px solid #e2e8f0; border-radius: 5px; white-space: nowrap; transition: all 0.15s; user-select: none; flex-shrink: 0; }
.do-renewals-toggle:hover { background: #edf2f7; border-color: #cbd5e0; }
.do-renewals-toggle input[type="checkbox"] { accent-color: #4ecdc4; width: 15px; height: 15px; cursor: pointer; }
.do-renewals-toggle.loading { opacity: 0.6; pointer-events: none; }
.do-prob-input.bulk-applied { background: #e6fffa; }
.do-prob-input.bulk-applied::placeholder { color: #285e61; font-style: italic; opacity: 1; }
#opp-overrides-table td { vertical-align: middle; text-align: left; }
#opp-overrides-table td.cell-num { text-align: right; }
#opp-overrides-table td:first-child, #opp-overrides-table td:nth-child(2) { max-width: none; overflow: visible; }
#opp-overrides-table a { color: #1a6fb5; text-decoration: none; }
#opp-overrides-table a:hover { color: #4ecdc4; text-decoration: underline; }
#opp-overrides-table .do-prob-input { width: 60px; border: 1px solid #e2e8f0; border-radius: 4px; padding: 0.3rem 0.4rem; text-align: right; font-size: 0.82rem; font-family: inherit; outline: none; background: white; }
#opp-overrides-table .do-prob-input:focus { border-color: #4ecdc4; box-shadow: 0 0 0 2px rgba(78,205,196,0.15); }
#opp-overrides-table .do-prob-input.has-value { background: #fffde7; border-color: #4ecdc4; font-weight: 600; }
#opp-overrides-table .do-reset-btn { background: none; border: none; cursor: pointer; color: #a0aec0; font-size: 0.75rem; padding: 0.2rem 0.4rem; border-radius: 3px; }
#opp-overrides-table .do-reset-btn:hover { color: #e53e3e; background: #fff5f5; }
#opp-overrides-table .do-reset-btn.hidden { visibility: hidden; }
.do-no-results { text-align: center; padding: 2rem; color: #a0aec0; font-size: 0.85rem; }
#opp-overrides-table .do-excluded-row { opacity: 0.5; }
#opp-overrides-table .do-excluded-row td { text-decoration: line-through; color: #a0aec0; }
#opp-overrides-table .do-excluded-row td:nth-last-child(-n+3) { text-decoration: none; }
#opp-overrides-table .do-exclude-cb { cursor: pointer; width: 16px; height: 16px; accent-color: #e53e3e; }

/* ── Bridge Detail Toggle ──────────────────────────────────────────────── */
.bridge-detail-toggle { display: flex; align-items: center; gap: 0.5rem; padding: 0.5rem 1.25rem; border-bottom: 1px solid #eee; background: #f8f9fa; font-size: 0.8rem; color: #555; }
.bridge-detail-toggle label { display: flex; align-items: center; gap: 0.35rem; cursor: pointer; font-weight: 500; }
.bridge-detail-toggle .retained-note { font-size: 0.72rem; color: #a0aec0; font-style: italic; }

/* ── Filter Panel Collapsible Sections ─────────────────────────────────── */
.filter-section { border: 1px solid #e5e7eb; border-radius: 6px; margin-bottom: 0.75rem; overflow: visible; }
.filter-section-header { display: flex; justify-content: space-between; align-items: center; padding: 0.5rem 0.75rem; cursor: pointer; background: #f8f9fa; border-bottom: 1px solid transparent; user-select: none; transition: background 0.15s; border-radius: 6px 6px 0 0; }
.filter-section:not(.expanded) .filter-section-header { border-radius: 6px; }
.filter-section-header:hover { background: #f0f2f5; }
.filter-section.expanded .filter-section-header { border-bottom-color: #e5e7eb; }
.filter-section-title { font-size: 0.82rem; font-weight: 600; color: #333; display: flex; align-items: center; gap: 0.4rem; }
.filter-section-chevron { font-size: 0.65rem; color: #999; transition: transform 0.2s; }
.filter-section.expanded .filter-section-chevron { transform: rotate(90deg); }
.filter-section-summary { font-size: 0.68rem; color: #999; font-weight: 400; max-width: 160px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.filter-section-body { padding: 0.5rem 0.75rem; display: none; }
.filter-section.expanded .filter-section-body { display: block; }
.filter-section-body .filter-group { margin-bottom: 0.75rem; }
.filter-section-body .filter-group:last-child { margin-bottom: 0.25rem; }

/* ── Account & Opportunity Detail Modals ──────────────────────────────── */
.modal.modal-wide { max-width: 1400px; }
.modal.modal-mid { max-width: 1250px; }
.modal-header-actions { display: flex; align-items: center; gap: 0.75rem; }
.sf-link { font-size: 0.8rem; color: #1a6fb5; text-decoration: none; padding: 0.3rem 0.6rem; border: 1px solid #1a6fb5; border-radius: 4px; white-space: nowrap; }
.sf-link:hover { background: #1a6fb5; color: white; }
.account-summary-cards, .opp-summary-cards { display: grid; gap: 0.75rem; padding: 0.75rem 1.25rem; border-bottom: 1px solid #eee; flex-shrink: 0; }
.account-summary-cards { grid-template-columns: repeat(4, 1fr); }
.opp-summary-cards { grid-template-columns: repeat(5, 1fr); }
.account-summary-cards .summary-card, .opp-summary-cards .summary-card { background: #f8f9fa; border-radius: 6px; padding: 0.6rem 0.9rem; min-width: 0; }
.summary-card .card-label { font-size: 0.68rem; color: #888; text-transform: uppercase; letter-spacing: 0.03em; margin-bottom: 0.15rem; }
.summary-card .card-value { font-size: 1.1rem; font-weight: 700; color: #1a1a2e; }
.summary-card .card-value.growing { color: #38a169; }
.summary-card .card-value.declining { color: #e53e3e; }
.summary-card .card-value.stable { color: #718096; }
.account-tabs { display: flex; align-items: center; gap: 0; border-bottom: 1px solid #eee; padding: 0 1.25rem; flex-shrink: 0; overflow: hidden; }
.account-tabs .tab-btn { background: none; border: none; border-bottom: 2px solid transparent; padding: 0.5rem 0.75rem; font-size: 0.82rem; font-weight: 500; color: #718096; cursor: pointer; transition: all 0.15s; white-space: nowrap; }
.account-tabs .tab-btn:hover { color: #1a1a2e; }
.account-tabs .tab-btn.active { color: #1a1a2e; border-bottom-color: #4ecdc4; }
.account-tab-content { padding: 0.75rem 1.25rem; }
.section-title { font-size: 0.85rem; font-weight: 600; color: #333; margin: 0 0 0.75rem 0; }
#opp-detail-modal .modal-body { padding: 0.75rem 1.25rem; }
#account-detail-modal .modal-body { padding: 0; } /* tabs handle their own padding */
.bridge-classification { display: inline-block; font-size: 0.72rem; font-weight: 600; padding: 0.15rem 0.45rem; border-radius: 3px; text-transform: capitalize; }
.bridge-classification.new { background: #c6f6d5; color: #22543d; }
.bridge-classification.expansion { background: #bee3f8; color: #2a4365; }
.bridge-classification.contraction { background: #fed7d7; color: #742a2a; }
.bridge-classification.churn { background: #e53e3e; color: white; }
.bridge-classification.retained { background: #edf2f7; color: #718096; }
.tab-bar-controls { display: flex; align-items: center; gap: 0.5rem; padding: 0.25rem 0; }
.tab-bar-controls .month-picker { display: flex; gap: 0.25rem; }
.tab-bar-controls .month-picker select { padding: 0.15rem 0.3rem; font-size: 0.72rem; border: 1px solid #ddd; border-radius: 4px; color: #4a5568; font-family: inherit; }
.tab-bar-controls .month-picker select:focus { border-color: #4ecdc4; outline: none; }
.month-range-sep { color: #aaa; font-size: 0.75rem; }
.control-separator { width: 1px; height: 16px; background: #ddd; margin: 0 0.15rem; }
.mode-toggle { display: inline-flex; border: 1px solid #d1d5db; border-radius: 5px; overflow: hidden; }
.mode-toggle button { font-size: 0.68rem; font-weight: 500; padding: 0.25rem 0.6rem; border: none; cursor: pointer; transition: all 0.15s; background: #f9fafb; color: #6b7280; font-family: inherit; }
.mode-toggle button:first-child { border-right: 1px solid #d1d5db; }
.mode-toggle button.active { background: #312556; color: white; font-weight: 600; }
.mode-toggle button:not(.active):hover { background: #e5e7eb; }
.detail-toggle-btn { font-size: 0.72rem; font-weight: 500; padding: 0.25rem 0.7rem; border: 1px solid #d1d5db; border-radius: 5px; cursor: pointer; background: #f9fafb; color: #4a5568; font-family: inherit; transition: all 0.15s; white-space: nowrap; }
.detail-toggle-btn:hover { background: #e5e7eb; }
.detail-toggle-btn.active { background: #312556; color: white; font-weight: 600; border-color: #312556; }
.prob-override-hint { font-size: 0.65rem; color: #a0aec0; display: block; font-weight: 400; }
.clickable-name { color: #1a6fb5; cursor: pointer; text-decoration: none; }
.clickable-name:hover { color: #4ecdc4; text-decoration: underline; }
.breakdown-row td { background: #f8fafc; font-size: 0.78rem; padding-top: 0.2rem; padding-bottom: 0.2rem; border-left: 2px solid #e2e8f0; }
.breakdown-row td:first-child { padding-left: 2rem; }
.product-breakdown-row td { background: #f8fafc; border-left: 2px solid #e2e8f0; }
.product-expand-toggle { cursor: pointer; display: inline-block; color: #94a3b8; font-size: 0.7rem; width: 1rem; text-align: center; transition: color 0.15s; }
.product-expand-toggle:hover { color: #1a1a2e; }
.forecast-badge { display: inline-block; font-size: 0.65rem; font-weight: 600; padding: 0.1rem 0.35rem; border-radius: 3px; margin-left: 0.35rem; }
.forecast-badge.closed { background: #c6f6d5; color: #22543d; }
.forecast-badge.commit { background: #bee3f8; color: #2a4365; }
.forecast-badge.best-case { background: #fef3c7; color: #92400e; }
.forecast-badge.most-likely { background: #e9d8fd; color: #553c9a; }
.forecast-badge.pipeline { background: #fed7d7; color: #742a2a; }
.modal-title-group { display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap; }
.modal-title-group h2 { margin: 0; }
.partner-badge { display: inline-flex; align-items: center; gap: 0.3rem; font-size: 0.72rem; font-weight: 600; padding: 0.25rem 0.6rem; border-radius: 4px; background: linear-gradient(135deg, #fff7ed, #ffedd5); color: #9a3412; border: 1px solid #fdba74; white-space: nowrap; }
.partner-badge .partner-factor { font-weight: 700; font-size: 0.8rem; color: #c2410c; }
/* #81: the account "partner badge" is now a generalized Channel indicator. The
   leading "Channel:" label renders in a muted weight so the channel name(s) read
   as the primary content; the rev-share factor (.partner-factor) still pops. */
.partner-badge .channel-badge-label { font-weight: 600; color: #4b5563; opacity: 0.85; }
/* #81: the account-modal Channel indicator is a NEUTRAL (grey/blue) chip — the
   amber accent historically meant "Akamai rev-share applies", which is wrong for
   non-rev-share channels (Direct, Cloudflare, Fastly). Amber is reserved only for
   the .partner-factor note (the per-row mrrFactor < 1). */
.partner-badge.channel-indicator { background: #eef2f7; color: #334155; border-color: #cbd5e1; }
.partner-badge.channel-indicator .partner-factor { font-weight: 700; font-size: 0.8rem; color: #c2410c; }
.partner-badge-inline { display: inline-flex; align-items: center; gap: 0.2rem; font-size: 0.65rem; font-weight: 600; padding: 0.1rem 0.35rem; border-radius: 3px; background: #fff7ed; color: #9a3412; border: 1px solid #fdba74; margin-left: 0.35rem; }
.tcv-annotation { font-size: 0.7rem; color: #c2410c; display: block; font-weight: 500; margin-top: 0.1rem; }
.projected-row td { background: #f0f6ff; font-style: italic; }
.projected-label { font-size: 0.6rem; font-weight: 600; color: #6b7db3; background: #dbeafe; padding: 0.08rem 0.3rem; border-radius: 3px; margin-left: 0.35rem; }
.modal-breadcrumb { font-size: 0.7rem; color: #1a6fb5; margin-bottom: 0.15rem; cursor: pointer; }
.modal-breadcrumb:hover { color: #4ecdc4; text-decoration: underline; }

/* ── Customers Tab ─────────────────────────────────────────────────────────── */
/* Chart container has its own h3.chart-title (matches the Live Model pattern),
   with the toggle + download button living inline on the right side of the title. */
.customers-chart-container { height: 540px; padding-bottom: 0.75rem; }
.customers-chart-container .chart-title {
  font-size: 1rem;
  font-weight: 600;
  color: #1a1a2e;
  margin-bottom: 0.75rem;
  display: flex;
  align-items: center;
  gap: 0.5rem;
}
.customers-chart-container canvas {
  /* Account for the chart-title height so the canvas stays within container bounds. */
  height: calc(100% - 2rem) !important;
}
/* Push controls + download to the right edge of the chart title row. */
.customers-chart-container .customers-controls { margin-left: auto; display: flex; align-items: center; gap: 0.5rem; }
.customers-chart-container .chart-download-btn { margin-left: 0.5rem; }
/* Forecast banner — shown when the user has any non-Closed forecast category
   selected. Same visual weight as the truncate banner, slightly different
   color to communicate informational rather than warning. */
.customers-forecast-banner {
  background: #eef2ff;
  border-left: 3px solid #6366f1;
  padding: 0.5rem 0.875rem;
  font-size: 0.82rem;
  color: #3730a3;
  /* Match the chart-container's 1.5rem margin-bottom above the banner so the
     gap below the banner equals the gap above. */
  margin-bottom: 1.5rem;
  border-radius: 0 4px 4px 0;
}
.customers-forecast-banner strong { color: #1e1b4b; }
/* "As of <month> (today/end of range)" indicator in the table-actions row.
   Left-aligned via margin-right:auto to push the PDF/CSV buttons flush right.
   Bumped from 0.75rem to 0.85rem and from #64748b to #1a1a2e so the snapshot
   month is reliably noticed — the previous styling was too subtle, users
   missed which month the table was anchored to. */
.customers-snapshot-label {
  margin-right: auto;
  font-size: 0.85rem;
  font-weight: 600;
  color: #1a1a2e;
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding-left: 0.5rem;
}
.customers-snapshot-label .info-icon { color: #94a3b8; font-weight: 400; }

/* Month picker — sits inline after the "As of <month>" label, letting the user
   browse any realized month without leaving the tab. */
.customers-snapshot-picker {
  font-size: 0.8rem;
  padding: 0.2rem 0.5rem;
  border: 1px solid #cbd5e0;
  border-radius: 4px;
  background: #fff;
  color: #1a1a2e;
  cursor: pointer;
  margin-left: 0.1rem;
  max-width: 10rem;
}
.customers-snapshot-picker:focus {
  outline: none;
  border-color: #4299e1;
  box-shadow: 0 0 0 2px rgba(66, 153, 225, 0.25);
}

/* Trend badges — color + arrow + label. Color blindness: never rely on color
   alone; the arrow + label carry the meaning. */
.trend-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  font-size: 0.7rem;
  font-weight: 600;
  padding: 0.15rem 0.5rem;
  border-radius: 3px;
  white-space: nowrap;
}
.trend-badge.trend-new { background: #c6f6d5; color: #22543d; }
.trend-badge.trend-growing { background: #c6f6d5; color: #22543d; }
.trend-badge.trend-stable { background: #edf2f7; color: #4a5568; }
.trend-badge.trend-declining { background: #feebc8; color: #7b341e; }
.trend-badge.trend-churned { background: #fed7d7; color: #742a2a; }
/* Pending: customer has only future-pipeline deals, hasn't started yet.
   Distinct from churned (which means they HAD MRR and now don't). Subtle
   blue-gray to read as "informational, not negative." */
.trend-badge.trend-pending { background: #e0e7ff; color: #3730a3; }

/* Empty state + truncation banner */
.customers-empty-state {
  background: white;
  border: 1px dashed #cbd5e0;
  border-radius: 8px;
  padding: 2rem;
  text-align: center;
  color: #4a5568;
  font-size: 0.9rem;
  margin-bottom: 1rem;
}
.customers-empty-state strong { color: #1a1a2e; }
.customers-truncate-banner {
  background: #fff7ed;
  border: 1px solid #fed7aa;
  border-radius: 6px;
  padding: 0.6rem 0.9rem;
  font-size: 0.8rem;
  color: #7c2d12;
  margin-bottom: 1rem;
  line-height: 1.4;
}
.customers-truncate-banner strong { color: #431407; }

/* Customers table — use default .data-table styling but allow first-column
   names to wrap. The clickable customer name uses the existing .clickable-name
   pattern from elsewhere in the app. */
#customers-table td:first-child { white-space: normal; }
/* Channel (6th column, #81) is categorical text — left-align it to match the
   Customer name column rather than inheriting the .data-table numeric right-align. */
#customers-table th:nth-child(6), #customers-table td:nth-child(6) { text-align: left; }
#customers-table tbody tr.row-churned { color: #a0aec0; }

/* ─── History tab + Time-Travel mode ──────────────────────────────────── */

/* High-contrast amber banner pinned to the very top of the page when in
   time-travel mode. Deliberately separate from .header so it survives layout
   shifts and prints. */
.time-travel-banner {
  background: linear-gradient(90deg, #fef3c7 0%, #fde68a 50%, #fef3c7 100%);
  border-bottom: 2px solid #d97706;
  color: #7c2d12;
  font-size: 0.9rem;
  box-shadow: 0 1px 4px rgba(0,0,0,0.05);
  position: sticky;
  top: 0;
  z-index: 1100;
}
.tt-banner-inner {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  padding: 0.6rem 1rem;
  max-width: 100%;
}
.tt-banner-icon {
  font-size: 1.25rem;
  line-height: 1;
}
.tt-banner-text { flex: 1; line-height: 1.35; }
.tt-banner-text strong { color: #7c2d12; font-weight: 600; }
.tt-banner-scenario { color: #92400e; }
.tt-banner-note { font-size: 0.75rem; color: #92400e; opacity: 0.85; margin-top: 0.1rem; }
.tt-banner-exit { background: #92400e; border-color: #78350f; color: #fff7ed; }
.tt-banner-exit:hover { background: #78350f; }

/* Page-wide read-only treatment while time-traveling. Editable cells lose the
   blue accents, mouse cursor reverts to default, export buttons gray out. */
body.body-time-travel td.editable {
  background: #f9fafb;
  color: #4b5563;
  cursor: not-allowed;
  border-left-color: transparent !important;
}
body.body-time-travel td.editable:hover {
  background: #f3f4f6;
}
/* Click-feedback flash for editable cells in time-travel mode. Without this,
   clicking a "locked" cell appeared to do nothing — the toast was the only
   signal. The flash is a 400ms amber tint that gives the user immediate
   confirmation the click registered. Pairs with the toast for double signal. */
body.body-time-travel td.editable.cell-tt-flash {
  background: #fef3c7 !important;
  transition: background 0.15s;
}
/* CSV / PDF exports stay ENABLED in time-travel mode.
   Previously gated by decision #36 (v1 punt); reversed 2026-05-19 — the
   export functions read from `currentMonthlyData` / `modelData`, which are
   already populated from `/api/snapshots/replay` in TT mode, so exports
   naturally produce snapshot-derived files. The filename (and the print
   header) carry the snapshot date so the file is clearly historical. */

/* Toast — bottom-right corner, fades in via display toggle. */
.tt-toast {
  position: fixed;
  bottom: 1.5rem;
  right: 1.5rem;
  background: #1f2937;
  color: white;
  padding: 0.55rem 0.9rem;
  border-radius: 6px;
  font-size: 0.85rem;
  box-shadow: 0 4px 12px rgba(0,0,0,0.2);
  z-index: 2000;
  max-width: 320px;
}

/* History page layout */
.history-page {
  padding: 0;
}
.history-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 1rem;
  flex-wrap: wrap;
}
.history-title {
  font-size: 1.4rem;
  margin: 0;
  color: #1a1a2e;
}
.history-health-banner {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  background: #ecfdf5;
  border: 1px solid #a7f3d0;
  border-radius: 6px;
  padding: 0.45rem 0.75rem;
  font-size: 0.82rem;
  color: #065f46;
}
.history-health-banner.stale {
  background: #fef3c7;
  border-color: #fcd34d;
  color: #92400e;
}
/* P3: small "up-to-date" pill — less prominent than the stale warning */
.history-health-banner.history-health-fresh {
  background: #f0fdf4;
  border-color: #bbf7d0;
  color: #166534;
  font-size: 0.75rem;
  padding: 0.25rem 0.55rem;
}
.history-health-banner .hhb-icon { font-weight: bold; }

.history-subtabs {
  display: flex;
  gap: 0;
  border-bottom: 1px solid #e2e8f0;
  margin-bottom: 1rem;
}
.history-subtab {
  background: transparent;
  border: none;
  padding: 0.55rem 1.1rem;
  font-size: 0.92rem;
  color: #4a5568;
  cursor: pointer;
  border-bottom: 2px solid transparent;
}
.history-subtab.active {
  color: #1a1a2e;
  font-weight: 600;
  border-bottom-color: #4a90d9;
}
.history-subtab:hover:not(.active) {
  background: #f7fafc;
  color: #2d3748;
}

.history-filterbar {
  display: flex;
  align-items: flex-end;
  gap: 0.75rem;
  flex-wrap: wrap;
  margin-bottom: 0.85rem;
  padding: 0.75rem;
  background: #f9fafb;
  border: 1px solid #e5e7eb;
  border-radius: 6px;
}
.history-filterbar-spacer { flex: 1; }
.hf-group {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  min-width: 130px;
}
.hf-label {
  font-size: 0.72rem;
  color: #6b7280;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-weight: 600;
}
.hf-group select,
.hf-group input[type="date"] {
  padding: 0.35rem 0.5rem;
  border: 1px solid #d1d5db;
  border-radius: 4px;
  font-size: 0.85rem;
  background: white;
}
.history-result {
  font-size: 0.85rem;
  color: #4b5563;
  margin-bottom: 0.5rem;
  min-height: 1rem;
}
.history-table-wrap {
  overflow-x: auto;
}
.history-table { width: 100%; font-size: 0.85rem; }
.history-table th { text-align: left; background: #f9fafb; }
.history-table td { vertical-align: top; padding: 0.55rem 0.65rem; text-align: left; }

.audit-badge {
  display: inline-block;
  font-size: 0.7rem;
  padding: 2px 7px;
  border-radius: 10px;
  background: #e2e8f0;
  color: #2d3748;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  font-weight: 600;
}
.audit-badge.trigger-nightly { background: #dbeafe; color: #1e40af; }
.audit-badge.trigger-manual  { background: #ccfbf1; color: #0f766e; }
.audit-badge.partial         { background: #fef3c7; color: #92400e; }
.audit-badge.entity-modelinput        { background: #d1fae5; color: #065f46; }
.audit-badge.entity-scenario          { background: #fef3c7; color: #92400e; }
.audit-badge.entity-opportunityoverride { background: #ede9fe; color: #5b21b6; }
.audit-badge.entity-snapshot          { background: #dbeafe; color: #1e3a8a; }

.audit-hash {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  background: #f3f4f6;
  border: 1px solid #e5e7eb;
  padding: 1px 5px;
  border-radius: 3px;
  font-size: 0.78rem;
  color: #4b5563;
}

.audit-display-path {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.78rem;
  color: #1f2937;
}
.audit-scn { color: #6b7280; font-size: 0.78rem; margin-left: 0.25rem; }
.audit-diff-cell { white-space: nowrap; }
.audit-old { color: #b91c1c; }
.audit-new { color: #047857; }
.audit-arrow { color: #6b7280; margin: 0 0.2rem; }
.audit-diff-trunc {
  font-size: 0.78rem;
  color: #6b7280;
  cursor: help;
  border-bottom: 1px dotted #cbd5e0;
}
.audit-group-toggle {
  background: transparent;
  border: none;
  font-size: 0.9rem;
  cursor: pointer;
  padding: 0.2rem 0.4rem;
  color: #4a5568;
  min-width: 24px;
  min-height: 24px;
  border-radius: 4px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.audit-group-toggle:hover { color: #1a1a2e; background: rgba(0,0,0,0.05); }
/* Make the whole parent row clickable via cursor hint */
tr.audit-group-parent { cursor: pointer; }
tr.audit-group-parent:hover td { background: #f0f4ff; }
.audit-group-child.hidden { display: none; }
.audit-group-child td { background: #fafbfc; font-size: 0.78rem; }

.btn-sm { padding: 0.25rem 0.6rem; font-size: 0.78rem; }

/* P12: hide scenario selector when in time-travel mode (snapshot is scenario-locked) */
body.body-time-travel .scenario-selector { display: none; }

/* Notes cell in the Live Model.
   Key trick: `position: absolute` on the child <span> pulls the note text
   out of the table layout flow. The cell becomes "empty" from the layout
   engine's perspective — column width is determined purely by numeric
   content (~110px), NEVER widened by notes. The span visually fills the
   cell via `inset: 0` and clips text to fit.
   Two modes via tbody.notes-expanded:
   - Collapsed (default): cell height ~2em, span shows 1 line + ellipsis
   - Expanded: cell height ~7em, span clamps to 5 lines + ellipsis
   Columns stay narrow in BOTH modes — only the row height changes. */
.notes-cell {
  position: relative;
  width: 1px;
  height: 2em;
  font-size: 0.78rem;
  color: #6b7280;
  font-style: italic;
  cursor: pointer;
  padding: 0;
  vertical-align: middle;
}
.notes-cell .notes-text {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  padding: 0 0.6rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* Expanded row: full text, NO clamp. Row auto-grows to fit the longest
   note. We switch the span from position:absolute (which can't push the
   parent cell taller) to normal flow + `overflow-wrap: anywhere`, which
   makes the cell's min-content = 1 character. That keeps columns at the
   th min-width (110px) while letting the row grow vertically to fit the
   longest wrapped note across all months. */
.model-table tbody.notes-expanded .notes-cell {
  height: auto;
  vertical-align: top;
}
.model-table tbody.notes-expanded .notes-cell .notes-text {
  position: static;
  display: block;
  inset: auto;
  align-items: initial;
  padding: 0.3rem 0.6rem;
  white-space: normal;
  overflow-wrap: anywhere;
  word-break: break-word;
  overflow: visible;
  text-overflow: clip;
  line-height: 1.35;
}

/* Notes row label chevron — mirrors .opex-collapse-toggle exactly. */
.notes-collapse-toggle {
  cursor: pointer;
  display: inline-block;
  color: #94a3b8;
  font-size: 0.7rem;
  width: 1rem;
  text-align: center;
  transition: color 0.15s;
  user-select: none;
}
.notes-collapse-toggle:hover { color: #1a1a2e; }
@media print {
  /* Hide the row toggle in print (it's interactive). */
  .notes-collapse-toggle { display: none !important; }
  /* In PRINT: always show notes in full. The on-screen state (collapsed
     vs expanded) is irrelevant — the printed deck needs the complete
     annotation for context. Same mechanism as the expanded-row CSS
     above: normal flow + overflow-wrap so columns stay narrow but the
     row grows vertically to fit the longest note. Font is also reduced
     so the small column widths can fit more text per line. */
  .model-table .row-notes .notes-cell {
    height: auto !important;
    vertical-align: top !important;
  }
  .model-table .row-notes .notes-cell .notes-text {
    position: static !important;
    display: block !important;
    inset: auto !important;
    padding: 0.15rem 0.3rem !important;
    white-space: normal !important;
    overflow-wrap: anywhere !important;
    word-break: break-word !important;
    overflow: visible !important;
    text-overflow: clip !important;
    -webkit-line-clamp: unset !important;
    line-clamp: unset !important;
    /* Very small font + tight line-height so narrow columns fit more
       characters per line. Note row only — other rows keep the normal
       print font size. */
    font-size: 4.5pt !important;
    line-height: 1.1 !important;
    letter-spacing: -0.01em !important;
  }
}
.notes-cell.has-note { color: #312556; font-style: normal; }
/* Time-travel: click still opens the modal (read-only); cursor stays
   pointer to indicate the cell is clickable, not "not-allowed". */

/* (Removed: notes-edit-wrap / notes-open-modal-btn — inline editor was
   replaced by a click → modal flow on 2026-05-20.) */

/* History list footer — pagination controls + total count. */
.history-list-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  font-size: 0.78rem;
  color: #6b7280;
  padding: 0.5rem 0.75rem;
  border-top: 1px solid #f0f0f0;
  flex-wrap: wrap;
}
.history-list-footer .pg-count { color: #6b7280; }
.history-list-footer .pg-controls {
  display: inline-flex;
  align-items: center;
  gap: 0.65rem;
}
.history-list-footer .pg-size-label {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  color: #6b7280;
}
.history-list-footer .pg-size {
  font-size: 0.78rem;
  padding: 0.15rem 0.3rem;
  border: 1px solid #d1d5db;
  border-radius: 3px;
  background: #fff;
}
.history-list-footer .pg-btn {
  border: 1px solid #d1d5db;
  background: #fff;
  color: #312556;
  border-radius: 3px;
  padding: 0.15rem 0.5rem;
  font-size: 0.85rem;
  cursor: pointer;
  font-family: inherit;
  line-height: 1.2;
}
.history-list-footer .pg-btn:hover:not(:disabled) { background: #f3f4f6; }
.history-list-footer .pg-btn:disabled { opacity: 0.4; cursor: not-allowed; }
.history-list-footer .pg-pageinfo { color: #4a5568; min-width: 6em; text-align: center; }

/* Audit search input in filter bar */
.history-audit-search-wrap {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  min-width: 180px;
  flex: 1;
}
.history-audit-search-wrap input[type="search"] {
  padding: 0.35rem 0.5rem;
  border: 1px solid #d1d5db;
  border-radius: 4px;
  font-size: 0.85rem;
  background: white;
}

/* ── Phase A: per-cell history right-click menu + deep-link chip ──────────
   The contextmenu handler on Live Model cells builds a tiny floating menu
   that links into the History → Activity tab with a (field × month) filter.
   The chip at the top of the Activity table announces the active filter
   with an × to clear and return to the global feed.
*/
.cell-history-menu {
  position: fixed;
  z-index: 9999;
  min-width: 240px;
  background: white;
  border: 1px solid #d1d5db;
  border-radius: 6px;
  box-shadow: 0 6px 16px rgba(0,0,0,0.15);
  padding: 0.25rem;
  font-size: 0.85rem;
}
.cell-history-menu-item {
  display: grid;
  grid-template-columns: 1.5rem 1fr;
  grid-template-rows: auto auto;
  gap: 0.1rem 0.6rem;
  align-items: center;
  width: 100%;
  background: transparent;
  border: none;
  padding: 0.5rem 0.6rem;
  cursor: pointer;
  text-align: left;
  border-radius: 4px;
  color: #1f2937;
}
.cell-history-menu-item:hover {
  background: #f3f4f6;
}
.cell-history-menu-icon {
  grid-row: 1 / 3;
  font-size: 1rem;
  color: #6b7280;
}
.cell-history-menu-text { font-weight: 500; }
.cell-history-menu-sub {
  font-size: 0.72rem;
  color: #6b7280;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.history-audit-percell-chip {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 0.75rem;
  margin: 0.5rem 0;
  background: #ecfeff;
  border: 1px solid #67e8f9;
  border-radius: 6px;
  font-size: 0.85rem;
}
.percell-chip-label { color: #0e7490; font-weight: 500; }
.percell-chip-pill {
  background: white;
  border: 1px solid #a5f3fc;
  border-radius: 4px;
  padding: 0.15rem 0.5rem;
  color: #0f172a;
}
.percell-chip-clear {
  margin-left: auto;
  background: transparent;
  border: 1px solid #cffafe;
  color: #0e7490;
  border-radius: 4px;
  padding: 0.15rem 0.5rem;
  font-size: 0.78rem;
  cursor: pointer;
}
.percell-chip-clear:hover { background: #cffafe; }

/* ── Phase B1: per-cell sync deltas section (2026-05-21) ──────────────
   Beneath the user-edit audit table, this section shows synthetic deltas
   computed by replaying the pre/post snapshots of Salesforce syncs that
   changed this cell's value. Visually distinct from the user-edit list
   (cyan tint + 🔄 icon) so users can tell "this value changed because of
   a sync" from "someone manually edited this." */
.history-audit-sync-deltas {
  margin-top: 1rem;
  padding: 0.75rem 1rem;
  background: #f0fdfa;
  border: 1px solid #99f6e4;
  border-radius: 6px;
}
.sync-delta-header {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  margin-bottom: 0.5rem;
}
.sync-delta-header strong { font-size: 0.9rem; color: #0f766e; }
.sync-delta-subhead { font-size: 0.78rem; color: #115e59; }
.sync-delta-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}
.sync-delta-row {
  display: grid;
  grid-template-columns: 1.5rem 1fr;
  gap: 0.5rem;
  padding: 0.5rem 0.6rem;
  background: white;
  border: 1px solid #ccfbf1;
  border-radius: 4px;
}
.sync-delta-icon { font-size: 1.1rem; line-height: 1.2; }
.sync-delta-body { display: flex; flex-direction: column; gap: 0.25rem; }
.sync-delta-headline {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  font-size: 0.82rem;
}
.sync-delta-ts { color: #6b7280; }
.sync-delta-actor { color: #9ca3af; font-size: 0.75rem; }
.sync-delta-values {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.85rem;
}
.sync-delta-was { color: #6b7280; }
.sync-delta-now { color: #0f172a; }
.sync-delta-up { color: #15803d; font-weight: bold; }
.sync-delta-down { color: #b91c1c; font-weight: bold; }
.sync-delta-diff { font-size: 0.78rem; padding: 0.05rem 0.4rem; border-radius: 3px; }
.sync-delta-diff.diff-up { background: #dcfce7; color: #166534; }
.sync-delta-diff.diff-down { background: #fee2e2; color: #991b1b; }
.sync-delta-actions { display: flex; gap: 0.5rem; margin-top: 0.15rem; }
.sync-delta-tt {
  background: transparent;
  border: 1px solid #99f6e4;
  color: #0e7490;
  padding: 0.2rem 0.6rem;
  font-size: 0.75rem;
  border-radius: 4px;
  cursor: pointer;
}
.sync-delta-tt:hover { background: #cffafe; }

/* ── Phase B2: "View cell changes" button + modal ─────────────────────────── */
.sync-cell-changes-btn {
  display: inline-block;
  margin-left: 0.5rem;
  padding: 0.1rem 0.5rem;
  background: #ecfeff;
  border: 1px solid #99f6e4;
  color: #0e7490;
  border-radius: 4px;
  font-size: 0.72rem;
  cursor: pointer;
  white-space: nowrap;
}
.sync-cell-changes-btn:hover { background: #cffafe; }

/* Use the existing .modal-overlay + .modal pattern (styles.css line 339-341).
   These rules just supply the Phase-B2-specific tweaks: max-width, subtitle
   styling, and stat-panel inside the body. */
.sync-cell-changes-card { max-width: 1000px; }
.sync-cell-changes-card .modal-subtitle { color: #6b7280; font-weight: 400; font-size: 0.85rem; margin-left: 0.4rem; }
.sync-cell-changes-card .modal-body { padding: 0.75rem 1rem; overflow-y: auto; flex: 1; }

.sync-cell-changes-stats {
  background: #f9fafb; border: 1px solid #e5e7eb; border-radius: 6px;
  padding: 0.5rem 0.75rem; margin-bottom: 0.75rem; font-size: 0.85rem;
}
.sync-cell-changes-stats-row { display: flex; gap: 1rem; color: #6b7280; margin-top: 0.15rem; }
.sync-cell-changes-hint {
  color: #6b7280; font-size: 0.78rem; margin-top: 0.4rem; padding-top: 0.4rem;
  border-top: 1px dashed #e5e7eb; cursor: help; font-style: italic;
}

.sync-cell-changes-toolbar {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 0.5rem; font-size: 0.82rem;
}
.sync-cell-changes-sort-select {
  padding: 0.2rem 0.4rem; border: 1px solid #d1d5db; border-radius: 4px; font-size: 0.82rem;
  background: white;
}

.sync-cell-changes-table { width: 100%; font-size: 0.85rem; border-collapse: collapse; }
.sync-cell-changes-table th, .sync-cell-changes-table td {
  text-align: left; padding: 0.4rem 0.6rem; border-bottom: 1px solid #f3f4f6;
}
.sync-cell-changes-table th { background: #f9fafb; font-weight: 600; color: #374151; }
.sync-cell-changes-table .sync-cell-num { font-variant-numeric: tabular-nums; text-align: right; }

.sync-cell-changes-pagination {
  display: flex; align-items: center; justify-content: center; gap: 1rem;
  margin-top: 0.75rem; padding: 0.5rem 0; font-size: 0.85rem;
}

/* Phase B3 in the modal: per-row expand for the drill-down */
.sync-cell-changes-expand {
  background: transparent; border: 1px solid transparent;
  color: #6b7280; font-size: 0.85rem; cursor: pointer;
  padding: 0.05rem 0.25rem; border-radius: 3px; margin-right: 0.25rem;
  font-family: inherit; line-height: 1;
}
.sync-cell-changes-expand:hover { background: #f3f4f6; color: #1f2937; }
.sync-cell-changes-expand:disabled { opacity: 0.5; cursor: wait; }
.sync-cell-changes-drill-row td { background: #f9fafb; padding: 0.5rem 0.75rem 0.75rem 2rem; }

/* ── Phase B3: drill-down inside per-cell sync delta rows ───────────────── */
.sync-delta-drill {
  background: transparent;
  border: 1px solid #99f6e4;
  color: #0e7490;
  padding: 0.2rem 0.6rem;
  font-size: 0.75rem;
  border-radius: 4px;
  cursor: pointer;
}
.sync-delta-drill:hover { background: #cffafe; }
.sync-delta-drill:disabled { opacity: 0.6; cursor: wait; }

.sync-delta-drill-body { margin-top: 0.5rem; }
.sync-drill-loading, .sync-drill-empty {
  padding: 0.5rem 0.75rem; background: #f9fafb; border-radius: 4px;
  color: #6b7280; font-size: 0.82rem;
}
.sync-drill-header {
  display: flex; flex-direction: column; gap: 0.1rem;
  margin-bottom: 0.4rem;
}
.sync-drill-header strong { font-size: 0.85rem; color: #0f766e; }
.sync-drill-subhead { font-size: 0.75rem; color: #6b7280; }
.sync-drill-table { width: 100%; font-size: 0.82rem; border-collapse: collapse; }
.sync-drill-table th, .sync-drill-table td {
  text-align: left; padding: 0.3rem 0.5rem; border-bottom: 1px solid #f3f4f6;
}
.sync-drill-table th { background: #f9fafb; color: #374151; font-weight: 600; }
.sync-drill-table .sync-cell-num { text-align: right; font-variant-numeric: tabular-nums; }
.sync-drill-opp-name { font-weight: 500; color: #1f2937; }
.sync-drill-opp-account { font-size: 0.72rem; color: #9ca3af; margin-top: 0.05rem; }
.sync-drill-cap { font-size: 0.72rem; color: #9ca3af; margin-top: 0.3rem; padding-left: 0.3rem; }

/* Print: ALWAYS hide the on-screen time-travel banner. It uses
   `position: sticky; top: 0` which doesn't behave reliably in print —
   the printed banner renders at unpredictable vertical positions
   (sometimes in the middle of a page, sometimes between table sections).
   The snapshot context is preserved in the print-header instead via
   buildPrintHeader() — when `currentSnapshotId` is set, the date line
   reads "Historical snapshot · <ts>" in amber bold, which is positioned
   reliably at the top of page 1 of the PDF.
   See web/app.js: buildPrintHeader + .print-header-snapshot CSS rule. */
@media print {
  .time-travel-banner { display: none !important; }
  .tt-toast { display: none !important; }
}
