/* src/styles/tracker.css — Master Tracker (route /sohk/tracker). OWNER-C.
 *
 * Targets the actual class names OWNER-A's components render — read straight
 * from src/pages/MasterTracker.js, src/components/tracker/{TrackerFilters,
 * BoardTable,PacingTable,CashPacingCard,TargetsModal}.js — not a speculative
 * vocabulary. NEW rules only: everything already in src/styles/app.css is
 * reused as-is, and this file loads AFTER app.css (see public/index.html) so
 * equal-specificity `.trk-*` rules here win over it where the two overlap on
 * purpose (e.g. widening `.sticky-col`'s single-column assumption to three).
 *
 * Reused verbatim from app.css, not redefined here: .cc-tabs/.cc-tab (role
 * tabs), .toggle (Board|Pacing, dialing source), .dd/.dd-btn/.dd-pop/.dd-opt
 * (every filter <Select>), .btn-primary/.btn-ghost, .field-input/.field-label,
 * .modal*/.journey-body (Targets modal, via src/components/Modal.js),
 * .wow-panel/.wow-scroll/.wow-table/.sticky-col/.th-label (board + pacing
 * table shell — ported from the Week-over-Week table), .panel-head/
 * .panel-title/.panel-title-sub, .tg-legend-*/.tg-dot/.tg-pos/.tg-warn/
 * .tg-neg/.tg-metric/.tg-dim/.tg-foot/.tg-sum-note/.tg-month-select (the
 * pace-tone + legend vocabulary ported from TargetsTab — reused directly for
 * the board legend popover), .ads-loading/.ads-spinner, .notes-empty,
 * .error-box, .auth-err.
 *
 * Cell tone classes ARE new here even though .tg-pos/.tg-warn/.tg-neg exist:
 * src/lib/pace.js's cellTone() returns bare "pos"/"warn"/"neg"/"" and
 * BoardTable.js/PacingTable.js render it as `trk-${tone}` (not `tg-${tone}`),
 * so the board/pacing data cells use a SEPARATE trk-pos/trk-warn/trk-neg
 * family, styled here as a full-cell wash rather than the tg-* badge look.
 */

/* =====================================================================
   1. Page chrome — src/pages/MasterTracker.js
   ===================================================================== */

.trk-shell {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.trk-toprow {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}

/* The Board|Pacing toggle + Targets/Refresh buttons reuse .tg-head-actions
   (app.css, from the Targets tab's own header row) — no new rule needed. */

/* Generic status box — the empty tab placeholder (Pending), a fetch error
   (ErrorPanel) and the COVERAGE notice all render one of these variants.
   Left-aligned (not centred): every use carries a heading/message/action
   stack, not a single short line.

   There is no synthetic variant any more, because there is no synthetic data:
   a view is either real query output or held with a reason. `trk-state-note`
   is the coverage voice — a window that stops short of today, or a filter with
   no baked slice behind it. It is deliberately quieter than the error red:
   nothing is broken, the numbers simply do not reach that far yet. */
.trk-state {
  padding: 16px 18px;
  border: 1px solid var(--hairline);
  border-radius: 14px;
  background: var(--card);
  color: var(--text-dim);
  font-size: 13px;
  line-height: 1.6;
}

.trk-state.trk-state-error {
  border-color: rgba(255, 107, 125, .3);
  background: #ff6b7d0f;
  color: #ffb4bd;
}

.trk-state.trk-state-note {
  border-color: rgba(245, 183, 90, .32);
  background: #f5b75a0d;
  color: var(--text);
}

.trk-state.trk-state-note strong {
  display: block;
  margin-bottom: 4px;
  color: #f5c877;
  font-weight: 650;
  letter-spacing: .01em;
}

.trk-state.trk-state-note ul {
  margin: 6px 0 0;
  padding-left: 18px;
}

.trk-state.trk-state-note li + li {
  margin-top: 4px;
}

/* The from/to/rep/calendar/dialer status line under the filter bar
   (MasterTracker.js). The board's own coverage-notes footer reuses the
   existing .tg-foot instead. */
.trk-coverage {
  font-size: 11.5px;
  color: var(--text-faint);
}

/* =====================================================================
   2. Filter bar — src/components/tracker/TrackerFilters.js
   ===================================================================== */

.trk-filters {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 14px 16px;
  border: 1px solid var(--hairline);
  border-radius: 16px;
  background: var(--card);
  margin-bottom: 4px;
  transition: opacity .15s;
}

.trk-filters.is-disabled {
  opacity: .5;
  pointer-events: none;
}

.trk-filter-row {
  display: flex;
  align-items: flex-end;
  gap: 12px;
  flex-wrap: wrap;
}

/* The period-token row reuses .toggle's look but needs to wrap onto more than
   one line at narrow widths — .toggle itself is `inline-flex` with no wrap. */
.toggle.trk-periods {
  flex-wrap: wrap;
}

.trk-custom {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

.trk-custom-hint {
  font-size: 10.5px;
  color: var(--text-faint);
  white-space: nowrap;
}

/* Select wrapper widths — .dd itself has no fixed width; .dd-btn's own
   min-width (140px, app.css) is enough for most, but the Calendar select's
   values are single letters and can be narrower. */
.trk-sel.trk-sel-sm .dd-btn {
  min-width: 84px;
}

.trk-dialer {
  display: flex;
  flex-direction: column;
  gap: 5px;
}

/* Pushes "Clear filters" to the end of its row. */
.trk-clear {
  margin-left: auto;
}

/* Small provenance line under the filter rows, inside the filter bar card —
   only rendered when the roster payload carries a source + observedAt, so it
   quietly disappears rather than showing a guess (TrackerFilters.js). */
.trk-roster-note {
  font-size: 11px;
  color: var(--text-faint);
}

/* "Captured views" summary — same quiet voice as the roster note, its own
   rule only so it can be targeted/removed independently later. */
.trk-captured-note {
  margin-top: -2px;
}

/* GET /api/tracker/windows honesty pass: a period token or a dialing-source
   button with no captured slice behind it renders `disabled`. `.toggle
   button` (app.css) has no disabled look of its own, so this is the "muted
   trk- rule" fallback the fix asked for. */
.trk-periods button:disabled,
.trk-dialer button:disabled {
  opacity: 0.38;
  cursor: not-allowed;
}

.trk-periods button:disabled:hover,
.trk-dialer button:disabled:hover {
  color: var(--text-dim);
}

/* Calendar / Lead source use a local FilterSelect (TrackerFilters.js) rather
   than the shared <Select>, because <Select> has no per-option disabling.
   `.dd-opt` (app.css) has no disabled look either, so this adds one; the
   trigger button itself stays the ordinary `.dd-btn` look since the control
   as a whole is never disabled, only some of its options are. */
.trk-filters .dd-opt:disabled,
.trk-filters .dd-opt.is-disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

.trk-filters .dd-opt:disabled:hover,
.trk-filters .dd-opt.is-disabled:hover {
  background: transparent;
}

/* =====================================================================
   3. Board table — src/components/tracker/BoardTable.js
   ===================================================================== */

.trk-panel {
  position: relative;
}

.trk-empty {
  padding-bottom: 6px;
}

.trk-admin-note {
  font-size: 12px;
  color: var(--text-dim);
  padding: 10px 14px;
  border: 1px solid var(--hairline);
  border-radius: 12px;
  background: #ffffff05;
  margin-bottom: 14px;
}

.trk-tablebar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 12px;
}

.trk-fixednote {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 11.5px;
  color: var(--text-faint);
}

.trk-pagers {
  display: inline-flex;
  gap: 6px;
}

.trk-pacing-actions {
  display: inline-flex;
  align-items: center;
  gap: 12px;
}

/* Bordered scroll frame — .wow-scroll's own `margin: 0 -6px` bleeds it to the
   panel edge, which reads fine for a single sticky column but looks
   unintentional once the frozen block is three columns wide and the header
   row has its own dark background; a visible frame reads as "this scrolls". */
.wow-scroll.trk-scroll {
  margin: 0;
  border: 1px solid var(--hairline);
  border-radius: 14px;
  position: relative;
}

/* .wow-table hard-codes `min-width: 860px`, sized for the Week-over-Week
   table's fixed 8ish columns; the tracker board can have 40+ rep columns, so
   it must be allowed to grow past that to its natural content width instead
   of squeezing every column to fit. */
.wow-table.trk-table {
  width: max-content;
  min-width: 100%;
}

/* Three frozen columns (Metric / Target / Needed for range), widths as CSS
   custom properties so the sticky `left` offsets always match the rendered
   widths exactly — one source of truth instead of duplicated magic numbers.
   .sticky-col (app.css) already supplies position:sticky, z-index and the
   background; these rules only add per-column width + left offset, and this
   file loads after app.css so the tied specificity resolves in its favour. */
.trk-table {
  --trk-fz1: 224px; /* Metric */
  --trk-fz2: 88px;  /* Target */
  --trk-fz3: 116px; /* Needed for range */
}

.trk-table th.trk-fz1,
.trk-table td.trk-fz1 {
  left: 0;
  width: var(--trk-fz1);
  min-width: var(--trk-fz1);
  max-width: var(--trk-fz1);
  white-space: normal;
  line-height: 1.35;
}

.trk-table th.trk-fz2,
.trk-table td.trk-fz2 {
  left: var(--trk-fz1);
  width: var(--trk-fz2);
  min-width: var(--trk-fz2);
  text-align: right;
}

.trk-table th.trk-fz3,
.trk-table td.trk-fz3 {
  left: calc(var(--trk-fz1) + var(--trk-fz2));
  width: var(--trk-fz3);
  min-width: var(--trk-fz3);
  text-align: right;
  border-right: 1px solid var(--hairline-strong);
}

/* Row-label hover affordance — the metric label's title carries the row's
   `help` text from the server; this just signals "hover me" the same way
   .th-label already does for the Week-over-Week table's column headers. */
.trk-metric-label {
  cursor: help;
  border-bottom: 1px dotted var(--hairline-strong);
  padding-bottom: 1px;
}

/* Rep / pod / team data columns. */
.trk-table td.trk-cell {
  font-variant-numeric: tabular-nums;
}

/* cursor:help ONLY where the title attribute actually carries something to
   read: rate cells (num/den, from pace.js cellTitle()) and void cells (the
   source's unavailable/undefined reason). A plain money/count/duration cell
   in "ok" status has no title, so it stays a normal cursor — a help cursor
   over nothing was the bug this scopes away. .trk-rate-cell is added by
   BoardTable.js's Cell() / PacingTable.js's ValueCell() whenever the row's
   kind is "rate"; .trk-void is added by both whenever the cell isn't "ok". */
.trk-table td.trk-cell.trk-rate-cell,
.trk-table td.trk-cell.trk-void {
  cursor: help;
}

.trk-table th.wow-th.trk-pod,
.trk-table td.trk-cell.trk-pod {
  background: #8b6dff14;
}

/* Pace-tone wash. cellTone()/formatValue() (src/lib/pace.js) only ever
   produce "pos" | "warn" | "neg" | "" — BoardTable.js and PacingTable.js
   both render that as the literal class `trk-${tone}`. */
.trk-table td.trk-cell.trk-pos {
  background: #34e07b1f;
  color: var(--pos);
  font-weight: 650;
}

.trk-table td.trk-cell.trk-warn {
  background: #ffb45429;
  color: #ffb454;
  font-weight: 650;
}

.trk-table td.trk-cell.trk-neg {
  background: #ff6b7d24;
  color: var(--neg);
  font-weight: 650;
}

/* Unavailable / no-value cell: the dash reads as quietly inert, not a zero. */
.trk-table td.trk-cell.trk-void {
  color: var(--text-faint);
  font-weight: 400;
}

/* TEAM TOTAL — always blue, never pace-graded (DECISIONS-v1.md M12). This
   rule is placed AFTER .trk-pos/.trk-warn/.trk-neg above on purpose: src/lib/
   pace.js's cellTone() has no column context, so a graded row's team cell
   can carry both a tone class and trk-team at once (see the "KNOWN GAP" test
   in tests/tracker-pace.test.mjs) — .trk-team must win that cascade, and
   with equal class-count specificity, later-in-file wins. */
.trk-table th.wow-th.trk-team,
.trk-table td.trk-cell.trk-team {
  background: #6d8bff1f !important;
  color: var(--text) !important;
  font-weight: 700;
}

.trk-table tbody tr:hover td.trk-cell.trk-team {
  background: #6d8bff2b !important;
}

/* Blue "team" legend dot — the pos/warn/neg dots are .tg-dot.tg-pos etc.
   (app.css); this is the one tone that vocabulary doesn't cover. */
.tg-dot.trk-dot-team {
  background: var(--accent);
}

/* =====================================================================
   4. Pacing view — src/components/tracker/PacingTable.js
   ===================================================================== */

.trk-pacing-table thead tr.trk-grouprow th {
  border-bottom: 1px solid var(--hairline);
  padding-top: 8px;
  padding-bottom: 8px;
}

.trk-groupcell {
  text-align: center;
  font-weight: 650;
  border-left: 1px solid var(--hairline);
}

/* Past-month groups read as reference, not the live target — dimmed relative
   to the current month's group (which has no extra class, i.e. full text). */
.trk-histgroup {
  color: var(--text-faint);
  font-weight: 550;
}

/* Week "Total" sub-column — both the th (week-group header) and the matching
   td (PacingTable.js's WeekCell) get this class. */
.trk-wtotal {
  font-weight: 650;
  border-left: 1px solid var(--hairline);
}

.trk-table td.trk-cell.trk-wtotal {
  color: var(--text);
}

/* Actual column — the one pacing column that gets a pace tone. */
.trk-table td.trk-cell.trk-actual {
  border-right: 1px solid var(--hairline-strong);
  font-weight: 700;
}

/* Plain history-week cell (not a Total column) — quieter than Actual since
   it is never graded, only ever a reference number. */
.trk-table td.trk-cell.trk-week {
  color: var(--text-dim);
  font-weight: 400;
}

/* =====================================================================
   5. CURRENT CASH PACING card — src/components/tracker/CashPacingCard.js
   ===================================================================== */

.wow-panel.trk-cashcard {
  margin-top: 16px;
  background: linear-gradient(180deg, #6d8bff0f, #ffffff02);
  border-color: var(--hairline);
}

.trk-cashgrid {
  display: grid;
  /* 200px, not 160px: a seven-digit cash figure with cents ("$1,234,567.89")
     at the tile's 22px tabular-numeral font needs more than 160px minus its
     own 16px side padding — it was clipping past the tile edge. */
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 12px;
  margin-top: 6px;
}

.trk-cashstat {
  background: linear-gradient(180deg, #ffffff08, #ffffff02);
  border: 1px solid var(--hairline);
  border-radius: 16px;
  padding: 14px 16px;
}

.trk-cashstat-label {
  font-size: 10.5px;
  font-weight: 650;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--text-faint);
}

.trk-cashstat-val {
  font-size: 22px;
  font-weight: 700;
  margin-top: 8px;
  letter-spacing: -.02em;
  /* Belt-and-suspenders alongside the wider tile above: a long unbroken
     numeral string (no spaces to wrap at) would otherwise overflow the tile
     instead of wrapping to a second line on a narrow viewport. */
  overflow-wrap: anywhere;
}

.trk-cashstat-val.trk-pos {
  color: var(--pos);
}

.trk-cashstat-val.trk-warn {
  color: #ffb454;
}

.trk-cashstat-val.trk-neg {
  color: var(--neg);
}

/* =====================================================================
   6. Targets modal (Settings-style) — src/components/tracker/TargetsModal.js
   ===================================================================== */

/* modal-wide caps at 520px (app.css); two side-by-side target columns need
   more room than that. */
.modal.trk-tgt-modal {
  max-width: 680px;
}

.trk-tgt-body {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.trk-tgt-cols {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 22px;
  margin-top: 14px;
}

.trk-tgt-grid {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin-top: 8px;
}

.trk-tgt-field {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 7px 0;
  border-bottom: 1px solid var(--hairline);
}

.trk-tgt-field:last-child {
  border-bottom: 0;
}

.trk-tgt-field .field-label.sm {
  margin-bottom: 0;
  flex: 1 1 auto;
  min-width: 0;
}

.trk-tgt-input {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex: none;
}

.trk-tgt-input .field-input.sm {
  width: 92px;
  text-align: right;
}

.trk-tgt-suffix {
  font-size: 11px;
  color: var(--text-faint);
  width: 14px;
}

@media (max-width: 620px) {
  .trk-tgt-cols {
    grid-template-columns: 1fr;
    gap: 18px;
  }
}

/* =====================================================================
   7. Financials tab — FinancialsTab.js / CommissionsPanel.js /
      SplitTestsTab.js (OWNER-B). Re-audited against the real markup in all
      three files, current as of CommissionsPanel.js's four-section (Closers/
      Setters/Triagers/Held) rewrite: .trk-fingrid is in FinancialsTab.js's
      calculator KPI row AND every one of CommissionsPanel.js's four section
      KPI rows; .trk-programrow/.trk-programhead is FinancialsTab.js's
      edit-mode program list; .trk-tierchips/.trk-tierchip is
      CommissionsPanel.js's tier legend, its "N held" section-tab badge, AND
      its inline per-row "held"/"Unknown" chips; .trk-splitgrid/.trk-splitcard/
      .trk-splitcard-title/.trk-splitcard-badge/.trk-metricpills/
      .trk-metricpill is SplitTestsTab.js. `.trk-pending` (the old single-line
      "policy pending" placeholder) is GONE from this pass — the rewrite pays
      setters and triagers instead of stubbing them out — and is deleted
      below with it: a selector nothing renders is worse than no selector,
      since it invites the next edit to "fix" a rule for markup that no
      longer exists. Kept as its own section rather than folded into 3-6
      because it is still the newest vocabulary and the one most likely to
      shift as these tabs grow. Naming follows the compact `trk-word`
      convention OWNER-A used in BoardTable.js/CashPacingCard.js
      (trk-cashgrid, trk-cashstat, …).
   ===================================================================== */

.trk-fingrid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 12px;
  margin-bottom: 16px;
}

.trk-programrow {
  display: grid;
  grid-template-columns: minmax(0, 2fr) 120px 100px 110px 80px;
  gap: 10px;
  align-items: center;
  padding: 10px 14px;
  border-bottom: 1px solid var(--hairline);
}

.trk-programrow:last-child {
  border-bottom: 0;
}

.trk-programrow.trk-programhead {
  font-size: 10.5px;
  font-weight: 650;
  text-transform: uppercase;
  letter-spacing: .05em;
  color: var(--text-faint);
}

.trk-tierchips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 10px 0 14px;
}

.trk-tierchip {
  font-size: 11px;
  color: var(--text-dim);
  border: 1px solid var(--hairline);
  border-radius: 999px;
  padding: 4px 11px;
  background: var(--card);
}

/* Split Tests — four placeholder cards; no existing primitive covers this. */
.trk-splitgrid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 14px;
}

.trk-splitcard {
  padding: 16px 18px;
  border: 1px solid var(--hairline);
  border-radius: 16px;
  background: linear-gradient(180deg, #ffffff08, #ffffff02);
}

.trk-splitcard-title {
  font-size: 14px;
  font-weight: 650;
  margin-bottom: 6px;
}

.trk-splitcard-badge {
  display: inline-block;
  font-size: 10.5px;
  font-weight: 650;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--text-faint);
  border: 1px solid var(--hairline);
  border-radius: 999px;
  padding: 3px 9px;
  margin-bottom: 10px;
}

.trk-metricpills {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.trk-metricpill {
  font-size: 11px;
  color: var(--text-dim);
  background: #ffffff08;
  border: 1px solid var(--hairline);
  border-radius: 999px;
  padding: 4px 10px;
}

/* =====================================================================
   8. Responsive — existing breakpoints (860 / 620). Frozen columns keep
      working on mobile because the sticky offsets are CSS-var driven, not
      viewport-relative; the columns just get narrower and the scroll frame
      (.trk-scroll) still scrolls horizontally under a fixed head.
   ===================================================================== */

@media (max-width: 860px) {
  .trk-filters {
    padding: 12px;
  }

  .trk-table {
    --trk-fz1: 168px;
    --trk-fz2: 72px;
    --trk-fz3: 92px;
  }
}

@media (max-width: 620px) {
  .trk-toprow {
    flex-direction: column;
    align-items: flex-start;
  }

  .trk-tablebar {
    flex-direction: column;
    align-items: flex-start;
    gap: 8px;
  }

  .trk-clear {
    margin-left: 0;
  }

  .trk-programrow {
    grid-template-columns: minmax(0, 1fr);
    gap: 4px;
  }

  .trk-programrow.trk-programhead {
    display: none;
  }
}
