/* ============================================================================
   Deep Field — Superadmin & CRO analytics console (view-scoped)

   Token-driven, flat, AA in both themes. Owns every .sa-* class and the
   #superadmin-tab-body scope. This sheet absorbed the former Section 3
   ("Superadmin") of deep-field.auth-admin.css — striping, .sa-panel,
   .sa-chip/.sa-dot and the mobile overflow guards live here now.

   Dynamic values (per-gesture accent swatches, computed bar widths,
   JS-toggled display) remain inline in views/superadmin.js by design —
   everything static belongs here.
   ========================================================================= */

/* ===== 1. Operator tables ============================================== */

/* Readable row striping for the operator tables (scoped to this view). */
#superadmin-tab-body .settings-table tbody tr:nth-child(even) td {
  background: var(--inset);
}

/* Density: operator tables run one step smaller and tighter than the app's
   tables (13px / 8px cells vs 15px / 12px) — these are scan-down surfaces. */
#superadmin-tab-body .settings-table { font-size: 0.8125rem; }
#superadmin-tab-body .settings-table th { padding: 8px 12px; }
#superadmin-tab-body .settings-table td { padding: 8px 12px; }

/* Methodology disclosure: dense caveat prose folds behind a one-line summary
   so pages lead with the chart + numbers. The full text stays in the DOM
   (a11y, ctrl-F) — it is collapsed, not removed. */
.sa-details { margin: 0 0 14px; max-width: 860px; }
.sa-details summary {
  cursor: pointer;
  font-size: 12px;
  font-weight: 600;
  color: var(--ink-62);
  user-select: none;
}
.sa-details summary:hover,
.sa-details summary:focus-visible { color: var(--text); }
.sa-details[open] summary { margin-bottom: 6px; }
.sa-details-body { font-size: 13px; color: var(--ink-62); margin: 0; }

/* Numeric cell: right-aligned, tabular figures for scan-down comparison. */
.sa-num {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* Table caption used by the console's dense tables. */
.sa-caption {
  caption-side: top;
  text-align: left;
  font-size: 13px;
  color: var(--ink-62);
  padding-bottom: 8px;
}

/* ===== 2. Panels & cards =============================================== */

/* Flat panel section (email editor, reminder cadence, KPI cards, etc.). */
.sa-panel {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 18px;
}

/* Card padding overrides for the denser operator surfaces. */
.sa-pad    { padding: 18px; }
.sa-pad-sm { padding: 14px; }

/* Outlined sub-panel nested inside a card (option groups, previews). */
.sa-outline {
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 16px;
}

/* Card header row: title left, controls right. */
.sa-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 12px;
}

/* Amber advisory banner (non-blocking warnings, e.g. stale data). */
.sa-warn-banner {
  border: 1px solid var(--num-amber);
  color: var(--num-amber);
  border-radius: 8px;
  padding: 10px 14px;
  margin-bottom: 16px;
}

/* Bordered list row (stacked settings rows with a control on the right). */
.sa-list-row {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 14px 0;
  border-bottom: 1px solid var(--border);
}

/* ===== 3. Stat blocks (KPI cards) ====================================== */

/* Uppercase micro-label above a stat value. */
.sa-kicker {
  font-size: 11px;
  color: var(--ink-62);
  text-transform: uppercase;
  letter-spacing: 0.4px;
}

/* Stat numerals. */
.sa-stat    { font-size: 22px; font-weight: 700; margin-top: 2px; }
.sa-stat-lg { font-size: 26px; font-weight: 800; margin-top: 4px; }

/* Stat-card grids. */
.sa-stat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 16px;
}
.sa-stat-grid--sm {
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 12px;
  margin: 16px 0;
}

/* ===== 4. Text roles ==================================================== */

.sa-muted  { color: var(--ink-62); }
/* De-emphasised but READABLE text (k-lock markers, "No image set", token
   hints). --ink-40 is the separators tint and fails AA at these sizes
   (2.34:1 caught by the Windtunnel axe gate); --ink-62 is the design
   system's secondary-text tint, AA 4.5:1 in both themes. */
.sa-faint  { color: var(--ink-62); }
.sa-good   { color: var(--num-green); }
.sa-bad    { color: var(--num-burgundy); }
.sa-warn   { color: var(--num-amber); }
.sa-strong { font-weight: 600; }

/* Secondary copy: 13px explainers and 12px footnotes. */
.sa-sub  { font-size: 13px; color: var(--ink-62); }
.sa-note { font-size: 12px; color: var(--ink-62); }

/* Inline error slot under a form control (JS toggles visibility). */
.sa-err {
  color: var(--num-burgundy);
  font-size: 12px;
  margin-top: 4px;
}

/* Full-width error line inside a filter bar. */
.sa-filter-err {
  flex-basis: 100%;
  color: var(--num-burgundy);
  font-size: 13px;
}

/* Async status slot under a form (reserves height so the layout is stable). */
.sa-status-slot {
  margin: 8px 0 0;
  font-size: 12px;
  min-height: 16px;
}

/* "Saved ✓" flash — JS raises opacity, the transition does the rest. */
.sa-flash-ok {
  color: var(--num-green);
  opacity: 0;
  transition: opacity 200ms ease;
}

/* Card/section title and its inline de-emphasised suffix. */
.sa-title { font-size: 18px; font-weight: 700; margin-bottom: 8px; }
.sa-h-sub { font-weight: 400; color: var(--ink-62); font-size: 13px; }

/* Large count beside a heading (e.g. "Organisations  128"). */
.sa-inline-count { font-size: 20px; font-weight: 700; margin-left: 8px; }

/* Muted empty-result table cell. */
.sa-empty-cell { padding: 16px 0; }

/* Readable measure cap for long explainer paragraphs. */
.sa-measure { max-width: 720px; }

/* Gold "platform" badge (superadmin-only affordances). */
.sa-gold-badge {
  font-size: 11px;
  background: var(--gold);
  color: var(--ink);
  padding: 1px 6px;
  border-radius: 8px;
  vertical-align: middle;
}

/* Monospace token chip (copyable ids, API keys). */
.sa-mono-chip {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12px;
  padding: 2px 8px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--inset);
  cursor: pointer;
}

/* ===== 5. Filters & forms ============================================== */

/* Filter bar: label+control columns, baseline-aligned, wraps on narrow. */
.sa-filters {
  display: flex;
  flex-wrap: wrap;
  gap: 12px 18px;
  align-items: flex-end;
}
/* Filter bar hosted in its own slim card. */
.sa-filters-card {
  padding: 14px 16px;
  margin-bottom: 18px;
}

/* One labelled filter control. */
.sa-filter {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 12px;
  color: var(--ink-62);
}

/* Compact console input (dates, selects, numbers in filter bars). */
.sa-input {
  padding: 6px 8px;
  border: 1px solid var(--border-14);
  border-radius: 8px;
  background: var(--panel);
  color: var(--text);
}
.sa-input--sm { width: 110px; }
.sa-input--xs { width: 90px; }

/* A .form-input that should shrink to its content (inline selects). */
.sa-inline-input { width: auto; display: inline-block; }

/* Native colour-well input (gesture accent picker). */
.sa-color-input { height: 40px; padding: 4px; }

/* Block label above a control. */
.sa-field-label {
  display: block;
  font-size: 12px;
  color: var(--ink-62);
  margin-bottom: 4px;
}

/* Inline checkbox label. */
.sa-inline-check {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  color: var(--ink-62);
}
/* Checkbox row inside a filter/option column. */
.sa-check-row {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  color: var(--text);
  padding-bottom: 6px;
}

/* ===== 6. Layout helpers =============================================== */

.sa-row {
  display: flex;
  gap: 10px;
  align-items: center;
  flex-wrap: wrap;
}

/* Right-aligned action row at the foot of a card/form. */
.sa-actions {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
  margin-top: 12px;
}

.sa-grid   { display: grid; gap: 12px; }
.sa-scroll { overflow-x: auto; }

/* Inline sub-nav row (nested .settings-tabs inside a toolbar). */
.sa-subnav { display: inline-flex; margin: 0; }

/* Centred chart legend row under a canvas/SVG. */
.sa-chart-legend {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin-top: 14px;
  font-size: 12px;
  color: var(--ink-62);
}

/* ===== 7. Media ========================================================= */

/* Charity/partner logo thumbnails: pinned WHITE in both themes — partner
   logos are designed for light grounds and must stay legible in dark. */
.sa-logo-thumb {
  height: 48px;
  max-width: 120px;
  vertical-align: middle;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: #FFF;
  padding: 4px;
}
/* The "new upload" preview variant (JS reveals it on file pick). */
.sa-logo-thumb--new { border-color: var(--num-green); }

/* Small gesture icon thumbnail in table rows. */
.sa-icon-thumb {
  height: 24px;
  width: auto;
  max-width: 80px;
  vertical-align: middle;
}

/* Colour swatches — background is injected inline (dynamic per gesture). */
.sa-swatch {
  display: inline-block;
  width: 14px;
  height: 14px;
  border-radius: 3px;
  vertical-align: middle;
  margin-right: 6px;
  border: 1px solid var(--border-14);
}
.sa-legend-swatch { display: inline-block; width: 22px; height: 10px; }

/* ===== 7b. Editors & previews (email/footer tab) ======================= */

/* Auto-resizing editor textareas; --mono for the raw-HTML footer editor. */
.sa-textarea { width: 100%; resize: vertical; font-family: inherit; font-size: 14px; }
.sa-textarea--mono {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 13px;
}

/* Sandboxed footer preview iframe: pinned WHITE — it mimics an email
   client's rendering surface, which does not follow the app theme. */
.sa-footer-preview {
  width: 100%;
  height: 72px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: #FFF;
}

/* Plain-text fallback preview block. */
.sa-pre {
  margin: 0;
  white-space: pre-wrap;
  word-break: break-word;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 13px;
  color: var(--text);
  background: var(--inset);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 10px;
  min-height: 40px;
}

/* Charity-view loading skeleton lines. */
.sa-skel-line { width: 60%; height: 12px; background: var(--track-bar); border-radius: 4px; }
.sa-skel-line--lg { width: 80%; height: 24px; margin-top: 10px; }

/* ===== 7c. Heatmap table (console) ===================================== */

.sa-left   { text-align: left; }
.sa-center { text-align: center; }

.sa-hm-rowhead {
  text-align: left;
  font-weight: 500;
  color: var(--ink-62);
  white-space: nowrap;
}
.sa-hm-th--compact { font-size: 10px; padding: 4px 2px; }
.sa-hm-cell { text-align: center; border-radius: 4px; padding: 10px 4px; }
.sa-hm-cell--compact { padding: 8px 2px; font-size: 10px; }

/* ===== 8. Inline SVG (sparklines, axes) ================================ */

.sa-axis-text  { fill: var(--ink-62); font-size: 10px; }
.sa-axis-line  { stroke: var(--border); }
.sa-spark-fill { fill: var(--num-green); opacity: 0.12; }
.sa-spark-dot  { fill: var(--num-green); }
.sa-spark-line {
  fill: none;
  stroke: var(--num-green);
  stroke-width: 2;
  stroke-linejoin: round;
  stroke-linecap: round;
}

/* ===== 9. Overlay dialog (charity-view invite modal) =================== */

.sa-overlay {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
  z-index: 1000;
  align-items: center;
  justify-content: center;
}
.sa-overlay-panel {
  background: var(--panel);
  border: 1px solid var(--border-14);
  border-radius: 12px;
  padding: 32px;
  width: 100%;
  max-width: 440px;
}

/* ===== 10. Status chips ================================================ */

/* Neutral status chip with a functional --num-* dot (colour restraint:
   neutral grounds, colour only as a small identity dot). */
.sa-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 2px 10px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 600;
  background: var(--inset);
  border: 1px solid var(--border-14);
  color: var(--text);
  white-space: nowrap;
}
.sa-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex: none;
}
.sa-dot--green    { background: var(--num-green); }
.sa-dot--amber    { background: var(--num-amber); }
.sa-dot--burgundy { background: var(--num-burgundy); }
.sa-dot--teal     { background: var(--num-teal); }
.sa-dot--neutral  { background: var(--ink-40); }

/* ===== 11. Spacing & misc utilities ==================================== */

.sa-m0 { margin: 0; }

.sa-mt-4  { margin-top: 4px; }
.sa-mt-6  { margin-top: 6px; }
.sa-mt-8  { margin-top: 8px; }
.sa-mt-10 { margin-top: 10px; }
.sa-mt-12 { margin-top: 12px; }
.sa-mt-16 { margin-top: 16px; }
.sa-mt-20 { margin-top: 20px; }
.sa-mt-24 { margin-top: 24px; }

.sa-mb-4  { margin-bottom: 4px; }
.sa-mb-6  { margin-bottom: 6px; }
.sa-mb-8  { margin-bottom: 8px; }
.sa-mb-10 { margin-bottom: 10px; }
.sa-mb-12 { margin-bottom: 12px; }
.sa-mb-14 { margin-bottom: 14px; }
.sa-mb-16 { margin-bottom: 16px; }
.sa-mb-18 { margin-bottom: 18px; }
.sa-mb-20 { margin-bottom: 20px; }
.sa-mb-24 { margin-bottom: 24px; }

.sa-ml-4 { margin-left: 4px; }

.sa-fs-12 { font-size: 12px; }
.sa-fs-13 { font-size: 13px; }
.sa-fs-14 { font-size: 14px; }
.sa-fs-16 { font-size: 16px; }

.sa-flex-1  { flex: 1; }
.sa-nowrap  { white-space: nowrap; }
.sa-pointer { cursor: pointer; }
.sa-end     { align-self: flex-end; }
.sa-inset   { background: var(--inset); }

/* Slim card padding for toolbars/canvas hosts. */
.sa-pad-slim { padding: 14px 16px; }

/* Width caps for inline form controls. */
.sa-max-140 { max-width: 140px; }
.sa-max-220 { max-width: 220px; }
.sa-max-240 { max-width: 240px; }
.sa-max-420 { max-width: 420px; }

/* Label above a canvas panel. */
.sa-panel-label { margin: 0 0 8px; font-size: 14px; font-weight: 600; }

/* Chart canvas fills its host card. */
.sa-canvas { width: 100%; display: block; }
.sa-svg-block { width: 100%; height: auto; display: block; }

/* Native checkbox at a comfortable operator size. */
.sa-checkbox { width: 18px; height: 18px; }

/* Fixed-width slot label in the reminder cadence rows. */
.sa-slot-label { min-width: 130px; font-weight: 600; }

/* Truncate long org names in the operator tables. */
.sa-ellipsis {
  max-width: 200px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Section heading that separates stacked page regions. */
.sa-section-h { margin: 32px 0 8px; }

/* Block hint text under an upload/file control. */
.sa-hint {
  display: block;
  font-size: 12px;
  color: var(--ink-62);
  margin-top: 4px;
}

/* ===== 12. Mobile guards =============================================== */

/* Never let the tab body force horizontal page scroll; wide tables scroll
   inside their own .table-wrap / card instead. */
#superadmin-tab-body { min-width: 0; }
#superadmin-tab-body .table-wrap { margin-bottom: var(--space-4); }
#superadmin-tab-body .card { min-width: 0; overflow-x: auto; }

/* ===== 7c. All-emails viewer (DEF-076) ================================== */
/* Read-only inventory + sample renders. No editing controls by design. */

.sa-samples-layout {
  display: grid;
  grid-template-columns: minmax(220px, 320px) 1fr;
  gap: 24px;
  align-items: start;
}
@media (max-width: 860px) {
  .sa-samples-layout { grid-template-columns: 1fr; }
}

.sa-samples-nav { min-width: 0; }
.sa-samples-group + .sa-samples-group { margin-top: 20px; }
.sa-samples-group-title {
  margin: 0 0 8px;
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-muted);
}
.sa-samples-list { list-style: none; margin: 0; padding: 0; }

.sa-samples-item {
  appearance: none;
  display: block;
  width: 100%;
  text-align: left;
  cursor: pointer;
  font: inherit;
  color: var(--text);
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 10px 12px;
  margin-bottom: 6px;
}
.sa-samples-item:hover { background: var(--panel-2); }
.sa-samples-item:focus-visible {
  outline: 2px solid var(--num-teal);
  outline-offset: 2px;
}
.sa-samples-item.is-selected {
  border-color: var(--num-teal);
  background: var(--panel-2);
}

.sa-samples-label { display: block; font-weight: 600; font-size: 14px; }
.sa-samples-note {
  display: block;
  margin-top: 4px;
  font-size: 12px;
  line-height: 1.45;
  color: var(--text-muted);
}
.sa-samples-variant { margin-left: 8px; vertical-align: middle; }

.sa-samples-viewer { min-width: 0; }
.sa-samples-empty { padding: 24px 0; }

/* Pinned WHITE, like .sa-footer-preview: it mimics a mail client's rendering
   surface, which does not follow the app theme. Framing chrome stays themed. */
.sa-sample-frame {
  width: 100%;
  height: 70vh;
  min-height: 420px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: #FFF;
}

/* The browser-render-not-Outlook caveat. Advisory, not an error. */
.sa-samples-caveat {
  border-left: 3px solid var(--num-amber);
}

/* ===== 13. Loop board (viral loop / K monitor) =========================== */
/*
   Flat, token-only, dual-theme.

   COLOUR RULE FOR THIS SECTION, stated so nobody "improves" it later:
   the ring ships in ONE NEUTRAL TREATMENT. No good/warn/crit palette, no
   red/amber/green, no "healthy range" tint. Benchmarks have deliberately not
   been agreed, so the board must not imply a verdict. --num-teal appears only
   as the SELECTION + FOCUS affordance (the same role it plays elsewhere in
   this sheet), never to say a number is good.
*/

/* Visually hidden but announced. Used by the console's live region. */
.sa-sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* --- filter bar: two rows, the shared date control on the second --------- */
.sa-loop-filters {
  display: block;
}
.sa-loop-filter-row + .sa-loop-filter-row {
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
}

/* --- mandatory on-surface copy ------------------------------------------ */
.sa-loop-disclaimer,
.sa-loop-hypothesis {
  max-width: 860px;
  font-size: 13px;
  line-height: 1.5;
  color: var(--text);
  border-left: 3px solid var(--border-14);
  padding-left: 12px;
}

/* --- layout: ring full-width, detail panel below (owner feedback
   2026-08-05 — the side-by-side split crowded the diagram's labels) ------- */
.sa-loop-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 18px;
  align-items: start;
  margin-bottom: 20px;
}
.sa-loop-canvas-card { min-width: 0; }
.sa-loop-svg {
  width: 100%;
  max-width: 1040px;
  margin: 0 auto;
  height: auto;
  display: block;
  overflow: visible;
}
.sa-loop-svg-help { margin-top: 8px; }
.sa-loop-detail { min-width: 0; }

/* On a phone the ring would otherwise shrink until its 10px labels are
   unreadable. Hold a legible minimum and let the diagram scroll inside its own
   card — the page body never scrolls sideways, and the <details> table below
   carries the same numbers for anyone who would rather not pan a diagram. */
@media (max-width: 700px) {
  .sa-loop-canvas-card { overflow-x: auto; }
  .sa-loop-svg { min-width: 620px; }
}

/* --- the ring itself ----------------------------------------------------- */
.sa-loop-guide {
  stroke: var(--border);
  stroke-width: 2;
}
.sa-loop-edge {
  stroke: var(--ink-62);
  stroke-width: 9;
}
.sa-loop-edge.is-selected {
  stroke: var(--num-teal);
}
.sa-loop-arrowhead { fill: var(--ink-62); }
.sa-loop-arrowhead.is-selected { fill: var(--num-teal); }

/* Fat invisible hit target over each arc: pointer + keyboard reachable. */
.sa-loop-hit {
  stroke: transparent;
  stroke-width: 34;
  cursor: pointer;
}

.sa-loop-edge-pct {
  font-size: 14px;
  font-weight: 700;
  fill: var(--text);
  font-variant-numeric: tabular-nums;
}
.sa-loop-edge-cap {
  font-size: 10px;
  fill: var(--ink-62);
  letter-spacing: 0.05em;
}
.sa-loop-edge-n {
  font-size: 10px;
  fill: var(--ink-62);
  font-variant-numeric: tabular-nums;
}

.sa-loop-node { cursor: pointer; }
/* --ink-62 rather than a border tint: these circles are meaningful graphical
   objects (WCAG 1.4.11 non-text contrast), not decorative hairlines. */
.sa-loop-node-ring {
  fill: var(--panel);
  stroke: var(--ink-62);
  stroke-width: 2;
}
.sa-loop-node.is-selected .sa-loop-node-ring {
  stroke: var(--num-teal);
  stroke-width: 3;
}
.sa-loop-node-num {
  font-size: 17px;
  font-weight: 600;
  fill: var(--text);
}
.sa-loop-node-label {
  font-size: 13px;
  font-weight: 600;
  fill: var(--text);
}
.sa-loop-node-count {
  font-size: 11.5px;
  fill: var(--ink-62);
  font-variant-numeric: tabular-nums;
}

/* K in the centre: both readings, same weight of voice. */
.sa-loop-k-num {
  font-size: 40px;
  font-weight: 800;
  fill: var(--text);
  font-variant-numeric: tabular-nums;
}
.sa-loop-k-cap {
  font-size: 11px;
  font-weight: 600;
  fill: var(--ink-62);
  letter-spacing: 0.04em;
}
.sa-loop-k-math {
  font-size: 12px;
  fill: var(--ink-62);
  font-variant-numeric: tabular-nums;
}

/* The second loop is NOT BUILT: dashed, de-emphasised, and labelled as such
   in words — the dashes alone are never the only carrier of that meaning. */
.sa-loop-l2 { cursor: pointer; }
.sa-loop-l2-ring {
  stroke: var(--ink-62);
  stroke-width: 2.5;
}
.sa-loop-l2-node {
  fill: var(--panel);
  stroke: var(--ink-62);
  stroke-width: 2;
}
.sa-loop-l2-title {
  font-size: 12px;
  font-weight: 700;
  fill: var(--ink-62);
  letter-spacing: 0.06em;
}
.sa-loop-l2-cap {
  font-size: 9.5px;
  fill: var(--ink-62);
  letter-spacing: 0.04em;
}

/* Visible focus on SVG nodes, belt AND braces: outline where the browser
   honours it, plus a stroke change that always lands. */
.sa-loop-svg :focus-visible {
  outline: 2px solid var(--num-teal);
  outline-offset: 2px;
}
.sa-loop-node:focus-visible .sa-loop-node-ring,
.sa-loop-l2:focus-visible .sa-loop-l2-ring { stroke: var(--num-teal); }
.sa-loop-hit:focus-visible { stroke: var(--num-teal); stroke-opacity: 0.25; }

/* --- key/value cells shared by the detail panel and the small panels ----- */
.sa-loop-kv {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 10px;
}
.sa-loop-kv-cell {
  background: var(--inset);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 10px 12px;
  min-width: 0;
}
.sa-loop-kv-n {
  font-size: 20px;
  font-weight: 700;
  line-height: 1.15;
  font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere;
}
.sa-loop-kv-l {
  font-size: 11.5px;
  color: var(--ink-62);
  margin-top: 3px;
}

.sa-loop-subhead {
  margin: 16px 0 8px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--ink-62);
}
.sa-loop-list {
  margin: 0;
  padding-left: 18px;
  list-style: disc outside;
  font-size: 13px;
  color: var(--text);
}
.sa-loop-list li { margin: 4px 0; }

/* The sample size that rides beside every rate. */
.sa-loop-n {
  font-size: 11px;
  font-weight: 400;
  color: var(--ink-62);
  white-space: nowrap;
}

/* A withheld cell is DESIGNED, not blank and never a zero.

   IT CARRIES A SENTENCE, NOT A NUMBER, so it must not be sized like one.
   `.sa-loop-kv` lays out at repeat(auto-fit, minmax(150px, 1fr)), which on a
   ~360px detail panel (the right column of .sa-loop-grid) and on a 390px phone
   settles at two columns whose content budget is ~130-133px. Measured in
   Chromium against the shipped face at both widths:

     "Hidden — too few people"      145.8px  — over by 12.8px  (PRE-EXISTING)
     "Hidden — cannot be filtered"  161.3px  — over by 28.3px

   With `white-space: nowrap` BOTH strings escaped the cell — the longer one
   past the card's own edge — so this was already broken before the second
   string existed. The chip wraps instead. Same colours, same tokens, same flat
   dashed treatment, same padding and radius: only the line count changes, and
   `text-wrap: balance` keeps the two lines even rather than orphaning a word.
   `max-width` + `overflow-wrap` are the belt-and-braces for a future string
   with a token longer than the column.

   The COMPACT in-ring form is a different string entirely (saLoopCellShort()
   returns the single word "hidden") and is deliberately untouched — nothing
   large may enter the ring. */
.sa-loop-hidden {
  display: inline-block;
  max-width: 100%;
  font-size: 11px;
  font-weight: 600;
  line-height: 1.35;
  color: var(--ink-62);
  background: var(--inset);
  border: 1px dashed var(--border-14);
  border-radius: 6px;
  padding: 1px 7px;
  white-space: normal;
  overflow-wrap: break-word;
  text-wrap: balance;
}

/* --- ranked leak list ---------------------------------------------------- */
.sa-loop-leaks { margin-bottom: 8px; }
.sa-loop-leak {
  appearance: none;
  display: grid;
  grid-template-columns: 28px minmax(140px, 1.4fr) minmax(120px, 1fr) auto;
  gap: 12px;
  align-items: center;
  width: 100%;
  text-align: left;
  font: inherit;
  color: var(--text);
  background: var(--panel);
  border: 0;
  border-top: 1px solid var(--border);
  border-radius: 8px;
  padding: 10px 8px;
  cursor: pointer;
}
.sa-loop-leak:hover { background: var(--panel-2); }
.sa-loop-leak:focus-visible {
  outline: 2px solid var(--num-teal);
  outline-offset: 2px;
}
.sa-loop-leak-rank {
  font-size: 15px;
  font-weight: 700;
  color: var(--ink-62);
  text-align: center;
  font-variant-numeric: tabular-nums;
}
.sa-loop-leak-name { font-size: 13.5px; font-weight: 600; }
.sa-loop-leak-lost { font-size: 13px; color: var(--ink-62); font-variant-numeric: tabular-nums; }
.sa-loop-leak-rate {
  font-size: 13px;
  font-weight: 600;
  text-align: right;
  font-variant-numeric: tabular-nums;
}
@media (max-width: 760px) {
  .sa-loop-leak { grid-template-columns: 24px 1fr auto; }
  .sa-loop-leak-lost { display: none; }
}

/* --- data confidence: shape + words carry the state, never colour -------- */
.sa-loop-conf { list-style: none; margin: 0; padding: 0; }
.sa-loop-conf-row {
  display: grid;
  grid-template-columns: 12px minmax(140px, 1.6fr) 110px 90px 1fr;
  gap: 10px;
  align-items: center;
  padding: 8px 0;
  border-top: 1px solid var(--border);
  font-size: 13px;
}
.sa-loop-conf-row:first-child { border-top: 0; }
.sa-loop-conf-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  border: 2px solid var(--ink-62);
  background: transparent;
}
.sa-loop-conf-dot.is-on { background: var(--text); border-color: var(--text); }
.sa-loop-conf-ev {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 12px;
  overflow-wrap: anywhere;
}
.sa-loop-conf-state { font-size: 12px; font-weight: 600; color: var(--ink-62); }
.sa-loop-conf-n { font-variant-numeric: tabular-nums; }
.sa-loop-conf-seen { font-size: 12px; color: var(--ink-62); }
@media (max-width: 760px) {
  .sa-loop-conf-row { grid-template-columns: 12px 1fr auto; }
  .sa-loop-conf-n, .sa-loop-conf-seen { display: none; }
}

.sa-loop-table { margin-top: 14px; }
.sa-loop-table table + table { margin-top: 16px; }

/* ===========================================================================
   LOOP BOARD — PARITY V2 (owner ruling 2026-08-05).
   Status colours derive from stored, editable benchmarks; the signal dots are
   the 25-signal layer; the Analyse card carries AI-generated copy. All colour
   comes from the Deep Field tokens: good = --num-green, warn = --num-amber,
   crit = --num-burgundy. Flat, dual-theme, no shadows, no gradients.
   =========================================================================== */

/* -- status colours on the ring -- */
.sa-loop-edge.is-good { stroke: var(--num-green); }
.sa-loop-edge.is-warn { stroke: var(--num-amber); }
.sa-loop-edge.is-crit { stroke: var(--num-burgundy); }
.sa-loop-arrowhead.is-good { fill: var(--num-green); }
.sa-loop-arrowhead.is-warn { fill: var(--num-amber); }
.sa-loop-arrowhead.is-crit { fill: var(--num-burgundy); }

/* Bottleneck halo: a wide, soft arc behind the worst hand-off. */
.sa-loop-halo { stroke-width: 22; opacity: 0.35; }
.sa-loop-halo.is-warn { stroke: var(--num-amber); }
.sa-loop-halo.is-crit { stroke: var(--num-burgundy); }
@keyframes sa-loop-pulse {
  0%, 100% { opacity: 0.4; }
  50% { opacity: 0.12; }
}
.sa-loop-pulse { animation: sa-loop-pulse 1.8s ease-in-out infinite; }

/* -- K centre: delta + verdict -- */
.sa-loop-k-delta {
  font-size: 12.5px; font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.sa-loop-k-delta.is-up { fill: var(--num-green); }
.sa-loop-k-delta.is-down { fill: var(--num-burgundy); }
.sa-loop-k-verdict {
  font-size: 12px; font-weight: 700; letter-spacing: 0.06em;
}
.sa-loop-k-verdict.is-good { fill: var(--num-green); }
.sa-loop-k-verdict.is-warn { fill: var(--num-amber); }

/* -- signal dots on the ring (SVG) -- */
.sa-loop-dot { cursor: pointer; }
.sa-loop-dot.is-live { fill: var(--num-green); stroke: none; }
.sa-loop-dot.is-wired { fill: var(--panel); stroke: var(--num-green); stroke-width: 2; }
.sa-loop-dot.is-missing { fill: var(--panel); stroke: var(--num-burgundy); stroke-width: 2; stroke-dasharray: 2.5 2; }
.sa-loop-dot.is-policy { fill: var(--ink-40); stroke: none; }
.sa-loop-dot:focus-visible { outline: none; stroke: var(--num-teal); stroke-width: 3; }

/* -- the same dot vocabulary in HTML (detail rows + legend) -- */
.sa-loop-dot-html {
  display: inline-block; width: 10px; height: 10px; border-radius: 50%;
  flex: none; vertical-align: middle;
}
.sa-loop-dot-html.is-live { background: var(--num-green); }
.sa-loop-dot-html.is-wired { background: transparent; border: 2px solid var(--num-green); }
.sa-loop-dot-html.is-missing { background: transparent; border: 2px dashed var(--num-burgundy); }
.sa-loop-dot-html.is-policy { background: var(--ink-40); }

/* -- status/state chips -- */
.sa-loop-chip {
  display: inline-block; font-size: 10px; font-weight: 700;
  letter-spacing: 0.05em; text-transform: uppercase;
  border-radius: 5px; padding: 1px 6px; margin-left: 6px; vertical-align: 1px;
}
.sa-loop-chip.is-live { color: var(--num-green); background: var(--soft-green); }
.sa-loop-chip.is-wired { color: var(--ink-62); background: var(--panel-2); border: 1px solid var(--border); }
.sa-loop-chip.is-missing { color: var(--num-burgundy); background: color-mix(in srgb, var(--num-burgundy) 10%, transparent); }
.sa-loop-chip.is-policy { color: var(--ink-62); background: var(--panel-2); }
.sa-loop-chip.is-warn { color: var(--num-amber); background: color-mix(in srgb, var(--num-amber) 12%, transparent); }

/* -- legend under the ring -- */
.sa-loop-legend {
  display: flex; gap: 14px; flex-wrap: wrap; justify-content: center;
  align-items: center; padding: 6px 12px 2px;
  font-size: 12px; color: var(--ink-62);
}
.sa-loop-legend-i { display: inline-flex; align-items: center; gap: 6px; }
.sa-loop-sw {
  display: inline-block; width: 10px; height: 10px; border-radius: 3px; flex: none;
}
.sa-loop-sw.is-good { background: var(--num-green); }
.sa-loop-sw.is-warn { background: var(--num-amber); }
.sa-loop-sw.is-crit { background: var(--num-burgundy); }
.sa-loop-legend-div { width: 1px; align-self: stretch; background: var(--border-14); }

/* -- focus banner: the biggest leak, front and centre -- */
.sa-loop-focus {
  display: flex; gap: 12px; align-items: center;
  margin: 0 0 16px; padding: 12px 16px;
  background: color-mix(in srgb, var(--num-burgundy) 8%, transparent);
  border: 1px solid var(--num-burgundy); border-radius: var(--radius-md);
  cursor: pointer; font-size: 14px;
}
.sa-loop-focus-ico {
  flex: none; width: 30px; height: 30px; border-radius: 50%;
  background: var(--num-burgundy); color: var(--paper);
  display: grid; place-items: center; font-weight: 800; font-size: 15px;
}
.sa-loop-focus-txt strong { color: var(--num-burgundy); }
.sa-loop-focus-go {
  margin-left: auto; flex: none; font-size: 13px; font-weight: 600;
  color: var(--num-burgundy); white-space: nowrap;
}
.sa-loop-focus:focus-visible { outline: 2px solid var(--num-teal); outline-offset: 2px; }

/* -- tooltip -- */
.sa-loop-tip {
  position: fixed; z-index: var(--z-toast); pointer-events: none; display: none;
  background: var(--panel); color: var(--text);
  border: 1px solid var(--border-14); border-radius: var(--radius-sm);
  padding: 9px 12px; font-size: 12.5px; max-width: 300px;
}
.sa-loop-tip-t { font-weight: 700; margin-bottom: 2px; }
.sa-loop-tip-t code { font-size: 11.5px; }
.sa-loop-tip-m { color: var(--ink-62); }

/* -- worth callout (deterministic k_if_fixed arithmetic) -- */
.sa-loop-worth {
  margin-top: 14px; padding: 12px 14px; font-size: 13.5px;
  background: var(--soft-green); border: 1px solid var(--num-green);
  border-radius: var(--radius-sm);
}
.sa-loop-worth strong { color: var(--num-green); }
.sa-loop-worth.is-na { background: var(--panel-2); border-color: var(--border); }
.sa-loop-worth.is-na strong { color: var(--ink-62); }

/* -- sparklines -- */
.sa-loop-spark-wrap { margin-top: 4px; }
.sa-loop-spark polyline { stroke: var(--num-teal); }
.sa-loop-spark circle { fill: var(--num-teal); }
.sa-loop-spark-wrap.is-good .sa-loop-spark polyline { stroke: var(--num-green); }
.sa-loop-spark-wrap.is-good .sa-loop-spark circle { fill: var(--num-green); }
.sa-loop-spark-wrap.is-warn .sa-loop-spark polyline { stroke: var(--num-amber); }
.sa-loop-spark-wrap.is-warn .sa-loop-spark circle { fill: var(--num-amber); }
.sa-loop-spark-wrap.is-crit .sa-loop-spark polyline { stroke: var(--num-burgundy); }
.sa-loop-spark-wrap.is-crit .sa-loop-spark circle { fill: var(--num-burgundy); }
.sa-loop-spark-cap { font-size: 11.5px; color: var(--ink-62); margin-top: 2px; }

/* -- signal rows in the detail panel -- */
.sa-loop-sig {
  display: flex; gap: 10px; align-items: flex-start;
  padding: 8px 0; border-top: 1px solid var(--border); font-size: 13px;
}
.sa-loop-sig:first-of-type { border-top: 0; }
.sa-loop-sig .sa-loop-dot-html { margin-top: 4px; }
.sa-loop-sig-main { min-width: 0; }
.sa-loop-sig-main code { font-size: 12px; }
.sa-loop-sig-cap { color: var(--ink-62); font-size: 12.5px; }
.sa-loop-sig-n {
  margin-left: auto; flex: none; font-variant-numeric: tabular-nums;
  font-weight: 600; text-align: right; font-size: 13px;
}
.sa-loop-sig-share {
  display: block; font-weight: 400; font-size: 11px; color: var(--ink-62);
}
.sa-loop-screens { color: var(--ink-40); font-size: 12.5px; }

/* -- the /tour demo entry funnel: a LEADING INDICATOR, not a loop number --
   Same de-emphasis vocabulary the board already uses for material that is not
   authoritative: the dashed outline of .sa-loop-hidden and the muted ink of the
   second loop. The dashes are never the only carrier of that meaning — the
   heading says "leading indicator" and the caption says it is not part of the
   live loop numbers, so the distinction survives greyscale, high contrast and
   a screen reader. Reuses .sa-loop-sig rows verbatim, so a demo step and a loop
   signal are read the same way; only the container is treated differently. */
.sa-loop-demo {
  border-style: dashed;
  border-color: var(--border-14);
  background: var(--inset);
}
.sa-loop-demo > h3 { color: var(--ink-62); }
.sa-loop-demo .sa-loop-sig { border-top-style: dashed; }

/* -- rate colouring + inline bars -- */
.sa-loop-rate.is-good { color: var(--num-green); }
.sa-loop-rate.is-warn { color: var(--num-amber); }
.sa-loop-rate.is-crit { color: var(--num-burgundy); }
.sa-loop-bar {
  display: block; height: 6px; border-radius: 3px; overflow: hidden;
  background: var(--track-bar); margin-top: 4px; min-width: 90px;
}
.sa-loop-bar i { display: block; height: 100%; border-radius: 3px; background: var(--num-teal); }
.sa-loop-bar i.is-good { background: var(--num-green); }
.sa-loop-bar i.is-warn { background: var(--num-amber); }
.sa-loop-bar i.is-crit { background: var(--num-burgundy); }
.sa-loop-bar.is-wide { min-width: 0; width: 100%; }

/* Leak rows grew a status line + fix chip. */
.sa-loop-leak-sc { display: block; font-weight: 400; font-size: 12px; color: var(--ink-62); }
.sa-loop-fix-chip {
  font-size: 12px; font-weight: 700; font-variant-numeric: tabular-nums;
  color: var(--num-green); background: var(--soft-green);
  border-radius: 7px; padding: 4px 9px; white-space: nowrap; align-self: center;
}
.sa-loop-fix-chip.is-ok { color: var(--ink-62); background: var(--panel-2); }

/* -- bar rows (reminder attribution + plan mix) -- */
.sa-loop-barrow {
  display: grid; grid-template-columns: 52px 1fr auto; gap: 10px;
  align-items: center; padding: 8px 0; border-top: 1px dashed var(--border);
  margin-bottom: 2px;
}
.sa-loop-barrow:first-of-type { border-top: 0; }
.sa-loop-barrow-label { font-weight: 700; font-size: 13px; text-transform: capitalize; }
.sa-loop-barrow-body { min-width: 0; }
.sa-loop-barrow-cap { font-size: 12px; color: var(--ink-62); margin-top: 3px; }
.sa-loop-barrow-n {
  font-variant-numeric: tabular-nums; font-weight: 600;
  font-size: 13px; text-align: right;
}

/* -- benchmarks editor -- */
.sa-loop-bmrow {
  display: grid; grid-template-columns: minmax(180px, 1.4fr) auto auto; gap: 12px;
  align-items: center; padding: 10px 0; border-top: 1px solid var(--border);
}
.sa-loop-bmrow:first-of-type { border-top: 0; }
.sa-loop-bmrow-name { font-weight: 600; font-size: 13.5px; }
.sa-loop-bmrow-f {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 12.5px; color: var(--ink-62); white-space: nowrap;
}
.sa-loop-bmrow-f .sa-input { width: 84px; }
.sa-loop-bm-actions { display: flex; align-items: center; gap: 12px; margin-top: 12px; }
@media (max-width: 720px) {
  .sa-loop-bmrow { grid-template-columns: 1fr; gap: 6px; }
}

/* -- Analyse card -- */
.sa-loop-analysis-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; margin-bottom: 10px;
}
.sa-loop-analysis-meta { font-size: 12px; color: var(--ink-62); margin-bottom: 8px; }
.sa-loop-analysis-summary { font-size: 14px; margin: 0 0 6px; }
.sa-loop-analysis-unavail {
  padding: 12px 14px; font-size: 13.5px;
  background: color-mix(in srgb, var(--num-amber) 10%, transparent);
  border: 1px solid var(--num-amber); border-radius: var(--radius-sm);
}

/* -- honesty footer -- */
.sa-loop-honest {
  margin-top: 22px; color: var(--ink-62); font-size: 12.5px; max-width: 88ch;
}
.sa-loop-honest strong { color: var(--text); }

/* Nothing on this board animates by default (bar the halo pulse); reduced
   motion holds the halo at a steady opacity and stops everything else. */
@media (prefers-reduced-motion: reduce) {
  .sa-loop-svg *,
  .sa-loop-leak,
  .sa-loop-detail {
    transition: none !important;
    animation: none !important;
  }
  .sa-loop-pulse { animation: none; opacity: 0.3; }
}
