/* ============================================================================
   dashboard.css — app-shell components for Primi internal dashboards.

   Requires primi-theme.css (tokens) and components.css (cards, KPIs, tables).
   Composes tokens only: no --pd-* value is redefined here, no hex literal is
   written here, no font is named here. Those three rules are what stopped the
   dashboards from drifting apart, and tools/check-design-drift.js enforces them.
   ============================================================================ */

/* ---- shell ---------------------------------------------------------------
   One container width for every screen. Three different widths across three
   tabs is why the nav appeared to jump when you switched. */
.pd-shell {
  --pd-shell-max: 1180px;
  max-width: var(--pd-shell-max);
  margin: 0 auto;
  padding: 0 var(--pd-space-5) var(--pd-space-8);
}
.pd-shell--wide { --pd-shell-max: 1400px; }

@media (max-width: 640px) {
  .pd-shell { padding: 0 var(--pd-space-4) var(--pd-space-7); }
}

/* ---- app bar ------------------------------------------------------------- */
.pd-appbar {
  position: sticky;
  top: 0;
  z-index: 30;
  background: var(--pd-surface);
  border-bottom: 1px solid var(--pd-border);
}
.pd-appbar-in {
  max-width: var(--pd-shell-max, 1180px);
  margin: 0 auto;
  padding: var(--pd-space-3) var(--pd-space-5);
  display: flex;
  align-items: center;
  gap: var(--pd-space-4);
  flex-wrap: wrap;
}
.pd-appbar-brand {
  display: flex;
  align-items: center;
  gap: var(--pd-space-2);
  text-decoration: none;
  color: var(--pd-text);
  flex: none;
}
.pd-appbar-brand:hover { color: var(--pd-text); }
/* The brand lockup is the WORDMARK ALONE. A text title beside it read as a
   second competing wordmark whose baseline never optically matched the logo's
   internal one — the "three fonts" complaint. The product name lives in each
   page's eyebrow instead. */
.pd-appbar-spacer { flex: 1 1 auto; }
.pd-appbar-meta {
  display: flex;
  align-items: center;
  gap: var(--pd-space-3);
  font-size: var(--pd-text-xs);
  color: var(--pd-muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

@media (max-width: 640px) {
  .pd-appbar-in { padding: var(--pd-space-3) var(--pd-space-4); gap: var(--pd-space-3); }
}

/* ---- tabs ----------------------------------------------------------------
   The active tab is marked with aria-current="page" and styled off that
   attribute — never a separate .on class. One source of truth means the
   accessible state and the visible state cannot disagree, which is exactly the
   class of bug that left one screen styling a --ink-3 variable that did not
   exist while its inactive tabs quietly fell back to a hardcoded grey. */
.pd-tabs {
  display: flex;
  gap: var(--pd-space-1);
  align-items: center;
  overflow-x: auto;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}
.pd-tabs::-webkit-scrollbar { display: none; }
.pd-tab {
  /* one size step BELOW the brand: navigation is the quiet voice */
  font-size: var(--pd-text-xs);
  line-height: 1;
  font-weight: var(--pd-weight-medium);
  color: var(--pd-muted);
  text-decoration: none;
  padding: 7px var(--pd-space-3);
  border-radius: var(--pd-radius-pill);
  border: 1px solid transparent;
  white-space: nowrap;
  flex: none;
}
.pd-tab:hover { color: var(--pd-text); background: var(--pd-surface-2); }
.pd-tab[aria-current="page"] {
  color: var(--pd-text);
  background: var(--pd-surface-2);
  border-color: var(--pd-border-strong);
  font-weight: var(--pd-weight-semi);
}
/* v2 preview tabs: same quiet voice, plus a small green marker so the
   proposal pages are unmistakable next to the live ones */
.pd-tab--v2 { color: var(--pd-text-secondary); border-color: var(--pd-green-200); }
.pd-tab--v2:hover, .pd-tab--v2[aria-current="page"] { border-color: var(--pd-green-500); }
.pd-v2 { display:inline-block; margin-left:4px; padding:1px 5px; border-radius:var(--pd-radius-sm); background:var(--pd-green-50); color:var(--pd-green-700); font-size:var(--pd-text-2xs); font-weight:var(--pd-weight-semi); letter-spacing:var(--pd-tracking-label); text-transform:uppercase; vertical-align:middle; }

/* ---- live pulse ---------------------------------------------------------- */
.pd-live {
  display: inline-flex;
  align-items: center;
  gap: var(--pd-space-2);
  font-size: var(--pd-text-xs);
  color: var(--pd-muted);
}
.pd-live::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: var(--pd-radius-pill);
  background: var(--pd-success-fill);
  flex: none;
}
.pd-live[data-state="stale"]::before { background: var(--pd-warn-fill); }
.pd-live[data-state="down"]::before { background: var(--pd-danger-fill); }

/* ---- diagnostics strip ---------------------------------------------------
   Collapses to a single green line when nothing is wrong, so the absence of
   problems is stated rather than merely implied by an empty space. */
.pd-diag {
  display: flex;
  flex-direction: column;
  gap: var(--pd-space-2);
  margin: var(--pd-space-5) 0 0;
  padding: var(--pd-space-3) var(--pd-space-4);
  background: var(--pd-surface);
  border: 1px solid var(--pd-border);
  border-left: 3px solid var(--pd-success-fill);
  border-radius: var(--pd-radius-md);
  font-size: var(--pd-text-sm);
}
.pd-diag[data-worst="warn"] { border-left-color: var(--pd-warn-fill); }
.pd-diag[data-worst="danger"] { border-left-color: var(--pd-danger-fill); }
.pd-diag-row {
  display: flex;
  align-items: baseline;
  gap: var(--pd-space-3);
  flex-wrap: wrap;
}
.pd-diag-row + .pd-diag-row { padding-top: var(--pd-space-2); border-top: 1px solid var(--pd-border); }
.pd-diag-label { font-weight: var(--pd-weight-semi); color: var(--pd-text); }
.pd-diag-row[data-level="ok"] .pd-diag-label { color: var(--pd-success); }
.pd-diag-row[data-level="warn"] .pd-diag-label { color: var(--pd-warn); }
.pd-diag-row[data-level="danger"] .pd-diag-label { color: var(--pd-danger); }
.pd-diag-detail { color: var(--pd-text-secondary); }
.pd-diag-action {
  margin-left: auto;
  font-size: var(--pd-text-xs);
  background: none;
  border: 1px solid var(--pd-border-strong);
  border-radius: var(--pd-radius-sm);
  color: var(--pd-text-secondary);
  padding: 3px var(--pd-space-2);
  cursor: pointer;
}
.pd-diag-action:hover { border-color: var(--pd-action); color: var(--pd-action); }

/* ---- funnel --------------------------------------------------------------
   A stepped bar list, not a tapered silhouette. The old shape forced a minimum
   visible width on small stages and forced each stage to look no wider than the
   one above it, so a stage that grew was drawn as shrinking. Here every bar is
   proportional to the true group max with no floor, and the value sits OUTSIDE
   the fill, so its contrast is fixed rather than depending on the fill. */
.pd-funnel { display: flex; flex-direction: column; gap: var(--pd-space-1); }
.pd-funnel-row {
  display: grid;
  grid-template-columns: minmax(120px, 1.1fr) minmax(0, 3fr) auto auto;
  align-items: center;
  gap: var(--pd-space-3);
  padding: var(--pd-space-2) 0;
}
.pd-funnel-row + .pd-funnel-row { border-top: 1px solid var(--pd-border); }
.pd-funnel-label { font-size: var(--pd-text-sm); color: var(--pd-text); }
.pd-funnel-track {
  height: 10px;
  background: var(--pd-surface-2);
  border-radius: var(--pd-radius-sm);
  overflow: hidden;
  min-width: 0;
}
.pd-funnel-fill {
  display: block;
  height: 100%;
  border-radius: var(--pd-radius-sm);
  background: var(--pd-series);
}
.pd-funnel-row[data-tone="muted"] .pd-funnel-fill { background: var(--pd-grey-400); }
.pd-funnel-value {
  font-family: var(--pd-font-num);
  font-size: var(--pd-text-sm);
  font-weight: var(--pd-weight-semi);
  font-variant-numeric: tabular-nums;
  text-align: right;
  min-width: 4.5ch;
  color: var(--pd-text);
}
.pd-funnel-rate {
  font-family: var(--pd-font-num);
  font-size: var(--pd-text-xs);
  color: var(--pd-muted);
  font-variant-numeric: tabular-nums;
  text-align: right;
  min-width: 7ch;
}
.pd-funnel-rate[data-tone="danger"] { color: var(--pd-danger); }

@media (max-width: 560px) {
  .pd-funnel-row {
    grid-template-columns: 1fr auto;
    grid-template-areas: "label value" "track rate";
    gap: var(--pd-space-1) var(--pd-space-3);
  }
  .pd-funnel-label { grid-area: label; }
  .pd-funnel-value { grid-area: value; }
  .pd-funnel-track { grid-area: track; }
  .pd-funnel-rate { grid-area: rate; }
}

/* ---- channel card --------------------------------------------------------
   A real <button>. It was a <div> with a click handler, so the drill-down was
   unreachable by keyboard. The key colour is passed in as --pd-ch by the page
   (--pd-ch: var(--pd-cat-2)) and never written as a hex, so re-theming a
   category cannot desync the dot from the chart. */
.pd-channel {
  --pd-ch: var(--pd-cat-1);
  display: flex;
  flex-direction: column;
  gap: var(--pd-space-3);
  width: 100%;
  text-align: left;
  background: var(--pd-surface);
  border: 1px solid var(--pd-border);
  border-radius: var(--pd-radius-lg);
  padding: var(--pd-space-4);
  cursor: pointer;
  font: inherit;
  color: inherit;
}
.pd-channel:hover { border-color: var(--pd-border-strong); }
.pd-channel[aria-pressed="true"] {
  border-color: var(--pd-ch);
  box-shadow: inset 0 0 0 1px var(--pd-ch);
}
.pd-channel-head {
  display: flex;
  align-items: center;
  gap: var(--pd-space-2);
}
.pd-channel-dot {
  width: 10px;
  height: 10px;
  border-radius: var(--pd-radius-sm);
  background: var(--pd-ch);
  flex: none;
}
.pd-channel-name {
  font-size: var(--pd-text-sm);
  font-weight: var(--pd-weight-semi);
}
.pd-channel-badge { margin-left: auto; }
/* Bars inside a channel card scale to THAT card's max, not a global max —
   otherwise every card but the biggest is a row of empty tracks. */
.pd-channel-bars { display: flex; flex-direction: column; gap: var(--pd-space-1); }

/* ---- drill-down ---------------------------------------------------------- */
.pd-drill {
  margin-top: var(--pd-space-3);
  padding: var(--pd-space-4);
  background: var(--pd-surface-2);
  border: 1px solid var(--pd-border);
  border-radius: var(--pd-radius-md);
}
.pd-drill[hidden] { display: none; }

/* ---- event feed ---------------------------------------------------------- */
.pd-feed { display: flex; flex-direction: column; }
.pd-feed-row {
  display: flex;
  align-items: baseline;
  gap: var(--pd-space-3);
  padding: var(--pd-space-2) 0;
  border-top: 1px solid var(--pd-border);
  font-size: var(--pd-text-sm);
}
.pd-feed-row:first-child { border-top: 0; }
.pd-feed-when {
  font-family: var(--pd-font-num);
  color: var(--pd-muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  flex: none;
  min-width: 11ch;
}
.pd-feed-what { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.pd-feed-meta { color: var(--pd-muted); font-size: var(--pd-text-xs); white-space: nowrap; flex: none; }

@media (max-width: 560px) {
  .pd-feed-row { flex-wrap: wrap; }
  .pd-feed-when { min-width: 0; order: 2; }
  .pd-feed-what { flex-basis: 100%; order: 1; }
  .pd-feed-meta { order: 3; }
}

/* ---- sparkline ----------------------------------------------------------- */
.pd-spark {
  display: flex;
  align-items: flex-end;
  gap: 2px;
  height: 34px;
}
.pd-spark-bar {
  flex: 1 1 0;
  min-width: 2px;
  background: var(--pd-series);
  border-radius: 1px 1px 0 0;
}
.pd-spark-bar[data-zero="1"] { background: var(--pd-border); height: 1px; }

/* ---- notes + methodology ------------------------------------------------- */
.pd-note {
  font-size: var(--pd-text-xs);
  line-height: var(--pd-lh-xs);
  color: var(--pd-muted);
  margin-top: var(--pd-space-3);
}
.pd-note strong { color: var(--pd-text-secondary); font-weight: var(--pd-weight-semi); }
.pd-method > summary {
  cursor: pointer;
  font-size: var(--pd-text-xs);
  color: var(--pd-muted);
  padding: var(--pd-space-2) 0;
}
.pd-method > summary:hover { color: var(--pd-text-secondary); }
.pd-method[open] > summary { color: var(--pd-text-secondary); }

/* ---- empty + null states -------------------------------------------------
   Three meanings that used to render identically. */
.pd-empty {
  padding: var(--pd-space-6) var(--pd-space-4);
  text-align: center;
  color: var(--pd-muted);
  font-size: var(--pd-text-sm);
}
.pd-state { font-variant-numeric: tabular-nums; }
.pd-state--na { color: var(--pd-muted); }
.pd-state--unavail {
  color: var(--pd-warn);
  font-size: 0.9em;
  border-bottom: 1px dotted currentColor;
  cursor: help;
}
.pd-of { color: var(--pd-muted); font-weight: var(--pd-weight-normal); }

/* ---- horizontal scroll container ----------------------------------------
   Wide content scrolls inside its own box; the page body never scrolls
   sideways. */
.pd-scroll-x {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

/* ---- focus --------------------------------------------------------------- */
.pd-shell a:focus-visible,
.pd-shell button:focus-visible,
.pd-appbar a:focus-visible,
.pd-appbar button:focus-visible {
  outline: 2px solid var(--pd-focus);
  outline-offset: 2px;
  border-radius: var(--pd-radius-sm);
}

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}
