/* ============================================================
   Kirkwood Route Intelligence — demonstration concept by PSI
   (Route Intelligence Platform demo surface).
   EXECUTIVE LIGHT THEME (binding) — matches Kirkwood's own decks:
   white pages, red bar motifs, navy ink. Backgrounds: page #F7F8FA,
   panels/cards #FFFFFF with hairline #D9E0E7 borders + very soft
   shadows; NO dark surfaces anywhere in the app UI. Ink: primary
   #0B1B2B; headings #0E2841 (semibold, sentence case); muted
   #56687A. BRAND CRIMSON #B20F31 (primary) / #E31B43 (hover,
   active): the deck's red-bar motif as a thin top-of-page bar and
   section accent rules, active nav, primary buttons, recommended
   route. Semantic states stay separate — pass #1E7B34, warn
   #B77800, fail #C22B2B — pills only, never brand. Warn is a
   documented PAIR: the spec's #B77800 is a GRAPHIC fill/stroke
   only (hazard overlays, app.js) — as text it is 3.68:1 on white,
   so all warn TEXT uses the darker AA ink --warn #A06800 (and
   #8F5D00 on the #F1F4F8 inset surfaces). Secondary accents
   sparing: steel blue #0F9ED5 (alternate routes, links),
   orange #E97132 (existing carriers). System executive type
   stack, base 15/1.55; 8px grid; tabular numerals throughout.
   ============================================================ */

:root {
  --bg: #F7F8FA;           /* page */
  --surface: #FFFFFF;      /* panels / cards */
  --surface-2: #F1F4F8;    /* inset fields, sub-cards */
  --border: #D9E0E7;       /* hairlines */
  --text: #0B1B2B;         /* primary ink */
  --heading: #0E2841;      /* headings — semibold, sentence case */
  --text-2: #33475C;       /* secondary ink */
  --muted: #56687A;
  --brand: #B20F31;        /* Kirkwood crimson — brand/identity accent */
  --brand-deep: #E31B43;   /* hover / active brand state */
  --brand-tint: #D4657D;   /* access laterals (dotted) on the light base */
  --accent: #0F9ED5;       /* steel blue — informational accent (graphics) */
  --accent-ink: #09719E;   /* steel blue as TEXT — AA on white AND the
                              tinted surfaces (5.43 white / 5.11 on --bg /
                              4.92 on --surface-2; #0A7CAD failed AA on
                              the tints — design-audit fix) */
  --ok: #1E7B34;           /* pass — status pills only */
  --warn: #A06800;         /* warn TEXT ink (AA on white); the spec fill
                              #B77800 rides graphics/strokes only */
  --fail: #C22B2B;         /* fail — check/status pills only */
  --slate-bright: #5E7186; /* slate ink for tertiary pills on light */
  --orange: #E97132;       /* existing-carrier overlay (lines) */
  --orange-ink: #C25012;   /* orange as TEXT — AA on white */
  /* map-layer palette (run map): corridor network = faint context on
     the light positron tiles */
  --ctx-interstate: #8CA1B4;
  --ctx-us-highway: #9AACBD;
  --ctx-state-local: #A9B9C7;
  --rail: #8A99A8;         /* thin dashed slate (off by default) */
  --river: #6E9FC0;        /* soft hydrology blue on the light base */
  --wetland: #196B24;      /* deck green, low-opacity fill */
  --reject: #7A8B9C;       /* rejected candidate — slate, dashed */
  --radius: 10px;
  --shadow: 0 1px 3px rgba(11, 27, 43, 0.06); /* very soft card shadow */
  --font: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI",
    "Helvetica Neue", Arial, sans-serif;
  --mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, monospace;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  height: 100%;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  font-size: 15px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

/* The deck's red-bar motif: a thin brand rule across the very top of
   every page (identity, never a status). */
body::before {
  content: "";
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 3px;
  background: var(--brand);
  z-index: 3000;
  pointer-events: none;
}

body {
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.hidden { display: none !important; }

/* Tiny eyebrow labels — the ONLY place uppercase/letterspacing lives;
   everything else is sentence case per the exec light theme. */
.label,
.rail-heading,
.kpi-label,
.legend-title,
.modal-kicker,
.ps-label {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--muted);
}

/* ---------------- Top bar ---------------- */

.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  height: 56px;
  padding: 0 24px;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  flex: 0 0 auto;
}

/* Brand block carries a red swoosh-style accent (the deck's red mark on
   white) + the navy wordmark. SHRINK-PROTECTED (design-audit fix): the
   flex squeeze used to sacrifice the client's own brand name first
   ("KIRKWOOD RO…" at 1512, "K…" at 1280 — even 1920 clipped) while the
   project <select> kept its full width. The lockup now never shrinks;
   the flexible piece is the project select (min-width:0), and below
   each width step the lockup degrades WHOLE — full name ≥1360, short
   "KIRKWOOD" 1200–1359, the red swoosh mark alone <1200 — never a
   mid-word ellipsis. */
.brand {
  position: relative;
  padding-left: 16px;
  flex: 0 0 auto;
}

/* Swoosh-style mark: a skewed crimson stroke, echoing the logo's red
   swoosh on white. Pure decoration — never carries meaning. */
.brand::before {
  content: "";
  position: absolute;
  left: 2px;
  top: 5px;
  bottom: 5px;
  width: 5px;
  border-radius: 3px;
  background: linear-gradient(168deg, var(--brand-deep), var(--brand));
  transform: skewX(-14deg);
}

.wordmark {
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.12em;
  color: var(--heading);
  white-space: nowrap;
}

/* Brand lockup swap : the HTML carries both the full and the short
   lockup; wide layouts show the full name, and below the ≤1360px step the
   short lockup swaps in WHOLE — the brand name never ellipsizes mid-word
   (design finding: "KIRKWOOD R…" at the classic 1280 projector width). */
.wm-short { display: none; }

.subtitle {
  font-size: 11px;
  color: var(--muted);
  letter-spacing: 0.04em;
  margin-top: 1px;
  white-space: nowrap;
}

/* Laptop widths: tighten the lockup's tracking and the toolbar gaps so
   the full product name always renders when the run controls are up
   (at 1600px the flex squeeze clipped "KIRKWOOD ROUTE INTELLIGENCE"). */
@media (max-width: 1750px) {
  .topbar { gap: 12px; }
  .wordmark { font-size: 12.5px; letter-spacing: 0.07em; }
  .subtitle { font-size: 10.5px; }
  .controls { gap: 10px; }
  .run-controls { gap: 10px; }
}

/* The subtitle is the one deliberately-binary piece: FULL at wide desk
   widths, absent below — never an ellipsized fragment (design audit: it
   clipped to "Feasibility & route intellige…" even at 1920 while the
   shrink-protected controls kept full width). 1900px leaves room for the
   whole line beside the full toolbar. */
@media (max-width: 1899px) {
  .subtitle { display: none; }
}

.controls {
  display: flex;
  align-items: center;
  gap: 16px;
}

.mode-badge {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 4px 10px;
  white-space: nowrap;
  transition: color 120ms ease, border-color 120ms ease;
}

.mode-badge.live {
  color: var(--accent-ink);
  border-color: rgba(15, 158, 213, 0.45);
}

/* data-mode badge: cached/live real data vs synthetic demo layers */
.mode-badge.data.real {
  color: var(--ok);
  border-color: rgba(30, 123, 52, 0.45);
}

.mode-badge.data.live-fetch {
  color: var(--accent-ink);
  border-color: rgba(15, 158, 213, 0.45);
}

.mode-badge.data.synthetic {
  color: var(--warn);
  border-color: rgba(183, 120, 0, 0.4);
}

select#project-select {
  background: var(--surface-2);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 6px 10px;
  font: inherit;
  font-size: 12.5px;
  max-width: 340px;
}

select#project-select:focus { outline: 1px solid var(--accent); }

/* Auto-approve switch */
.toggle {
  display: flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
  user-select: none;
}

.toggle input { display: none; }

.toggle .track {
  width: 30px;
  height: 16px;
  border-radius: 999px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  position: relative;
  transition: background 120ms ease, border-color 120ms ease;
  flex: 0 0 auto;
}

.toggle .thumb {
  position: absolute;
  top: 2px;
  left: 2px;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--muted);
  transition: transform 120ms ease, background 120ms ease;
}

.toggle input:checked + .track { background: rgba(15, 158, 213, 0.20); border-color: var(--accent-ink); }
.toggle input:checked + .track .thumb { transform: translateX(14px); background: var(--accent); }

.toggle-text { font-size: 12px; color: var(--muted); }

/* Buttons */
.btn {
  font: inherit;
  font-size: 12.5px;
  font-weight: 600;
  border-radius: 8px;
  border: 1px solid var(--border);
  background: var(--surface-2);
  color: var(--text);
  padding: 7px 16px;
  cursor: pointer;
  transition: background 120ms ease, border-color 120ms ease, opacity 120ms ease;
}

.btn:hover:not(:disabled) { border-color: var(--muted); }
.btn:disabled { opacity: 0.45; cursor: not-allowed; }

/* Primary action = brand crimson */
.btn.primary {
  background: var(--brand);
  border-color: var(--brand);
  color: #FFFFFF;
}
.btn.primary:hover:not(:disabled) { background: var(--brand-deep); border-color: var(--brand-deep); }

.btn.danger {
  background: transparent;
  border-color: rgba(194, 43, 43, 0.45);
  color: var(--fail);
}
.btn.danger:hover:not(:disabled) { background: rgba(194, 43, 43, 0.07); }

.btn.ghost { background: transparent; color: var(--muted); }
.btn.small { padding: 3px 10px; font-size: 11px; }

/* ---------------- Shell / layout ---------------- */

.shell {
  display: flex;
  flex: 1 1 auto;
  min-height: 0;
}

/* ---------------- Left rail: pipeline tracker ---------------- */

/* Scoped to the <aside> so the rule can never leak onto map divIcons
   (the RR crossing chip once carried class "rail" and inherited this
   block's padding/overflow —  fix). */
aside.rail {
  flex: 0 0 280px;
  border-right: 1px solid var(--border);
  background: var(--surface);
  padding: 16px;
  overflow-y: auto;
}

.rail-heading { margin: 0 8px 8px; }

.rail-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.rail-item {
  display: grid;
  grid-template-columns: 16px 1fr auto;
  align-items: center;
  gap: 8px;
  padding: 8px;
  border-radius: 8px;
  font-size: 12.5px;
  color: var(--muted);
  transition: background 120ms ease, color 120ms ease;
}

.rail-item.running, .rail-item.done, .rail-item.warn { color: var(--text); }

.rail-item .dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  justify-self: center;
  background: transparent;
  border: 1.5px solid var(--border);
  transition: background 120ms ease, border-color 120ms ease;
}

.rail-item.running .dot {
  background: var(--accent);
  border-color: var(--accent-ink);
  animation: kfa-pulse 1.6s ease-in-out infinite;
}
.rail-item.done .dot { background: var(--ok); border-color: var(--ok); }
.rail-item.warn .dot { background: var(--warn); border-color: var(--warn); }

.rail-dur {
  font-size: 11px;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

/* Gate rows: amber diamond markers, visually distinct from stages */
.rail-item.gate .diamond {
  width: 8px;
  height: 8px;
  justify-self: center;
  transform: rotate(45deg);
  background: transparent;
  border: 1.5px solid rgba(183, 120, 0, 0.5);
  transition: background 120ms ease, border-color 120ms ease;
}

.rail-item.gate { color: var(--muted); }

.rail-item.gate.waiting {
  background: rgba(183, 120, 0, 0.06);
  color: var(--warn);
  cursor: pointer; /* click reopens a minimized gate card */
}
.rail-item.gate.waiting .diamond {
  background: var(--warn);
  border-color: var(--warn);
  animation: kfa-pulse 1.6s ease-in-out infinite;
}
.rail-item.gate.approved { color: var(--text); }
.rail-item.gate.approved .diamond { background: var(--ok); border-color: var(--ok); }
.rail-item.gate.rejected { color: var(--fail); }
.rail-item.gate.rejected .diamond { background: var(--fail); border-color: var(--fail); }

@keyframes kfa-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.4; }
}

/* ---------------- Main column ---------------- */

.main {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  padding: 16px 24px;
  gap: 14px;
  overflow: hidden;
}

/* Banners */
#banners { display: flex; flex-direction: column; gap: 8px; }
#banners:empty { display: none; }

.banner {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 16px;
  border-radius: 8px;
  border: 1px solid var(--border);
  background: var(--surface);
  font-size: 12.5px;
}

.banner .banner-text { flex: 1 1 auto; }
.banner .banner-dismiss {
  background: none;
  border: none;
  color: var(--muted);
  font-size: 14px;
  cursor: pointer;
  padding: 0 4px;
  line-height: 1;
}
.banner .banner-dismiss:hover { color: var(--text); }

.banner.success { border-color: rgba(30, 123, 52, 0.4); background: rgba(30, 123, 52, 0.07); }
.banner.warn { border-color: rgba(183, 120, 0, 0.35); background: rgba(183, 120, 0, 0.06); }
.banner.error { border-color: rgba(194, 43, 43, 0.35); background: rgba(194, 43, 43, 0.06); }

/* ---------------- KPI band: Vision-card layout  -------- */

.kpis {
  display: grid;
  grid-template-columns: repeat(8, minmax(0, 1fr));
  gap: 8px;
  flex: 0 0 auto;
}

@media (max-width: 1500px) {
  .kpis { grid-template-columns: repeat(4, 1fr); }
}

@media (max-width: 1000px) {
  .kpis { grid-template-columns: repeat(2, 1fr); }
}

.kpi {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 10px 16px;
  min-width: 0;
}

.kpi-value {
  /* Executive numerals: large and LIGHT-weight with tabular figures.
     Scale down with the viewport instead of ellipsizing — a clipped
     "15.2–23.…" range read as broken at 1600px. 1.15vw keeps the widest
     range strings inside an eight-up card in Details mode. */
  font-size: clamp(16px, 1.15vw, 24px);
  font-weight: 300;
  color: var(--heading);
  font-variant-numeric: tabular-nums;
  margin-top: 4px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Summary mode runs six-up — the numerals get the full executive size. */
body[data-runmode="summary"] .kpi-value {
  font-size: clamp(17px, 1.45vw, 27px);
}
body[data-runmode="summary"] .kpi-value.kpi-text { font-size: 13.5px; }

.kpi-value.kpi-text {
  font-size: 13.5px;
  font-weight: 500;
  line-height: 1.35;
  white-space: normal;
  min-height: 34px;
}

.kpi-value.kpi-text.clamp2 .v {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.kpi-value .unit {
  font-size: 11px;
  font-weight: 500;
  color: var(--muted);
  margin-left: 4px;
}

.kpi-sub {
  font-size: 11px;
  color: var(--muted);
  min-height: 16px;
  font-variant-numeric: tabular-nums;
  /* sub-lines carry decision-critical qualifiers (AACE class,
     at-risk flags) — wrap to two lines instead of ellipsizing them. */
  white-space: normal;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  line-height: 1.4;
  overflow: hidden;
}

.kpi-sub.warn-text { color: var(--warn); }
.kpi-value.fail-text { color: var(--fail); }

/* ---------------- Permissions stats strip  ------------- */

.permit-strip {
  display: flex;
  align-items: center;
  gap: 12px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 8px 16px;
  font-size: 12px;
  flex: 0 0 auto;
  min-width: 0;
}

/* Recommended-route chip rides the brand crimson (recommended-route highlight) */
.ps-route {
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 600;
  color: var(--brand);
  border: 1px solid rgba(178, 15, 49, 0.45);
  border-radius: 6px;
  padding: 1px 8px;
  white-space: nowrap;
  flex: 0 0 auto;
}

.ps-body {
  flex: 1 1 auto;
  min-width: 0;
  color: var(--muted);
  /* the stats block wraps to a second line instead of dropping
     its trailing stats (the gas-crossing count never rendered at 1366) */
  white-space: normal;
  font-variant-numeric: tabular-nums;
  line-height: 1.5;
}

.ps-body b {
  font-weight: 600;
  color: var(--text);
}

.ps-body.pending { font-style: italic; }

.ps-grade {
  flex: 0 0 auto;
  margin-left: auto;
  font-size: 11px;
  color: var(--muted);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 2px 10px;
  white-space: nowrap;
}

/* ---------------- Workspace: map + tabs ---------------- */

.workspace {
  display: flex;
  gap: 16px;
  flex: 1 1 auto;
  min-height: 0;
}

.map-pane {
  flex: 3 1 0;
  min-width: 0;
  position: relative;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  overflow: hidden;
  background: var(--surface);
}

#map { position: absolute; inset: 0; background: var(--bg); }

.leaflet-container { background: var(--bg); font-family: var(--font); }
.leaflet-container .leaflet-control-attribution {
  background: rgba(255, 255, 255, 0.88);
  color: var(--muted);
  font-size: 9px;
}
.leaflet-container .leaflet-control-attribution a { color: var(--muted); }
.leaflet-tooltip {
  background: var(--surface-2);
  border: 1px solid var(--border);
  color: var(--text);
  font-size: 11px;
  border-radius: 6px;
  box-shadow: none;
}
.leaflet-tooltip::before { display: none; }
.leaflet-bar a {
  background: var(--surface-2);
  color: var(--text);
  border-bottom-color: var(--border);
}
.leaflet-bar a:hover { background: var(--border); }

.map-note {
  position: absolute;
  top: 8px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 800;
  background: rgba(255, 255, 255, 0.94);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 4px 12px;
  font-size: 11px;
  color: var(--muted);
}

/* Layer visibility toggles (top-right overlay) */
.layer-toggles {
  position: absolute;
  top: 8px;
  right: 8px;
  z-index: 800;
  background: rgba(255, 255, 255, 0.94);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 8px 12px;
  font-size: 11px;
  color: var(--muted);
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.layer-toggles .legend-title { margin-bottom: 4px; }

.layer-toggles label {
  display: flex;
  align-items: center;
  gap: 6px;
  cursor: pointer;
  user-select: none;
  white-space: nowrap;
}

.layer-toggles label:hover { color: var(--text); }

.layer-toggles input[type="checkbox"] {
  width: 12px;
  height: 12px;
  margin: 0;
  accent-color: var(--accent-ink);
}

.lt-sep { border-top: 1px solid var(--border); margin: 4px 0; }
.lt-note { font-size: 9.5px; color: var(--muted); opacity: 0.8; }

.map-legend {
  position: absolute;
  /* bottom-RIGHT — the Leaflet zoom controls own the top-left and
     the legend must never stack under them at short map heights. */
  right: 8px;
  bottom: 8px;
  z-index: 800;
  background: rgba(255, 255, 255, 0.94);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 8px 12px;
  font-size: 11px;
  color: var(--muted);
  line-height: 1.8;
  max-width: 260px;
}

.legend-title { margin-bottom: 2px; }
.legend-sep { border-top: 1px solid var(--border); margin: 4px 0; }

.legend-row { display: flex; align-items: center; gap: 8px; }

.sw { flex: 0 0 auto; }

.sw.line { width: 18px; height: 0; }
/* Route hierarchy — the candidates dominate; the network is context */
.sw.solid-brand { border-top: 4px solid var(--brand); }
.sw.solid-steel { border-top: 3px solid var(--accent); }
.sw.dash-reject { border-top: 2px dashed var(--reject); }
.sw.solid-ctx { border-top: 2px solid var(--ctx-interstate); opacity: 0.6; }
.sw.dash-grey { border-top: 1.5px dashed var(--rail); }
.sw.dash-deep-orange { border-top: 1.5px dashed #B85F28; }
.sw.dash-orange { border-top: 2px dashed var(--orange); }
.sw.solid-river { border-top: 2.5px solid var(--river); }
.sw.dot-tint { border-top: 2px dotted var(--brand-tint); }

.sw.fill-wetland {
  width: 14px;
  height: 10px;
  background: rgba(25, 107, 36, 0.2);
  border: 1px solid rgba(25, 107, 36, 0.5);
  border-radius: 2px;
}

/* FEMA NFHL flood hazard zone swatch */
.sw.fill-flood {
  width: 14px;
  height: 10px;
  background: rgba(245, 158, 11, 0.14);
  border: 1px solid rgba(183, 120, 0, 0.35);
  border-radius: 2px;
}

.sw.ring {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  border: 2px solid var(--heading); /* navy ring reads on the white legend */
  margin: 0 4px;
}

.sw.xing {
  width: 12px;
  height: 12px;
  border-radius: 3px;
  border: 1px solid var(--warn);
  background: rgba(255, 255, 255, 0.95);
  margin: 0 3px;
}

/* Rejected-candidate marker in the legend: slate glyph (never red — the
   rejected comparator is a documented reference, not an error state) */
.legend-x {
  color: var(--reject);
  font-weight: 700;
}

.legend-rec { color: var(--brand); }

/* Crossing markers (recommended route, top lead-time items): divIcons */
.xing-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  border-radius: 4px;
  background: rgba(255, 255, 255, 0.95);
  border: 1.5px solid var(--warn);
  color: var(--warn);
  font-family: var(--mono);
  font-size: 7.5px;
  font-weight: 700;
  letter-spacing: 0.02em;
  overflow: hidden;
}

/* Modifier is "xrail" (not "rail") so it can never collide with the
   pipeline-sidebar rail rules above. */
.xing-icon.xrail { border-color: var(--slate-bright); color: var(--slate-bright); }
.xing-icon.gas { border-color: var(--orange); color: var(--orange-ink); }

/* ---------------- Tabs pane ---------------- */

.tabs-pane {
  flex: 2 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  position: relative; /* anchors the off-screen-columns chip below */
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  background: var(--surface);
  overflow: hidden;
}

/* Explicit off-screen-columns affordance (design-audit fix): macOS
   overlay scrollbars can render NOTHING at rest — the edge fade alone
   left execs unaware that Status/Miles sat off-screen. Whenever the
   active register pane has columns past its right edge (the same
   .overflow-right class the fades use), a floating chip names the
   interaction; it disappears once the pane is scrolled fully right. */
.tabs-pane:has(> .tab-panels > .panel.active.overflow-right)::after {
  content: "Scroll \2192  more columns";
  position: absolute;
  right: 10px;
  bottom: 10px;
  z-index: 7;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.05em;
  color: var(--slate-bright);
  background: rgba(255, 255, 255, 0.94);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 3px 10px;
  pointer-events: none;
  box-shadow: var(--shadow);
}

.tabbar {
  display: flex;
  /* Design-audit fix: at demo widths the 8-tab strip hid up to half its
     tabs behind a scrollbar-less 28px fade — easy to miss on a
     projector. Wrap to a second row instead; the fade affordance still
     covers any future horizontal overflow. */
  flex-wrap: wrap;
  border-bottom: 1px solid var(--border);
  flex: 0 0 auto;
  overflow-x: auto;
}

.tab {
  font: inherit;
  font-size: 13px;
  font-weight: 500;
  color: var(--muted);
  background: none;
  border: none;
  border-bottom: 2px solid transparent;
  padding: 8px 16px;
  cursor: pointer;
  white-space: nowrap;
  transition: color 120ms ease, border-color 120ms ease;
  position: relative;
}

.tab:hover { color: var(--text); }
.tab.active { color: var(--text); border-bottom-color: var(--brand); }

/* Unread indicator: small steel dot on tabs that received content */
.tab.unread::after {
  content: "";
  position: absolute;
  top: 8px;
  right: 6px;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--accent);
}

.tab-panels {
  position: relative;
  flex: 1 1 auto;
  min-height: 0;
}

.panel {
  display: none;
  position: absolute;
  inset: 0;
  overflow-y: auto;
  /* The PANEL is the horizontal scroll container for over-wide
     registers (sticky headers stay panel-scoped); edge fades below
     signal the hidden columns. */
  overflow-x: auto;
  padding: 16px;
  /* Any scrollbars inside the registers sit on-palette, never a bright
     classic band. NOTE (design-audit fix): scrollbar-color is an
     INHERITED property — the html-level rule below made Chromium IGNORE
     the ::-webkit-scrollbar rules here and fall back to macOS overlay
     scrollbars, i.e. NO visible affordance that decision-critical
     register columns sat off-screen. Resetting to auto re-enables the
     classic styled bar; Firefox gets the standard properties via the
     @supports block. */
  scrollbar-color: auto;
}

@supports not selector(::-webkit-scrollbar) {
  .panel { scrollbar-width: thin; scrollbar-color: #AEBBC8 var(--surface-2); }
}

/* -- register overflow affordance: edge fades only while columns are
      actually off-screen sideways (class toggled in tabs.init) -- */
.panel.overflow-left {
  -webkit-mask-image: linear-gradient(to right, transparent 0,
    #000 24px, #000 100%);
  mask-image: linear-gradient(to right, transparent 0, #000 24px, #000 100%);
}
.panel.overflow-right {
  -webkit-mask-image: linear-gradient(to right, #000 0,
    #000 calc(100% - 24px), transparent 100%);
  mask-image: linear-gradient(to right, #000 0, #000 calc(100% - 24px),
    transparent 100%);
}
.panel.overflow-left.overflow-right {
  -webkit-mask-image: linear-gradient(to right, transparent 0, #000 24px,
    #000 calc(100% - 24px), transparent 100%);
  mask-image: linear-gradient(to right, transparent 0, #000 24px,
    #000 calc(100% - 24px), transparent 100%);
}

/* Wide registers keep column shape and ride the panel's horizontal
   scroll instead of crushing every text column to a word per line;
   narrow tables (flood zones, package phases, RFS outlook) stay
   width:100% and simply fit. */
[data-reg-table] > table { min-width: 640px; }

/* The ROW and crossing registers carry long prose columns (corridor
   names, permit terms) — a wider floor keeps those columns readable
   instead of one word per line at the pane edge. */
#reg-row [data-reg-table] > table,
#reg-crossing [data-reg-table] > table { min-width: 780px; }

/* (design finding): the confirmed-route table's "Corridors used"
   column and the diversity table's tail column crushed to a character
   per line at 1512 — the same wide-register treatment as #reg-row now
   applies: a readable min-width floor, riding the panel's existing
   horizontal scroll + edge fades. (with the per-row interconnect
   chips lifted out of the Label column, the candidates table's floor
   drops to 640px — Status and Miles now sit inside the first ~450px.) */
.cands-table { min-width: 640px; }
.div-table { min-width: 720px; }
.cost-table { min-width: 560px; }
.risk-table { min-width: 620px; }
#scoring-table { min-width: 620px; }

/* -- sticky lead column (design-audit fix) --------------------------
   Every wide register keeps its identity column (Route / Rule) pinned
   while the panel scrolls sideways, so a row never loses its subject:
   an exec side-scrolling to Miles/Latency still sees WHICH candidate
   each value belongs to. left:-16px mirrors the sticky-header top:-16px
   convention (panels pad 16px; the cell pins at the pane edge). */
.cands-table th:first-child, .cands-table td:first-child,
.div-table th:first-child, .div-table td:first-child,
.cost-table th:first-child, .cost-table td:first-child,
.risk-table th:first-child, .risk-table td:first-child,
#scoring-table th:first-child, #scoring-table td:first-child,
[data-reg-table] > table th:first-child,
[data-reg-table] > table td:first-child {
  position: sticky;
  left: -16px;
  background: var(--surface);
  z-index: 2;
  /* hairline seam so columns sliding beneath read as intentional */
  box-shadow: inset -1px 0 0 var(--border);
}

/* Corner cells (sticky header row × sticky lead column) ride above both. */
.panel .cands-table th:first-child,
.panel .div-table th:first-child,
.panel .cost-table th:first-child,
.panel .risk-table th:first-child,
.panel #scoring-table th:first-child,
.panel [data-reg-table] > table th:first-child { z-index: 6; }

/* Pinned cells inherit row-hover tint so the column never looks detached. */
tr.clickable:hover td:first-child { background: var(--surface-2); }

/* Classic (always-rendered) scrollbars on the register panes: the thumb
   is a mid-slate so the horizontal bar reads as a real affordance —
   var(--border) was invisible against the white panel (design audit:
   execs never discovered the off-screen Status/Miles columns). */
.panel::-webkit-scrollbar { width: 9px; height: 9px; }
.panel::-webkit-scrollbar-thumb {
  background: #AEBBC8;
  border-radius: 5px;
  border: 2px solid var(--surface);
}
.panel::-webkit-scrollbar-thumb:hover { background: var(--slate-bright); }
.panel::-webkit-scrollbar-track { background: var(--surface-2); }

.panel.active { display: block; }

/* Register "Corridors used" cells: cap width so dozens of OSM segment
   names can never push the STATUS verdict off-screen; the full list
   rides in the hover title. */
td.corridors-cell { max-width: 240px; }

/* Long reference strings (policy refs) ellipsize with the full text in
   the hover title instead of widening the register. */
td.clip-cell {
  max-width: 130px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.empty-state {
  color: var(--muted);
  font-size: 12.5px;
  padding: 8px 0;
}

.panel-section { margin-bottom: 24px; }
.panel-section > .label { margin-bottom: 8px; }

/* Activity feed */
.activity-feed { font-family: var(--mono); font-size: 12px; }

.log-line {
  display: flex;
  gap: 8px;
  padding: 2px 0;
  align-items: baseline;
}

.log-stage {
  flex: 0 0 96px;
  color: var(--accent-ink);
  font-size: 10px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  text-align: right;
  opacity: 0.85;
}

.log-text { color: var(--text); white-space: pre-wrap; word-break: break-word; }

.log-line.marker .log-text { color: var(--muted); }
.log-line.marker .log-stage { color: var(--muted); }

/* Tables */
table {
  width: 100%;
  border-collapse: collapse;
  font-size: 12.5px;
}

th {
  text-align: left;
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--muted);
  padding: 6px 8px;
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}

/* Register tables scroll under sticky headers (register UX).
   Headers may wrap to two lines here: pinning a column to its longest
   header word ("Contribution $M-eq", "Crossing adders") is what pushed
   registers past the pane edge at laptop widths. */
.panel table th,
.view-screen table th {
  position: sticky;
  top: -16px; /* panels pad 16px; headers pin to the pane edge */
  background: var(--surface);
  z-index: 5;
  box-shadow: 0 1px 0 var(--border);
  white-space: normal;
}

/* pin at the SCROLL CONTAINER's true edge (the view pads 20px —
   same convention as the panels' -16px). With top:0 the header stuck
   20px below the visible edge and previous rows painted above it,
   reading as a rendering glitch mid-scroll. */
.view-screen table th { top: -20px; }

td {
  padding: 6px 8px;
  border-bottom: 1px solid var(--border);
  vertical-align: top;
  font-variant-numeric: tabular-nums;
}

td.num, th.num { text-align: right; }
td.mono { font-family: var(--mono); font-size: 11.5px; white-space: nowrap; }

tr.clickable { cursor: pointer; transition: background 120ms ease; }
tr.clickable:hover { background: var(--surface-2); }

/* ---------------- Register filter bar (register UX) ----------------
   Candidate chips + type select + text search + row count, above the
   200-plus-row ROW / crossing / schedule registers. */

.filter-bar {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
  margin: 4px 0 8px;
}

.filter-chips { display: flex; gap: 4px; flex-wrap: wrap; }

.f-chip {
  font: inherit;
  font-size: 10.5px;
  font-weight: 600;
  font-family: var(--mono);
  color: var(--muted);
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 2px 10px;
  cursor: pointer;
  transition: color 120ms ease, border-color 120ms ease;
}

.f-chip:hover { color: var(--text); border-color: var(--muted); }

.f-chip.active {
  color: var(--text);
  border-color: var(--accent-ink);
  background: rgba(15, 158, 213, 0.10);
}

.filter-bar select {
  background: var(--bg);
  color: var(--text-2);
  border: 1px solid var(--border);
  border-radius: 6px;
  font: inherit;
  font-size: 11px;
  padding: 2px 6px;
  max-width: 180px;
}

.filter-bar input[type="search"] {
  background: var(--bg);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 6px;
  font: inherit;
  font-size: 11px;
  padding: 3px 8px;
  width: 160px;
}

.filter-bar input[type="search"]:focus,
.filter-bar select:focus { outline: 1px solid var(--accent); }

.filter-count {
  margin-left: auto;
  font-size: 10.5px;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* Status pills */
.pill {
  display: inline-block;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 2px 8px;
  border-radius: 999px;
  border: 1px solid;
  white-space: nowrap;
  transition: color 120ms ease, border-color 120ms ease;
}

.pill.ok { color: #1E7B34; border-color: rgba(30, 123, 52, 0.5); }
.pill.warn { color: var(--warn); border-color: rgba(183, 120, 0, 0.4); }
.pill.fail { color: var(--fail); border-color: rgba(194, 43, 43, 0.4); }
.pill.accent { color: var(--accent-ink); border-color: rgba(15, 158, 213, 0.45); }
.pill.violet { color: var(--slate-bright); border-color: rgba(94, 113, 134, 0.45); }
.pill.orange { color: var(--orange-ink); border-color: rgba(233, 113, 50, 0.45); }
.pill.neutral { color: var(--muted); border-color: var(--border); }
/* Brand pill: the recommended route only (identity, not a status verdict) */
.pill.brand { color: var(--brand); border-color: rgba(178, 15, 49, 0.45); }
/* Rejected comparator: slate + dashed, echoing the map treatment (never
   red). Text ink is --slate-bright (5.02:1 — the map slate #7A8B9C is
   only 3.50:1 at pill size, a WCAG AA fail); the dashed #7A8B9C border
   keeps the visual tie to the slate route. */
.pill.rejected { color: var(--slate-bright); border-color: rgba(122, 139, 156, 0.8); border-style: dashed; }

/* Rejection reasons under a candidate's status pill */
.reject-reasons {
  font-size: 11px;
  color: var(--muted);
  margin-top: 4px;
  line-height: 1.5;
}

/* Permissions headline rows (Crossings & Permits tab, shape) */
.perm-headline {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 6px 10px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 8px;
  margin-bottom: 6px;
  font-size: 12px;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

.perm-headline b { font-weight: 600; color: var(--text); }

.ph-route {
  flex: 0 0 auto;
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 600;
  color: var(--accent-ink);
}

/* Bore/plow construction-mix bar (Budgetary Cost Estimate table) */
.mix-bar {
  display: flex;
  width: 110px;
  height: 8px;
  border-radius: 4px;
  overflow: hidden;
  background: var(--surface-2);
  border: 1px solid var(--border);
}

.mix-bore { background: var(--accent); display: block; height: 100%; }
.mix-plow { background: var(--slate-bright); display: block; height: 100%; }

.mix-text {
  font-size: 10.5px;
  color: var(--muted);
  margin-top: 2px;
  white-space: nowrap;
}

/* Budgetary column: mid figure with low–high band beneath */
.cost-mid { font-weight: 600; }
.cost-band { font-size: 10.5px; color: var(--muted); }

/* Known-unknowns register (feasibility-grade honesty) */
ul.unknowns {
  margin: 8px 0;
  padding-left: 24px;
}
ul.unknowns li { margin: 2px 0; }

/* Key figures grid (RIP input card roll-up, scoring weights) */
.figure-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
  gap: 8px;
  margin-bottom: 16px;
}

.figure {
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 8px 12px;
}

.figure .f-label {
  font-size: 10px;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--muted);
}

.figure .f-value {
  font-size: 15px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  margin-top: 2px;
}

/* ---------------- acquisition cards (Project & Data tab) -------------- */
.acq-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: 8px;
  margin-bottom: 8px;
}

.acq-card {
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 8px 12px;
  min-width: 0;
}

.acq-card.is-fallback {
  border-color: rgba(183, 120, 0, 0.3);
}

.acq-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
}

.acq-name {
  font-size: 12px;
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.acq-badge {
  flex: none;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.08em;
  border-radius: 999px;
  border: 1px solid var(--border);
  padding: 2px 7px;
  white-space: nowrap;
}

.acq-badge.real { color: #1E7B34; border-color: rgba(30, 123, 52, 0.5); }
/* Fallback badge sits on the --surface-2 inset acquisition cards: the
   9px/700wt text needs the deeper warn ink there (#A06800 was 4.25:1 on
   #F1F4F8 — AA fail; #8F5D00 is 5.10:1). */
.acq-badge.fallback { color: #8F5D00; border-color: rgba(183, 120, 0, 0.4); }
.acq-badge.synthetic { color: var(--muted); }

.acq-src {
  font-size: 11px;
  color: var(--text);
  margin-top: 5px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.acq-meta {
  display: flex;
  gap: 10px;
  font-size: 11px;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  margin-top: 3px;
}

.acq-license {
  font-size: 10px;
  color: var(--muted);
  margin-top: 3px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Verification counts row */
.check-counts { display: flex; gap: 8px; margin-bottom: 16px; }

.ledger-note { font-size: 11px; color: var(--muted); margin-top: 8px; }

/* Provenance drawer */
.drawer {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: 320px;
  max-width: 85%;
  background: var(--surface-2);
  border-left: 1px solid var(--border);
  transform: translateX(100%);
  transition: transform 120ms ease;
  z-index: 20;
  display: flex;
  flex-direction: column;
}

.drawer.open { transform: translateX(0); }

.drawer-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 16px;
  border-bottom: 1px solid var(--border);
  flex: 0 0 auto;
}

.drawer-title {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--muted);
}

.drawer-body { padding: 16px; overflow-y: auto; font-size: 12.5px; }

.prov-entry {
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 8px 12px;
  margin-bottom: 8px;
  background: var(--surface);
}

.prov-entry .p-id { font-family: var(--mono); font-size: 10.5px; color: var(--accent-ink); }
.prov-entry .p-label { font-weight: 600; margin: 2px 0; }
.prov-entry .p-value { font-variant-numeric: tabular-nums; }
.prov-entry .p-meta { font-size: 11px; color: var(--muted); margin-top: 4px; }

.drawer-check-detail { color: var(--muted); font-size: 12px; margin-bottom: 16px; }

/* Feasibility Study tab */
.doc-toolbar {
  display: flex;
  justify-content: flex-end;
  margin-bottom: 8px;
}

a.download-link {
  font-size: 12px;
  font-weight: 600;
  color: var(--accent-ink);
  text-decoration: none;
  border: 1px solid rgba(15, 158, 213, 0.45);
  border-radius: 8px;
  padding: 4px 12px;
  transition: background 120ms ease;
}

a.download-link:hover { background: rgba(15, 158, 213, 0.1); }

.md-body h1 { font-size: 18px; margin: 16px 0 8px; }
.md-body h2 { font-size: 15px; margin: 16px 0 8px; }
.md-body h3 { font-size: 13px; margin: 16px 0 4px; color: var(--muted); text-transform: uppercase; letter-spacing: 0.05em; }
.md-body p { margin: 8px 0; }
.md-body ul { margin: 8px 0; padding-left: 24px; }
.md-body li { margin: 2px 0; }
.md-body hr { border: none; border-top: 1px solid var(--border); margin: 16px 0; }
.md-body table { margin: 0; }

/* Long unbroken tokens (artifact paths, corridor refs) wrap instead of
   pushing the prose column past the pane edge. */
.md-body { overflow-wrap: break-word; }

/* Wide study tables (data-layer basis, corridor lists) scroll inside
   their own wrapper — the prose column never widens or bleeds. */
.md-table-wrap {
  margin: 8px 0 16px;
  max-width: 100%;
  overflow-x: auto;
  scrollbar-color: var(--border) transparent;
}

.md-body strong { font-weight: 600; }

/* ---------------- Deliverables tab ---------------- */

/* section A5 study tiering: Snapshot / Full feasibility package /
   GIS & field / Data group sections. Light-theme surfaces only; the
   available-count chip goes calm pass-green once the whole group has
   landed (semantic state, never brand crimson). */
.dgroup { margin: 14px 0 0; }
.dgroup:first-of-type { margin-top: 8px; }

.dgroup-head {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin: 0 2px 6px;
}

.dgroup-title {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--heading);
  white-space: nowrap;
}

.dgroup-sub {
  flex: 1 1 auto;
  min-width: 0;
  font-size: 11px;
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.dgroup-count {
  flex: 0 0 auto;
  font-family: var(--mono);
  font-size: 10px;
  font-variant-numeric: tabular-nums;
  color: var(--muted);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 1px 8px;
  background: var(--surface-2);
  white-space: nowrap;
}

.dgroup-count.all {
  color: var(--ok);
  border-color: rgba(30, 123, 52, 0.35);
  background: rgba(30, 123, 52, 0.06);
}

.deliverable-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.deliverable-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 12px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 8px;
  transition: opacity 120ms ease, border-color 120ms ease;
}

.deliverable-row.unavailable { opacity: 0.45; }

.fmt-badge {
  flex: 0 0 44px;
  text-align: center;
  font-family: var(--mono);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.06em;
  color: var(--accent-ink);
  border: 1px solid rgba(15, 158, 213, 0.45);
  border-radius: 6px;
  padding: 3px 0;
}

.deliverable-row.unavailable .fmt-badge {
  color: var(--muted);
  border-color: var(--border);
}

.d-info { flex: 1 1 auto; min-width: 0; }
.d-name { font-size: 12.5px; font-weight: 600; }
.d-desc {
  font-size: 11px;
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.d-after {
  flex: 0 0 auto;
  font-size: 11px;
  color: var(--muted);
  white-space: nowrap;
}

.dl-btn {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border: 1px solid rgba(15, 158, 213, 0.45);
  border-radius: 8px;
  color: var(--accent-ink);
  text-decoration: none;
  transition: background 120ms ease;
}

.dl-btn:hover { background: rgba(15, 158, 213, 0.1); }

/* Banner action button (anchor styled as .btn) */
a.btn { text-decoration: none; display: inline-block; }
.banner .banner-action { flex: 0 0 auto; white-space: nowrap; }

/* ---------------- Gate modal ---------------- */

.overlay {
  position: fixed;
  inset: 0;
  background: rgba(14, 40, 65, 0.38);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
}

/* compositor workaround (design finding, verified at 1280 & 1512):
   parts of the tabs pane (tab row, register headings, panel text) paint
   ABOVE the modal scrim — a Chromium compositing artifact the reviewer
   isolated to .tabs-pane after A/B-eliminating the mask fades, the
   view-in animation, overlay promotion, isolation and rounded-clip.
   Belt-and-braces renderer fix: while any scrim overlay (gate / wizard /
   provenance) or the coach is open, the overlayDim module (app.js) sets
   body.overlay-open and the pane content is hidden outright — the scrim
   then dims that region uniformly. The gate's "view the full register"
   flow already minimizes the modal before showing the register, so
   nothing legitimate is lost; layout is preserved (visibility, not
   display). */
body.overlay-open .tabs-pane { visibility: hidden; }

.modal {
  width: 560px;
  max-width: calc(100vw - 48px);
  max-height: calc(100vh - 96px);
  overflow-y: auto;
  background: var(--surface);
  border: 1px solid var(--border);
  border-top: 3px solid var(--brand);
  border-radius: var(--radius);
  box-shadow: 0 16px 48px rgba(11, 27, 43, 0.16);
  padding: 24px;
}

.modal-kicker { color: var(--warn); margin-bottom: 8px; }

.modal-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
}

/* Minimized-gate chip: bottom-right, amber — the run is waiting on a human. */
.gate-chip {
  position: fixed;
  right: 20px;
  bottom: 44px;
  z-index: 1001;
  background: var(--surface-2);
  border: 1px solid var(--warn);
  color: var(--warn);
  border-radius: 999px;
  padding: 8px 16px;
  font: inherit;
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
  box-shadow: 0 6px 24px rgba(11, 27, 43, 0.14);
  animation: chip-pulse 1.6s ease-in-out infinite;
}

.gate-chip:hover { background: rgba(183, 120, 0, 0.08); }

.gate-chip.hidden { display: none; }

@keyframes chip-pulse {
  0%, 100% { box-shadow: 0 6px 24px rgba(11, 27, 43, 0.14), 0 0 0 0 rgba(183, 120, 0, 0.3); }
  50% { box-shadow: 0 6px 24px rgba(11, 27, 43, 0.14), 0 0 0 6px rgba(183, 120, 0, 0); }
}

.modal h2 { margin: 0 0 16px; font-size: 18px; font-weight: 600; color: var(--heading); }

.gate-summary table { margin-bottom: 8px; }
.gate-summary .kv-key {
  color: var(--muted);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  white-space: nowrap;
}

/* Gate-summary sub-tables live in a modal, not a scroll pane */
.gate-summary th { position: static; box-shadow: none; }

.gate-section-label {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 12px 0 4px;
}

.gate-question {
  margin: 16px 0 8px;
  font-weight: 600;
  font-size: 13.5px;
}

#gate-note {
  width: 100%;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 8px;
  color: var(--text);
  font: inherit;
  font-size: 12.5px;
  padding: 8px;
  resize: vertical;
  margin-bottom: 16px;
}

#gate-note:focus { outline: 1px solid var(--accent); }

.modal-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
}

/* Client governance principle beneath the gate actions  */
.gate-governance {
  margin-top: 16px;
  padding-top: 8px;
  border-top: 1px solid var(--border);
  font-size: 11px;
  font-style: italic;
  color: var(--muted);
  text-align: center;
  letter-spacing: 0.02em;
}

/* ---------------- Footer ---------------- */

.footer {
  flex: 0 0 auto;
  padding: 8px 24px;
  font-size: 11px;
  color: var(--muted);
  letter-spacing: 0.03em;
  border-top: 1px solid var(--border);
  background: var(--surface);
}

/* the client's investment-thesis value loop, echoed above the
   legal line (attributed style, no emoji). Quiet in the light theme. */
.footer-loop {
  font-weight: 500;
  color: var(--text-2);
  letter-spacing: 0.02em;
}

/* Subtle scrollbars — scrollbar-color inherits, so the html rule keeps
   every scroll container on-palette in standards-mode browsers too. */
html { scrollbar-color: var(--border) transparent; }
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--border); border-radius: 5px; }
::-webkit-scrollbar-thumb:hover { background: #C3CEDA; }

/* ============================================================
   / EXEC-DECK SURFACES: workflow ribbon (the deck's
   Discover - Screen - Underwrite - Deliver - Learn), Corridors
   screening view w/ Leaflet schematic, Executive portfolio view,
   Ask drawer, run-view underwriting/BOQ/opex/risk additions,
   presenter mode. Same token set; tabular numerals throughout.
   ============================================================ */

/* ---------------- workflow ribbon (topbar nav) ----------------
   The client's operating workflow IS the navigation. Active step =
   crimson; a run in flight pins a pulsing steel dot to its step. */

.ribbon {
  display: flex;
  align-items: stretch;
  gap: 2px;
  padding: 2px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--bg);
}

/* Workflow steps read as calm sentence-case words; the crimson
   underline (below) marks the active step. */
.ribbon-btn {
  position: relative;
  font: inherit;
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: 0.01em;
  color: var(--muted);
  background: transparent;
  border: none;
  border-radius: 6px;
  padding: 5px 14px 7px;
  cursor: pointer;
  transition: color 120ms ease, background 120ms ease;
}

.ribbon-btn:hover { color: var(--heading); }

.ribbon-btn.active {
  color: var(--heading);
  background: var(--surface);
  box-shadow: var(--shadow);
}

/* Crimson underline marks the active workflow step (brand = active nav) */
.ribbon-btn.active::after {
  content: "";
  position: absolute;
  left: 12px;
  right: 12px;
  bottom: 3px;
  height: 2px;
  border-radius: 1px;
  background: var(--brand);
}

/* A live pipeline pins a pulsing steel dot to the step it is executing */
.ribbon-btn.running::before {
  content: "";
  position: absolute;
  top: 5px;
  right: 5px;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--accent);
  animation: kfa-pulse 1.6s ease-in-out infinite;
}

/* Run controls only apply to the Underwrite/Deliver (run) surface.
   min-width:0 lets the group compress via its elastic project select —
   without it the flex min-content floor kept the whole group at full
   width and the Run button clipped past the viewport once the brand
   lockup became shrink-protected (design-audit fix). */
.run-controls { display: flex; align-items: center; gap: 16px; min-width: 0; }
body[data-view="corridors"] .run-controls,
body[data-view="executive"] .run-controls { display: none; }

/* ---------------- full-screen views ---------------- */

.view-screen {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  padding: 20px 28px 32px;
}

.view-inner {
  max-width: 1360px;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.view-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 16px;
}

/* Section headings: navy semibold, sentence case, roomier */
.view-title {
  font-size: 23px;
  font-weight: 600;
  letter-spacing: 0;
  color: var(--heading);
  margin-top: 2px;
}

/* Views carry a short brand accent rule under the heading block — the
   deck's red section-rule motif. */
.view-head > div:first-child { position: relative; padding-bottom: 10px; }
.view-head > div:first-child::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  width: 44px;
  height: 3px;
  border-radius: 2px;
  background: var(--brand);
}

.view-head-right {
  display: flex;
  align-items: center;
  gap: 8px;
  padding-bottom: 2px;
}

.screening-label {
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  /* palette discipline: these are descriptive provenance/scope
     labels, not cautions — muted slate outline pills so --warn amber
     stays reserved for genuine state (AT RISK, WARN checks, SFHA,
     the gate-awaiting chip and the Human Approval Gate kicker). */
  color: var(--muted);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 3px 10px;
  white-space: nowrap;
}

.panel-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 20px;
  margin-bottom: 16px;
  min-width: 0;
}

.panel-card > .label { margin-bottom: 8px; }

.sub-line {
  font-size: 11px;
  color: var(--muted);
  margin-top: 2px;
  font-variant-numeric: tabular-nums;
}

.method-note { font-size: 11px; }

/* ---------------- Corridors view (Discover / Screen) ---------------- */

/* The ranked register needs a little more room than the schematic —
   5/6 split (was 6/6) so the table's action column stays on-screen. */
.corridors-grid {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
  gap: 16px;
  align-items: start;
}

/* Below ~1360 the two-up grid cannot hold the ranked register without
   bleeding past the viewport edge — stack map over table instead. */
@media (max-width: 1359px) {
  .corridors-grid { grid-template-columns: 1fr; }
}

/* Leaflet corridor schematic (replaces the old abstract SVG chart) */
#corridors-map {
  width: 100%;
  height: 480px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 8px;
  z-index: 0;
}

/* Node markers by exec-deck class (divIcons) */
.cor-node-icon { background: transparent; border: none; }

.cor-node-dot {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  border: 2px solid #FFFFFF;
  background: var(--bg);
}

.cor-node-dot.growth { background: var(--brand); border-color: #FFFFFF; }
.cor-node-dot.demand { background: var(--accent); border-color: #FFFFFF; }
.cor-node-dot.emerging { background: var(--bg); border-color: var(--slate-bright); }

.cor-node-label {
  background: rgba(255, 255, 255, 0.92);
  border: 1px solid var(--border);
  color: var(--text-2);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.04em;
  padding: 0 5px;
  border-radius: 4px;
  box-shadow: none;
}

/* Design-audit declutter: labels hidden by the low-zoom collision pass
   (corridorsView.declutterLabels) — hover tooltips still name nodes. */
.cor-node-label.cor-label-hidden { display: none; }

/* Node-class legend under the schematic */
.node-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  margin-top: 8px;
  font-size: 10.5px;
  color: var(--muted);
}

.node-key { display: inline-flex; align-items: center; gap: 6px; }

.node-key .dot-sw {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  border: 2px solid var(--border); /* hairline halo on the white card */
  flex: 0 0 auto;
}

.node-key .dot-sw.growth { background: var(--brand); }
.node-key .dot-sw.demand { background: var(--accent); }
.node-key .dot-sw.emerging { background: var(--bg); border-color: var(--slate-bright); }

.node-key .line-sw {
  width: 18px;
  height: 0;
  flex: 0 0 auto;
}

tr.selected-row { background: var(--surface-2); }

/* Ranked-corridor register: compact paddings + stacked action buttons
   so the full row (rank → actions) fits its grid column at ≥1280. */
.rank-table th,
.rank-table td { padding: 6px; }

.rank-table td:last-child .btn {
  display: block;
  width: max-content;
  margin: 0 0 4px;
}

.rank-table .pri-cell { min-width: 96px; }

/* Priority cell: number + proportional bar (tabular numerals) */
.pri-cell {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 110px;
}

.pri-num {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  min-width: 34px;
  text-align: right;
}

.pri-bar {
  flex: 1 1 auto;
  height: 5px;
  border-radius: 3px;
  background: var(--surface-2);
  overflow: hidden;
}

.pri-bar > span { display: block; height: 100%; border-radius: 3px; }

/* Subscore chips (demand / gap / deliv / returns). In the ranked
   register the four chips stack 2×2 (compact variant) — a single
   nowrap chip row was the column that pushed SIGNALS and the action
   buttons past the right viewport edge at 1280–1680. The drill panel
   (.drill-subs) keeps the one-row flex layout. */
.ss-chips { white-space: nowrap; }

td.ss-chips { white-space: normal; min-width: 158px; }

td.ss-chips .ss-chip {
  width: calc(50% - 4px);
  max-width: 150px; /* single-column layouts: chips stay chip-sized */
  justify-content: space-between;
  margin: 0 2px 3px 0;
  box-sizing: border-box;
}

.ss-chip {
  display: inline-flex;
  align-items: baseline;
  gap: 4px;
  font-size: 10.5px;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 1px 6px;
  margin-right: 4px;
  background: var(--bg);
}

.ss-chip .ss-k {
  font-weight: 500;
  font-size: 9.5px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--muted);
}

/* New Opportunity Alert card (Vision format) — brand crimson accent */
.alert-card {
  background: var(--surface);
  border: 1px solid rgba(178, 15, 49, 0.25);
  border-left: 3px solid var(--brand);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 20px;
  margin-bottom: 16px;
}

.alert-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}

.alert-kicker {
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--brand);
}

.alert-score {
  font-size: 13px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 2px 12px;
  background: var(--bg);
}

.alert-title {
  font-size: 17px;
  font-weight: 600;
  color: var(--heading);
  margin: 8px 0;
}

.alert-reasons { margin: 8px 0; padding-left: 18px; }
.alert-reasons li { margin-bottom: 4px; font-size: 12.5px; }

.reason-cites { margin-left: 6px; }

.alert-signals { margin: 4px 0 8px; padding-left: 18px; }
.alert-signals li { margin-bottom: 4px; font-size: 12px; }

.alert-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px solid var(--border);
}

.alert-actions { display: flex; gap: 8px; }

/* Signal / source citation chips + links */
.sig-chip {
  display: inline-block;
  font-family: var(--mono);
  font-size: 9.5px;
  color: var(--muted);
  border: 1px solid var(--border);
  border-radius: 5px;
  padding: 0 5px;
  margin-right: 3px;
  text-decoration: none;
  vertical-align: baseline;
}

.sig-chip.linked { color: var(--accent-ink); border-color: rgba(15, 158, 213, 0.4); }
.sig-chip.linked:hover { border-color: var(--accent-ink); }

.src-link { color: var(--accent-ink); text-decoration: none; }
.src-link:hover { text-decoration: underline; }

.drill-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 8px;
}

.drill-title { font-size: 15px; font-weight: 600; color: var(--heading); margin-top: 2px; }

.drill-subs { display: flex; flex-wrap: wrap; gap: 4px; margin: 6px 0 10px; }

/* ---------------- Executive view (Learn) ---------------- */

.exec-rollups {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 8px;
  margin-bottom: 16px;
}

@media (max-width: 1100px) {
  .exec-rollups { grid-template-columns: repeat(2, 1fr); }
}

.exec-rollups .figure {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 10px 16px;
}

.exec-rollups .f-value {
  font-size: 24px;
  font-weight: 300; /* executive numerals: large, light, tabular */
  color: var(--heading);
  font-variant-numeric: tabular-nums;
}

.unit-sub { font-size: 11px; font-weight: 500; color: var(--muted); }

.exec-cards {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 16px;
  align-items: start;
}

@media (max-width: 1200px) {
  .exec-cards { grid-template-columns: 1fr; }
}

.sparkline {
  width: 100%;
  height: auto;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 8px;
}

.spark-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 8px;
  font-size: 11px;
  font-variant-numeric: tabular-nums;
}

.spark-key { display: inline-flex; align-items: center; gap: 6px; }
.spark-key .sw.line { width: 18px; display: inline-block; }
.spark-key.muted { color: var(--muted); }

/* Easements dashboard tiles (F2 states) */
.ease-tiles {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 8px;
  margin-bottom: 8px;
}

.ease-tile {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 8px 4px;
  text-align: center;
}

.ease-tile.risk { border-color: rgba(194, 43, 43, 0.45); }
.ease-tile.risk .ease-n { color: var(--fail); }

.ease-n {
  font-size: 19px;
  font-weight: 300;
  color: var(--heading);
  font-variant-numeric: tabular-nums;
}

.ease-k {
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
  margin-top: 2px;
}

/* ---------------- run-view  additions ---------------- */

.uw-grid {
  display: grid;
  /* auto-fit so the grid drops to 3-across inside the ~520px tabs
     pane — dollar values must never clip to "−$1…" (client-visible). */
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 8px;
  margin-bottom: 8px;
}

.uw-metric {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 8px 12px;
  min-width: 0;
}

.uw-metric .f-value {
  font-size: 15px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  margin-top: 2px;
  white-space: nowrap;
  /* money figures are short (−$19.6M) — never ellipsize them;
     the auto-fit grid guarantees the 150px floor. */
  overflow: visible;
}

.uw-metric.primary { border-color: rgba(15, 158, 213, 0.5); }
.uw-metric.primary .f-value { color: var(--accent-ink); }

.uw-metric .f-label {
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--muted);
}

/* figure_id chips (provenance click-through) */
.fig-chip {
  font-family: var(--mono);
  font-size: 9.5px;
  color: var(--accent-ink);
  background: transparent;
  border: 1px solid rgba(15, 158, 213, 0.35);
  border-radius: 5px;
  padding: 0 5px;
  cursor: pointer;
  white-space: nowrap;
}

.fig-chip:hover { border-color: var(--accent-ink); }

.warn-li { color: var(--warn); }

/* ---------------- Ask drawer (section D) ---------------- */


.ask-launch:hover:not(:disabled) { background: rgba(15, 158, 213, 0.1); }
.ask-launch:disabled { opacity: 0.4; cursor: not-allowed; }

.ask-drawer {
  position: fixed;
  top: 56px;
  right: 0;
  bottom: 0;
  width: 460px;
  max-width: 92vw;
  background: var(--surface);
  border-left: 1px solid var(--border);
  box-shadow: -12px 0 32px rgba(11, 27, 43, 0.12);
  transform: translateX(100%);
  transition: transform 180ms ease;
  z-index: 60;
  display: flex;
  flex-direction: column;
  padding: 16px;
  gap: 8px;
}

.ask-drawer.open { transform: translateX(0); }

.ask-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 8px;
}

.ask-run { font-family: var(--mono); font-size: 11px; color: var(--muted); margin-top: 2px; }

.ask-verbs { display: flex; gap: 6px; }

.verb-chip {
  font: inherit;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--muted);
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 3px 12px;
  cursor: pointer;
}

.verb-chip.active { color: var(--accent-ink); border-color: rgba(15, 158, 213, 0.5); }
.verb-chip:disabled { opacity: 0.4; cursor: not-allowed; }
.verb-chip.static { cursor: default; font-size: 9.5px; padding: 1px 8px; margin-right: 6px; }

.ask-note { font-size: 11.5px; color: var(--muted); }

.ask-chips { display: flex; flex-wrap: wrap; gap: 6px; }

.ask-chip {
  font: inherit;
  font-size: 11.5px;
  color: var(--text);
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 4px 10px;
  cursor: pointer;
  text-align: left;
  transition: border-color 120ms ease;
}

.ask-chip:hover { border-color: var(--accent-ink); }

.ask-form { display: flex; gap: 8px; align-items: flex-end; }

.ask-form textarea {
  flex: 1 1 auto;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 8px;
  color: var(--text);
  font: inherit;
  font-size: 12.5px;
  padding: 8px;
  resize: vertical;
}

.ask-form textarea:focus { outline: 1px solid var(--accent); }

.ask-thread {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.qa-card {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 8px 12px;
}

.qa-q { font-weight: 600; font-size: 12.5px; margin-bottom: 6px; }

.qa-a {
  font-size: 12.5px;
  white-space: pre-wrap;
  word-break: break-word;
  font-variant-numeric: tabular-nums;
}

.qa-meta { margin-top: 6px; }

.qa-cites { margin-left: 8px; display: inline-flex; flex-wrap: wrap; gap: 4px; }

.guard-badge {
  display: inline-block;
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  border-radius: 999px;
  border: 1px solid;
  padding: 1px 8px;
  font-variant-numeric: tabular-nums;
}

.guard-badge.ok { color: #1E7B34; border-color: rgba(30, 123, 52, 0.5); }
.guard-badge.fail { color: var(--fail); border-color: rgba(194, 43, 43, 0.45); }

.guard-flags { margin: 6px 0 0; padding-left: 18px; font-size: 11.5px; }
.guard-flags code { font-family: var(--mono); font-size: 10.5px; }

mark.flag-token {
  background: rgba(194, 43, 43, 0.14);
  color: var(--fail);
  border-radius: 3px;
  padding: 0 2px;
}

.ask-guard-note {
  font-size: 10.5px;
  color: var(--muted);
  border-top: 1px solid var(--border);
  padding-top: 8px;
}

.draft-json {
  font-family: var(--mono);
  font-size: 10.5px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 8px;
  overflow-x: auto;
  max-height: 260px;
  overflow-y: auto;
  margin: 8px 0;
}

/* F3/G2 — Kirkwood data imports card (Deliverables-style rows) */
.import-row { margin-bottom: 8px; justify-content: space-between; }
.import-row > div:first-child { min-width: 0; }
.import-pick { flex: 0 0 auto; cursor: pointer; }
.import-report { word-break: break-word; }
.import-report .pill { margin-right: 6px; }

/* ---------------- Presenter mode (?presenter=1) ----------------
   Step-through overlay of the DEMO_SCRIPT beats: bottom-center card,
   arrow keys advance, ESC exits. Never blocks the surface behind it. */

.presenter {
  position: fixed;
  left: 50%;
  bottom: 40px;
  transform: translateX(-50%);
  z-index: 1200;
  width: 760px;
  max-width: calc(100vw - 48px);
  background: rgba(255, 255, 255, 0.97);
  border: 1px solid var(--border);
  border-top: 3px solid var(--brand);
  border-radius: var(--radius);
  padding: 14px 20px 12px;
  box-shadow: 0 16px 48px rgba(11, 27, 43, 0.16);
}

.presenter-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
}

.presenter-kicker {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--brand);
}

.presenter-meta {
  font-size: 10.5px;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.presenter-title {
  font-size: 16px;
  font-weight: 600;
  color: var(--heading);
  margin: 6px 0 4px;
}

.presenter-do {
  font-size: 11.5px;
  color: var(--accent-ink);
  margin-bottom: 4px;
}

.presenter-do b { font-weight: 700; letter-spacing: 0.06em; }

.presenter-say {
  font-size: 12.5px;
  color: var(--text-2);
  line-height: 1.5;
}

.presenter-keys {
  margin-top: 8px;
  padding-top: 6px;
  border-top: 1px solid var(--border);
  font-size: 10px;
  color: var(--muted);
  letter-spacing: 0.04em;
  display: flex;
  justify-content: space-between;
  gap: 8px;
}

.presenter-keys kbd {
  font-family: var(--mono);
  font-size: 9.5px;
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 0 5px;
  background: var(--surface-2);
  color: var(--text-2);
}

.presenter-progress {
  display: flex;
  gap: 4px;
  margin-top: 8px;
}

.presenter-progress span {
  flex: 1 1 auto;
  height: 2px;
  border-radius: 1px;
  background: var(--border);
}

.presenter-progress span.done { background: var(--brand); }

/* ---------------- Coverage view (requirements traceability) ----------
   Learn-side matrix rendered by coverageView from GET /api/coverage.
   Status pills stay semantic (pass green / warn amber / slate neutral) —
   never brand crimson. */

.footer-link {
  color: var(--muted);
  text-decoration: underline;
  text-underline-offset: 2px;
  transition: color 120ms ease;
}

.footer-link:hover { color: var(--text); }

.coverage-counts {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
  margin: 10px 0 4px;
}

.coverage-sources {
  margin-top: 10px;
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 3px 12px;
  font-size: 11px;
  color: var(--muted);
}

.coverage-source-row { display: contents; }
.coverage-source-row .mono { color: var(--text-2); }

.coverage-matrix-card table { font-size: 11.5px; }
.coverage-matrix-card td { vertical-align: top; }
.cov-src { white-space: nowrap; }
.cov-where { max-width: 260px; overflow-wrap: anywhere; }
.cov-notes {
  max-width: 300px;
  color: var(--muted);
  font-size: 11px;
  overflow-wrap: anywhere;
}

/* ============================================================
    FINISHED-PRODUCT LAYER (the design documentation)
   Sections: A wizard · B what-if · C profile strip / provenance
   modal / executive charts / view transitions · E import
   workspace / integrations view · global focus + reduced motion.
   Palette discipline: navy family + crimson brand accent only;
   semantic status colors stay in pills/checks.
   ============================================================ */

/* ---------------- global focus states (polish) ---------------- */

button:focus-visible,
a:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
.f-chip:focus-visible,
.fig-chip:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
  border-radius: 4px;
}

/* ---------------- smooth view transitions (§C) ----------------
   Surfaces slide-fade in when shown; skipped under reduced motion. */

@keyframes view-in {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: none; }
}

.view-anim { animation: view-in 180ms ease both; }

/* ---------------- §A New Project wizard ---------------- */

.modal.wizard {
  width: min(980px, 94vw);
  max-height: 92vh;
  display: flex;
  flex-direction: column;
}

.wiz-kicker { color: var(--brand); }

.wiz-steps {
  display: flex;
  gap: 18px;
  list-style: none;
  margin: 10px 0 0;
  padding: 0;
  font-size: 11.5px;
  color: var(--muted);
}

.wiz-steps li {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  letter-spacing: 0.04em;
}

.wiz-steps li.active { color: var(--text); }
.wiz-steps li.done { color: var(--text-2); }

.wiz-n {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  border: 1px solid var(--border);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 10px;
  font-variant-numeric: tabular-nums;
}

.wiz-steps li.active .wiz-n {
  border-color: var(--brand);
  color: var(--brand);
}

.wiz-steps li.done .wiz-n {
  background: var(--brand);
  border-color: var(--brand);
  color: #FFFFFF;
}

.wiz-body { flex: 1 1 auto; min-height: 0; overflow-y: auto; margin-top: 14px; }

.wiz-step { display: none; }
.wiz-step.active { display: block; }

.wiz-sites-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.7fr) minmax(240px, 1fr);
  gap: 14px;
}

.wiz-map-wrap { position: relative; }

#wiz-map {
  height: 420px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--bg);
}

.wiz-map-hint {
  position: absolute;
  top: 8px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 800;
  background: rgba(255, 255, 255, 0.94);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 4px 12px;
  font-size: 11px;
  color: var(--muted);
  white-space: nowrap;
}

.wiz-side { display: flex; flex-direction: column; gap: 8px; min-width: 0; }

.wiz-type { display: flex; gap: 6px; }

.wiz-count { text-transform: none; letter-spacing: 0; color: var(--muted); font-weight: 500; }

.wiz-site-list { display: flex; flex-direction: column; gap: 6px; }

.wiz-site {
  display: flex;
  align-items: center;
  gap: 8px;
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 6px 8px;
  background: var(--surface-2);
}

.wiz-site .site-dot {
  flex: 0 0 auto;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  border: 2px solid #FFFFFF;
  background: var(--brand);
}

.wiz-site input[type="text"] {
  flex: 1 1 auto;
  min-width: 0;
  background: transparent;
  border: none;
  border-bottom: 1px solid transparent;
  color: var(--text);
  font-family: var(--font);
  font-size: 12.5px;
  padding: 2px 0;
}

.wiz-site input[type="text"]:focus {
  outline: none;
  border-bottom-color: var(--accent-ink);
}

.wiz-site .site-ll {
  font-family: var(--mono);
  font-size: 10.5px;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.wiz-site .site-remove {
  flex: 0 0 auto;
  background: none;
  border: none;
  color: var(--muted);
  font-size: 14px;
  cursor: pointer;
  padding: 0 2px;
  line-height: 1;
}

.wiz-site .site-remove:hover { color: var(--fail); }

.wiz-site.empty {
  border-style: dashed;
  background: transparent;
  color: var(--muted);
  font-size: 12px;
  justify-content: center;
  padding: 9px 8px;
}

.wiz-site.outside { border-color: rgba(183, 120, 0, 0.5); }
.wiz-site .site-outside {
  font-size: 10px;
  color: var(--warn);
  white-space: nowrap;
}

.wiz-nodes { display: flex; flex-wrap: wrap; gap: 4px; }

.wiz-form {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px 18px;
}

.wiz-field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.wiz-span2 { grid-column: span 2; }

.wiz-field input[type="text"],
.wiz-field input[type="date"],
.wiz-field textarea {
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 6px;
  color: var(--text);
  font-family: var(--font);
  font-size: 12.5px;
  padding: 7px 10px;
}

.wiz-field input:focus,
.wiz-field textarea:focus { outline: 1px solid var(--accent); }

.wiz-field input[type="date"] { color-scheme: light; }

.wiz-field input[type="range"] {
  width: 100%;
  accent-color: var(--brand);
}

.wiz-help { font-size: 10.5px; color: var(--muted); }

.wiz-val {
  text-transform: none;
  letter-spacing: 0;
  color: var(--text);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.wiz-avoid { display: flex; flex-wrap: wrap; gap: 6px 16px; font-size: 12.5px; }

.wiz-avoid label {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  cursor: pointer;
  color: var(--text-2);
}

.wiz-avoid input[type="checkbox"] { accent-color: var(--brand); }

.wiz-review { font-size: 12.5px; }

.wiz-review .brief-card {
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface-2);
  padding: 14px 16px;
  margin-bottom: 12px;
}

.wiz-review .brief-kv { display: grid; grid-template-columns: 210px 1fr; gap: 4px 14px; }
.wiz-review .brief-kv .k { color: var(--muted); font-size: 11px; text-transform: uppercase; letter-spacing: 0.07em; padding-top: 2px; }
.wiz-review .brief-kv .v { font-variant-numeric: tabular-nums; }

.wiz-error {
  margin-top: 10px;
  border: 1px solid rgba(194, 43, 43, 0.35);
  background: rgba(194, 43, 43, 0.06);
  border-radius: 8px;
  padding: 8px 12px;
  font-size: 12px;
  color: var(--fail);
}

.wiz-actions { justify-content: space-between; }
.wiz-actions-right { display: flex; gap: 8px; }

/* Design-audit AA fix: --brand-tint is a GRAPHICS ink (dotted laterals)
   — as 10px text on white it is 3.53:1. --brand crimson is ~7:1. */
.pill.user-created { color: var(--brand); border-color: rgba(178, 15, 49, 0.3); }

/* region outline swatches used in the wizard side note. Demo regions:
   steel blue (design-audit treatment). §B2 territory: the wide
   Louisiana–Mississippi cache is contract-pinned to a LIGHT crimson
   tint — kept deliberately faint (dotted hairline, 4% wash) so it reads
   as the placeable brand surface, not a data state or exclusion zone. */
.region-sw {
  display: inline-block;
  width: 14px;
  height: 10px;
  border: 1.5px dashed rgba(15, 158, 213, 0.6);
  background: rgba(15, 158, 213, 0.07);
  border-radius: 2px;
  vertical-align: -1px;
  margin-right: 4px;
}

.region-sw.territory {
  border: 1.5px dotted rgba(178, 15, 49, 0.45);
  background: rgba(178, 15, 49, 0.05);
}

/* ---------------- §B what-if panel ---------------- */

.whatif-card {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface-2);
  padding: 14px 16px;
  margin-bottom: 16px;
}

.wf-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 10px;
}

.wf-title { font-size: 12.5px; font-weight: 600; }

.wf-scenario-pill {
  font-size: 10px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--accent-ink);
  border: 1px solid rgba(15, 158, 213, 0.5);
  border-radius: 999px;
  padding: 2px 10px;
}

.wf-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px 22px;
}

@media (max-width: 1300px) {
  .wf-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.wf-slider {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 44px;
  gap: 2px 8px;
  align-items: center;
  font-size: 11.5px;
  color: var(--text-2);
}

.wf-slider input[type="range"] {
  grid-column: 1 / 2;
  width: 100%;
  accent-color: var(--accent-ink);
  height: 18px;
}

.wf-slider .wf-w {
  grid-column: 2;
  grid-row: 1 / 3;
  align-self: center;
  font-family: var(--mono);
  font-size: 11px;
  color: var(--text);
  font-variant-numeric: tabular-nums;
  text-align: right;
}

.wf-slider.changed .wf-w { color: var(--accent-ink); }

.wf-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  margin-top: 12px;
}

.wf-wacc { display: inline-flex; align-items: center; gap: 6px; font-size: 11.5px; color: var(--muted); }

.wf-wacc .f-chip { min-width: 44px; text-align: center; }

.wf-deltas { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }

.delta-chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 2px 10px;
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  color: var(--text-2);
  background: var(--surface);
}

.delta-chip .dk { color: var(--muted); font-size: 10px; text-transform: uppercase; letter-spacing: 0.05em; }
.delta-chip.up { border-color: rgba(15, 158, 213, 0.5); color: var(--accent-ink); }
.delta-chip.down { border-color: rgba(183, 120, 0, 0.4); color: var(--warn); }
.delta-chip.flip { border-color: rgba(178, 15, 49, 0.45); color: var(--brand); }

.wf-note { font-size: 11px; color: var(--muted); margin-top: 8px; }

/* FLIP re-rank: rows transition transform when the scenario re-orders them */
#scoring-slot tbody tr { transition: transform 420ms cubic-bezier(0.22, 1, 0.36, 1), background 120ms ease; }
tr.rank-up td:first-child { box-shadow: inset 3px 0 0 var(--accent); }
tr.rank-down td:first-child { box-shadow: inset 3px 0 0 var(--warn); }

.wf-busy { opacity: 0.55; pointer-events: none; }

/* ---------------- §C elevation profile strip ---------------- */

.profile-strip {
  position: absolute;
  left: 8px;
  right: 8px;
  bottom: 8px;
  z-index: 820;
  background: rgba(255, 255, 255, 0.95);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 8px 12px 6px;
}

.map-pane.has-profile .map-legend { bottom: 148px; }
/* collapsed strip = header row only (~44px) */
.map-pane.has-profile.profile-collapsed .map-legend { bottom: 56px; }
.profile-strip.collapsed .profile-chart { display: none; }

.strip-chevron {
  margin-left: 8px;
  flex: 0 0 auto;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 6px;
  color: var(--muted);
  font: inherit;
  font-size: 10px;
  line-height: 1;
  padding: 3px 7px;
  cursor: pointer;
}
.strip-chevron:hover { color: var(--text); border-color: var(--muted); }

/* recommended candidate chip — same crimson language as the map legend */
.f-chip.prof-rec {
  color: var(--brand);
  border-color: rgba(178, 15, 49, 0.5);
}
.f-chip.prof-rec.active {
  background: rgba(178, 15, 49, 0.08);
  color: var(--brand);
  border-color: var(--brand);
}

/* outside-cached-coverage hatch on the strip SVG */
.prof-unc-line { stroke: var(--reject); stroke-width: 2; opacity: 0.8; }
.prof-unc { opacity: 0.45; }
.prof-unc-label {
  fill: var(--warn);
  font-size: 9px;
  font-family: var(--mono);
  letter-spacing: 0.04em;
}

/* legend chip (short map panes) */
.legend-chip {
  position: absolute;
  right: 8px;
  bottom: 8px;
  z-index: 810;
  display: none;
  background: rgba(255, 255, 255, 0.94);
  border: 1px solid var(--border);
  border-radius: 999px;
  color: var(--muted);
  font: inherit;
  font-size: 11px;
  padding: 4px 12px;
  cursor: pointer;
}
.legend-chip:hover { color: var(--text); border-color: var(--muted); }
.map-pane.has-profile .legend-chip { bottom: 148px; }
.map-pane.has-profile.profile-collapsed .legend-chip { bottom: 56px; }
.map-pane.map-short .legend-chip { display: block; }
.map-pane.map-short .map-legend { display: none; }
.map-pane.map-short .map-legend.peek {
  display: block;
  bottom: 40px;
  max-height: calc(100% - 56px);
  overflow-y: auto;
}
.map-pane.map-short.has-profile .map-legend.peek { bottom: 180px; }
.map-pane.map-short.has-profile.profile-collapsed .map-legend.peek { bottom: 88px; }
/* short panes also slim the layers panel so it clears the zoom control */
.map-pane.map-short .layer-toggles { max-height: 45%; overflow-y: auto; }

/* Head row wraps: crossing/geology chips flow onto extra lines at
   laptop widths instead of running past the map pane's clipped edge. */
.profile-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 2px 10px;
  margin-bottom: 4px;
}

.profile-chips { display: inline-flex; flex-wrap: wrap; gap: 4px; }

.profile-meta {
  margin-left: auto;
  font-size: 10.5px;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  /* flex-basis 0 so the long meta line can never force a wrap that
     strands the collapse chevron on its own row — it fills whatever is
     left of the head row and ellipsizes. */
  flex: 1 1 0;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  text-align: right;
}

.profile-chart { position: relative; }
.profile-chart svg { display: block; width: 100%; height: 96px; }

.prof-area { fill: rgba(15, 158, 213, 0.14); }
.prof-line { fill: none; stroke: var(--accent); stroke-width: 1.6; }
.prof-axis { stroke: var(--border); stroke-width: 1; }
.prof-tick {
  fill: var(--muted);
  font-size: 8.5px;
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
}

/* geology band tints — same constructability family used on the map,
   kept very quiet so the elevation line stays the subject */
.geo-band { opacity: 0.16; }
.geo-band.geo-soft { fill: #2E8B57; }        /* alluvium / soft — plow-friendly */
.geo-band.geo-mixed { fill: #6B7F46; }       /* mixed sediments */
.geo-band.geo-hard { fill: #8A6D3B; }        /* consolidated / rock adder */
.geo-band.geo-urban { fill: #56687A; }       /* urban / developed — bore */
.geo-band.geo-wet { fill: #196B24; }         /* wetland exposure */

.prof-flag { stroke: rgba(183, 120, 0, 0.6); stroke-width: 1; stroke-dasharray: 2 3; }
.prof-flag-label {
  fill: var(--text-2);
  font-size: 8.5px;
  font-family: var(--font);
}

.prof-cursor { stroke: var(--heading); stroke-width: 1; opacity: 0.55; }
.prof-cursor-dot { fill: var(--heading); }

.prof-hover {
  position: absolute;
  top: 2px;
  left: 8px;
  font-size: 10px;
  font-family: var(--mono);
  color: var(--text);
  background: rgba(255, 255, 255, 0.92);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 1px 7px;
  pointer-events: none;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.profile-legend {
  display: flex;
  gap: 12px;
  font-size: 9.5px;
  color: var(--muted);
  margin-top: 2px;
  flex-wrap: wrap;
}

.profile-legend .geo-key {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}

.profile-legend .geo-sw {
  width: 10px;
  height: 8px;
  border-radius: 2px;
  opacity: 0.55;
}

/* ---------------- §C provenance modal ---------------- */

.modal.fig-modal { width: min(640px, 92vw); }

.fig-kicker { color: var(--accent-ink); }

.fig-body { font-size: 12.5px; max-height: 60vh; overflow-y: auto; }

.fig-id-line {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 10px;
}

.fig-id-line .p-id {
  font-family: var(--mono);
  font-size: 12px;
  color: var(--accent-ink);
}

.fig-value-hero {
  font-size: 24px;
  font-weight: 300;
  color: var(--heading);
  font-variant-numeric: tabular-nums;
  margin-bottom: 12px;
}

.fig-value-hero .unit { font-size: 13px; color: var(--muted); font-weight: 500; margin-left: 6px; }

.fig-chain { display: grid; grid-template-columns: 120px 1fr; gap: 6px 14px; margin-bottom: 12px; }
.fig-chain .k {
  color: var(--muted);
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  padding-top: 2px;
}
.fig-chain .v { word-break: break-word; }

.fig-raw {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 10px 12px;
  font-family: var(--mono);
  font-size: 10.5px;
  color: var(--text-2);
  overflow-x: auto;
  white-space: pre;
}

.fig-copy-row { display: flex; justify-content: flex-end; margin: 8px 0 0; }

/* ---------------- §C executive SVG charts ---------------- */

.chart-svg { display: block; width: 100%; }

.gantt-label {
  fill: var(--text-2);
  font-size: 10px;
  font-family: var(--font);
}

.gantt-tick {
  fill: var(--muted);
  font-size: 8.5px;
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
}

.gantt-grid { stroke: var(--border); stroke-width: 0.7; opacity: 0.7; }

/* palette discipline: chart series ride the steel/slate ramp —
   crimson stays reserved for brand / recommended-route language, so a
   red Construction bar can never read as "problem phase". */
.gantt-seg-design { fill: #46647E; }
.gantt-seg-row { fill: #0F9ED5; }
.gantt-seg-construction { fill: #E97132; }
.gantt-seg-turnover { fill: #A9BDCE; }
.gantt-whisker { stroke: var(--text-2); stroke-width: 1.1; }

.capex-cat-design { fill: #46647E; }
.capex-cat-easements { fill: #0F9ED5; }
.capex-cat-environmental { fill: #6B7F46; }
.capex-cat-crossings { fill: #E97132; }
.capex-cat-construction { fill: #78899A; } /* : cost ≠ crimson */

.chart-key {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 14px;
  font-size: 10px;
  color: var(--muted);
  margin-top: 6px;
}

.chart-key .ck {
  display: inline-flex;
  align-items: center;
  gap: 5px;
}

.chart-key .ck-sw { width: 10px; height: 8px; border-radius: 2px; display: inline-block; }

.prod-axis { stroke: var(--border); stroke-width: 1; }
.prod-grid { stroke: var(--border); stroke-width: 0.6; opacity: 0.6; }
.prod-tick {
  fill: var(--muted);
  font-size: 8.5px;
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
}

/* ---------------- §E import workspace ---------------- */

.dropzone {
  border: 1.5px dashed var(--border);
  border-radius: var(--radius);
  padding: 22px 16px;
  text-align: center;
  color: var(--muted);
  font-size: 12.5px;
  cursor: pointer;
  transition: border-color 120ms ease, background 120ms ease;
  background: transparent;
  width: 100%;
  font-family: var(--font);
}

.dropzone:hover, .dropzone.dragover {
  border-color: var(--accent-ink);
  background: rgba(15, 158, 213, 0.05);
  color: var(--text-2);
}

.dropzone .dz-types { font-size: 10.5px; margin-top: 4px; display: block; }

.import-report-card {
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface);
  padding: 12px 14px;
  margin-top: 10px;
}

.irc-head {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin-bottom: 8px;
}

.irc-file { font-family: var(--mono); font-size: 11px; color: var(--text-2); word-break: break-all; }

.irc-class {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 11.5px;
  color: var(--muted);
}

.irc-class select {
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 6px;
  color: var(--text);
  font-size: 11.5px;
  padding: 3px 8px;
}

.irc-checks { margin: 8px 0; }
.irc-checks td { font-size: 11.5px; }

.irc-counts { display: flex; flex-wrap: wrap; gap: 6px; margin: 8px 0; }

.irc-actions { display: flex; gap: 8px; justify-content: flex-end; margin-top: 8px; }

.applied-badge {
  display: flex;
  align-items: center;
  gap: 8px;
  border: 1px solid rgba(30, 123, 52, 0.35);
  border-radius: 8px;
  padding: 6px 10px;
  font-size: 11.5px;
  background: rgba(30, 123, 52, 0.05);
  margin-top: 6px;
}

.applied-badge .ab-what { flex: 1 1 auto; min-width: 0; }
.applied-badge .ab-prov { font-family: var(--mono); font-size: 10px; color: var(--muted); white-space: nowrap; }

/* ---------------- §E integrations view ---------------- */

.integr-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 16px;
  margin-bottom: 16px;
}

@media (max-width: 1200px) {
  .integr-grid { grid-template-columns: 1fr; }
}

.dropin-card .di-title {
  font-size: 13px;
  font-weight: 600;
  margin-bottom: 4px;
}

.dropin-card .di-status { margin: 6px 0; }

/* Fixed layout: auto layout sized the sample column to the longest
   one-line curl command and pushed the whole table ~1000px past the
   viewport. Paths wrap at slashes; curl text scrolls in .curl-text. */
.endpoint-table {
  table-layout: fixed;
  width: 100%;
}

.endpoint-table th:nth-child(1) { width: 58px; }
.endpoint-table th:nth-child(2) { width: 27%; }

.endpoint-table td { vertical-align: top; }
/* Paths wrap at any slash under fixed layout (overrides td.mono's
   nowrap, which would otherwise overlap the sample column). */
.endpoint-table td.path-cell {
  white-space: normal;
  overflow-wrap: anywhere;
}

.method-pill {
  display: inline-block;
  font-family: var(--mono);
  font-size: 10px;
  font-weight: 600;
  border-radius: 4px;
  padding: 1px 7px;
  letter-spacing: 0.04em;
}

.method-pill.get { color: var(--accent-ink); border: 1px solid rgba(15, 158, 213, 0.45); }
.method-pill.post { color: #1E7B34; border: 1px solid rgba(30, 123, 52, 0.45); }
.method-pill.delete { color: var(--fail); border: 1px solid rgba(194, 43, 43, 0.4); }
.method-pill.sse { color: var(--slate-bright); border: 1px solid rgba(94, 113, 134, 0.45); }

.curl-block {
  position: relative;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 6px 66px 6px 10px;
  font-family: var(--mono);
  font-size: 10.5px;
  color: var(--text-2);
  overflow-x: auto;
  white-space: pre;
  margin-top: 4px;
}

.copy-btn {
  position: absolute;
  top: 4px;
  right: 4px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 4px;
  color: var(--muted);
  font-size: 10px;
  padding: 1px 8px;
  cursor: pointer;
  font-family: var(--font);
}

.copy-btn:hover { color: var(--text); border-color: var(--muted); }
.copy-btn.copied { color: #1E7B34; border-color: rgba(30, 123, 52, 0.45); }

.prod-integr-list { margin: 6px 0 0; padding-left: 18px; font-size: 12px; color: var(--text-2); }
.prod-integr-list li { margin-bottom: 3px; }

/* fingerprint chip (§D surface in the verification tab) */
.fingerprint-row {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface-2);
  padding: 8px 12px;
  margin: 10px 0;
}

.fingerprint-row .fp-hash {
  font-family: var(--mono);
  font-size: 10.5px;
  color: var(--accent-ink);
  word-break: break-all;
}

.fingerprint-row .fp-label {
  font-size: 10px;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--muted);
  white-space: nowrap;
}

/* ---------------- reduced motion (binding: contract §F) ---------------- */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* two-up executive card rows (charts + workspaces pair naturally) */
.exec-cards.two { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (max-width: 1200px) {
  .exec-cards.two { grid-template-columns: 1fr; }
}

/* ring legs: keep candidate chips on one line in the profile strip */
.profile-chips .f-chip { white-space: nowrap; }
.profile-head .label { white-space: nowrap; }

/* ============================================================
    FIX PASS — width robustness, gate ergonomics, palette
   discipline (design-audit findings)
   ============================================================ */

/* -- KPI at-risk flag: a pill on the value row, never prose tail -- */
.kpi-flag {
  display: inline-block;
  vertical-align: baseline;
  margin-left: 6px;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  border-radius: 999px;
  padding: 1px 8px;
  border: 1px solid var(--border);
  color: var(--muted);
}
.kpi-flag.warn { color: var(--warn); border-color: rgba(183, 120, 0, 0.45); }
.kpi-flag.ok { color: var(--ok); border-color: rgba(30, 123, 52, 0.45); }

/* -- topbar control row: no wrapped buttons, no clipped select -- */
.controls .btn, .toggle-text { white-space: nowrap; }
/* The select is the topbar's designated flex victim (design-audit fix:
   the brand lockup is shrink-protected, so squeeze lands HERE); the
   full project name rides in the hover title (app.js keeps it synced). */
.controls { min-width: 0; }
#project-select { min-width: 0; text-overflow: ellipsis; }
@media (min-width: 1600px) {
  /* Elastic select: grows into leftover space (up to the 340px cap) but
     can give it back down to a readable floor — the brand lockup and the
     run controls are the protected pieces (design-audit fix). */
  #project-select { min-width: 170px; flex: 1 1 auto; }
}

/* -- gate modal: decision buttons always visible (sticky footer);
      the layers/summary table scrolls inside its own region -- */
#gate-modal .modal {
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
#gate-modal .modal-head, #gate-modal h2, #gate-modal .gate-question,
#gate-modal #gate-note, #gate-modal .modal-actions,
#gate-modal .gate-governance { flex: 0 0 auto; }
#gate-modal .gate-summary {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  max-height: 52vh;
}

/* license prose collapses to a short chip (full text on hover) */
.lic-chip {
  font-size: 11px;
  color: var(--muted);
  border-bottom: 1px dotted var(--border);
  cursor: help;
  white-space: nowrap;
}

/* -- tab strip overflow affordance: edge fades only when overflowing -- */
.tabbar { position: relative; scrollbar-width: none; }
.tabbar::-webkit-scrollbar { display: none; }
.tabbar.overflow-left {
  -webkit-mask-image: linear-gradient(to right, transparent 0,
    #000 28px, #000 100%);
  mask-image: linear-gradient(to right, transparent 0, #000 28px, #000 100%);
}
.tabbar.overflow-right {
  -webkit-mask-image: linear-gradient(to right, #000 0,
    #000 calc(100% - 28px), transparent 100%);
  mask-image: linear-gradient(to right, #000 0, #000 calc(100% - 28px),
    transparent 100%);
}
.tabbar.overflow-left.overflow-right {
  -webkit-mask-image: linear-gradient(to right, transparent 0, #000 28px,
    #000 calc(100% - 28px), transparent 100%);
  mask-image: linear-gradient(to right, transparent 0, #000 28px,
    #000 calc(100% - 28px), transparent 100%);
}

/* -- exec chart source tag (fresh-session hydration label) -- */
.chart-src {
  font-family: var(--mono);
  font-size: 10px;
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
  color: var(--muted);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 1px 8px;
  margin-left: 8px;
}

/* -- wizard: out-of-region quick-picks + step-1 inline note -- */
.f-chip.chip-outside {
  opacity: 0.45;
  cursor: not-allowed;
  border-style: dashed;
}
.wiz-outside-note {
  border: 1px solid rgba(183, 120, 0, 0.35);
  background: rgba(245, 158, 11, 0.08);
  border-radius: 8px;
  color: var(--warn);
  font-size: 11.5px;
  padding: 6px 10px;
  margin-top: 6px;
}
/* site rows: the NAME owns the flex slack (it was truncating while the
   row had free space); coords stay, full pair rides the tooltip */
.wiz-site input[type="text"] { flex: 1 1 auto; min-width: 0; }
.wiz-site .site-ll { flex: 0 0 auto; }

/* -- one range-slider look everywhere: slate track, steel-blue accent,
      white-on-accent thumb (three different native looks shipped) -- */
.wiz-field input[type="range"],
.wf-slider input[type="range"],
.wf-wacc input[type="range"] {
  -webkit-appearance: none;
  appearance: none;
  height: 18px;
  background: transparent;
  accent-color: var(--accent-ink);
}
.wiz-field input[type="range"]::-webkit-slider-runnable-track,
.wf-slider input[type="range"]::-webkit-slider-runnable-track,
.wf-wacc input[type="range"]::-webkit-slider-runnable-track {
  height: 4px;
  border-radius: 2px;
  background: var(--border);
}
.wiz-field input[type="range"]::-webkit-slider-thumb,
.wf-slider input[type="range"]::-webkit-slider-thumb,
.wf-wacc input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: #FFFFFF;
  border: 3px solid var(--accent);
  margin-top: -5px;
}
.wiz-field input[type="range"]::-moz-range-track,
.wf-slider input[type="range"]::-moz-range-track,
.wf-wacc input[type="range"]::-moz-range-track {
  height: 4px;
  border-radius: 2px;
  background: var(--border);
}
.wiz-field input[type="range"]::-moz-range-progress,
.wf-slider input[type="range"]::-moz-range-progress,
.wf-wacc input[type="range"]::-moz-range-progress {
  height: 4px;
  border-radius: 2px;
  background: var(--accent);
}
.wiz-field input[type="range"]::-moz-range-thumb,
.wf-wacc input[type="range"]::-moz-range-thumb {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: #FFFFFF;
  border: 3px solid var(--accent);
}

/* -- integrations curl samples: text scrolls in its own inner span and
      never runs beneath the overlaid Copy chip -- */
.curl-block {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  padding: 6px 8px 6px 10px; /* replaces the old 66px copy gutter */
  overflow-x: hidden;
  white-space: normal;
}
.curl-block .curl-text {
  flex: 1 1 auto;
  min-width: 0;
  overflow-x: auto;
  white-space: pre;
  padding-bottom: 2px;
}
.curl-block .copy-btn { position: static; flex: 0 0 auto; }

/* ============================================================
   In-app guidance surfaces (first-time-user sweep, Aug 2026):
   step strip (workflow subtitle), run hint (live pipeline line),
   gate purpose sentence, post-run What-next card, first-visit
   coach marks, guided-tour overlay controls. Palette discipline:
   brand crimson = attention/identity (spotlight ring, primary
   actions); amber = waiting-on-human (matches the gate chip);
   pass-green tint only on the completion card (mirrors
   .banner.success); steel blue = informational.
   ============================================================ */

/* -- workflow step subtitle strip (under the topbar) -- */

.step-strip {
  flex: 0 0 auto;
  padding: 4px 24px 5px;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  font-size: 11.5px;
  color: var(--muted);
  letter-spacing: 0.02em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.step-strip b {
  color: var(--text-2);
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  font-size: 10.5px;
}

.step-strip:empty { display: none; }

/* -- live run hint under the pipeline rail -- */

.run-hint {
  margin-top: 14px;
  padding: 10px 8px 0;
  border-top: 1px solid var(--border);
  font-size: 11px;
  line-height: 1.55;
  color: var(--muted);
  letter-spacing: 0.02em;
}

/* Waiting on the human = amber, same semantics as the gate chip/rail. */
.run-hint.waiting { color: var(--warn); }

/* -- gate purpose sentence (steel blue = informational accent) -- */

.gate-purpose {
  margin: -10px 0 14px;
  font-size: 12px;
  line-height: 1.5;
  color: var(--accent-ink);
}

/* -- post-run What-next card -- */

#whatnext:empty { display: none; }

.wn-card {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px 24px;
  padding: 12px 16px;
  border-radius: 8px;
  border: 1px solid rgba(30, 123, 52, 0.4);
  background: rgba(30, 123, 52, 0.07);
}

.wn-head {
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: 0;
}

.wn-mark {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  border: 1px solid rgba(30, 123, 52, 0.55);
  color: var(--ok);
}

/* CEO-audit fix: a run with FAILED verification checks must not wear the
   pass-green completion card — fail ink on the mark, fail-tinted frame. */
.wn-card.wn-card-fail {
  border-color: rgba(194, 43, 43, 0.4);
  background: rgba(194, 43, 43, 0.06);
}

.wn-mark.wn-mark-fail {
  border-color: rgba(194, 43, 43, 0.55);
  color: var(--fail);
}

.wn-title {
  font-size: 15px;
  font-weight: 600;
  color: var(--heading);
}

.wn-sub {
  font-size: 11.5px;
  color: var(--text-2);
  font-variant-numeric: tabular-nums;
}

.wn-actions {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
}

.wn-ask {
  margin-left: 8px;
  font-size: 12px;
  color: var(--accent-ink);
  text-decoration: underline;
  text-underline-offset: 2px;
  white-space: nowrap;
}

.wn-ask:hover { color: var(--text); }

/* -- first-visit coach marks (spotlight overlay) -- */

.coach {
  position: fixed;
  inset: 0;
  z-index: 1300; /* above the tour overlay (1200) and gate chrome (1001) */
}

/* Spotlight ring: brand crimson (attention/identity, never an error);
   its box-shadow paints the dimmed scrim with a cut-out around the
   target, so the highlighted control stays at full brightness. */
.coach-ring {
  position: absolute;
  border: 2px solid var(--brand);
  border-radius: 10px;
  box-shadow: 0 0 0 9999px rgba(14, 40, 65, 0.42);
  pointer-events: none;
  transition: left 160ms ease, top 160ms ease, width 160ms ease, height 160ms ease;
}

.coach-card {
  position: absolute;
  width: 380px;
  max-width: calc(100vw - 32px);
  background: var(--surface);
  border: 1px solid var(--border);
  border-top: 3px solid var(--brand);
  border-radius: var(--radius);
  padding: 14px 16px 12px;
  box-shadow: 0 16px 48px rgba(11, 27, 43, 0.16);
}

.coach-kicker {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
}

.coach-title {
  font-size: 15px;
  font-weight: 600;
  color: var(--heading);
  margin: 5px 0 4px;
}

.coach-text {
  font-size: 12.5px;
  color: var(--text-2);
  line-height: 1.5;
}

.coach-actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-top: 12px;
}

.coach-actions-right {
  display: flex;
  align-items: center;
  gap: 8px;
}

/* -- guided-tour overlay controls (presenter surface) -- */

.presenter-head-right {
  display: flex;
  align-items: center;
  gap: 10px;
}

.presenter-nav {
  display: flex;
  align-items: center;
  gap: 8px;
}

/* ============================================================
   Responsive topbar (layout sweep, Aug 2026). Lives at the END of the
   sheet: these override equal-specificity base rules (.controls,
   select#project-select, .ribbon-btn, .mode-badge), and the cascade
   resolves equal specificity by source order.
   ============================================================ */

/* ≤2039px: with the brand lockup shrink-protected (design-audit fix),
   the full toolbar + full subtitle need ~2050px at base paddings — a
   modest tightening keeps the run controls fully on-screen at 1920
   while brand, subtitle and every control stay whole. */
@media (max-width: 2039px) {
  .topbar { gap: 12px; padding: 0 18px; }
  .controls { gap: 8px; }
  .run-controls { gap: 8px; }
  .ribbon-btn { padding: 5px 9px 7px; }
  /* LIVE badges carry a model id — cap them so a long model name can
     never push the Run button past the edge (full text on hover title
     is unnecessary: the /api/meta surface carries it). */
  .mode-badge {
    padding: 4px 7px;
    letter-spacing: 0.06em;
    max-width: 180px;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  #tour-btn, #new-project-btn { padding: 7px 10px; }
}

/* ≤1750px: the Guided tour button (first-time-user sweep) added ~120px
   to the toolbar — reclaim it from the flexible pieces so the wordmark
   still renders in full at laptop widths (same guarantee as the original
   1600px fix above; source order lets these win at equal specificity). */
@media (max-width: 1750px) {
  select#project-select { max-width: 210px; }
  #tour-btn, #new-project-btn { padding: 7px 11px; }
  .mode-badge { padding: 4px 8px; letter-spacing: 0.07em; }
  .ribbon-btn { padding: 5px 10px 7px; }
  .controls { gap: 8px; }
  .run-controls { gap: 8px; }
  .wordmark { font-size: 12px; letter-spacing: 0.05em; }
}

/* ≤1520px: the full toolbar (ribbon + badges + New Project + run
   controls) is wider than the window minus a slim lockup — shrink the
   flexible pieces (project select, gaps, paddings) before anything can
   push past the right viewport edge (body overflow is hidden, so an
   oversized topbar CLIPS controls rather than scrolling). */
@media (max-width: 1520px) {
  .topbar { padding: 0 16px; gap: 10px; }
  .controls { gap: 6px; }
  .run-controls { gap: 6px; }
  select#project-select { max-width: 190px; }
  .ribbon-btn { padding: 5px 8px 7px; font-size: 12px; }
  .wordmark { font-size: 11.5px; letter-spacing: 0.04em; }
  .mode-badge { padding: 4px 7px; letter-spacing: 0.05em; }
  #tour-btn, #new-project-btn { padding: 7px 9px; font-size: 12px; }
  /* The auto-approve caption goes before any control can clip (the
     switch keeps its hover title; the ≤1380 step already did this —
     with the shrink-protected lockup it moves up to the 1520 step). */
  .toggle-text { display: none; }
}

/* ≤1380px: column-priority drop — the auto-approve caption (the switch
   keeps its hover title) and badge/button padding go before any control
   clips; the select ellipsizes the project name. */
@media (max-width: 1380px) {
  .toggle-text { display: none; }
  select#project-select { max-width: 170px; }
  .mode-badge { padding: 4px 7px; letter-spacing: 0.06em; }
  .ribbon-btn { padding: 5px 8px 7px; letter-spacing: 0.05em; }
  #new-project-btn, #tour-btn { padding: 7px 10px; }
  .brand { padding-left: 10px; }
}

/* ≤1360px (1280 projector/older-MacBook widths): the run-controls
   row starves the brand block, and the previous shrink steps ended in a
   mid-word ellipsis on the product's own name ("KIRKWOOD R…"). The short
   lockup swaps in whole beside the swoosh, the badges tighten, and the
   full name rides in the hover title. */
@media (max-width: 1360px) {
  .wm-full { display: none; }
  .wm-short { display: inline; }
  .wordmark { font-size: 12px; letter-spacing: 0.08em; }
  .mode-badge { font-size: 9px; padding: 3px 6px; letter-spacing: 0.04em; }
  select#project-select { max-width: 150px; }
  .ribbon-btn { padding: 5px 7px 7px; letter-spacing: 0.03em; }
  .topbar { gap: 8px; }
  .controls { gap: 6px; }
  .run-controls { gap: 6px; }
}

/* <1200px: the toolbar alone outweighs the width — the lockup collapses
   DELIBERATELY to the red swoosh mark (the logo's own reduction), never
   a mid-word brand ellipsis; the full name stays in the hover title on
   the .brand block. */
@media (max-width: 1199px) {
  .wordmark { display: none; }
  .brand { width: 14px; min-height: 32px; }
}

/* ============================================================
   EXECUTIVE SUMMARY / DETAILS DISCLOSURE (exec light reskin).
   The run view defaults to SUMMARY: the Vision output card as the
   hero, the map, a plain-language run narrative, gate prompts and
   the post-run What-next card. ONE Details toggle reveals the full
   tab row (registers / scoring / verification / BOQ) — engineer
   depth intact, one click away. Nothing is deleted; surfaces are
   only shown/hidden by the body[data-runmode] switch.
   ============================================================ */

/* -- mode switch (segmented control, right-aligned above the band) -- */

.disclose-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex: 0 0 auto;
  min-height: 30px;
}

.disclose-note {
  font-size: 12.5px;
  color: var(--muted);
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.seg {
  display: inline-flex;
  gap: 2px;
  padding: 2px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface);
  box-shadow: var(--shadow);
  flex: 0 0 auto;
}

.seg-btn {
  font: inherit;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--muted);
  background: transparent;
  border: none;
  border-radius: 999px;
  padding: 4px 16px;
  cursor: pointer;
  transition: color 120ms ease, background 120ms ease;
}

.seg-btn:hover { color: var(--heading); }

.seg-btn.active {
  color: #FFFFFF;
  background: var(--brand);
}

/* -- the Vision output card (summary hero) -- */

.summary-hero {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 16px 20px 14px;
  flex: 0 0 auto;
}

.hero-top {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}

.hero-kicker {
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--brand);
}

.hero-project {
  font-size: 19px;
  font-weight: 600;
  color: var(--heading);
  margin-top: 2px;
}

.hero-sub {
  font-size: 12px;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

.hero-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 8px 24px;
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--border);
}

@media (max-width: 1200px) {
  .hero-grid { grid-template-columns: repeat(2, 1fr); }
}

.hero-cell { min-width: 0; }

.hero-cell .hk {
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--muted);
}

.hero-cell .hv {
  font-size: clamp(18px, 1.5vw, 27px);
  font-weight: 300; /* executive numerals — large, light, tabular */
  color: var(--heading);
  font-variant-numeric: tabular-nums;
  margin-top: 2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.hero-cell .hv .unit {
  font-size: 12px;
  font-weight: 500;
  color: var(--muted);
  margin-left: 4px;
}

.hero-cell .hv.hv-text {
  font-size: 13.5px;
  font-weight: 500;
  line-height: 1.4;
  white-space: normal;
  /* Duct specs run long — three lines in the hero (the two-line
     clamp cut the spec mid-token at every width; the cell has vertical
     room since its siblings are one-line numerals). Full text rides in
     the hover title (kpis.set mirror); complete spec in Details. */
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
}

.hero-cell .hs {
  font-size: 11px;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  line-height: 1.4;
}

/* -- plain-language run narrative (summary side pane) -- */

.narrative-pane {
  flex: 1.15 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  background: var(--surface);
  overflow: hidden;
}

.narrative-head {
  flex: 0 0 auto;
  padding: 12px 16px 8px;
  border-bottom: 1px solid var(--border);
}

.narrative-body {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  padding: 12px 16px;
}

.nar-line {
  display: flex;
  gap: 10px;
  font-size: 13px;
  line-height: 1.5;
  color: var(--text-2);
  padding: 4px 0;
}

.nar-line .nar-dot {
  flex: 0 0 auto;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  margin-top: 6px;
  background: var(--border);
}

.nar-line.done .nar-dot { background: var(--ok); }
.nar-line.now .nar-dot {
  background: var(--accent);
  animation: kfa-pulse 1.6s ease-in-out infinite;
}
.nar-line.gate .nar-dot { background: var(--warn); }
.nar-line.now { color: var(--text); }

.nar-empty { font-size: 13px; color: var(--muted); padding: 4px 0; }

.narrative-foot {
  flex: 0 0 auto;
  padding: 8px 16px 12px;
  border-top: 1px solid var(--border);
  font-size: 11.5px;
  color: var(--muted);
}

/* -- what shows in which mode --
   Summary: hero + 6-chip band + map + narrative. The permit strip,
   the full tab pane and the extra KPI chips live behind Details. */

body[data-runmode="summary"] .tabs-pane { display: none; }
body[data-runmode="summary"] .permit-strip { display: none; }
/* The elevation profile strip is engineering depth — Details only.
   With it hidden, the legend returns to its normal corner. */
body[data-runmode="summary"] .profile-strip { display: none; }
body[data-runmode="summary"] .map-pane.has-profile .map-legend { bottom: 8px; }
body[data-runmode="summary"] .map-pane.has-profile .legend-chip { bottom: 8px; }
body[data-runmode="summary"] .map-pane.map-short.has-profile .map-legend.peek { bottom: 40px; }
body[data-runmode="summary"] .kpi[data-kpi="project"],
body[data-runmode="summary"] .kpi[data-kpi="design"],
body[data-runmode="summary"] .kpi[data-kpi="npv"] { display: none; }
body[data-runmode="summary"] .kpis { grid-template-columns: repeat(6, minmax(0, 1fr)); }
/* (design finding): the hero card and the chip band stack ~90px
   apart — the three chips that duplicate hero cells (Length / Cost /
   Delivery) drop their verbatim-identical sub-lines in Summary so the
   hero stays the primary read. Values and verdict pills (AT RISK sits
   in the label row) remain; the sub-lines return in Details. */
body[data-runmode="summary"] .kpi[data-kpi="length"] .kpi-sub,
body[data-runmode="summary"] .kpi[data-kpi="cost"] .kpi-sub,
body[data-runmode="summary"] .kpi[data-kpi="delivery"] .kpi-sub { display: none; }
@media (max-width: 1200px) {
  body[data-runmode="summary"] .kpis { grid-template-columns: repeat(3, 1fr); }
}
@media (max-width: 760px) {
  body[data-runmode="summary"] .kpis { grid-template-columns: repeat(2, 1fr); }
}

/* Summary reads like a document: if the hero + band + map exceed the
   viewport (laptop heights), the page scrolls instead of crushing the
   map to a sliver — the map keeps an executive-usable floor. */
body[data-runmode="summary"] .main { overflow-y: auto; }
body[data-runmode="summary"] .workspace { min-height: 360px; }

body[data-runmode="details"] .summary-hero { display: none; }
body[data-runmode="details"] .narrative-pane { display: none; }
body[data-runmode="details"] .kpi[data-kpi="diversity"] { display: none; }

/* -- gate modal: capped 3-row summary + register link -- */

.gate-more {
  display: block;
  margin: 6px 0 2px;
  font-size: 12px;
  color: var(--accent-ink);
  text-decoration: underline;
  text-underline-offset: 2px;
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  text-align: left;
  font-family: var(--font);
}

.gate-more:hover { color: var(--heading); }

/* -- Discover landing: top-5 ranked corridors + View all expander -- */

.viewall-row {
  display: flex;
  justify-content: center;
  margin-top: 8px;
}

/* ============================================================
   Gap-closure additions (auditor feasible items, exec light theme):
   interconnect chips + summary interconnect line (IDP-11 in the app),
   signal-freshness caption (VIS-01 visibility), diverse-path readiness
   (EXD-13 prototype slice). Muted/steel-blue info styling only — brand
   crimson stays reserved for identity (top bar, active nav, primary
   buttons, recommended route).
   ============================================================ */

/* Indicative interconnection chips on the Routes & ROW candidate rows —
   sig-chip family styling; basis rides the hover title. Chips WRAP
   (design-audit fix: nowrap chips set a 412px min-width on the Label
   column and pushed Status/Miles off-screen, clipping '· indicative'
   mid-word at the viewport edge). */
.ic-chips { margin-top: 3px; }

.ic-chip {
  display: inline-block;
  font-family: var(--mono);
  font-size: 9.5px;
  color: var(--muted);
  border: 1px solid var(--border);
  border-radius: 5px;
  padding: 0 5px;
  margin: 1px 3px 1px 0;
  vertical-align: baseline;
  white-space: normal;
  overflow-wrap: anywhere;
}

/* Endpoint interconnects are endpoint-derived — identical for every
   candidate of a run — so they render ONCE above the candidates table
   instead of six duplicate chips across the rows (design-audit fix). */
.ic-note {
  font-size: 11.5px;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  margin: 0 0 8px;
}
.ic-note .ic-chip { font-size: 10px; }

/* One muted line under the Vision output card: nearest carrier
   interconnects + regen/ILA spacing-rule count (indicative). */
.hero-interconnect {
  font-size: 12px;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px solid var(--border);
}

/* Corridors view-head freshness caption ("Signals verified as of …"). */
.signals-fresh {
  font-size: 11.5px;
  color: var(--muted);
  white-space: nowrap;
}

/* Per-signal verified date in the corridor drill-down rows. */
.sig-verified {
  font-size: 10.5px;
  color: var(--muted);
  margin-left: 4px;
  white-space: nowrap;
}

/* EXD-13 diverse-path readiness section (Diversity & Scoring tab). */
.dvp-count { font-size: 13px; color: var(--text-2); }

.dvp-num {
  font-size: 15px;
  font-weight: 600;
  color: var(--heading);
  font-variant-numeric: tabular-nums;
}

.dvp-paths {
  margin: 6px 0 0;
  padding-left: 18px;
  font-size: 12px;
  color: var(--text-2);
}

.dvp-paths li { margin-bottom: 4px; }

/* ============================================================
    — market-signal demand markers + corridor→study gesture.
   Palette discipline (executive light binding): crimson =
   brand identity (dc_campus demand anchors), steel blue = informational
   (power), slate = tertiary (policy). No dark surfaces; hairline
   borders; AA inks only for text.
   ============================================================ */

/* Layer toggle — a small white card control on both maps. */
.sig-toggle-ctl {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: var(--shadow);
}

.sig-toggle {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 10px;
  font-size: 12px;
  font-weight: 500;
  color: var(--text-2);
  cursor: pointer;
  user-select: none;
  white-space: nowrap;
}

.sig-toggle input {
  accent-color: var(--brand);
  margin: 0;
  cursor: pointer;
}

/* Cluster badge (low zoom / co-located signals): white disc, ring in the
   dominant kind's color, count in heading ink. */
.sig-cluster-icon { background: transparent; border: none; }

.sig-cluster {
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.93);
  border: 2.5px solid var(--brand);
  color: var(--heading);
  font-weight: 600;
  font-size: 11.5px;
  text-align: center;
  box-shadow: var(--shadow);
}

.sig-cluster.power { border-color: var(--accent); }
.sig-cluster.policy { border-color: var(--slate-bright); }

/* Signal popup: kind kicker, magnitude line, quote snippet, source link. */
.sig-pop { font-size: 13px; line-height: 1.45; max-width: 300px; }

.sig-pop-kind {
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.sig-pop-kind.dc { color: var(--brand); }
.sig-pop-kind.power { color: var(--accent-ink); }
.sig-pop-kind.policy { color: var(--slate-bright); }

.sig-pop b { color: var(--heading); }

.sig-pop-mag { color: var(--text-2); margin: 2px 0; }

.sig-pop-quote {
  color: var(--muted);
  font-style: italic;
  border-left: 2px solid var(--border);
  padding-left: 8px;
  margin: 6px 0;
}

.sig-pop-src { font-size: 12px; margin-top: 4px; }
.sig-pop-src a { color: var(--accent-ink); }

.sig-pop-list {
  margin: 6px 0 0;
  padding-left: 2px;
  list-style: none;
}

.sig-pop-list li { margin-bottom: 6px; }
.sig-pop-list a { color: var(--accent-ink); }

/* Legend swatches for the three signal kinds (corridor map card). */
.sig-sw {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  display: inline-block;
  border: 2px solid var(--brand);
  background: rgba(178, 15, 49, 0.1);
  margin-right: 2px;
  vertical-align: -1px;
}

.sig-sw.power { border-color: var(--accent); background: rgba(15, 158, 213, 0.18); }
.sig-sw.policy { border-color: var(--slate-bright); background: rgba(122, 139, 156, 0.15); }

.sig-legend-note { color: var(--muted); font-size: 11px; }

/* Corridor-line popup (map gesture into the wizard). */
.cor-pop { font-size: 13px; }
.cor-pop b { color: var(--heading); }
.cor-pop-actions { margin-top: 8px; }

/* Drill-panel action pair (Open project + Study this corridor). */
.drill-actions {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  justify-content: flex-end;
}

/* Wizard prefill provenance note (corridor→study gesture). */
.wiz-prefill-note {
  font-size: 12px;
  color: var(--text-2);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-left: 3px solid var(--brand);
  border-radius: 6px;
  padding: 7px 10px;
  margin-bottom: 8px;
}

/* KirkwoodGPT pre-run hint: transient pointer under the topbar (replaces
   the old greyed-out launcher, which read as broken). */
.gpt-hint {
  position: fixed; top: 64px; right: 24px; z-index: 260;
  max-width: 340px; background: #FFFFFF; color: #0B1B2B;
  border: 1px solid #D9E0E7; border-left: 3px solid #B20F31;
  border-radius: 8px; padding: 10px 14px; font-size: 13px; line-height: 1.5;
  box-shadow: 0 4px 16px rgba(11, 27, 43, 0.12);
  opacity: 0; pointer-events: none; transition: opacity 250ms ease;
}
.gpt-hint.show { opacity: 1; }
@keyframes pulseAttn { 0%,100% { box-shadow: 0 0 0 0 rgba(178,15,49,.45); }
  50% { box-shadow: 0 0 0 7px rgba(178,15,49,0); } }
.pulse-attn { animation: pulseAttn 1.1s ease-in-out 4; }
@media (prefers-reduced-motion: reduce) { .pulse-attn { animation: none; } }
