/* ============================================================
   Brand & Store — Overall Performance  (bs-ov-*)
   Scoped to .bs-ov-page. Tokens only. DataTable owns the cancel table.
   ============================================================ */

/* Source-of-Revenue color tokens (per spec §5 — applied to bar fills + chart segments).
   Declared globally so other dashboards (Source-of-Revenue cross-portal) can reuse. */
:root {
  --svc-livestream: #8B5CF6;
  --svc-affiliate: #F97316;
  --svc-paid-ads: #EC4899;
  --svc-video: #14B8A6;
  --svc-short-tab: #F59E0B;
  --svc-product-cards: #06B6D4;
  --svc-offsite: #84CC16;
}

/* Chart series tokens for the GMV-by-Period trend combo. Dedicated to this
   page's target/achievement series so they don't couple to the unrelated
   --svc-short-tab amber (which happens to share #F59E0B). --chart-achievement
   maps to the canonical positive/success token. The dark pill on the bullet
   chart is INTENTIONALLY theme-constant (white text on a dark chip over a
   light/inset track), so --chart-pill-bg keeps the same value in both themes. */
.bs-ov-page {
  --chart-target: #F59E0B;
  --chart-achievement: var(--color-success, #22C55E);
  --chart-pill-bg: rgba(8, 10, 15, 0.85);
  --chart-pill-fg: #ffffff;
  --bs-hl-mute: 0.1;    /* click-to-highlight muted-sibling opacity — ~90% transparent (feedback 2026-06-09) */
}

/* ── Click-to-highlight (feedback 2026-06-09) ──────────────────────────────
   HTML/CSS surfaces (KPI cards, donut table rows). SVG surfaces mute via inline
   :fill-opacity/:opacity bindings instead (per-element). --bs-hl-mute is pure
   opacity (theme-agnostic); the active-row accent uses color-mix on --color-action
   so it resolves correctly in both themes. The classes are global so the shared
   donut keeps working on the pages that reuse it (fallback opacity 0.22). */
.is-hl-muted  { opacity: var(--bs-hl-mute, 0.22); transition: opacity var(--transition-base, 0.2s ease); }
.is-hl-active { opacity: 1; transition: opacity var(--transition-base, 0.2s ease); }
.bs-ov-kpi-card,
.bs-ov-sord-tbl tbody tr,
.bs-ov-sord-compact-tbl tbody tr { cursor: pointer; }
.bs-ov-sord-tbl tbody tr.is-hl-active td,
.bs-ov-sord-compact-tbl tbody tr.is-hl-active td {
  background: color-mix(in srgb, var(--color-action) 9%, transparent);
  box-shadow: inset 3px 0 0 var(--color-action);
}

.bs-ov-page { display: flex; flex-direction: column; gap: var(--space-5, 20px); min-width: 0; }
.bs-ov-page > * { min-width: 0; }

.bs-ov-section { display: flex; flex-direction: column; gap: var(--space-3, 12px); }
.bs-ov-section-header { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: var(--space-3, 12px); }

/* B5a/B7c: stack title + subtitle vertically inside card__header--split so the
   subtitle drops onto its own line (card__title is a span by default). */
.bs-ov-card-header-titles { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
/* Item 10 — title row holds an inline help (?) next to the heading text. */
.bs-ov-card-header-titles .card__title { display: inline-flex; align-items: center; gap: 6px; white-space: normal; }
.bs-ov-card-header-titles .card__subtitle { display: block; margin-top: 0; }
.bs-ov-card-header-titles--tight { gap: 2px; }
.bs-ov-card-header-titles--tight .card__subtitle { margin-top: 0; line-height: 1.4; }

.bs-ov-state { padding: var(--space-6, 24px); text-align: center; color: var(--text-tertiary, #8C95A4); font-size: var(--font-small, 12px); }
.bs-ov-state--error { color: var(--color-danger, #DC2626); }
.bs-ov-caveat { margin-top: var(--space-3, 12px); padding: var(--space-2, 8px) var(--space-3, 12px); background: color-mix(in srgb, var(--color-warning) 12%, var(--bg-surface)); color: var(--text-primary); border: 1px solid var(--color-warning, #F59E0B); border-radius: var(--radius-sm, 6px); font-size: 12px; line-height: 1.4; }

/* ── KPI band ── */
.bs-ov-kpi-grid { display: grid; gap: var(--space-4, 16px); margin-top: var(--space-3, 12px); }
.bs-ov-kpi-grid--primary { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.bs-ov-kpi-grid--secondary { grid-template-columns: repeat(5, minmax(0, 1fr)); }
.bs-ov-kpi-card { display: flex; flex-direction: column; gap: 4px; padding: var(--space-4, 16px); background: var(--bg-surface, #fff); border: 1px solid var(--border-subtle, #E2E8F0); border-radius: var(--radius-md, 8px); min-width: 0; position: relative; }
.bs-ov-kpi-card--secondary { background: var(--bg-base); border-style: dashed; }
/* B4: per spec §2 — KPI label = uppercase 700 with 0.08em tracking. */
.bs-ov-kpi-label { font-size: 11px; font-weight: 700; color: var(--text-tertiary, #8C95A4); text-transform: uppercase; letter-spacing: 0.08em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; display: flex; align-items: center; gap: 6px; }
.bs-ov-kpi-icon { display: inline-flex; width: 16px; height: 16px; align-items: center; justify-content: center; color: var(--color-action, #2563EB); flex-shrink: 0; }
.bs-ov-kpi-icon svg { width: 14px; height: 14px; }
.bs-ov-kpi-card--cost .bs-ov-kpi-icon { color: var(--color-brand, #CB222A); }
/* feedback 2026-06-08 #1 — KPI value right-aligned (SOCOM .metric-card__value parity). */
.bs-ov-kpi-value { font-size: 20px; font-weight: 700; font-family: var(--font-mono, 'Geist Mono', monospace); font-variant-numeric: tabular-nums; color: var(--text-primary, #111318); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; text-align: right; }
/* Cost-metric card: no extra color treatment — delta badges own the color flip */
.bs-ov-kpi-card--cost .bs-ov-kpi-label::after { content: ''; }

/* Compare toggle wrap */
.bs-ov-compare-wrap { display: flex; align-items: center; gap: var(--space-3, 12px); flex-wrap: wrap; }
.bs-ov-compare-note { font-size: 11px; color: var(--text-tertiary); white-space: nowrap; }
.bs-ov-date-input { height: 28px; padding: 0 var(--space-2, 8px); border: 1px solid var(--border-default); border-radius: var(--radius-sm, 6px); background: var(--bg-inset); font-family: var(--font-mono, monospace); font-size: 12px; color: var(--text-primary); }
.bs-ov-custom-picker { display: inline-flex; align-items: center; gap: var(--space-2, 8px); }
.bs-ov-date-sep { color: var(--text-tertiary); font-size: 12px; }

/* Expander row */
.bs-ov-expander-row { display: flex; align-items: center; gap: var(--space-3, 12px); margin-top: var(--space-4, 16px); }
.bs-ov-expander-line { flex: 1; height: 1px; background: var(--border-default); }
.bs-ov-btn-expand { display: inline-flex; align-items: center; gap: 6px; height: 30px; padding: 0 var(--space-4, 16px); border-radius: var(--radius-full, 999px); border: 1px solid var(--border-default); background: var(--bg-surface); color: var(--text-secondary); font-size: 12px; font-weight: 600; cursor: pointer; transition: all var(--transition-fast, 0.15s); white-space: nowrap; }
.bs-ov-btn-expand:hover { border-color: var(--color-action); color: var(--color-action); }
.bs-ov-btn-expand--open { border-color: var(--color-action); color: var(--color-action); background: color-mix(in srgb, var(--color-action) 10%, var(--bg-surface)); }

/* Secondary KPI panel — animated open/close */
.bs-ov-kpi-secondary { overflow: hidden; max-height: 0; opacity: 0; transition: max-height 0.3s ease, opacity 0.25s ease, margin-top 0.2s ease; margin-top: 0; }
.bs-ov-kpi-secondary--open { max-height: 300px; opacity: 1; margin-top: var(--space-3, 12px); }

/* ── GMV vs Target — bullet chart ── */
.bs-ov-bullet { display: flex; flex-direction: column; gap: var(--space-3, 12px); padding: var(--space-1, 4px) 0; }
.bs-ov-bullet-row { display: flex; align-items: center; gap: var(--space-4, 16px); }
.bs-ov-bullet-label { flex-shrink: 0; width: 148px; font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.06em; color: var(--text-secondary); }
.bs-ov-bullet-track { position: relative; flex: 1; height: 48px; background: var(--bg-inset); border-radius: var(--radius-sm, 6px); overflow: visible; }
.bs-ov-bullet-fill { position: absolute; top: 10px; height: 28px; background: var(--color-action); border-radius: 4px; transition: width 0.4s ease; }
/* Run-rate band: diagonal stripes */
.bs-ov-bullet-fill--rr { background: repeating-linear-gradient(135deg, color-mix(in srgb, var(--color-action) 45%, transparent) 0, color-mix(in srgb, var(--color-action) 45%, transparent) 5px, color-mix(in srgb, var(--color-action) 12%, transparent) 5px, color-mix(in srgb, var(--color-action) 12%, transparent) 10px); top: 4px; height: 40px; }
/* Actual bar overlaid on top of run-rate in full-month row */
.bs-ov-bullet-fill--actual { position: absolute; top: 10px; height: 28px; background: var(--color-action); border-radius: 4px 0 0 4px; }
/* 3-tier compliance fill — Actual coloured vs target (≥100% green · ≥90% amber ·
   else red), mirroring the ATP onsite bars. Placed after the base/--actual rules
   so the tier background wins (equal specificity → source order). */
.bs-ov-bullet-fill--ok    { background: var(--color-success, #22C55E); }
.bs-ov-bullet-fill--warn  { background: var(--color-warning, #EAB308); }
.bs-ov-bullet-fill--below { background: var(--color-danger, #EF4444); }
/* Run-rate projection band — same 3 tiers as diagonal stripes vs full-month target. */
.bs-ov-bullet-fill--rr-ok    { background: repeating-linear-gradient(135deg, color-mix(in srgb, var(--color-success, #22C55E) 50%, transparent) 0, color-mix(in srgb, var(--color-success, #22C55E) 50%, transparent) 5px, color-mix(in srgb, var(--color-success, #22C55E) 14%, transparent) 5px, color-mix(in srgb, var(--color-success, #22C55E) 14%, transparent) 10px); }
.bs-ov-bullet-fill--rr-warn  { background: repeating-linear-gradient(135deg, color-mix(in srgb, var(--color-warning, #EAB308) 50%, transparent) 0, color-mix(in srgb, var(--color-warning, #EAB308) 50%, transparent) 5px, color-mix(in srgb, var(--color-warning, #EAB308) 14%, transparent) 5px, color-mix(in srgb, var(--color-warning, #EAB308) 14%, transparent) 10px); }
.bs-ov-bullet-fill--rr-below { background: repeating-linear-gradient(135deg, color-mix(in srgb, var(--color-danger, #EF4444) 50%, transparent) 0, color-mix(in srgb, var(--color-danger, #EF4444) 50%, transparent) 5px, color-mix(in srgb, var(--color-danger, #EF4444) 14%, transparent) 5px, color-mix(in srgb, var(--color-danger, #EF4444) 14%, transparent) 10px); }
/* Target marker — a bold vertical goalpost that reads clearly ON TOP of the
   measure bar even when Actual/Run-Rate overshoot the target (GMV achievement
   often >100%, unlike ATP's ≤100% compliance where the bar stops short).
   White core + dark outline is theme-independent: the bar tiers (green/amber/
   red) are the same in both themes, so the marker must contrast against THEM,
   not against the surface. Pokes above + below the bar so it never looks
   "inside" the fill. z-index above fills (auto) and value pills (2). */
/* feedback 2026-06-08 #3 (+ follow-up, image #3) — target marker is a clean
   SOLID bar: no diamond cap, no halo/outline. --text-primary → solid black in
   light (the user's ask) / solid white in dark, high-contrast against the fill
   in BOTH themes. */
.bs-ov-bullet-tick {
  position: absolute; top: -8px; bottom: -10px;
  width: 6px; border-radius: 2px;
  background: var(--text-primary);
  transform: translateX(-50%);
  z-index: 6;
}
.bs-ov-bullet-tick--full { top: -9px; bottom: -11px; }
/* "Target: ₫X" — solid label chip (inverted) so it reads clearly off the bar. */
.bs-ov-bullet-tick-label {
  position: absolute; top: -31px; left: 50%; transform: translateX(-50%);
  font-size: 10px; font-weight: 700; letter-spacing: 0.02em;
  color: var(--bg-surface); background: var(--text-primary);
  white-space: nowrap; padding: 1px 6px; border-radius: 4px; z-index: 7;
}
/* Value pill */
.bs-ov-bullet-pill { position: absolute; top: 16px; transform: translateX(-100%) translateX(-4px); background: var(--chart-pill-bg, rgba(8,10,15,0.85)); color: var(--chart-pill-fg, #fff); font-family: var(--font-mono, monospace); font-size: 11px; font-weight: 700; padding: 2px 7px; border-radius: 4px; white-space: nowrap; pointer-events: none; z-index: 2; }
/* B5b: Full-Month row exposes two pills — actual (inner, sits on the blue
   actual segment) and run-rate (outer, sits at the end of the striped band).
   Vertical offsets keep them on their respective bars (RR bar top:4 h:40,
   actual bar top:10 h:28). The RR pill is also shifted slightly to the right
   when the actual pill is close enough to collide. */
.bs-ov-bullet-pill--inner { top: 14px; }
.bs-ov-bullet-pill--rr { top: 14px; }
/* X-axis ticks */
.bs-ov-bullet-axis { display: flex; justify-content: space-between; margin-left: 164px; font-family: var(--font-mono, monospace); font-size: 10px; color: var(--text-tertiary); border-top: 1px solid var(--border-default); padding-top: 4px; }
.bs-ov-bullet-axis-tick { flex: 1; text-align: left; }
.bs-ov-bullet-axis-tick:last-child { text-align: right; }
/* Legend */
.bs-ov-bullet-legend { margin-left: 164px; }
.bs-ov-sw--rr { display: inline-block; width: 24px; height: 10px; background: repeating-linear-gradient(135deg, rgba(37,99,235,0.45) 0, rgba(37,99,235,0.45) 5px, rgba(37,99,235,0.12) 5px, rgba(37,99,235,0.12) 10px); border-radius: 2px; margin-right: 4px; vertical-align: middle; }
/* Insight cards */
.bs-ov-insight-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--space-3, 12px); margin-top: var(--space-3, 12px); }
/* Item 4 — the bullet chart emits THREE insight cards (MTD Achievement /
   Run Rate vs Full Month / Target GMV) with the --three modifier, but the
   modifier was never defined → the 3rd card fell to a second row under the
   2-col default. Pin it to a single 3-up row. */
.bs-ov-insight-grid--three { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.bs-ov-insight-card { padding: var(--space-3, 12px) var(--space-4, 16px); background: var(--bg-base); border: 1px solid var(--border-default); border-radius: var(--radius-md, 8px); display: flex; flex-direction: column; gap: 4px; }
/* feedback 2026-06-08 — insight-card numbers right-aligned (KPI-card parity). */
.bs-ov-insight-value { font-family: var(--font-mono, monospace); font-size: 22px; font-weight: 700; font-variant-numeric: tabular-nums; text-align: right; }
.bs-ov-insight--good { color: var(--gd-good, #16A34A); }
.bs-ov-insight--bad { color: var(--gd-bad, #DC2626); }
/* feedback 2026-06-08 — comment right-aligned together with the value. */
.bs-ov-insight-desc { font-size: 11px; color: var(--text-secondary); text-align: right; }

/* ── GMV vs Target — fallback cards ── */
.bs-ov-tgt-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--space-4, 16px); margin-top: var(--space-3, 12px); }
.bs-ov-tgt-card { display: flex; flex-direction: column; gap: 4px; padding: var(--space-4, 16px); background: var(--bg-inset, #F8FAFC); border: 1px solid var(--border-subtle, #E2E8F0); border-radius: var(--radius-md, 8px); min-width: 0; }
.bs-ov-tgt-card--strong { background: var(--bg-surface, #fff); border-color: var(--color-action, #2563EB); }
.bs-ov-tgt-card--strong .bs-ov-kpi-value { color: var(--color-action, #2563EB); }

/* ── Trend combo ── */
/* feedback 2026-06-09 — header controls row (Data-labels dropdown + grain toggle). */
.bs-ov-trend-controls { display: flex; align-items: center; gap: var(--space-3, 12px); flex-wrap: wrap; }
/* Data-labels per-series dropdown (reuses .pnl-export-menu button + dropdown shell). */
.bs-ov-label-menu { position: relative; }
.bs-ov-label-dropdown { padding: 6px; min-width: 168px; }
.bs-ov-label-opt { display: flex; align-items: center; gap: 8px; padding: 6px 8px; font-size: 12px; color: var(--text-primary); cursor: pointer; border-radius: var(--radius-sm, 6px); white-space: nowrap; }
.bs-ov-label-opt:hover { background: var(--bg-hover); }
.bs-ov-label-opt input { accent-color: var(--color-action); cursor: pointer; margin: 0; }
.bs-ov-label-sw { display: inline-block; width: 12px; height: 12px; border-radius: 3px; flex-shrink: 0; }
.bs-ov-trend-wrap { width: 100%; min-width: 0; }
.bs-ov-legend { display: flex; gap: var(--space-4, 16px); justify-content: center; margin-top: var(--space-2, 8px); font-size: 12px; color: var(--text-secondary, #5F6775); }
.bs-ov-legend span { display: inline-flex; align-items: center; gap: 6px; }
.bs-ov-sw { display: inline-block; width: 12px; height: 12px; }

/* ── Source of Revenue — ranked bars ── */
.bs-ov-sor-note { margin: var(--space-1, 4px) 0 var(--space-3, 12px); font-size: 12px; line-height: 1.4; color: var(--text-tertiary, #8C95A4); }
.bs-ov-sor { display: flex; flex-direction: column; gap: var(--space-2, 8px); margin-top: var(--space-2, 8px); }
.bs-ov-sor-row { display: grid; grid-template-columns: 200px 1fr 130px 70px; align-items: center; gap: var(--space-3, 12px); }
.bs-ov-sor-name { font-size: 13px; color: var(--text-primary, #111318); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bs-ov-sor-bar-wrap { background: var(--bg-inset, #EAEBEE); border-radius: var(--radius-xs, 4px); height: 18px; overflow: hidden; }
.bs-ov-sor-bar { height: 100%; background: var(--color-action, #2563EB); border-radius: var(--radius-xs, 4px); }
.bs-ov-sor-gmv, .bs-ov-sor-pct { font-size: 12px; text-align: right; font-variant-numeric: tabular-nums; color: var(--text-secondary, #5F6775); font-family: var(--font-mono, monospace); }

/* ── Source of Revenue — per-platform donuts (Item 7) ── */
.bs-ov-sor-donuts { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-5, 20px); margin-top: var(--space-3, 12px); }
.bs-ov-sord { display: flex; flex-direction: column; gap: var(--space-3, 12px); padding: var(--space-4, 16px); background: var(--bg-base); border: 1px solid var(--border-default); border-radius: var(--radius-md, 8px); min-width: 0; }
.bs-ov-sord-head { display: flex; align-items: center; gap: var(--space-2, 8px); min-height: 22px; }
.bs-ov-sord-plat { font-size: 13px; font-weight: 700; color: var(--text-primary); }
.bs-ov-sord-body { display: flex; flex-direction: column; gap: var(--space-3, 12px); }
.bs-ov-sord-chart { min-width: 0; }
.bs-ov-sord-tbl { width: 100%; border-collapse: collapse; font-size: var(--font-small, 12px); }
.bs-ov-sord-tbl th { background: var(--bg-inset); text-align: center; font-size: var(--font-xs); font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-secondary); padding: 4px 8px; border-bottom: 1px solid var(--border-default); }
.bs-ov-sord-tbl td { padding: 5px 8px; border-bottom: 1px solid var(--border-subtle); color: var(--text-secondary); }
.bs-ov-sord-tbl tbody tr:nth-child(even) td { background: color-mix(in srgb, var(--text-primary) 3.5%, transparent); }
.bs-ov-sord-num { text-align: right; font-variant-numeric: tabular-nums; font-family: var(--font-mono, monospace); white-space: nowrap; }
.bs-ov-sord-dot { display: inline-block; width: 8px; height: 8px; border-radius: 2px; margin-right: 6px; vertical-align: middle; }
@media (max-width: 900px) { .bs-ov-sor-donuts { grid-template-columns: 1fr; } }

/* ── Top Cancel Reason — horizontal bar chart ── */
.bs-ov-cancel-controls { display: flex; align-items: center; gap: var(--space-3, 12px); flex-wrap: wrap; }
.bs-ov-ctrl-sep { width: 1px; height: 20px; background: var(--border-default); flex-shrink: 0; }
.bs-ov-cancel-chart { width: 100%; min-width: 0; overflow-x: auto; }

/* ── Block 7 stub ── */
.bs-ov-deferred-stub { opacity: 0.7; }
.bs-ov-deferred-stub code { font-family: var(--font-mono, monospace); font-size: 11px; background: var(--bg-inset); padding: 1px 5px; border-radius: 3px; }

/* ── Responsive ── */
@media (max-width: 1024px) {
  .bs-ov-kpi-grid--primary { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .bs-ov-kpi-grid--secondary { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .bs-ov-tgt-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .bs-ov-sor-row { grid-template-columns: 130px 1fr 96px 56px; }
  .bs-ov-insight-grid { grid-template-columns: 1fr; }
  /* Item 4 — keep the three achievement/target cards on one line down to
     tablet (they're compact metric cards); only collapse on phones (<=640). */
  .bs-ov-insight-grid--three { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .bs-ov-bullet-axis { margin-left: 0; }
  .bs-ov-bullet-legend { margin-left: 0; }
  .bs-ov-bullet-label { width: 100px; }
  .bs-ov-compare-wrap { flex-wrap: wrap; }
}
@media (max-width: 640px) {
  .bs-ov-kpi-grid--primary { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .bs-ov-kpi-grid--secondary { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .bs-ov-sor-row { grid-template-columns: 100px 1fr 80px 50px; }
  .bs-ov-insight-grid--three { grid-template-columns: 1fr; }
  .bs-ov-bullet-label { display: none; }
  .bs-ov-bullet-axis { margin-left: 0; }
  .bs-ov-bullet-legend { margin-left: 0; }
}

/* Page-scoped [data-tooltip] dark pill — matches the framework pattern
   in styles.css (per-component, scoped via attribute + ::after). Used
   on the bullet ticks (Target MTD / Full Month) and the compare-note
   caveat. Replaces native title= which doesn't bubble in our stack. */
/* NOTE: the tick is intentionally position:absolute (see .bs-ov-bullet-tick) so
   it stretches into a full-height target LINE across the bar. It is still a
   positioned ancestor, so the ::after hover tooltip anchors to it correctly —
   do NOT add position:relative here (that collapses the line to 0 height). */
.bs-ov-compare-note[data-tooltip] { position: relative; }
.bs-ov-bullet-tick[data-tooltip]::after,
.bs-ov-compare-note[data-tooltip]::after {
  content: attr(data-tooltip);
  position: absolute;
  bottom: calc(100% + 6px);
  left: 50%;
  transform: translateX(-50%) translateY(2px);
  background: rgba(8, 10, 15, 0.95);
  color: #ffffff;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.01em;
  padding: 6px 10px;
  border-radius: 4px;
  max-width: 280px;
  white-space: normal;
  text-align: center;
  line-height: 1.4;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.15s ease, transform 0.15s ease;
  z-index: 1000;
}
.bs-ov-bullet-tick[data-tooltip]:hover::after,
.bs-ov-compare-note[data-tooltip]:hover::after {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}

/* ── Ranked share-bar list (By Customer Type, affiliate breakdowns) ──────────
   Used by bs-shopper-member, bs-affiliate-campaign, bs-affiliate-content. These
   classes were referenced by markup but never styled, so the bars rendered
   invisible (plain text). Token-based horizontal share bars. */
.bs-ov-ranked-list { display: flex; flex-direction: column; gap: var(--space-4, 16px); }
.bs-ov-ranked-row { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.bs-ov-ranked-row__label {
  font-size: var(--font-body, 14px); color: var(--text-primary, #111318);
  display: flex; align-items: baseline; gap: 6px; min-width: 0;
}
.bs-ov-ranked-row__label strong { font-weight: 700; text-transform: capitalize; }
.bs-ov-ranked-row__bar {
  position: relative; width: 100%; height: 10px; border-radius: 999px;
  background: var(--bg-hover, #EDEEF1); overflow: hidden;
}
.bs-ov-ranked-row__fill {
  height: 100%; border-radius: 999px; min-width: 2px;
  background: var(--color-action, #2563EB);
  transition: width var(--transition-base, 250ms ease);
}
.bs-ov-ranked-row__values {
  font-size: var(--font-small, 12px); color: var(--text-secondary, #5F6775);
  font-variant-numeric: tabular-nums;
}

/* ── B&S page card-stack spacing ─────────────────────────────────────────────
   The gold-standard .bs-ov-page sets a flex-column gap so sibling .card
   sections don't touch (.card itself has no margin). These page roots were
   missing it, so their cards rendered flush against each other. Same
   gold-standard block; explicitly scoped to ecom roots (SOCOM untouched). */
.bs-shopper-member-page,
.aging-page,
.doi-page,
.bs-affiliate-campaign-page,
.bs-affiliate-content-page,
.bs-affiliate-raw-page,
.bs-media-daily-page {
  display: flex;
  flex-direction: column;
  gap: var(--space-5, 20px);
  min-width: 0;
}

/* ============================================================
   Detail Performance by Groupbrand / Store table (.bs-ov-detail-*)
   Was entirely UNSTYLED (classes referenced in JS, defined nowhere) → raw
   table, no sticky header, no borders, no tabular-nums (2026-05-31 audit
   blocker). Styled here to the ecom standard: self-contained scroll wrap +
   sticky <thead> (the ATP "Wide detail tables" recipe), full grid borders,
   right-aligned tabular numerics. ============================================ */
/* Item 9 — detail table controls: compare pills + export + expand-all */
.bs-ov-detail-controls { display: flex; align-items: center; gap: var(--space-2, 8px); flex-wrap: wrap; }
.bs-ov-pillbtn {
  display: inline-flex; align-items: center; gap: 5px; height: 30px; padding: 0 var(--space-3, 12px);
  border: 1px solid var(--border-default); border-radius: var(--radius-full, 999px);
  background: var(--bg-surface); color: var(--text-secondary);
  font-size: 12px; font-weight: 600; cursor: pointer; white-space: nowrap;
  transition: all var(--transition-fast, 0.15s);
}
.bs-ov-pillbtn:hover:not([disabled]) { border-color: var(--color-action); color: var(--color-action); }
.bs-ov-pillbtn[disabled] { opacity: 0.5; cursor: default; }
.bs-ov-pillbtn-ico { font-size: 12px; line-height: 1; opacity: 0.85; }

.bs-ov-detail-wrap {
  max-height: calc(100vh - 240px);
  overflow: auto;                       /* own both axes → sticky thead pins */
  border: 1px solid var(--border-default, #E2E8F0);
  border-radius: var(--radius-md, 10px);
}
.bs-ov-detail-tbl {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--font-data, 13px);
}
.bs-ov-detail-tbl thead {        /* stick the cohesive <thead>, not the cells */
  position: sticky;
  top: 0;
  z-index: 2;
}
.bs-ov-detail-th,
.bs-ov-detail-entity,
.bs-ov-detail-num {
  border: 1px solid var(--border-subtle, #EEF1F5);
  padding: 6px var(--space-3, 12px);
  white-space: nowrap;
}
/* Headers — bold + centered (portfolio table standard). */
.bs-ov-detail-th {
  background: var(--bg-inset, #EAEBEE);
  font-size: var(--font-xs, 11px);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-secondary, #5F6775);
  text-align: center;
}
.bs-ov-detail-num {
  text-align: right;
  font-variant-numeric: tabular-nums;
  font-family: var(--font-mono, ui-monospace, monospace);
}
.bs-ov-detail-entity { text-align: left; position: sticky; left: 0; z-index: 1; background: var(--bg-surface); }
.bs-ov-detail-grow { cursor: pointer; }
/* Zebra striping — alternating group rows for scan-readability. */
.bs-ov-detail-tbl tbody tr.bs-ov-detail-grow:nth-of-type(even) td { background: color-mix(in srgb, var(--text-primary) 3.5%, transparent); }
.bs-ov-detail-grow:hover td { background: var(--bg-hover, #F1F5F9); }
.bs-ov-detail-gname { font-weight: 600; }
.bs-ov-detail-srow td { color: var(--text-secondary, #5F6775); }
.bs-ov-detail-srow .bs-ov-detail-entity { padding-left: var(--space-6, 24px); }
.bs-ov-detail-chev {
  display: inline-block;
  margin-right: 6px;
  transition: transform 0.15s ease;
  color: var(--text-tertiary, #8C95A4);
}
.bs-ov-detail-chev--open { transform: rotate(90deg); }
/* Delta = light-tinted heatmap pills (color-coded, not oversaturated). */
.bs-ov-delta { display: inline-block; padding: 1px 7px; border-radius: 5px; font-variant-numeric: tabular-nums; font-weight: 600; }
.bs-ov-delta--good { color: var(--color-success, #16A34A); background: color-mix(in srgb, var(--color-success) 14%, transparent); }
.bs-ov-delta--bad  { color: var(--color-danger, #DC2626); background: color-mix(in srgb, var(--color-danger) 14%, transparent); }
.bs-ov-delta--flat { color: var(--text-tertiary, #8C95A4); }

/* ── KPI prior-period delta badge (mig 225) + vs-Target toggle (mig 224) ── */
/* feedback 2026-06-08 #2 — comparison row presented like SOCOM .metric-card__trend:
   a bled divider above + right-aligned colored TEXT (no tinted chip). The color
   still comes from .bs-ov-delta--good/--bad/--flat (text-color); background:none
   overrides the detail-table pill tint those classes also carry. */
.bs-ov-kpi-delta { display: flex; justify-content: flex-end; align-items: center; gap: 4px; margin: 7px calc(-1 * var(--space-4, 16px)) 0; padding: 7px var(--space-4, 16px) 0; border-top: 1px solid var(--border-default); font-size: 11px; font-weight: 700; font-family: var(--font-mono); font-variant-numeric: tabular-nums; background: none; }
.bs-ov-kpi-delta-mode { font-weight: 500; opacity: 0.6; font-size: 10px; }
.bs-ov-pillbtn--active { background: var(--color-action, #2563EB); border-color: var(--color-action, #2563EB); color: #fff; }
