/**
 * Vantage — instrument panel.
 *
 * This file previously held 588 lines that NEVER APPLIED: it was not linked
 * from index.html, and it referenced a token vocabulary that does not exist
 * in this design system (--space-6, --radius-xl, --bg-secondary, --text-base,
 * --success-600, --surface-1). Unresolved var() is silently the property's
 * initial value, so even had it loaded most of it would have done nothing.
 * The drill-down modal it also duplicated is owned by additions.css, which
 * uses the real tokens. All of it is gone.
 *
 * Only real tokens are used here: --sp-N, --r-N, --bg-*, --text-N, --border*,
 * --success/--warning/--danger, --accent, --font-ui/--font-mono.
 *
 * TWO COLOUR CHANNELS, NEVER CROSSED
 *   status      green / amber / red  — how healthy is this signal
 *   interaction gold (--accent)      — what can you touch
 * The old view tinted clickable values with the accent AND status colours,
 * so "gold" meant both "hover me" and nothing in particular. Keeping the
 * channels separate is what lets the panel be read at a glance.
 *
 * Colour is never the only signal: every row carries a status dot with a
 * distinct shape treatment, a screen-reader status word, and — for tracked
 * metrics — a marker whose POSITION relative to the threshold tick is the
 * actual reading.
 */

/* ══════════════ Shell ══════════════ */

.vt-wrap {
  container-type: inline-size;
  container-name: vantage;
}

/* ══════════════ Status ribbon ══════════════
   The verdict. On a healthy target this is one calm line; exceptions
   promote themselves here so the operator never scans for them. */

.vt-ribbon {
  border: 1px solid var(--border);
  border-left: 3px solid var(--text-4);
  border-radius: var(--r-md);
  background: var(--bg-card);
  padding: var(--sp-4) var(--sp-5);
  margin-bottom: var(--sp-4);
}
.vt-ribbon[data-status="ok"]   { border-left-color: var(--success); }
.vt-ribbon[data-status="warn"] { border-left-color: var(--warning); }
.vt-ribbon[data-status="bad"]  { border-left-color: var(--danger); }

.vt-ribbon-head {
  display: flex;
  align-items: baseline;
  gap: var(--sp-3);
  flex-wrap: wrap;
}

.vt-ribbon-dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--text-4);
  flex: 0 0 auto;
  align-self: center;
}
.vt-ribbon[data-status="ok"]   .vt-ribbon-dot { background: var(--success); }
.vt-ribbon[data-status="warn"] .vt-ribbon-dot { background: var(--warning); }
.vt-ribbon[data-status="bad"]  .vt-ribbon-dot { background: var(--danger); }

/* A live target should feel live. One slow breath on the healthy dot only —
   an amber or red dot must not pulse, because motion competes with the
   exception rows that actually need reading. */
@media (prefers-reduced-motion: no-preference) {
  .vt-ribbon[data-status="ok"] .vt-ribbon-dot { animation: vt-breathe 3.2s ease-in-out infinite; }
}
@keyframes vt-breathe {
  0%, 100% { opacity: 1;   box-shadow: 0 0 0 0 rgba(52, 211, 153, 0.35); }
  50%      { opacity: 0.7; box-shadow: 0 0 0 4px rgba(52, 211, 153, 0); }
}

.vt-ribbon-state {
  font-size: 15px;
  font-weight: 600;
  color: var(--text-1);
  letter-spacing: -0.01em;
}

.vt-ribbon-count {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 11.5px;
  color: var(--text-3);
  margin-left: auto;
}

.vt-exceptions {
  margin-top: var(--sp-4);
  display: flex;
  flex-direction: column;
  gap: 1px;
  background: var(--border);            /* hairline separators via gap */
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  overflow: hidden;
  /* Fixed columns, not fractions. With `minmax(_, 1.4fr)` these rows spread
     across the full content width — on a 2200px monitor the category sat at
     the far left and its target text at the far right with ~900px of nothing
     between, so reading one exception meant tracking across the whole screen.
     A cap keeps the four fields in one glance regardless of viewport. */
  max-width: 780px;
}

.vt-exc {
  display: grid;
  grid-template-columns: 104px minmax(0, 1fr) 84px 116px;
  gap: var(--sp-3);
  align-items: baseline;
  padding: var(--sp-2) var(--sp-3);
  background: var(--bg-surface);
  font-size: 12.5px;
  /* It jumps to its panel, so it is a real button — reset the chrome. */
  border: 0;
  width: 100%;
  text-align: left;
  font-family: inherit;
  cursor: pointer;
  transition: background 0.12s;
}
.vt-exc:hover { background: var(--bg-elevated); }
.vt-exc:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.vt-exc-cat {
  color: var(--text-3);
  text-transform: uppercase;
  letter-spacing: 0.07em;
  font-size: 10px;
  font-weight: 600;
}
.vt-exc-label { color: var(--text-2); }
.vt-exc-val {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  text-align: right;
}
.vt-exc[data-status="warn"] .vt-exc-val { color: var(--warning); }
.vt-exc[data-status="bad"]  .vt-exc-val { color: var(--danger); }
.vt-exc-limit {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--text-3);
  text-align: right;
  white-space: nowrap;
}
.vt-exc-more {
  padding: var(--sp-2) var(--sp-3);
  background: var(--bg-surface);
  font-size: 11.5px;
  color: var(--text-3);
}

.vt-gaps {
  margin-top: var(--sp-3);
  font-size: 11.5px;
  color: var(--text-3);
  padding-left: calc(8px + var(--sp-3));
}

/* Narrow: the four-column exception row cannot hold its shape, so it stacks
   into label-over-figure instead of pushing the target text off screen. */
@container vantage (max-width: 560px) {
  .vt-exc {
    grid-template-columns: 1fr auto;
    row-gap: 2px;
  }
  .vt-exc-cat   { grid-column: 1 / -1; }
  .vt-exc-label { grid-column: 1; }
  .vt-exc-val   { grid-column: 2; }
  .vt-exc-limit { grid-column: 1 / -1; text-align: left; }
  .vt-ribbon-count { margin-left: 0; width: 100%; }
}

/* ══════════════ Toolbar ══════════════ */

.vt-toolbar {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  flex-wrap: wrap;
  margin: 0 0 var(--sp-3);
  min-height: 28px;
}
.vt-edit-hint { font-size: 11px; color: var(--text-3); }
.vt-hidden-list { display: inline-flex; gap: var(--sp-2); flex-wrap: wrap; align-items: center; }
.vt-chip {
  font-size: 11px;
  padding: 2px var(--sp-2);
  border: 1px dashed var(--border-mid);
  border-radius: var(--r-sm);
  background: transparent;
  color: var(--text-3);
  cursor: pointer;
  font-family: inherit;
}
.vt-chip:hover { color: var(--accent); border-color: var(--border-accent); }

/* ══════════════ Panel grid ══════════════
   Cards on a row share a height (the grid default, `stretch`) so their top
   and bottom edges line up. Rows still differ in length, and a short panel
   carries its leftover against its own bottom border where it reads as
   padding. The two failure modes to avoid — both tried on the dashboard and
   both reported — are pooling all the slack into ONE void under the headline
   (`margin-top: auto`) and spreading it between every row
   (`justify-content: space-between`). Neither appears here. */

.vt-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(268px, 1fr));
  gap: var(--sp-3);
}

@container vantage (max-width: 620px) {
  .vt-grid { grid-template-columns: 1fr; }
  /* A "wide" panel has nothing to span into on a single column. */
  .vt-grid .vt-panel { grid-column: span 1 !important; }
}

.vt-panel {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-top: 2px solid var(--text-4);
  border-radius: var(--r-md);
  padding: var(--sp-4);
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.vt-panel[data-status="ok"]   { border-top-color: var(--success); }
.vt-panel[data-status="warn"] { border-top-color: var(--warning); }
.vt-panel[data-status="bad"]  { border-top-color: var(--danger); }
.vt-panel[data-status="none"] { border-top-color: var(--border-mid); }

.vt-panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-2);
  margin: 0 0 var(--sp-3);
}

.vt-panel-title {
  font-size: 10.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--text-3);
  margin: 0;
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  min-width: 0;
}

.vt-rows { display: flex; flex-direction: column; gap: var(--sp-3); }

/* ══════════════ Edit mode ══════════════ */

.vt-grip { cursor: grab; color: var(--text-4); letter-spacing: 0; }
.vt-grid.is-editing .vt-panel { cursor: grab; border-style: dashed; }
.vt-grid.is-editing .vt-panel:hover { border-color: var(--border-accent); }

.vt-panel-tools { display: inline-flex; gap: 2px; flex: 0 0 auto; }
.vt-tool {
  width: 22px; height: 22px;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--border-mid);
  border-radius: var(--r-sm);
  background: transparent;
  color: var(--text-3);
  font-size: 11px;
  line-height: 1;
  cursor: pointer;
  font-family: inherit;
}
.vt-tool:hover { color: var(--accent); border-color: var(--border-accent); }
.vt-tool:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

.vt-dragging { opacity: 0.4; }
.vt-drop { outline: 2px dashed var(--accent); outline-offset: 2px; }

/* ══════════════ Row ══════════════ */

.vt-row {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: baseline;
  gap: var(--sp-2) var(--sp-3);
}

.vt-label {
  font-size: 12px;
  color: var(--text-2);
  line-height: 1.35;
  min-width: 0;
}

.vt-note {
  display: block;
  font-size: 10.5px;
  color: var(--text-4);
  font-style: italic;
}

.vt-figure {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  justify-self: end;
}

/* Tabular numerals are not cosmetic here: the values tween between polls,
   and proportional digits make a counting number jitter horizontally. */
.vt-value {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--text-1);
  letter-spacing: -0.01em;
  white-space: nowrap;
}

.vt-dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--text-4);
  flex: 0 0 auto;
}
.vt-row[data-status="ok"]   .vt-dot { background: var(--success); }
.vt-row[data-status="warn"] .vt-dot { background: var(--warning); }
.vt-row[data-status="bad"]  .vt-dot { background: var(--danger); }
/* Unmeasured is a hollow ring, not a filled dot — visibly a different kind
   of thing from "measured and fine", which is the distinction the old view
   lost by rendering both as a plain grey value. */
.vt-row[data-status="none"] .vt-dot {
  background: transparent;
  box-shadow: inset 0 0 0 1px var(--text-4);
}

.vt-row[data-status="warn"] .vt-value { color: var(--warning); }
.vt-row[data-status="bad"]  .vt-value { color: var(--danger); }
.vt-row[data-status="none"] .vt-value { color: var(--text-3); }

.vt-sr {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ══════════════ The threshold track ══════════════
   The signature device. A hairline, a faintly shaded acceptable band, a tick
   at this metric's own limit, and a marker at the current value. Direction is
   carried by which side of the tick the band sits on, so no legend is needed
   and "higher is better" versus "lower is better" cannot be confused — which
   is exactly what the three old gauges got wrong. */

.vt-track {
  grid-column: 1 / -1;
  position: relative;
  height: 3px;
  border-radius: 2px;
  background: var(--bg-input);
  margin-top: 1px;
}

.vt-track-band {
  position: absolute;
  top: 0; bottom: 0;
  background: rgba(52, 211, 153, 0.16);
  border-radius: 2px;
}
.vt-track[data-dir="lower"]  .vt-track-band { left: 0; width: var(--tick); }
.vt-track[data-dir="higher"] .vt-track-band { left: var(--tick); right: 0; }

.vt-track-tick {
  position: absolute;
  top: -2px; bottom: -2px;
  width: 1px;
  background: var(--text-3);
  opacity: 0.75;
}

.vt-track-mark {
  position: absolute;
  top: 50%;
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--text-2);
  transform: translate(-50%, -50%);
  border: 1.5px solid var(--bg-card);
}
.vt-row[data-status="ok"]   .vt-track-mark { background: var(--success); }
.vt-row[data-status="warn"] .vt-track-mark { background: var(--warning); }
.vt-row[data-status="bad"]  .vt-track-mark { background: var(--danger); }

/* ══════════════ Interaction ══════════════
   Gold means touchable, and nothing else. The old view needed a banner to
   explain that values were clickable; a persistent dotted underline says it
   without prose. */

.vt-clickable { cursor: pointer; }
.vt-clickable .vt-value {
  text-decoration: underline;
  text-decoration-style: dotted;
  text-underline-offset: 3px;
  text-decoration-color: var(--text-4);
  transition: color 0.15s, text-decoration-color 0.15s;
}
.vt-clickable:hover .vt-value,
.vt-clickable:focus-visible .vt-value {
  color: var(--accent);
  text-decoration-color: var(--accent);
}
.vt-clickable:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: var(--r-sm);
}

/* Severity change is the one event worth interrupting for. Once, on the
   panel edge — not a loop, which would become wallpaper. */
.vt-pulse { animation: vt-pulse 900ms ease-out 1; }
@keyframes vt-pulse {
  0%   { box-shadow: 0 0 0 0 var(--accent-glow); }
  100% { box-shadow: 0 0 0 10px rgba(211, 158, 87, 0); }
}
@media (prefers-reduced-motion: reduce) {
  .vt-pulse { animation: none; }
}

/* A category the collector could not read. Deliberately plain: it must not
   look like a measured "zero", which is the failure mode this whole view is
   built to avoid. */
.vt-unavailable {
  font-size: 11.5px;
  color: var(--text-3);
  font-style: italic;
  padding: var(--sp-2) 0;
}

/* ══════════════ Diagnostics ══════════════
   Measured defect: at 390px every one of the 19 diagnostic buttons sat past
   the right edge (scrollWidth 512 vs clientWidth 228) with overflow-x visible
   and no ancestor that scrolled — all 19 were unreachable on a phone. A wrapping
   flex row fixes it without a horizontal scroller, which would have hidden
   them behind a gesture instead. */

/* Grouped, not a flat strip of 19 ghost buttons. The old list was one row per
   tool — a raw slug in a min-width:260px inline-styled span, then the button —
   which forced every row to 641px. At 390px all 19 sat past the right edge
   with no scroller: the panel was inert on a phone.
   Grouping also answers the question the flat list could not: which of these
   nineteen do I want? "Cache & I/O" and "Replication" are findable;
   nineteen equal-weight buttons are a wall. */

.vt-diag-groups {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  gap: var(--sp-3);
}

.vt-diag-group {
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  padding: var(--sp-3);
  background: var(--bg-surface);
  min-width: 0;
}

.vt-diag-group-title {
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--text-3);
  margin: 0 0 var(--sp-2);
}

.vt-diag-btns { display: flex; flex-direction: column; gap: 2px; }

/* min-width: 0 plus wrapping text is the load-bearing pair. flex-wrap alone
   did not fix the overflow: a flex item will not shrink below its min-content
   width, and these labels are nowrap by default. */
.vt-diag-btn {
  display: block;
  width: 100%;
  min-width: 0;
  text-align: left;
  white-space: normal;
  background: transparent;
  border: 0;
  border-radius: var(--r-sm);
  padding: 5px var(--sp-2);
  font: inherit;
  font-size: 12px;
  color: var(--text-2);
  cursor: pointer;
  transition: background 0.12s, color 0.12s;
}
.vt-diag-btn:hover { background: var(--bg-card); color: var(--accent); }
.vt-diag-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.vt-diag-btn[data-running="1"] { color: var(--accent); }
.vt-diag-btn .vt-diag-req {
  display: block;
  font-size: 10px;
  color: var(--text-4);
}

/* ══════════════ Light theme ══════════════
   The tokens already flip, so only the two hand-mixed alphas need a pass. */

[data-theme="light"] .vt-track { background: rgba(0, 0, 0, 0.08); }
[data-theme="light"] .vt-track-band { background: rgba(16, 145, 105, 0.18); }
[data-theme="light"] .vt-track-mark { border-color: var(--bg-card); }

/* ══════════════════════════════════════════════════════════════════════
   Drill-down
   ----------------------------------------------------------------------
   The overlay an operator opens from a panel row. Emitted by
   modules/vantage-drilldown.js; every class here is `dd-` prefixed so it
   cannot collide with the panel grid above or with additions.css.
   ══════════════════════════════════════════════════════════════════════ */

body.dd-open { overflow: hidden; }

.dd-modal {
  position: fixed;
  inset: 0;
  z-index: 2400;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  padding: 0;
  background: var(--bg-overlay);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  animation: dd-fade 0.16s ease-out;
}
@media (min-width: 720px) {
  .dd-modal { align-items: center; padding: var(--sp-6); }
}
.dd-modal[data-reduced] { animation: none; }
@keyframes dd-fade { from { opacity: 0; } to { opacity: 1; } }

.dd-panel {
  display: flex;
  flex-direction: column;
  width: min(1180px, 100%);
  max-height: 100dvh;
  background: var(--bg-card);
  border: 1px solid var(--border-mid);
  border-radius: var(--r-lg) var(--r-lg) 0 0;
  box-shadow: 0 24px 64px rgba(0, 0, 0, 0.5);
  overflow: hidden;
  animation: dd-rise 0.2s cubic-bezier(0.16, 1, 0.3, 1);
}
@media (min-width: 720px) {
  .dd-panel { max-height: min(860px, 92vh); border-radius: var(--r-lg); }
}
.dd-modal[data-reduced] .dd-panel { animation: none; }
@keyframes dd-rise {
  from { opacity: 0; transform: translateY(14px) scale(0.99); }
  to   { opacity: 1; transform: none; }
}

/* ── Header ────────────────────────────────────────────────────────── */
/* `flex-shrink: 0` on both fixed bands is load-bearing, not defensive.
   The panel is a flex column whose body takes the remaining space; without
   it, a narrow viewport compresses the header and the reconciliation strip
   below their content height and the explanatory note renders underneath
   the filter box. Seen at 390px, not reasoned about. */
.dd-head {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-4);
  padding: var(--sp-5) var(--sp-6);
  border-bottom: 1px solid var(--border);
  flex-wrap: wrap;
  flex-shrink: 0;
}
.dd-head-main { min-width: 0; flex: 1 1 240px; }
.dd-title {
  margin: 0;
  font-size: 17px;
  font-weight: 650;
  letter-spacing: -0.01em;
  color: var(--text-1);
}
.dd-sub {
  margin: 3px 0 0;
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  font-size: 11.5px;
  color: var(--text-3);
  flex-wrap: wrap;
}
.dd-conn { font-weight: 600; color: var(--text-2); }
.dd-scope {
  padding: 1px 7px;
  border: 1px solid var(--border);
  border-radius: 999px;
  font-size: 10.5px;
  letter-spacing: 0.02em;
}
.dd-head-actions { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; }

.dd-btn {
  padding: 6px 12px;
  background: transparent;
  border: 1px solid var(--border-mid);
  border-radius: var(--r-md);
  color: var(--text-2);
  font-family: inherit;
  font-size: 12px;
  font-weight: 550;
  cursor: pointer;
  transition: background 0.12s, color 0.12s, border-color 0.12s;
}
.dd-btn:hover:not(:disabled) {
  background: var(--bg-elevated);
  color: var(--text-1);
  border-color: var(--border-strong);
}
.dd-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.dd-btn:disabled { opacity: 0.4; cursor: not-allowed; }
.dd-btn-accent { color: var(--accent); border-color: var(--border-accent); }
.dd-btn-accent:hover:not(:disabled) { background: var(--accent-dim); color: var(--accent-light); }
.dd-btn-close { color: var(--text-3); }

/* ── Reconciliation strip ──────────────────────────────────────────────
   The card figure and this list figure were read at different moments.
   Both are stated, with both times, so a difference reads as timing
   rather than as a defect. */
.dd-recon {
  display: flex;
  align-items: baseline;
  gap: var(--sp-2);
  flex-wrap: wrap;
  padding: var(--sp-3) var(--sp-6);
  border-bottom: 1px solid var(--border);
  background: var(--bg-elevated);
  font-size: 12px;
  color: var(--text-2);
  min-height: 40px;
  flex-shrink: 0;
}
.dd-recon[data-state="loading"] { color: var(--text-4); }
.dd-recon[data-state="differs"] {
  border-left: 2px solid var(--warning);
  background: color-mix(in srgb, var(--warning) 6%, var(--bg-elevated));
}
.dd-recon-item b {
  font-family: var(--font-mono);
  font-size: 14px;
  font-weight: 650;
  color: var(--text-1);
}
.dd-t { color: var(--text-4); font-size: 11px; }
.dd-recon-sep { color: var(--text-4); }
.dd-recon-why {
  flex-basis: 100%;
  color: var(--warning);
  font-size: 11.5px;
}
.dd-recon-note {
  flex-basis: 100%;
  color: var(--text-3);
  font-size: 11.5px;
  line-height: 1.5;
}

/* ── Body ──────────────────────────────────────────────────────────── */
.dd-body { flex: 1; min-height: 0; overflow-y: auto; }

.dd-loading {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-3);
  padding: var(--sp-12) var(--sp-6);
  color: var(--text-3);
  font-size: 13px;
}
.dd-spin {
  width: 15px; height: 15px;
  border: 2px solid var(--border-mid);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: dd-spin 0.75s linear infinite;
}
@keyframes dd-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .dd-spin { animation-duration: 2.5s; } }

.dd-error {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  margin: var(--sp-6);
  padding: var(--sp-5);
  background: var(--danger-bg);
  border: 1px solid var(--danger-border);
  border-radius: var(--r-md);
  font-size: 13px;
  color: var(--text-2);
}
.dd-error strong { color: var(--danger); }

.dd-note {
  margin: var(--sp-4) var(--sp-6);
  padding: var(--sp-4);
  border-radius: var(--r-md);
  font-size: 12px;
  line-height: 1.55;
  color: var(--text-2);
  border: 1px solid var(--border);
  background: var(--bg-elevated);
}
.dd-note-warn {
  border-color: var(--warning-border);
  background: var(--warning-bg);
}
.dd-note strong { color: var(--text-1); }

.dd-facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: var(--sp-3);
  margin: 0;
  padding: var(--sp-5) var(--sp-6) var(--sp-2);
}
.dd-fact { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.dd-fact dt {
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-3);
}
.dd-fact dd {
  margin: 0;
  font-size: 16px;
  font-weight: 620;
  color: var(--text-1);
  overflow-wrap: anywhere;
}
.dd-fact dd.dd-mono { font-family: var(--font-mono); font-size: 13px; }

/* ── Table ─────────────────────────────────────────────────────────── */
.dd-table-wrap { padding: var(--sp-4) 0 var(--sp-6); }

.dd-toolbar {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: 0 var(--sp-6) var(--sp-3);
}
.dd-filter { flex: 1 1 200px; max-width: 320px; }
.dd-filter input {
  width: 100%;
  padding: 6px 10px;
  background: var(--bg-elevated);
  border: 1px solid var(--border-mid);
  border-radius: var(--r-md);
  color: var(--text-1);
  font-family: inherit;
  font-size: 12px;
}
.dd-filter input::placeholder { color: var(--text-4); }
.dd-filter input:focus-visible { outline: 2px solid var(--accent); outline-offset: -1px; }
.dd-count {
  font-family: var(--font-mono);
  font-size: 11.5px;
  color: var(--text-3);
  white-space: nowrap;
}

/* Wide tables scroll inside their own box; the panel never scrolls
   sideways. */
.dd-scroll { overflow-x: auto; }

.dd-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 12.5px;
}
.dd-table thead th {
  position: sticky;
  top: 0;
  z-index: 1;
  padding: 0;
  background: var(--bg-card);
  border-bottom: 1px solid var(--border-mid);
  text-align: left;
  white-space: nowrap;
}
.dd-table thead th.dd-r { text-align: right; }
.dd-table thead th.dd-grow { width: 99%; }

.dd-sort {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  width: 100%;
  padding: 9px var(--sp-4);
  background: none;
  border: 0;
  color: var(--text-3);
  font-family: inherit;
  font-size: 10.5px;
  font-weight: 650;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  text-align: inherit;
  cursor: pointer;
}
.dd-r .dd-sort { justify-content: flex-end; }
.dd-sort:hover { color: var(--text-1); }
.dd-sort.is-active { color: var(--accent); }
.dd-sort:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.dd-caret { font-size: 8px; }

.dd-td {
  padding: 7px var(--sp-4);
  border-bottom: 1px solid var(--border);
  color: var(--text-2);
  vertical-align: top;
}
.dd-table tbody tr:last-child .dd-td { border-bottom: 0; }
.dd-table tbody tr:hover .dd-td { background: rgba(255, 255, 255, 0.025); }
/* A measurement never wraps. "86 MB" broken across two lines reads as two
   values, and it makes every row in the table a different height. */
.dd-r { text-align: right; white-space: nowrap; }
.dd-mono { font-family: var(--font-mono); font-size: 11.5px; }
.dd-mono:not(.dd-sql) { white-space: nowrap; }
.dd-strong { color: var(--text-1); font-weight: 600; }
.dd-muted { color: var(--text-3); }
.dd-accent { color: var(--accent); font-weight: 600; }
.dd-ok { color: var(--success); font-weight: 600; }
.dd-warn { color: var(--warning); font-weight: 600; }
.dd-bad { color: var(--danger); font-weight: 600; }

/* SQL is the widest column and the one an operator most wants whole.
   Clamped to three lines rather than one, with the full text on the
   title, because a single ellipsised line of SQL identifies nothing. */
.dd-sql .dd-cell {
  display: -webkit-box;
  -webkit-line-clamp: 3;
  line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
  max-width: 62ch;
  overflow-wrap: anywhere;
}
.dd-nomatch { text-align: center; color: var(--text-3); padding: var(--sp-8); }

.dd-empty {
  padding: var(--sp-10) var(--sp-6);
  text-align: center;
}
.dd-empty-title {
  margin: 0 0 var(--sp-2);
  font-size: 14px;
  font-weight: 600;
  color: var(--text-2);
}
.dd-empty-body {
  margin: 0 auto;
  max-width: 46ch;
  font-size: 12.5px;
  line-height: 1.6;
  color: var(--text-3);
}

.dd-sr {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ── Narrow viewports ──────────────────────────────────────────────────
   Below 720px the table becomes one card per row: a horizontally
   scrolling eight-column table on a phone is a table nobody reads. */
@media (max-width: 719px) {
  .dd-table thead { display: none; }
  .dd-table, .dd-table tbody, .dd-table tr { display: block; }
  .dd-table tr {
    padding: var(--sp-3) var(--sp-5);
    border-bottom: 1px solid var(--border);
  }
  .dd-td {
    display: flex;
    justify-content: space-between;
    gap: var(--sp-4);
    padding: 3px 0;
    border: 0;
    text-align: left;
  }
  .dd-td::before {
    content: attr(data-label);
    flex: 0 0 auto;
    font-size: 10.5px;
    font-weight: 650;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--text-4);
  }
  .dd-td .dd-cell { text-align: right; min-width: 0; }
  .dd-sql .dd-cell { max-width: none; -webkit-line-clamp: 4; line-clamp: 4; }
  .dd-head { padding: var(--sp-4) var(--sp-5); }
  .dd-recon, .dd-toolbar { padding-left: var(--sp-5); padding-right: var(--sp-5); }
  .dd-facts, .dd-note, .dd-error { margin-left: var(--sp-5); margin-right: var(--sp-5); }
  .dd-facts { padding-left: 0; padding-right: 0; }
}

/* ══════════════ Light theme ══════════════
   In light mode --bg-elevated and --bg-card are BOTH #ffffff, so the
   reconciliation strip loses its band and reads as part of the header.
   Measured against a real paint, not assumed from the token names. */
[data-theme="light"] .dd-table tbody tr:hover .dd-td { background: rgba(0, 0, 0, 0.03); }
[data-theme="light"] .dd-panel { box-shadow: 0 24px 64px rgba(0, 0, 0, 0.18); }
[data-theme="light"] .dd-recon { background: var(--bg-base); }
[data-theme="light"] .dd-recon[data-state="differs"] {
  background: color-mix(in srgb, var(--warning) 10%, var(--bg-base));
}
[data-theme="light"] .dd-filter input { background: var(--bg-base); }
