/* ============================================================
   Phase 10 Slice 4A — Dashboard (Operations Cockpit).
   Vanilla port of /Dashboard/styles.css (Claude Design export)
   into our existing shell. Dashboard-only class names (.kpi,
   .cockpit, .donut, .system-strip, .sys-pip, .feed-item, etc.)
   are unique to the dashboard and don't collide with shared
   rules; collisions on .card / .card-title / .page-header /
   .page-title are resolved by .page-dashboard X overrides.

   File split note: this file used to live inside saas-shell.css
   (lines 390-2568). It was extracted on 2026-05-15 so the shared
   shell CSS stays focused on cross-page chrome and the dashboard
   can be loaded as its own cacheable bundle. Load order matters
   — index.html must link saas-shell.css BEFORE this file so the
   base .modal-backdrop / .card / .page-header rules cascade
   correctly and the dashboard's overrides win.

   Real loaded data only — no fake gauges / "Healthy" wording /
   queue UI / chart modals / action menus / fake sparklines.
   ============================================================ */

/* Scoped local tokens — kept under .page-dashboard so they
   never leak to the other shell pages. */
.page-dashboard {
  --d-radius:    8px;
  --d-radius-lg: 12px;
  --d-radius-xl: 16px;
  --d-card-pad:  16px 18px;
  --d-card-shadow:
    0 1px 2px rgba(32, 56, 45, 0.04),
    0 4px 14px rgba(32, 56, 45, 0.05);
  --d-border-soft: rgba(0, 0, 0, 0.05);
  --d-accent-wash: rgba(67, 145, 109, 0.07);
  --d-serif: 'EB Garamond', Georgia, serif;
  --d-mono:  'SF Mono', 'Cascadia Code', Consolas, Menlo, monospace;
  --d-text-dim: #9aa6a0;
}

/* Dashboard owns its own column-flex layout (overrides the
   2-col .dashboard-grid used by the Usage page). max-width +
   margin auto matches the export's .page rule so wide-monitor
   content centers like the screenshots, instead of stretching. */
.page-dashboard .page {
  display: flex;
  flex-direction: column;
  gap: 14px;
  max-width: 1480px;
  margin: 0 auto;
  padding: 4px 4px 0;
  width: 100%;
}

/* Trim the outer .page-root padding when it's hosting the
   dashboard — the export expects a tight ~8-12px outer gap, not
   the 28px top / 48px bottom shared rule. Scoped via :has() so
   the other pages keep their original padding. */
.page-root:has(.page-dashboard) {
  padding: 8px clamp(8px, 2vw, 20px) 20px;
}
/* When the nav is collapsed, the show-nav floating button sits in
   the gap to the left of the page. Give the dashboard extra left
   padding in that state so the button doesn't crowd the content. */
.app.nav-hidden .page-root:has(.page-dashboard) {
  padding-left: clamp(52px, 5vw, 72px);
}

/* Mount animation — mirrors the React entrance in Dashboard.html.
   The .page-surface starts slightly translated down + opaque-less,
   then settles when .is-mounted is added by triggerMount(). */
.page-dashboard .page-surface {
  opacity: 0;
  transform: translateY(8px);
  transition: opacity 320ms ease, transform 320ms cubic-bezier(.16, .84, .44, 1);
  will-change: opacity, transform;
}
.page-dashboard .page-surface.is-mounted {
  opacity: 1;
  transform: translateY(0);
}
/* Release the GPU layer completely once the entrance is done.
   ``will-change: auto`` alone is not enough — ``transform:
   translateY(0)`` from .is-mounted is still a transform value
   and browsers keep promoted compositor layers as long as a
   transform is applied (even an identity one). With the layer
   held, ANY paint inside .page-surface (sys-pip background
   hover, sys-pip-arrow opacity/transform, KPI box-shadow on
   hover) re-rasterises the entire surface, which is what the
   user sees as flicker on the cockpit / activity / status rows
   below the KPI strip. Snapping to transform:none + transition:
   none after mount drops the layer and scopes paint to the
   actual changed regions. translateY(0) → none is visually
   identity, so this snap is invisible. */
.page-dashboard .page-surface.has-mounted-once {
  will-change: auto;
  transform: none;
  transition: none;
}

/* =============================================================
   1. Page header (compact: title + subtitle | range + actions)
   ============================================================= */
.page-dashboard .page-header {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 18px;
  padding: 6px 2px 14px;
  border-bottom: 1px solid var(--d-border-soft);
  /* Reset shared .page-header { margin-bottom: 24px } from saas-shell.css:283
     so the dashboard's section gap (14px from .page) controls spacing. */
  margin-bottom: 0;
}
.page-dashboard .page-header-l {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
}
.page-dashboard .page-title {
  margin: 0;
  font-family: var(--d-serif);
  color: var(--accent);
  font-size: 30px;
  line-height: 1.1;
  font-weight: 500;
  letter-spacing: -0.3px;
}
.page-dashboard .page-sub {
  margin: 0;
  color: var(--text-muted);
  font-size: 14px;
  line-height: 1.5;
  max-width: 720px;
}
.page-dashboard .page-header-r {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  justify-content: flex-end;
}

/* Range tabs — segmented control, white bg, hairline divider, accent-wash active */
.page-dashboard .range-seg {
  display: inline-flex;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 8px;
  overflow: hidden;
  height: 32px;
}
.page-dashboard .range-seg-btn {
  appearance: none;
  border: 0;
  border-right: 1px solid var(--d-border-soft);
  background: transparent;
  font-family: var(--d-serif);
  font-size: 13px;
  padding: 0 12px;
  height: 100%;
  display: inline-flex;
  align-items: center;
  color: var(--text-muted);
  cursor: pointer;
  transition: color 0.12s ease, background 0.12s ease;
}
.page-dashboard .range-seg-btn:last-child { border-right: 0; }
.page-dashboard .range-seg-btn:hover { color: var(--accent); }
.page-dashboard .range-seg-btn.active {
  background: var(--d-accent-wash);
  color: var(--accent);
  font-weight: 600;
}
.page-dashboard .range-seg-btn[aria-disabled="true"],
.page-dashboard .range-seg-btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
  color: var(--text-muted);
}

/* Buttons — primary + ghost. Compound selectors (.btn.btn-X) raise
   specificity to 0,2,1 so shared components.css .btn.btn-sm (0,2,0)
   no longer wins on padding / font-size. text-shadow:none kills the
   dark glow leaked from the shared .btn rule. */
.page-dashboard .btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 32px;
  padding: 0 14px;
  border-radius: 8px;
  font-family: var(--d-serif);
  font-size: 13.5px;
  font-weight: 500;
  cursor: pointer;
  border: 1px solid transparent;
  text-shadow: none;
  letter-spacing: 0;
  transition: transform 0.12s ease, box-shadow 0.12s ease, border-color 0.12s ease, color 0.12s ease;
  white-space: nowrap;
}
.page-dashboard .btn.btn-sm {
  height: 30px;
  padding: 0 12px;
  font-size: 13px;
}
.page-dashboard .btn.btn-primary {
  background: linear-gradient(140deg, #2e7a55 0%, #1f573b 100%);
  color: #fff;
  border-color: rgba(0, 0, 0, 0.18);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.18),
    0 1px 2px rgba(0, 0, 0, 0.10);
}
.page-dashboard .btn.btn-primary:hover {
  transform: translateY(-1px);
  filter: none;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.20),
    0 4px 12px rgba(31, 87, 59, 0.25);
}
.page-dashboard .btn.btn-ghost {
  background: #fff;
  color: var(--text);
  border-color: var(--border);
  box-shadow: 0 1px 2px rgba(32, 56, 45, 0.04);
}
.page-dashboard .btn.btn-ghost:hover {
  border-color: var(--accent-3);
  color: var(--accent);
  filter: none;
  background: #fff;
}

/* =============================================================
   2. System status strip — bordered card with grid of pips.
   All 4 pips share an equal column (matches the export's
   auto-fit minmax pattern). Cells are grid-laid internally
   (icon | text | arrow) with explicit overflow so the arrow
   doesn't push the value/sub on hover and the row below
   doesn't repaint when hovering.
   ============================================================= */
.page-dashboard .system-strip {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--d-radius-lg);
  box-shadow: var(--d-card-shadow);
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  overflow: hidden;
  isolation: isolate; /* new stacking context — scopes z-order */
  contain: paint;     /* hard paint boundary — sys-pip hover
                         repaints never leak to siblings below
                         (works in tandem with page-surface
                         dropping its compositor layer). */
}
.page-dashboard .sys-pip {
  display: grid;
  grid-template-columns: 28px minmax(0, 1fr) 13px;
  align-items: center;
  gap: 12px;
  padding: 12px 16px;
  text-decoration: none;
  color: var(--text);
  position: relative;
  transition: background 0.15s ease;
  min-width: 0;
  overflow: hidden;
}
.page-dashboard .sys-pip + .sys-pip { border-left: 1px solid var(--d-border-soft); }
.page-dashboard .sys-pip-icon {
  width: 28px;
  height: 28px;
  border-radius: 7px;
  background: var(--d-accent-wash);
  color: var(--accent);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.page-dashboard .sys-pip-text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1;
  min-width: 0;
}
.page-dashboard .sys-pip-label {
  font-family: var(--d-serif);
  font-size: 10px;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--text-muted);
  font-weight: 600;
}
.page-dashboard .sys-pip-value {
  font-family: var(--d-serif);
  font-size: 15px;
  font-weight: 500;
  color: var(--text);
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  letter-spacing: -0.1px;
}
/* Single-line ellipsised sub so the wide pip doesn't bloat the strip
   height. -webkit-line-clamp:2 was making the strip 60+px instead of
   the export's ~52px. */
.page-dashboard .sys-pip-sub {
  font-family: var(--d-serif);
  font-size: 12px;
  color: var(--text-muted);
  line-height: 1.45;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}
.page-dashboard .sys-pip-sub b {
  color: var(--text);
  font-weight: 600;
}

/* =============================================================
   3. KPI strip — 4-up tiles. Every tile has a real visual.
   Container queries reflow value-beside-spark on wide tiles.
   ============================================================= */
.page-dashboard .kpi-strip {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 10px;
}
.page-dashboard .kpi {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--d-radius-lg);
  padding: 12px 14px 10px;
  box-shadow: var(--d-card-shadow);
  position: relative;
  display: grid;
  grid-template-rows: auto auto auto auto;
  gap: 4px;
  min-height: 134px;
  container-type: inline-size;
  /* transform was in the transition list but nothing animates the
     transform on hover — declaring it kept the tile on a GPU
     compositing layer which got re-evaluated whenever neighbouring
     elements (like sys-pip on hover) repainted, contributing to
     the cross-section flicker. Now only box-shadow transitions. */
  transition: box-shadow 0.18s ease;
}
.page-dashboard .kpi:hover {
  box-shadow:
    0 1px 2px rgba(32, 56, 45, 0.06),
    0 8px 22px rgba(32, 56, 45, 0.08);
}
.page-dashboard .kpi-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 8px;
}
.page-dashboard .kpi-label-row {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
}
.page-dashboard .kpi-label {
  font-family: var(--d-serif);
  font-size: 10.5px;
  letter-spacing: 1.1px;
  text-transform: uppercase;
  color: var(--text-muted);
  font-weight: 600;
}
.page-dashboard .kpi-info {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 13px;
  height: 13px;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.05);
  color: var(--text-muted);
  font-family: var(--d-mono);
  font-size: 9px;
  font-weight: 700;
  cursor: help;
  position: relative;
  flex-shrink: 0;
}
.page-dashboard .kpi-info:hover { background: var(--d-accent-wash); color: var(--accent); }
.page-dashboard .kpi-info-tip {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  background: #1a2620;
  color: #f6f9f7;
  border-radius: 8px;
  padding: 9px 12px;
  font-family: var(--d-serif);
  font-size: 12px;
  line-height: 1.45;
  width: 220px;
  font-weight: 400;
  text-transform: none;
  letter-spacing: 0;
  text-align: left;
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.25);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s ease;
  z-index: 60;
}
.page-dashboard .kpi-info-tip::before {
  content: '';
  position: absolute;
  top: -5px;
  left: 6px;
  border-left: 6px solid transparent;
  border-right: 6px solid transparent;
  border-bottom: 6px solid #1a2620;
}
.page-dashboard .kpi-info:hover .kpi-info-tip,
.page-dashboard .kpi-info:focus .kpi-info-tip { opacity: 1; pointer-events: auto; }
.page-dashboard .kpi-value-row {
  display: flex;
  align-items: baseline;
  gap: 8px;
  flex-wrap: wrap;
}
.page-dashboard .kpi-value {
  font-family: var(--d-serif);
  font-size: 26px;
  font-weight: 400;
  color: var(--text);
  line-height: 1.05;
  letter-spacing: -0.3px;
  display: inline-flex;
  align-items: baseline;
  gap: 4px;
}
.page-dashboard .metric-value {
  display: inline-flex;
  align-items: baseline;
  gap: 4px;
}
/* Tabular numerals + a reserved min-width on the inner number span
   so count-up animations don't widen the row mid-flight (the cause
   of the "%" and "m:s" suffix jitter you reported). */
.page-dashboard .kpi-num {
  display: inline-block;
  font-variant-numeric: tabular-nums;
  min-width: 1.6em;
}
.page-dashboard .metric-num {
  display: inline-block;
  font-variant-numeric: tabular-nums;
  min-width: 1.6em;
}
.page-dashboard .kpi-value .unit {
  font-size: 12px;
  color: var(--text-muted);
  font-weight: 400;
  letter-spacing: 0;
}
.page-dashboard .kpi-delta {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  font-family: var(--d-mono);
  font-size: 10.5px;
  padding: 1px 6px;
  border-radius: 4px;
  font-weight: 500;
  white-space: nowrap;
}
.page-dashboard .kpi-delta.up   { background: rgba(46, 142, 93, 0.08); color: #2e8e5d; }
.page-dashboard .kpi-delta.down { background: rgba(176, 72, 72, 0.08); color: #b04848; }
.page-dashboard .kpi-spark {
  height: 38px;
  margin: 2px -4px 0;
  padding: 0 4px;
  display: flex;
  align-items: center;
  justify-content: stretch;
}
.page-dashboard .kpi-spark svg { display: block; width: 100%; height: 100%; }

/* Hover indicators for the small KPI sparklines — bindSparkHover()
   toggles [hidden] off on mousemove and positions both elements
   via style.left. The scrub-line spans the full spark slot
   vertically; the tip floats above the data point. */
.page-dashboard .kpi-spark,
.page-dashboard .metric-chart { position: relative; }
.page-dashboard .scrub-line {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 1px;
  background: rgba(0, 0, 0, 0.22);
  pointer-events: none;
  transform: translateX(-0.5px);
  z-index: 2;
}
.page-dashboard .spark-tip {
  position: absolute;
  background: #1a2620;
  color: #f6f9f7;
  padding: 4px 8px;
  border-radius: 6px;
  font-family: var(--d-mono, 'SF Mono', Consolas, monospace);
  font-size: 10.5px;
  line-height: 1.2;
  pointer-events: none;
  transform: translate(-50%, calc(-100% - 6px));
  white-space: nowrap;
  box-shadow: 0 6px 14px rgba(0, 0, 0, 0.25);
  z-index: 3;
}
.page-dashboard .spark-tip .spark-tip-label {
  display: block;
  font-family: var(--d-serif, 'EB Garamond', Georgia, serif);
  font-size: 10px;
  color: rgba(255, 255, 255, 0.65);
  margin-bottom: 2px;
  letter-spacing: 0.3px;
}
.page-dashboard .spark-tip strong {
  font-weight: 600;
  color: #fff;
  font-family: var(--d-mono, 'SF Mono', Consolas, monospace);
}
/* The moving dot the cursor drags along the sparkline curve. JS
   positions it at (pointX, pointY); transform centers it on that
   coordinate so the dot's middle sits exactly on the line. */
.page-dashboard .scrub-dot {
  position: absolute;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #fff;
  border: 1.5px solid #43916d;
  transform: translate(-50%, -50%);
  pointer-events: none;
  z-index: 3;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.15);
}
.page-dashboard [hidden] { display: none !important; }

/* Decorative category glyph in the top-right of every KPI head —
   non-interactive (a span, not a button). Matches the export's
   visual: chart/dollar/clock/spark icons that identify the metric
   family. The export's hover-revealed expand button (kpi-expand)
   is dropped because it opens a 4B modal. */
.page-dashboard .kpi-glyph {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: 5px;
  background: var(--d-accent-wash);
  color: var(--accent);
  flex-shrink: 0;
}
.page-dashboard .kpi-glyph svg { display: block; }
.page-dashboard .kpi-foot {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 8px;
  font-family: var(--d-serif);
  font-size: 11px;
  color: var(--text-muted);
  border-top: 1px solid var(--d-border-soft);
  padding-top: 6px;
  margin-top: 4px;
}
.page-dashboard .kpi-foot b {
  font-family: var(--d-mono);
  font-weight: 500;
  color: var(--text);
  font-size: 11.5px;
}

@container (min-width: 420px) {
  .page-dashboard .kpi {
    grid-template-columns: 1fr 220px;
    grid-template-rows: auto auto auto;
    column-gap: 18px;
    align-items: center;
    padding: 14px 16px 12px;
  }
  .page-dashboard .kpi-head      { grid-column: 1 / -1; grid-row: 1; }
  .page-dashboard .kpi-value-row { grid-column: 1; grid-row: 2; }
  .page-dashboard .kpi-spark     { grid-column: 2; grid-row: 2; height: 44px; }
  .page-dashboard .kpi-foot      { grid-column: 1 / -1; grid-row: 3; }
  .page-dashboard .kpi-value     { font-size: 30px; }
}

/* =============================================================
   4. Cockpit row — Activity (1.7fr) + Status (1fr), 410px tall.
   ============================================================= */
.page-dashboard .cockpit {
  display: grid;
  grid-template-columns: minmax(0, 1.7fr) minmax(0, 1fr);
  gap: 12px;
  align-items: stretch;
}
.page-dashboard .cockpit > .card {
  height: 410px;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  padding: var(--d-card-pad);
  border-radius: var(--d-radius-lg);
  box-shadow: var(--d-card-shadow);
}

/* Card head — overrides shared shell .card-title. */
.page-dashboard .card-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 12px;
  margin-bottom: 10px;
}
.page-dashboard .card-head-l {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.page-dashboard .card-title {
  margin: 0;
  font-family: var(--d-serif);
  font-size: 16px;
  font-weight: 600;
  color: var(--text);
  letter-spacing: -0.1px;
  text-transform: none;
}
.page-dashboard .card-sub {
  font-family: var(--d-serif);
  font-size: 12px;
  color: var(--text-muted);
  line-height: 1.4;
}
.page-dashboard .card-footnote {
  font-family: var(--d-serif);
  font-size: 11px;
  color: var(--d-text-dim);
  margin-top: 8px;
  text-align: right;
}
.page-dashboard .card-empty {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  padding: 24px 16px;
  text-align: center;
  font-family: var(--d-serif);
  font-size: 13px;
  color: var(--text-muted);
}
.page-dashboard .card-empty p { margin: 0; }

/* Activity card */
.page-dashboard .activity-card { gap: 10px; }
.page-dashboard .activity-meta {
  display: flex;
  gap: 18px;
  margin-top: 4px;
  flex-shrink: 0;
}
.page-dashboard .activity-meta-item {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.page-dashboard .activity-meta-item-label {
  font-family: var(--d-serif);
  font-size: 11px;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--text-muted);
  font-weight: 600;
}
.page-dashboard .activity-meta-item-value {
  font-family: var(--d-serif);
  font-size: 22px;
  font-weight: 500;
  color: var(--text);
  line-height: 1;
  letter-spacing: -0.4px;
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
}
.page-dashboard .activity-meta-item-value .unit {
  font-size: 12px;
  color: var(--text-muted);
  font-weight: 400;
  letter-spacing: 0;
}

/* Area chart */
.page-dashboard .area-chart {
  width: 100%;
  flex: 1;
  min-height: 220px;
  margin-top: 8px;
  position: relative;
  display: flex;
  align-items: stretch;
}
.page-dashboard .area-chart svg {
  display: block;
  width: 100%;
  height: 100%;
  overflow: visible;
}
.page-dashboard .area-chart .grid-line { stroke: rgba(0, 0, 0, 0.05); stroke-width: 1; }
.page-dashboard .area-chart .axis-label {
  font-family: var(--d-serif);
  font-size: 10.5px;
  fill: var(--d-text-dim);
  letter-spacing: 0.4px;
}
.page-dashboard .area-chart .area-hit { cursor: crosshair; }

/* Vertical scrub-line that bindAreaHover injects into every
   .area-chart on mouseenter — gives the activity chart a clear
   visual indicator of which day the cursor is reviewing (not just
   a floating tooltip). */
.page-dashboard .area-scrub {
  position: absolute;
  top: 12px;
  bottom: 28px;
  width: 1px;
  background: rgba(0, 0, 0, 0.22);
  pointer-events: none;
  transform: translateX(-0.5px);
  z-index: 2;
}

/* Floating chart tip (used by both area chart + sparkline hover). */
.page-dashboard .chart-tip {
  position: absolute;
  pointer-events: none;
  background: #1a2620;
  color: #f6f9f7;
  border-radius: 8px;
  padding: 8px 10px;
  font-family: var(--d-serif);
  font-size: 12px;
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.25);
  white-space: nowrap;
  transform: translate(-50%, -110%);
  z-index: 5;
  min-width: 140px;
}
.page-dashboard .chart-tip .tt-title {
  font-family: var(--d-mono);
  font-size: 10.5px;
  color: rgba(255, 255, 255, 0.7);
  letter-spacing: 0.4px;
  text-transform: uppercase;
  margin-bottom: 4px;
}
.page-dashboard .chart-tip .tt-row {
  display: flex;
  gap: 10px;
  align-items: center;
  justify-content: space-between;
}
.page-dashboard .chart-tip .tt-row .dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  display: inline-block;
  margin-right: 6px;
}
.page-dashboard .chart-tip .tt-row b {
  font-family: var(--d-mono);
  font-weight: 600;
  color: #fff;
}
.page-dashboard .chart-tip[hidden] { display: none; }

/* Legend */
.page-dashboard .legend {
  display: flex;
  gap: 14px;
  align-items: center;
  font-family: var(--d-serif);
  font-size: 12px;
  color: var(--text-muted);
  margin-top: 10px;
  flex-shrink: 0;
}
.page-dashboard .legend-item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.page-dashboard .legend-swatch {
  width: 10px;
  height: 10px;
  border-radius: 2px;
  display: inline-block;
}
.page-dashboard .legend-swatch.success { background: #2e8e5d; }
.page-dashboard .legend-swatch.failed  { background: #b04848; }
.page-dashboard .legend-meta {
  margin-left: auto;
  color: var(--d-text-dim);
  font-size: 11.5px;
}

/* Status card */
.page-dashboard .status-card { gap: 0; }
/* Stacked layout — donut centered on top, status list below.
   Replaces the prior side-by-side layout (export's later iteration
   moved to a vertical stack so the list reads as a proper legend
   under the chart). */
.page-dashboard .donut-wrap {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 16px;
  margin-top: 8px;
  flex: 1;
  min-height: 0;
  padding: 4px 0;
}
.page-dashboard .donut {
  position: relative;
  width: 170px;
  height: 170px;
  flex-shrink: 0;
  align-self: center;
}
.page-dashboard .donut svg {
  width: 100%;
  height: 100%;
  display: block;
  /* The .active arc thickens to stroke-width 30 which extends
     past the viewBox. overflow: visible lets the thickened stroke
     draw past the SVG edge instead of clipping. */
  overflow: visible;
}
.page-dashboard .donut svg circle[data-seg] {
  transition: opacity 0.18s ease, stroke-width 0.22s cubic-bezier(.16, .84, .44, 1);
}
.page-dashboard .donut svg circle[data-seg].dim {
  opacity: 0.32;
}
/* Hover state — the hovered arc grows outward so it visually
   "underlines" the matching status row in the legend. Paired with
   .dim on the other arcs, the active slice reads clearly. */
.page-dashboard .donut svg circle[data-seg].active {
  stroke-width: 30;
  filter: drop-shadow(0 2px 5px rgba(0, 0, 0, 0.22)) brightness(1.04);
}
/* Cursor changes on the arcs make it discoverable that they're
   hoverable in addition to the legend rows. */
.page-dashboard .donut svg circle[data-seg] { cursor: pointer; }
.page-dashboard .status-row.is-active {
  background: var(--d-accent-wash);
}

/* Donut hover tip — injected lazily by bindDonutHover and pinned
   inside .donut (which is position:relative). Shows label + count
   + percentage on arc hover. Used in both the cockpit and the
   modal status panels.

   Positioned BELOW the cursor (translate-Y +12px) rather than
   above. The cockpit donut is the top child of .donut-wrap inside
   a .card with overflow:hidden — anchoring the tip above the
   cursor risked clipping when the user hovered the upper arcs.
   Below-cursor positioning sits inside the legend area (which is
   logically related anyway). */
.page-dashboard .donut .donut-tip,
.modal-backdrop .donut .donut-tip {
  position: absolute;
  background: #1a2620;
  color: #f6f9f7;
  padding: 6px 10px;
  border-radius: 8px;
  font-family: var(--d-mono, 'SF Mono', Consolas, monospace);
  font-size: 11.5px;
  line-height: 1.3;
  pointer-events: none;
  transform: translate(-50%, 12px);
  white-space: nowrap;
  box-shadow: 0 8px 18px rgba(0, 0, 0, 0.30);
  z-index: 5;
}
.page-dashboard .donut .donut-tip strong,
.modal-backdrop .donut .donut-tip strong {
  color: #fff;
  font-weight: 600;
}
.page-dashboard .donut .donut-tip-label,
.modal-backdrop .donut .donut-tip-label {
  display: block;
  font-family: var(--d-serif, 'EB Garamond', Georgia, serif);
  font-size: 10.5px;
  letter-spacing: 0.3px;
  margin-bottom: 3px;
  font-weight: 500;
  text-transform: uppercase;
}
.page-dashboard .donut .donut-tip-pct,
.modal-backdrop .donut .donut-tip-pct {
  color: rgba(255, 255, 255, 0.65);
  margin-left: 4px;
}
/* .donut needs to be position:relative for the tip to anchor. The
   cockpit version already is (rule above); .modal-backdrop's donut
   is created with inline style="width:...;height:..." which doesn't
   include position, so re-apply here. */
.modal-backdrop .donut { position: relative; }
.page-dashboard .donut-center {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  pointer-events: none;
  text-align: center;
}
.page-dashboard .donut-center-value {
  font-family: var(--d-serif);
  font-size: 32px;
  font-weight: 500;
  color: var(--text);
  line-height: 1;
  letter-spacing: -0.6px;
}
.page-dashboard .donut-center-label {
  font-family: var(--d-serif);
  font-size: 10px;
  letter-spacing: 1.1px;
  text-transform: uppercase;
  color: var(--text-muted);
  margin-top: 6px;
  white-space: nowrap;
}
.page-dashboard .donut-center-sub {
  font-family: var(--d-serif);
  font-size: 11.5px;
  color: var(--d-text-dim);
  margin-top: 2px;
}
.page-dashboard .status-list {
  flex: 1;
  min-width: 0;
  min-height: 0;
  overflow-y: auto;
  scrollbar-gutter: stable;
  padding-right: 4px;
  margin-right: -4px;
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.page-dashboard .status-list::-webkit-scrollbar { width: 6px; }
.page-dashboard .status-list::-webkit-scrollbar-thumb { background: rgba(0, 0, 0, 0.10); border-radius: 6px; }
.page-dashboard .status-list::-webkit-scrollbar-thumb:hover { background: rgba(0, 0, 0, 0.18); }
.page-dashboard .status-row {
  display: grid;
  grid-template-columns: 10px minmax(0, 1fr) 44px 46px;
  gap: 10px;
  align-items: center;
  padding: 6px 8px;
  border-radius: 6px;
  cursor: default;
  transition: background 0.12s ease;
}
.page-dashboard .status-row:hover { background: var(--d-accent-wash); }
.page-dashboard .status-row .dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  flex-shrink: 0;
}
.page-dashboard .status-row .label {
  font-family: var(--d-serif);
  font-size: 13.5px;
  color: var(--text);
  text-transform: capitalize;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.page-dashboard .status-row .count {
  font-family: var(--d-mono);
  font-size: 12.5px;
  color: var(--text);
  font-weight: 500;
  text-align: right;
}
.page-dashboard .status-row .pct {
  font-family: var(--d-mono);
  font-size: 11px;
  color: var(--d-text-dim);
  text-align: right;
}

/* =============================================================
   5. Secondary row — 3 equal metric cards
   ============================================================= */
.page-dashboard .sec-row {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 12px;
}
.page-dashboard .metric-card {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--d-radius-lg);
  box-shadow: var(--d-card-shadow);
  padding: 14px 16px;
  display: flex;
  flex-direction: column;
  gap: 0;
  /* Equal heights across the secondary row so Tokens / Duration /
     Cost line up regardless of which visual is present. Matches the
     export's compact ~168px secondary card height. */
  min-height: 168px;
}
.page-dashboard .metric-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 6px;
}
.page-dashboard .metric-label {
  font-family: var(--d-serif);
  font-size: 11px;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--text-muted);
  font-weight: 600;
}
.page-dashboard .metric-value {
  font-family: var(--d-serif);
  font-size: 26px;
  font-weight: 400;
  color: var(--text);
  line-height: 1;
  letter-spacing: -0.3px;
}
.page-dashboard .metric-value .unit {
  font-size: 13px;
  color: var(--text-muted);
  margin-left: 4px;
  letter-spacing: 0;
}
.page-dashboard .metric-sub {
  font-family: var(--d-serif);
  font-size: 12px;
  color: var(--text-muted);
  margin-top: 4px;
}
.page-dashboard .metric-sub b {
  font-family: var(--d-mono);
  color: var(--text);
  font-weight: 500;
}
.page-dashboard .metric-chart {
  width: 100%;
  margin-top: 14px;
  margin-bottom: 6px;
  min-height: 52px;
  display: flex;
  align-items: center;
}
.page-dashboard .metric-chart svg { width: 100%; height: auto; display: block; }
.page-dashboard .split-row {
  display: flex;
  gap: 12px;
  align-items: center;
  justify-content: space-between;
  font-family: var(--d-serif);
  font-size: 11.5px;
  color: var(--text-muted);
  margin-top: 8px;
}
.page-dashboard .split-row b {
  font-family: var(--d-mono);
  font-weight: 500;
  color: var(--text);
}
.page-dashboard .split-row .dim { color: var(--d-text-dim); }

/* =============================================================
   6. Work row — Continue Working + Activity feed (520px tall).
   ============================================================= */
.page-dashboard .work-row {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
  gap: 12px;
  align-items: stretch;
}
.page-dashboard .work-row > .card {
  height: 520px;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  padding: var(--d-card-pad);
  border-radius: var(--d-radius-lg);
  box-shadow: var(--d-card-shadow);
}

.page-dashboard .wf-table {
  display: flex;
  flex-direction: column;
  flex: 1;
  overflow-y: auto;
  scrollbar-gutter: stable;
  margin-right: -4px;
  padding-right: 4px;
}
.page-dashboard .wf-table::-webkit-scrollbar { width: 6px; }
.page-dashboard .wf-table::-webkit-scrollbar-thumb { background: rgba(0, 0, 0, 0.10); border-radius: 6px; }
.page-dashboard .wf-row {
  display: grid;
  grid-template-columns: 28px minmax(0, 1fr) 90px 100px 18px;
  gap: 10px;
  align-items: center;
  padding: 10px 8px;
  border-radius: 8px;
  border-top: 1px solid var(--d-border-soft);
  cursor: pointer;
  position: relative;
  text-decoration: none;
  color: inherit;
  transition: background 0.12s ease;
}
.page-dashboard .wf-row:first-child { border-top: 0; }
.page-dashboard .wf-row:hover { background: var(--d-accent-wash); }
.page-dashboard .wf-row:hover .wf-arrow { opacity: 1; transform: translateX(0); }
/* Inset focus ring — the global ``main.css :focus-visible`` rule
   draws a 2 px outline OUTSIDE the element box. With ``.work-row >
   .card { overflow: hidden }`` plus ``.wf-table { overflow-y: auto }``,
   that outline gets clipped at the card edges and at the scroller's
   horizontal bounds when a row is focused. An inset ``box-shadow``
   renders inside the row's own bounds — never clipped by the parent
   chain, no layout shift, hover background still wins on hover. */
.page-dashboard .wf-row:focus-visible {
  outline: none;
  box-shadow: inset 0 0 0 2px var(--accent-2, #43916d);
}
.page-dashboard .wf-icon {
  width: 28px;
  height: 28px;
  background: var(--d-accent-wash);
  color: var(--accent);
  border-radius: 7px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.page-dashboard .wf-name {
  font-family: var(--d-serif);
  font-size: 14.5px;
  color: var(--text);
  font-weight: 500;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.page-dashboard .wf-meta {
  font-family: var(--d-serif);
  font-size: 11.5px;
  color: var(--d-text-dim);
}
.page-dashboard .wf-status {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-family: var(--d-serif);
  font-size: 11.5px;
  color: var(--text-muted);
}
.page-dashboard .wf-status .dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #9aa6a0;
}
.page-dashboard .wf-status.active {
  color: #2e8e5d;
  font-weight: 600;
}
.page-dashboard .wf-status.active .dot {
  background: #2e8e5d;
  box-shadow: 0 0 0 0 rgba(46, 142, 93, 0.45);
  animation: dash-pulse-g 1.6s infinite;
}
@keyframes dash-pulse-g {
  0%   { box-shadow: 0 0 0 0 rgba(46, 142, 93, 0.45); }
  100% { box-shadow: 0 0 0 7px rgba(46, 142, 93, 0); }
}
.page-dashboard .wf-success {
  display: flex;
  flex-direction: column;
  gap: 3px;
  font-family: var(--d-mono);
  font-size: 11px;
  color: var(--text-muted);
}
.page-dashboard .wf-success .dim { color: var(--d-text-dim); }
.page-dashboard .wf-success-bar {
  height: 4px;
  border-radius: 3px;
  overflow: hidden;
  background: rgba(0, 0, 0, 0.06);
}
.page-dashboard .wf-success-bar > span {
  display: block;
  height: 100%;
  background: #2e8e5d;
}
.page-dashboard .wf-arrow {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--accent);
  opacity: 0;
  transform: translateX(-4px);
  transition: opacity 0.15s ease, transform 0.15s ease;
}

/* Section link — "Open all workflows →" footer in Continue
   Working. The export ships this as a navigation link, not a
   modal trigger, so it renders in 4A. */
.page-dashboard .section-link {
  margin-top: 12px;
  font-family: var(--d-serif);
  font-size: 13px;
  color: var(--accent);
  align-self: flex-start;
  padding-top: 8px;
  border-top: 1px solid var(--d-border-soft);
  width: 100%;
  flex-shrink: 0;
  text-decoration: none;
  transition: color 0.12s ease;
}
.page-dashboard .section-link:hover { color: var(--accent-2); }

/* Activity feed (right column of work row) */
.page-dashboard .feed-card .feed {
  display: flex;
  flex-direction: column;
  gap: 14px;
  margin-top: 4px;
  flex: 1;
  overflow-y: auto;
  scrollbar-gutter: stable;
  padding-right: 4px;
  margin-right: -4px;
}
.page-dashboard .feed-card .feed::-webkit-scrollbar { width: 6px; }
.page-dashboard .feed-card .feed::-webkit-scrollbar-thumb { background: rgba(0, 0, 0, 0.10); border-radius: 6px; }
.page-dashboard .feed-group-label {
  font-family: var(--d-serif);
  font-size: 10.5px;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  color: var(--text-muted);
  font-weight: 700;
  margin-bottom: 6px;
  padding: 0 4px;
}
.page-dashboard .feed-list { display: flex; flex-direction: column; }
.page-dashboard .feed-item {
  display: grid;
  grid-template-columns: 16px minmax(0, 1fr) 70px;
  gap: 10px;
  padding: 7px 4px;
  align-items: center;
  position: relative;
  border-radius: 6px;
  text-decoration: none;
  color: inherit;
  cursor: pointer;
  transition: background 0.12s ease;
}
.page-dashboard .feed-item:hover { background: rgba(0, 0, 0, 0.025); }
/* Inset focus ring — same reasoning as .wf-row above: the activity
   feed scroller (``.feed-card .feed`` has ``overflow-y: auto``) plus
   the card wrapper's ``overflow: hidden`` would clip an outside-the-
   box outline. ``box-shadow: inset`` keeps the ring inside the row. */
.page-dashboard .feed-item:focus-visible {
  outline: none;
  box-shadow: inset 0 0 0 2px var(--accent-2, #43916d);
}
.page-dashboard .feed-rail {
  position: relative;
  width: 16px;
  align-self: stretch;
  display: flex;
  align-items: center;
  justify-content: center;
}
.page-dashboard .feed-rail::before {
  content: '';
  position: absolute;
  left: 50%;
  top: 0;
  bottom: 0;
  width: 1.5px;
  background: rgba(0, 0, 0, 0.08);
  transform: translateX(-50%);
}
.page-dashboard .feed-item:first-child .feed-rail::before { top: 50%; }
.page-dashboard .feed-item:last-child .feed-rail::before { bottom: 50%; }
.page-dashboard .feed-rail .dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: #9aa6a0;
  border: 2px solid #fff;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.08);
  z-index: 1;
}
.page-dashboard .feed-item[data-st="completed"] .dot { background: #2e8e5d; }
.page-dashboard .feed-item[data-st="approved"]  .dot { background: #4a9d6a; }
.page-dashboard .feed-item[data-st="running"]   .dot { background: #e0a437; animation: dash-pulse-y 1.7s infinite; }
.page-dashboard .feed-item[data-st="failed"]    .dot { background: #b04848; }
.page-dashboard .feed-item[data-st="needs"]     .dot { background: #cc9237; }
@keyframes dash-pulse-y {
  0%   { box-shadow: 0 0 0 0 rgba(224, 164, 55, 0.55), 0 0 0 1px rgba(0, 0, 0, 0.08); }
  100% { box-shadow: 0 0 0 7px rgba(224, 164, 55, 0), 0 0 0 1px rgba(0, 0, 0, 0.08); }
}
.page-dashboard .feed-body {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.page-dashboard .feed-line {
  font-family: var(--d-serif);
  font-size: 13.5px;
  color: var(--text);
  display: flex;
  gap: 6px;
  align-items: baseline;
  min-width: 0;
}
.page-dashboard .feed-line .target {
  color: var(--accent);
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}
.page-dashboard .feed-line .verb { color: var(--text-muted); }
.page-dashboard .feed-detail {
  font-family: var(--d-serif);
  font-size: 11.5px;
  color: var(--d-text-dim);
  min-height: 16px;
}
.page-dashboard .feed-time {
  font-family: var(--d-mono);
  font-size: 11px;
  color: var(--d-text-dim);
  text-align: right;
}

/* =============================================================
   Responsive breakpoints
   ============================================================= */
@media (max-width: 1280px) {
  .page-dashboard .kpi-strip      { grid-template-columns: repeat(4 minmax(0, 1fr)); }
}
@media (max-width: 1140px) {
  .page-dashboard .system-strip   { grid-template-columns: minmax(0, 1fr) repeat(3, minmax(0, 1fr)); }
  .page-dashboard .cockpit        { grid-template-columns: 1fr; }
  .page-dashboard .cockpit > .card { height: auto; min-height: 360px; }
  .page-dashboard .sec-row        { grid-template-columns: 1fr; }
  .page-dashboard .work-row       { grid-template-columns: 1fr; }
  .page-dashboard .work-row > .card { height: auto; min-height: 420px; }
}
@media (max-width: 900px) {
  .page-dashboard .page-header    { grid-template-columns: 1fr; }
  .page-dashboard .page-header-r  { justify-content: flex-start; flex-wrap: wrap; }
  .page-dashboard .system-strip   { grid-template-columns: 1fr 1fr; }
  .page-dashboard .sys-pip:nth-child(odd)   { border-left: 0; }
  .page-dashboard .sys-pip:nth-child(n+2)   { border-top: 1px solid var(--d-border-soft); }
  .page-dashboard .wf-row         { grid-template-columns: 28px minmax(0, 1fr) auto 18px; }
  .page-dashboard .wf-success     { display: none; }
}
@media (max-width: 640px) {
  .page-dashboard .kpi-strip      { grid-template-columns: 1fr; }
  .page-dashboard .activity-meta  { flex-wrap: wrap; gap: 12px; }
  .page-dashboard .system-strip   { grid-template-columns: 1fr; }
  .page-dashboard .sys-pip + .sys-pip { border-left: 0; border-top: 1px solid var(--d-border-soft); }
  .page-dashboard .donut-wrap     { flex-direction: column; align-items: center; gap: 14px; }
  .page-dashboard .donut          { margin: 0 auto; }
}

/* =============================================================
   ADDITIONAL EXPORT COMPONENTS — appended below the original
   dashboard block. These pieces were missing from the previous
   pass (action menu, sys-pip-tag/gauge/arrow, tab-row,
   card-expand, kpi-expand, inline-table, split-bar, modals,
   page-meta). Ported 1:1 from /Dashboard/styles.css + sections.jsx.
   ============================================================= */

/* ----- Page meta (inline below title) ------------------------- */
.page-dashboard .page-meta {
  display: flex;
  align-items: center;
  gap: 10px;
  font-family: var(--d-serif);
  font-size: 12.5px;
  color: var(--text-muted);
  flex-wrap: wrap;
  line-height: 1.5;
}
.page-dashboard .page-meta b {
  font-weight: 500;
  color: var(--text);
}
.page-dashboard .page-meta .dot-sep {
  color: var(--d-text-dim);
}

/* Hide the prior "page-sub" wide subtitle — the new layout uses
   inline .page-meta directly (matches the export's PageHeader). */
.page-dashboard .page-sub { display: none; }

/* ----- Action menu (⋯ submenu) -------------------------------- */
.page-dashboard .action-menu {
  position: relative;
  display: inline-flex;
}
.page-dashboard .action-menu-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 6px;
  border: 1px solid var(--border);
  background: #fff;
  color: var(--text-muted);
  cursor: pointer;
  transition: all 0.15s ease;
  padding: 0;
}
.page-dashboard .action-menu-btn:hover,
.page-dashboard .action-menu.open .action-menu-btn {
  background: var(--d-accent-wash);
  color: var(--accent);
  border-color: var(--accent-3);
}
.page-dashboard .action-menu-pop {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  min-width: 220px;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: 0 12px 28px rgba(32, 56, 45, 0.10), 0 1px 3px rgba(32, 56, 45, 0.06);
  padding: 6px;
  z-index: 40;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.page-dashboard .action-menu-pop[hidden] { display: none; }
.page-dashboard .action-menu-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  border-radius: 6px;
  border: 0;
  background: transparent;
  text-align: left;
  font-family: var(--d-serif);
  font-size: 13px;
  color: var(--text);
  cursor: pointer;
  transition: background 0.12s ease;
}
.page-dashboard .action-menu-item:hover { background: var(--d-accent-wash); color: var(--accent); }
.page-dashboard .action-menu-item .ico { display: inline-flex; flex-shrink: 0; }
.page-dashboard .action-menu-item .action-menu-kbd {
  margin-left: auto;
  font-family: var(--d-mono);
  font-size: 10.5px;
  color: var(--d-text-dim);
  border: 1px solid var(--d-border-soft);
  border-radius: 4px;
  padding: 1px 5px;
  background: rgba(0, 0, 0, 0.02);
}
.page-dashboard .action-menu-divider {
  height: 1px;
  background: var(--d-border-soft);
  margin: 4px 0;
}

/* ----- System pip — tag, gauge, arrow extras ------------------ */
.page-dashboard .sys-pip-tag {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-family: var(--d-mono);
  font-size: 10px;
  padding: 2px 6px;
  border-radius: 4px;
  letter-spacing: 0.2px;
  font-weight: 500;
}
.page-dashboard .sys-pip-tag .dot {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: currentColor;
}
.page-dashboard .sys-pip-tag.tone-ok   { background: rgba(46, 142, 93, 0.10); color: #2e8e5d; }
.page-dashboard .sys-pip-tag.tone-warn { background: rgba(224, 164, 55, 0.12); color: #e0a437; }
.page-dashboard .sys-pip-tag.tone-err  { background: rgba(176, 72, 72, 0.10); color: #b04848; }
.page-dashboard .sys-pip-gauge {
  display: block;
  height: 3px;
  background: rgba(0, 0, 0, 0.06);
  border-radius: 3px;
  overflow: hidden;
  margin: 3px 0 1px;
  width: 100%;
}
.page-dashboard .sys-pip-gauge > span {
  display: block;
  height: 100%;
  background: linear-gradient(90deg, #43916d, #62af8b);
  border-radius: 3px;
}
.page-dashboard .sys-pip-arrow {
  font-family: var(--d-mono);
  font-size: 13px;
  color: var(--accent);
  flex-shrink: 0;
  opacity: 0;
  transform: translateX(-4px);
  transition: opacity 0.15s ease, transform 0.15s ease;
  align-self: center;
}
.page-dashboard .sys-pip:hover { background: var(--d-accent-wash); }
.page-dashboard .sys-pip:hover .sys-pip-arrow { opacity: 1; transform: translateX(0); }

/* ----- Card head: tab-row + card-expand ----------------------- */
.page-dashboard .tab-row {
  display: inline-flex;
  gap: 2px;
  background: rgba(0, 0, 0, 0.035);
  border-radius: 8px;
  padding: 2px;
}
.page-dashboard .tab-row button {
  border: 0;
  background: transparent;
  font-family: var(--d-serif);
  font-size: 12px;
  padding: 4px 10px;
  height: 24px;
  border-radius: 6px;
  color: var(--text-muted);
  cursor: pointer;
  transition: background 0.12s ease, color 0.12s ease, box-shadow 0.12s ease;
}
.page-dashboard .tab-row button:hover { color: var(--accent); }
.page-dashboard .tab-row button.active {
  background: #fff;
  color: var(--text);
  font-weight: 600;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.06);
}
.page-dashboard .card-expand {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  border-radius: 5px;
  border: 1px solid var(--d-border-soft);
  background: #fff;
  color: var(--text-muted);
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.15s ease, background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
  padding: 0;
}
.page-dashboard .card:hover .card-expand,
.page-dashboard .metric-card:hover .card-expand,
.page-dashboard .card-expand:focus-visible {
  opacity: 1;
}
.page-dashboard .card-expand:hover {
  background: var(--d-accent-wash);
  color: var(--accent);
  border-color: var(--accent-3);
}
/* kpi-expand sits in the absolute top-right corner of the tile,
   not pushed in by .kpi-head padding. Matches the export's "↗"
   affordance positioning. */
.page-dashboard .kpi-expand {
  position: absolute;
  top: 10px;
  right: 10px;
  z-index: 2;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: 5px;
  border: 1px solid var(--d-border-soft);
  background: #fff;
  color: var(--text-muted);
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.15s ease, background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
  padding: 0;
}
.page-dashboard .kpi:hover .kpi-expand,
.page-dashboard .kpi-expand:focus-visible { opacity: 1; }
.page-dashboard .kpi-expand:hover {
  background: var(--d-accent-wash);
  color: var(--accent);
  border-color: var(--accent-3);
}
/* The decorative .kpi-glyph slot from the previous patch is
   superseded by the working .kpi-expand button. Hide leftover
   markup if any old emitter still ships .kpi-glyph. */
.page-dashboard .kpi-glyph { display: none; }

/* ----- Inline table (Chart/Table card view + modal table) ----- */
.page-dashboard .inline-table {
  margin-top: 8px;
  display: flex;
  flex-direction: column;
  min-height: 0;
  flex: 1;
}
.page-dashboard .inline-table-head {
  display: grid;
  grid-template-columns: 1fr 60px 80px 70px 70px;
  gap: 12px;
  padding: 10px 12px;
  font-family: var(--d-serif);
  font-size: 10.5px;
  letter-spacing: 1.1px;
  text-transform: uppercase;
  color: var(--text-muted);
  font-weight: 600;
  border-bottom: 1px solid var(--d-border-soft);
  background: var(--bg-soft, #f7f9f8);
  border-radius: 6px 6px 0 0;
}
.page-dashboard .status-card .inline-table-head {
  grid-template-columns: minmax(0, 1fr) 50px 64px 80px;
  gap: 10px;
}
.page-dashboard .inline-table-body {
  flex: 1;
  overflow-y: auto;
  scrollbar-gutter: stable;
}
.page-dashboard .inline-table-row {
  display: grid;
  grid-template-columns: 1fr 60px 80px 70px 70px;
  gap: 12px;
  padding: 9px 12px;
  align-items: center;
  font-family: var(--d-serif);
  font-size: 13px;
  color: var(--text);
  border-bottom: 1px solid var(--d-border-soft);
}
.page-dashboard .status-card .inline-table-row {
  grid-template-columns: minmax(0, 1fr) 50px 64px 80px;
  gap: 10px;
}
.page-dashboard .inline-table-row:last-child { border-bottom: 0; }
.page-dashboard .inline-table-row:hover { background: var(--d-accent-wash); }
.page-dashboard .inline-table-row .mono {
  font-family: var(--d-mono);
  font-size: 12px;
  text-align: right;
}
.page-dashboard .inline-table-row .swatch-row {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.page-dashboard .mini-bar {
  height: 4px;
  border-radius: 3px;
  background: rgba(0, 0, 0, 0.06);
  overflow: hidden;
}
.page-dashboard .mini-bar > span {
  display: block;
  height: 100%;
}

/* ----- Split bar (Tokens input/output) ------------------------ */
.page-dashboard .split-bar {
  height: 6px;
  border-radius: 4px;
  overflow: hidden;
  background: rgba(0, 0, 0, 0.05);
  display: flex;
}
.page-dashboard .split-bar-in  { background: #2e8e5d; }
.page-dashboard .split-bar-out { background: #62af8b; }

/* ----- Modal (backdrop + dialog) ------------------------------
   These rules augment the base .modal-backdrop defined in main.css
   (the generic confirm-modal scrim). They target the dashboard's
   richer modal-shell + summary + chart-frame markup. The selectors
   intentionally do NOT scope under .page-dashboard because the
   dashboard wraps the modal in <div class="page-dashboard"> at the
   body level — the deeper .modal-X children are dashboard-only by
   class name, so child-class scoping is sufficient. */
.modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(20, 30, 26, 0.42);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 100;
  animation: dash-modal-fade-in 180ms ease-out;
}
@keyframes dash-modal-fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}
.modal-backdrop .modal-shell{
  background: #fff;
  border-radius: 14px;
  box-shadow: 0 30px 60px rgba(0, 0, 0, 0.25), 0 4px 12px rgba(0, 0, 0, 0.10);
  width: min(1080px, calc(100vw - 32px));
  max-height: calc(100vh - 64px);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  font-family: var(--d-serif, 'EB Garamond', Georgia, serif);
  animation: dash-modal-pop 220ms cubic-bezier(.16, .84, .44, 1);
}
@keyframes dash-modal-pop {
  from { opacity: 0; transform: translateY(8px) scale(0.98); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
.modal-backdrop .modal-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 16px;
  /* Tighter vertical padding so head + summary leave enough room
     for the chart inside the modal-shell's 92vh max-height — was
     pushing the chart below the visible viewport before. */
  padding: 12px 20px 10px;
  border-bottom: 1px solid rgba(0, 0, 0, 0.05);
}
.modal-backdrop .modal-head-l {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}
.modal-backdrop .modal-title {
  margin: 0;
  font-family: var(--d-serif, 'EB Garamond', Georgia, serif);
  font-size: 22px;
  font-weight: 500;
  color: var(--text);
  letter-spacing: -0.2px;
}
.modal-backdrop .modal-sub {
  font-size: 13px;
  color: var(--text-muted);
}
.modal-backdrop .modal-head-r {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  flex-shrink: 0;
}
.modal-backdrop .modal-head-r .range-seg {
  display: inline-flex;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 8px;
  overflow: hidden;
  height: 30px;
}
.modal-backdrop .modal-head-r .range-seg button {
  border: 0;
  border-right: 1px solid rgba(0, 0, 0, 0.05);
  background: transparent;
  font-family: var(--d-serif, 'EB Garamond', Georgia, serif);
  font-size: 12.5px;
  padding: 0 12px;
  color: var(--text-muted);
  cursor: pointer;
}
.modal-backdrop .modal-head-r .range-seg button:last-child { border-right: 0; }
.modal-backdrop .modal-head-r .range-seg button:hover { color: var(--accent); }
.modal-backdrop .modal-head-r .range-seg button.active {
  background: rgba(67, 145, 109, 0.07);
  color: var(--accent);
  font-weight: 600;
}
.modal-backdrop .modal-close {
  width: 32px;
  height: 32px;
  border-radius: 6px;
  border: 1px solid var(--border);
  background: #fff;
  color: var(--text-muted);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: all 0.15s ease;
}
.modal-backdrop .modal-close:hover {
  background: rgba(67, 145, 109, 0.07);
  color: var(--accent);
  border-color: var(--accent-3);
}
.modal-backdrop .modal-body {
  padding: 18px 20px 20px;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.modal-backdrop .modal-activity .modal-body { max-height: 70vh; }
.modal-backdrop .modal-shell.feed {
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.modal-backdrop .modal-shell.feed-group-label {
  font-family: var(--d-serif, 'EB Garamond', Georgia, serif);
  font-size: 10.5px;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  color: var(--text-muted);
  font-weight: 700;
  margin-bottom: 6px;
  padding: 0 4px;
}
.modal-backdrop .modal-shell.feed-list { display: flex; flex-direction: column; }
.modal-backdrop .modal-shell.feed-item {
  display: grid;
  grid-template-columns: 16px minmax(0, 1fr) 70px;
  gap: 10px;
  padding: 8px 4px;
  align-items: center;
  position: relative;
  border-radius: 6px;
  text-decoration: none;
  color: inherit;
}
.modal-backdrop .modal-shell.feed-item:hover { background: rgba(0, 0, 0, 0.025); }
.modal-backdrop .modal-shell.feed-rail {
  position: relative;
  width: 16px;
  align-self: stretch;
  display: flex;
  align-items: center;
  justify-content: center;
}
.modal-backdrop .modal-shell.feed-rail::before {
  content: '';
  position: absolute;
  left: 50%;
  top: 0;
  bottom: 0;
  width: 1.5px;
  background: rgba(0, 0, 0, 0.08);
  transform: translateX(-50%);
}
.modal-backdrop .modal-shell.feed-item:first-child .feed-rail::before { top: 50%; }
.modal-backdrop .modal-shell.feed-item:last-child .feed-rail::before { bottom: 50%; }
.modal-backdrop .modal-shell.feed-rail .dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: #9aa6a0;
  border: 2px solid #fff;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.08);
  z-index: 1;
}
.modal-backdrop .modal-shell.feed-item[data-st="completed"] .dot { background: #2e8e5d; }
.modal-backdrop .modal-shell.feed-item[data-st="approved"]  .dot { background: #4a9d6a; }
.modal-backdrop .modal-shell.feed-item[data-st="running"]   .dot { background: #e0a437; }
.modal-backdrop .modal-shell.feed-item[data-st="failed"]    .dot { background: #b04848; }
.modal-backdrop .modal-shell.feed-item[data-st="needs"]     .dot { background: #cc9237; }
.modal-backdrop .modal-shell.feed-body {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.modal-backdrop .modal-shell.feed-line {
  font-family: var(--d-serif, 'EB Garamond', Georgia, serif);
  font-size: 13.5px;
  color: var(--text);
  display: flex;
  gap: 6px;
  align-items: baseline;
}
.modal-backdrop .modal-shell.feed-line .target { color: var(--accent, #316e51); font-weight: 500; }
.modal-backdrop .modal-shell.feed-line .verb { color: var(--text-muted); }
.modal-backdrop .modal-shell.feed-detail {
  font-family: var(--d-serif, 'EB Garamond', Georgia, serif);
  font-size: 11.5px;
  color: rgba(154, 166, 160, 1);
}
.modal-backdrop .modal-shell.feed-time {
  font-family: var(--d-mono, 'SF Mono', Consolas, monospace);
  font-size: 11px;
  color: rgba(154, 166, 160, 1);
  text-align: right;
}

/* ----- Modal sub-components (eyebrow, summary, chart-frame,
   breakdown, foot) — wire-up for the new modal markup. ------- */
.modal-backdrop .modal-eyebrow {
  font-family: var(--d-serif, 'EB Garamond', Georgia, serif);
  font-size: 11px;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--text-muted);
  font-weight: 600;
}
.modal-backdrop .modal-title { font-size: 20px; font-weight: 600; }
.modal-backdrop .modal-summary {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 10px;
}
.modal-backdrop .modal-summary-item {
  background: var(--bg-soft, #f6f9f7);
  border: 1px solid rgba(0, 0, 0, 0.05);
  border-radius: 8px;
  /* Tighter summary cards so they don't eat the vertical budget
     that the chart needs to stay in view. */
  padding: 8px 12px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.modal-backdrop .modal-summary-label {
  font-family: var(--d-serif, 'EB Garamond', Georgia, serif);
  font-size: 10.5px;
  letter-spacing: 1.1px;
  text-transform: uppercase;
  color: var(--text-muted);
  font-weight: 600;
}
.modal-backdrop .modal-summary-value {
  font-family: var(--d-serif, 'EB Garamond', Georgia, serif);
  font-size: 20px;
  font-weight: 500;
  color: var(--text);
  letter-spacing: -0.3px;
}
.modal-backdrop .modal-summary-sub {
  font-size: 11px;
  color: var(--d-text-dim, #9aa6a0);
}
.modal-backdrop .modal-chart-frame {
  background: linear-gradient(180deg, #fcfdfc 0%, #f6f9f7 100%);
  border: 1px solid rgba(0, 0, 0, 0.05);
  border-radius: 10px;
  padding: 16px 18px 12px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.modal-backdrop .modal-chart-toolbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  margin-bottom: 4px;
}
.modal-backdrop .modal-chart-toolbar-l {
  display: flex;
  gap: 14px;
  align-items: baseline;
  font-family: var(--d-serif, 'EB Garamond', Georgia, serif);
  font-size: 12.5px;
  color: var(--text-muted);
}
.modal-backdrop .modal-chart-toolbar-l strong {
  font-family: var(--d-mono, 'SF Mono', Consolas, monospace);
  font-weight: 600;
  color: var(--text);
  font-size: 13px;
}
.modal-backdrop .modal-chart-area {
  min-height: 200px;
  position: relative;
}
.modal-backdrop .modal-chart-area .area-chart { height: 100% !important; min-height: 200px; }
.modal-backdrop .modal-breakdown {
  background: #fff;
  border: 1px solid rgba(0, 0, 0, 0.05);
  border-radius: 10px;
  overflow: hidden;
}
.modal-backdrop .modal-breakdown-head {
  display: grid;
  grid-template-columns: 1fr 80px 100px 100px 90px;
  gap: 10px;
  padding: 10px 16px;
  font-family: var(--d-serif, 'EB Garamond', Georgia, serif);
  font-size: 10.5px;
  letter-spacing: 1.1px;
  text-transform: uppercase;
  color: var(--text-muted);
  font-weight: 600;
  background: var(--bg-soft, #f6f9f7);
  border-bottom: 1px solid rgba(0, 0, 0, 0.05);
}
.modal-backdrop .modal-breakdown-row {
  display: grid;
  grid-template-columns: 1fr 80px 100px 100px 90px;
  gap: 10px;
  padding: 10px 16px;
  align-items: center;
  font-family: var(--d-serif, 'EB Garamond', Georgia, serif);
  font-size: 13px;
  color: var(--text);
  border-bottom: 1px solid rgba(0, 0, 0, 0.05);
}
.modal-backdrop .modal-breakdown-row:last-child { border-bottom: 0; }
.modal-backdrop .modal-breakdown-row:hover { background: var(--d-accent-wash); }
/* Status breakdown table — 4 columns (dropped the fake 14d). */
.modal-backdrop .modal-breakdown-status .modal-breakdown-head,
.modal-backdrop .modal-breakdown-status .modal-breakdown-row {
  grid-template-columns: minmax(0, 1fr) 80px 100px minmax(0, 1fr);
}
/* Metric breakdown table — Cost / Duration / Tokens get a 3-col
   grid: Day | Runs | <metric value + mini-bar>. Keeps the metric
   value mono-aligned and lets the bar fill the rest of the row. */
.modal-backdrop .modal-breakdown-metric .modal-breakdown-head,
.modal-backdrop .modal-breakdown-metric .modal-breakdown-row {
  grid-template-columns: minmax(0, 1fr) 80px minmax(160px, 1.2fr);
}
.modal-backdrop .modal-breakdown-metric .modal-breakdown-row .metric-mini {
  width: 72px;
  display: inline-block;
  vertical-align: middle;
  margin-left: 10px;
}
.modal-backdrop .modal-breakdown-row .mono {
  font-family: var(--d-mono, 'SF Mono', Consolas, monospace);
  font-size: 12px;
}
.modal-backdrop .modal-breakdown-row .right { text-align: right; }
.modal-backdrop .modal-breakdown-row .mini-bar {
  height: 4px;
  border-radius: 3px;
  background: rgba(0, 0, 0, 0.06);
  overflow: hidden;
}
.modal-backdrop .modal-breakdown-row .mini-bar > span {
  display: block;
  height: 100%;
  background: #2e8e5d;
}
.modal-backdrop .modal-breakdown-row .swatch {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.modal-backdrop .modal-breakdown-row .swatch::before {
  content: '';
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--swatch-color, #2e8e5d);
}
.modal-backdrop .modal-foot {
  padding: 12px 20px;
  border-top: 1px solid rgba(0, 0, 0, 0.05);
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 12px;
  color: var(--d-text-dim, #9aa6a0);
  font-family: var(--d-serif, 'EB Garamond', Georgia, serif);
  background: var(--bg-soft, #f6f9f7);
}

/* ----- Staggered entrance — fade + lift each top-level section
   into place, then each KPI tile individually. Triggered when JS
   adds .is-mounted to .page-surface (see triggerMount). Matches
   the export's "page entrance animation" pattern. -------------- */
.page-dashboard .page > .page-header,
.page-dashboard .page > .system-strip,
.page-dashboard .page > .kpi-strip,
.page-dashboard .page > .cockpit,
.page-dashboard .page > .sec-row,
.page-dashboard .page > .work-row {
  opacity: 0;
  transform: translateY(6px);
  transition: opacity 0.5s cubic-bezier(.16, .84, .44, 1), transform 0.5s cubic-bezier(.16, .84, .44, 1);
}
.page-dashboard .page > .page-header { transition-delay: 0.02s; }
.page-dashboard .page > .system-strip { transition-delay: 0.06s; }
.page-dashboard .page > .kpi-strip { transition-delay: 0.12s; }
.page-dashboard .page > .cockpit { transition-delay: 0.20s; }
.page-dashboard .page > .sec-row { transition-delay: 0.28s; }
.page-dashboard .page > .work-row { transition-delay: 0.36s; }
.page-dashboard .kpi-strip .kpi {
  opacity: 0;
  transform: translateY(6px);
  transition: opacity 0.45s cubic-bezier(.16, .84, .44, 1), transform 0.45s cubic-bezier(.16, .84, .44, 1);
}
.page-dashboard .kpi-strip .kpi:nth-child(1) { transition-delay: 0.12s; }
.page-dashboard .kpi-strip .kpi:nth-child(2) { transition-delay: 0.18s; }
.page-dashboard .kpi-strip .kpi:nth-child(3) { transition-delay: 0.24s; }
.page-dashboard .kpi-strip .kpi:nth-child(4) { transition-delay: 0.30s; }
.page-dashboard .page-surface.is-mounted .page > *,
.page-dashboard .page-surface.is-mounted .kpi-strip .kpi {
  opacity: 1;
  transform: none;
}
/* After the first entrance lands, kill the transition so any
   subsequent renderDashboard() (range switch, tab toggle) doesn't
   re-trigger the fade-up on freshly-inserted sections — that was
   the cascade of repaint flicker on rows below the sys-pip. */
.page-dashboard .page-surface.has-mounted-once .page > *,
.page-dashboard .page-surface.has-mounted-once .kpi-strip .kpi {
  opacity: 1 !important;
  transform: none !important;
  transition: none !important;
}
/* Dashboard-scoped visually-hidden utility (Slice 4D-2). Used to
   carry accessible text adjacent to decorative dashboard widgets
   (mini-bars) where the percentage is otherwise conveyed only
   visually. Dashboard-scoped class name on purpose so it cannot
   accidentally style any non-dashboard surface elsewhere in the
   app. No display:none / visibility:hidden — those remove the
   element from the accessibility tree too. */
.page-dashboard .dash-sr-only {
  position: absolute !important;
  width: 1px !important;
  height: 1px !important;
  padding: 0 !important;
  margin: -1px !important;
  overflow: hidden !important;
  clip: rect(0, 0, 0, 0) !important;
  white-space: nowrap !important;
  border: 0 !important;
}

@media (prefers-reduced-motion: reduce) {
  .page-dashboard .page > *,
  .page-dashboard .kpi-strip .kpi {
    transition: none !important;
    opacity: 1 !important;
    transform: none !important;
  }
  .modal-backdrop, .modal-backdrop .modal-shell { animation: none !important; }
}

/* Responsive — drop modal grid to single column on narrow screens */
@media (max-width: 700px) {
  .modal-backdrop .modal-shell { width: calc(100vw - 16px); max-height: calc(100vh - 16px); }
  .modal-backdrop .modal-summary { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .modal-backdrop .modal-breakdown-head,
  .modal-backdrop .modal-breakdown-row { grid-template-columns: 1fr 60px 70px 60px; }
  .modal-backdrop .modal-breakdown-head span:nth-child(4),
  .modal-backdrop .modal-breakdown-row .right:nth-child(4) { display: none; }
}
